AvoidCallingFinalize: constructor false negative fix
This commit is contained in:
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user