AvoidCallingFinalize: constructor false negative fix

This commit is contained in:
Mykhailo Palahuta
2020-07-16 19:21:22 +03:00
parent 2eedff056c
commit 9bbb6aab4d
2 changed files with 31 additions and 41 deletions

View File

@ -4,11 +4,9 @@
package net.sourceforge.pmd.lang.java.rule.errorprone;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import net.sourceforge.pmd.lang.java.ast.ASTBlock;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
@ -21,57 +19,31 @@ public class AvoidCallingFinalizeRule extends AbstractJavaRule {
private static final Pattern FINALIZE_METHOD_PATTERN = Pattern.compile("^(.+\\.)?finalize$");
@Override
public Object visit(ASTBlock block, Object data) {
List<ASTPrimaryExpression> finalizeMethodCalls = getIncorrectFinalizeMethodCalls(block);
for (ASTPrimaryExpression finalizeMethodCall : finalizeMethodCalls) {
addViolation(data, finalizeMethodCall);
public Object visit(ASTPrimaryExpression primaryExpression, Object data) {
if (isIncorrectFinalizeMethodCall(primaryExpression)) {
addViolation(data, primaryExpression);
}
return data;
}
private List<ASTPrimaryExpression> getIncorrectFinalizeMethodCalls(ASTBlock block) {
if (isFinalizeMethodBlock(block)) {
return getNotSuperFinalizeMethodCalls(block);
}
return getFinalizeMethodCalls(block);
private boolean isIncorrectFinalizeMethodCall(ASTPrimaryExpression primaryExpression) {
return isFinalizeMethodCall(primaryExpression)
&& (isNotInFinalizeMethod(primaryExpression) || isNotSuperMethodCall(primaryExpression));
}
private boolean isFinalizeMethodBlock(ASTBlock block) {
ASTMethodDeclaration methodDeclaration = block.getFirstParentOfType(ASTMethodDeclaration.class);
return methodDeclaration != null && isFinalizeMethodDeclaration(methodDeclaration);
private boolean isNotInFinalizeMethod(ASTPrimaryExpression primaryExpression) {
ASTMethodDeclaration methodDeclaration = primaryExpression.getFirstParentOfType(ASTMethodDeclaration.class);
return methodDeclaration == null || isNotFinalizeMethodDeclaration(methodDeclaration);
}
private boolean isNotFinalizeMethodDeclaration(ASTMethodDeclaration methodDeclaration) {
return !isFinalizeMethodDeclaration(methodDeclaration);
}
private boolean isFinalizeMethodDeclaration(ASTMethodDeclaration methodDeclaration) {
return "finalize".equals(methodDeclaration.getName()) && methodDeclaration.getArity() == 0;
}
private List<ASTPrimaryExpression> getNotSuperFinalizeMethodCalls(ASTBlock block) {
List<ASTPrimaryExpression> finalizeMethodCalls = getFinalizeMethodCalls(block);
List<ASTPrimaryExpression> notSuperCalls = new ArrayList<>();
for (ASTPrimaryExpression finalizeMethodCall : finalizeMethodCalls) {
if (isNotSuperMethodCall(finalizeMethodCall)) {
notSuperCalls.add(finalizeMethodCall);
}
}
return notSuperCalls;
}
private boolean isNotSuperMethodCall(ASTPrimaryExpression primaryExpression) {
ASTPrimaryPrefix primaryPrefix = primaryExpression.getFirstChildOfType(ASTPrimaryPrefix.class);
return primaryPrefix == null || !primaryPrefix.usesSuperModifier();
}
private List<ASTPrimaryExpression> getFinalizeMethodCalls(ASTBlock block) {
List<ASTPrimaryExpression> primaryExpressions = block.findDescendantsOfType(ASTPrimaryExpression.class);
List<ASTPrimaryExpression> finalizeMethodCalls = new ArrayList<>();
for (ASTPrimaryExpression primaryExpression : primaryExpressions) {
if (isFinalizeMethodCall(primaryExpression)) {
finalizeMethodCalls.add(primaryExpression);
}
}
return finalizeMethodCalls;
}
private boolean isFinalizeMethodCall(ASTPrimaryExpression primaryExpression) {
return hasFinalizeName(primaryExpression) && getArgsCount(primaryExpression) == 0;
}
@ -98,4 +70,9 @@ public class AvoidCallingFinalizeRule extends AbstractJavaRule {
}
return -1;
}
private boolean isNotSuperMethodCall(ASTPrimaryExpression primaryExpression) {
ASTPrimaryPrefix primaryPrefix = primaryExpression.getFirstChildOfType(ASTPrimaryPrefix.class);
return primaryPrefix == null || !primaryPrefix.usesSuperModifier();
}
}

View File

@ -117,6 +117,19 @@ public class Foo {
finalize++;
return finalize;
}
}
]]></code>
</test-code>
<test-code>
<description>super.finalize in constructor false-negative test</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public Foo() throws Throwable {
super.equals(new String());
super.finalize();
}
}
]]></code>
</test-code>