[java] Fix FN in UnnecessaryLocalBeforeReturn

- Fixes #1775
This commit is contained in:
Juan Martín Sotuyo Dodero
2019-04-16 14:04:46 -03:00
parent 0dd0ce1b06
commit 28c3752088
2 changed files with 24 additions and 3 deletions

View File

@ -24,7 +24,6 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
import net.sourceforge.pmd.lang.symboltable.Scope;
import net.sourceforge.pmd.lang.symboltable.ScopedNode;
import net.sourceforge.pmd.properties.PropertyDescriptor;
@ -115,6 +114,12 @@ public class UnnecessaryLocalBeforeReturnRule extends AbstractJavaRule {
final ASTReturnStatement rtn) {
final ASTVariableInitializer initializer = variableDeclaration.getAccessNodeParent()
.getFirstDescendantOfType(ASTVariableInitializer.class);
// Get the block statements for each, so we can compare apples to apples
final ASTBlockStatement initializerStmt = variableDeclaration.getAccessNodeParent()
.getFirstParentOfType(ASTBlockStatement.class);
final ASTBlockStatement rtnStmt = rtn.getFirstParentOfType(ASTBlockStatement.class);
if (initializer != null) {
final List<ASTName> referencedNames = initializer.findDescendantsOfType(ASTName.class);
for (final ASTName refName : referencedNames) {
@ -128,9 +133,10 @@ public class UnnecessaryLocalBeforeReturnRule extends AbstractJavaRule {
if (entry.getKey().getName().equals(refName.getImage())) {
// Variable found! Check usage locations
for (final NameOccurrence occ : entry.getValue()) {
final ScopedNode location = occ.getLocation();
final ASTBlockStatement location = occ.getLocation().getFirstParentOfType(ASTBlockStatement.class);
// Is it used after initializing our "unnecessary" local but before the return statement?
if (isAfter(location, initializer) && isAfter(rtn, location)) {
if (isAfter(location, initializerStmt) && isAfter(rtnStmt, location)) {
return true;
}
}

View File

@ -229,6 +229,21 @@ public class UnnecessaryLocalBeforeReturnFP {
sideEffect(m);
return i;
}
}
]]></code>
</test-code>
<test-code>
<description>#1775 [java] False negative in UnnecessaryLocalBeforeReturn when splitting statements across multiple lines</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class UnnecessaryLocalBeforeReturnFP {
public Object test2() {
int i = 0;
Object o = thing()
.make(i);
return o; // true positive
}
}
]]></code>
</test-code>