/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.finalizers;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.java.symboltable.MethodScope;
import net.sourceforge.pmd.lang.symboltable.ScopedNode;
public class AvoidCallingFinalizeRule extends AbstractJavaRule {
private Set<MethodScope> checked = new HashSet<>();
public Object visit(ASTCompilationUnit acu, Object ctx) {
checked.clear();
return super.visit(acu, ctx);
}
public Object visit(ASTName name, Object ctx) {
if (name.getImage() == null || !name.getImage().endsWith("finalize")) {
return ctx;
}
if (!checkForViolation(name)) {
return ctx;
}
addViolation(ctx, name);
return ctx;
}
public Object visit(ASTPrimaryPrefix pp, Object ctx) {
List<ASTPrimarySuffix> primarySuffixes = pp.jjtGetParent().findChildrenOfType(ASTPrimarySuffix.class);
ASTPrimarySuffix firstSuffix = null;
if (!primarySuffixes.isEmpty()) {
firstSuffix = primarySuffixes.get(0);
}
if (firstSuffix == null || firstSuffix.getImage() == null || !firstSuffix.getImage().endsWith("finalize")) {
return super.visit(pp, ctx);
}
if (!checkForViolation(pp)) {
return super.visit(pp, ctx);
}
addViolation(ctx, pp);
return super.visit(pp, ctx);
}
private boolean checkForViolation(ScopedNode node) {
MethodScope meth = node.getScope().getEnclosingScope(MethodScope.class);
if (meth != null && "finalize".equals(meth.getName())) {
return false;
}
if (meth != null && checked.contains(meth)) {
return false;
}
if (meth != null) {
checked.add(meth);
}
return true;
}
}