Fixed bug reported by Paul Rowe; UnusedLocal was return duplicate entries. Fixed by ensuring that the same scope was not checked twice. Hm. Will this also result in some missed hits?

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@2817 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Tom Copeland
2004-07-20 15:13:10 +00:00
parent 7b5b1f2aa9
commit 26fa9de45b
2 changed files with 30 additions and 5 deletions

View File

@ -35,6 +35,7 @@ public class UnusedLocalVariableTest extends SimpleAggregatorTst {
new TestDescriptor(TEST14, "an assignment does not a usage make", 1, rule),
new TestDescriptor(TEST15, "a compound assignment operator doth a usage make", 0, rule),
new TestDescriptor(TEST16, "assignment to a member field means used", 0, rule),
new TestDescriptor(TEST17, "make sure scopes are working", 3, rule),
});
}
@ -178,4 +179,12 @@ public class UnusedLocalVariableTest extends SimpleAggregatorTst {
" b.buz = 2;" + PMD.EOL +
" }" + PMD.EOL +
"}";
private static final String TEST17 =
"public class Foo {" + PMD.EOL +
" void bar() {" + PMD.EOL +
" int x = 2;" + PMD.EOL +
" if (true) {int y =2;int j =3;} " + PMD.EOL +
" }" + PMD.EOL +
"}";
}

View File

@ -5,10 +5,13 @@ package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.ast.ASTCompilationUnit;
import net.sourceforge.pmd.symboltable.NameOccurrence;
import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
import net.sourceforge.pmd.symboltable.Scope;
import java.text.MessageFormat;
import java.util.HashSet;
@ -21,14 +24,27 @@ public class UnusedLocalVariableRule extends AbstractRule {
private Set visited = new HashSet();
public Object visit(ASTCompilationUnit acu, Object data) {
visited.clear();
return super.visit(acu, data);
}
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (node.jjtGetParent().jjtGetParent() instanceof ASTLocalVariableDeclaration && !visited.contains(node.jjtGetParent().jjtGetParent())) {
visited.add(node.jjtGetParent().jjtGetParent());
Map locals = node.getScope().getVariableDeclarations();
if (node.jjtGetParent().jjtGetParent() instanceof ASTLocalVariableDeclaration) {
Scope scope = node.getScope();
if (visited.contains(scope)) {
return data;
} else {
visited.add(scope);
}
Map locals = scope.getVariableDeclarations();
for (Iterator i = locals.keySet().iterator(); i.hasNext();) {
VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
if (!actuallyUsed((List)locals.get(decl))) {
((RuleContext) data).getReport().addRuleViolation(createRuleViolation((RuleContext) data, decl.getLine(), MessageFormat.format(getMessage(), new Object[]{decl.getImage()})));
List usages = (List)locals.get(decl);
if (!actuallyUsed(usages)) {
RuleContext ctx = ((RuleContext) data);
RuleViolation ruleViolation = createRuleViolation(ctx, decl.getLine(), MessageFormat.format(getMessage(), new Object[]{decl.getImage()}));
ctx.getReport().addRuleViolation(ruleViolation);
}
}
}