You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a field is changed at the end of a method and is not used again in that method, than PMD reports that the written value is unused. Even though the value is used in another method that is called later in the processing.
Code Sample demonstrating the issue:
See original code and suppression and checks result in:
/** * Handles the parsing of a translation file from Qt. */staticclassQtTranslationSaxParserextendsDefaultHandler {
privatestaticfinalStringCONTEXT = "context";
privatestaticfinalStringCONTEXT_NAME = "name";
privatestaticfinalStringMESSAGE = "message";
privatestaticfinalStringMESSAGE_NUMERUS_ATTRIBUTE = "numerus";
privatestaticfinalStringMESSAGE_NUMERUS_ENABLED_VALUE = "yes";
privatestaticfinalStringNUMERUSFORM = "numerusform";
privatestaticfinalStringROOT = "TS";
privatestaticfinalStringSOURCE = "source";
privatestaticfinalStringTRANSLATION = "translation";
privatestaticfinalStringTRANSLATION_ATTR_TYPE = "type";
// The locator will be initialized within setDocumentLocator, which will be called by SAXParser.@SuppressFBWarnings("NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
@SuppressWarnings("NullAway")
privateLocatordocumentLocator;
privatefinalReportreport;
privatefinalIssueBuilderbuilder = newIssueBuilder();
privatefinalDeque<String> elementTypeStack = newArrayDeque<>();
privatefinalMap<String, String> expectedElementTypeParents = newHashMap<>();
privateStringcontextName = "";
privateStringsourceValue = "";
privateStringtranslationType = "";
privatebooleanhasTranslatedString = false;
privatebooleantranslationTagFound = false;
privatebooleanmessageIsNumerus = false;
privateintlastColumnNumber;
/** * Creates a new instance of {@link QtTranslationSaxParser}. * * @param report * the issues * @param fileName * path to the translation file */QtTranslationSaxParser(finalReportreport, finalStringfileName) {
super();
expectedElementTypeParents.put(ROOT, null);
expectedElementTypeParents.put(CONTEXT, ROOT);
expectedElementTypeParents.put(CONTEXT_NAME, CONTEXT);
expectedElementTypeParents.put(MESSAGE, CONTEXT);
expectedElementTypeParents.put(NUMERUSFORM, TRANSLATION);
expectedElementTypeParents.put(TRANSLATION, MESSAGE);
expectedElementTypeParents.put(SOURCE, MESSAGE);
this.report = report;
builder.setFileName(fileName);
}
@OverridepublicvoidsetDocumentLocator(finalLocatorlocator) {
documentLocator = locator;
}
@OverridepublicvoidstartElement(finalStringnamespaceURI,
finalStringlocalName, finalStringkey, finalAttributesatts) {
verifyElementTypeRelation(key);
elementTypeStack.push(key);
switch (key) {
caseCONTEXT_NAME:
throwParsingExceptionBecauseOfDuplicatedOccurrence(!contextName.isEmpty(), key);
break;
caseSOURCE:
throwParsingExceptionBecauseOfDuplicatedOccurrence(!sourceValue.isEmpty(), key);
break;
caseTRANSLATION:
throwParsingExceptionBecauseOfDuplicatedOccurrence(translationTagFound, key);
translationTagFound = true;
translationType = atts.getValue(TRANSLATION_ATTR_TYPE);
if (translationType != null) {
applyTranslationType();
}
break;
caseMESSAGE:
builder.setLineStart(documentLocator.getLineNumber());
builder.setColumnStart(lastColumnNumber);
messageIsNumerus = MESSAGE_NUMERUS_ENABLED_VALUE.equals(atts.getValue(MESSAGE_NUMERUS_ATTRIBUTE));
break;
caseNUMERUSFORM:
if (!messageIsNumerus) {
thrownewParsingException(
"Element type \"%s\" is allowed only if the attribute \"%s\" within the parent element \"%s\" is set to \"%s\" (line %d).",
NUMERUSFORM,
MESSAGE_NUMERUS_ATTRIBUTE,
MESSAGE,
MESSAGE_NUMERUS_ENABLED_VALUE,
documentLocator.getLineNumber());
}
break;
default:
break;
}
lastColumnNumber = documentLocator.getColumnNumber();
}
@OverridepublicvoidendElement(finalStringuri, finalStringlocalName, finalStringqName) {
elementTypeStack.pop();
lastColumnNumber = documentLocator.getColumnNumber();
if (CONTEXT.equals(qName)) {
contextName = "";
return;
}
if (!MESSAGE.equals(qName)) {
return;
}
throwParsingExceptionBecauseOfMissingElementType(contextName.isEmpty(), CONTEXT_NAME);
throwParsingExceptionBecauseOfMissingElementType(sourceValue.isEmpty(), SOURCE);
throwParsingExceptionBecauseOfMissingElementType(!translationTagFound, TRANSLATION);
if (translationType != null) {
// In case the translation type is "unfinished" and we found a translation,// change the type to TRANSLATION_TYPE_UNFINISHED_NOT_EMPTY.// This case is not handled within {@link #applyTranslationType(String)}// because it is not an official state within a translation file of Qt.if (TRANSLATION_TYPE_UNFINISHED.equals(translationType) && hasTranslatedString) {
builder.setSeverity(Severity.WARNING_LOW);
builder.setMessage(TRANSLATION_TYPE_UNFINISHED_NOT_EMPTY_MESSAGE);
builder.setCategory(TRANSLATION_TYPE_UNFINISHED_NOT_EMPTY);
}
builder.setLineEnd(documentLocator.getLineNumber());
builder.setColumnEnd(documentLocator.getColumnNumber());
report.add(builder.build());
}
// prepare for next message blockhasTranslatedString = false;
translationTagFound = false;
sourceValue = "";
}
@Override@SuppressWarnings("PMD.UnusedAssignment") // false positive in PMD 7.0.0publicvoidcharacters(finalchar[] ch, finalintstart, finalintlength) {
lastColumnNumber = documentLocator.getColumnNumber();
if (CONTEXT_NAME.equals(elementTypeStack.getFirst())) {
contextName = newString(ch, start, length);
}
if (SOURCE.equals(elementTypeStack.getFirst())) {
sourceValue = newString(ch, start, length);
}
if (TRANSLATION.equals(elementTypeStack.getFirst())) {
// In case the message is numerus, the decision is made by a separate element.// Keep the value to true if it is already set.hasTranslatedString |= !messageIsNumerus;
}
if (NUMERUSFORM.equals(elementTypeStack.getFirst())) {
hasTranslatedString = true;
}
}
privatevoidverifyElementTypeRelation(finalStringelement) {
Stringparent = expectedElementTypeParents.getOrDefault(element, "");
if (parent == null) {
if (!elementTypeStack.isEmpty()) {
thrownewParsingException("Element type \"%s\" does not expect to be a root element (line %d).",
element,
documentLocator.getLineNumber());
}
return;
}
if (!parent.isEmpty() && !elementTypeStack.getFirst().equals(parent)) {
thrownewParsingException(
"Element type \"%s\" expects to be a child element of element type \"%s\" (line %d).",
element,
parent,
documentLocator.getLineNumber());
}
}
@SuppressWarnings("NullAway")
privatevoidthrowParsingExceptionBecauseOfDuplicatedOccurrence(finalbooleanshouldThrow,
finalStringelement) {
if (shouldThrow) {
thrownewParsingException(
"Element type \"%s\" can be used only once within element type \"%s\" (line %d).",
element,
expectedElementTypeParents.get(element),
documentLocator.getLineNumber());
}
}
@SuppressWarnings("NullAway")
privatevoidthrowParsingExceptionBecauseOfMissingElementType(finalbooleanshouldThrow, finalStringelement) {
if (shouldThrow) {
thrownewParsingException(
"Missing or empty element type \"%s\" within element type \"%s\" (line %d).",
element,
expectedElementTypeParents.get(element),
documentLocator.getLineNumber());
}
}
privatevoidapplyTranslationType() {
switch (translationType) {
caseTRANSLATION_TYPE_OBSOLETE:
builder.setSeverity(Severity.WARNING_NORMAL);
builder.setMessage(TRANSLATION_TYPE_OBSOLETE_MESSAGE);
break;
caseTRANSLATION_TYPE_UNFINISHED:
builder.setSeverity(Severity.WARNING_LOW);
builder.setMessage(TRANSLATION_TYPE_UNFINISHED_MESSAGE);
break;
caseTRANSLATION_TYPE_VANISHED:
builder.setSeverity(Severity.WARNING_NORMAL);
builder.setMessage(TRANSLATION_TYPE_VANISHED_MESSAGE);
break;
default:
thrownewParsingException("Unknown translation state \"%s\" (line %d).",
translationType,
documentLocator.getLineNumber());
}
builder.setCategory(translationType);
}
@OverridepublicvoidendDocument() throwsSAXException {
builder.close();
}
}
Expected outcome:
PMD reports a violation at line ..., but that's wrong. That's a false positive.
PMD 6.x did not report a violation.
Running PMD through:[Maven]
The text was updated successfully, but these errors were encountered:
Affects PMD Version:
7.0.0
Rule:
UnusedAssignment
Please provide the rule name and a link to the rule documentation:
(https://pmd.github.io/pmd/pmd_rules_java_bestpractices.html#unusedassignment)
Description:
When a field is changed at the end of a method and is not used again in that method, than PMD reports that the written value is unused. Even though the value is used in another method that is called later in the processing.
Code Sample demonstrating the issue:
See original code and suppression and checks result in:
Expected outcome:
PMD reports a violation at line ..., but that's wrong. That's a false positive.
PMD 6.x did not report a violation.
Running PMD through: [Maven]
The text was updated successfully, but these errors were encountered: