1 /***
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd.rules;
5
6 import net.sourceforge.pmd.AbstractRule;
7 import net.sourceforge.pmd.RuleContext;
8 import net.sourceforge.pmd.RuleViolation;
9 import net.sourceforge.pmd.ast.ASTCompilationUnit;
10 import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
11 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
12 import net.sourceforge.pmd.symboltable.NameOccurrence;
13 import net.sourceforge.pmd.symboltable.Scope;
14 import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
15
16 import java.text.MessageFormat;
17 import java.util.HashSet;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22
23 public class UnusedLocalVariableRule extends AbstractRule {
24
25 private Set visited = new HashSet();
26
27 public Object visit(ASTCompilationUnit acu, Object data) {
28 visited.clear();
29 return super.visit(acu, data);
30 }
31
32 public Object visit(ASTVariableDeclaratorId node, Object data) {
33 if (node.jjtGetParent().jjtGetParent() instanceof ASTLocalVariableDeclaration) {
34 Scope scope = node.getScope();
35 if (visited.contains(scope)) {
36 return data;
37 } else {
38 visited.add(scope);
39 }
40 Map locals = scope.getVariableDeclarations();
41 for (Iterator i = locals.keySet().iterator(); i.hasNext();) {
42 VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
43
44
45
46 if (decl.isArray()) {
47 continue;
48 }
49 List usages = (List) locals.get(decl);
50 if (!actuallyUsed(usages)) {
51 RuleContext ctx = ((RuleContext) data);
52 RuleViolation ruleViolation = createRuleViolation(ctx, decl, MessageFormat.format(getMessage(), new Object[]{decl.getImage()}));
53 ctx.getReport().addRuleViolation(ruleViolation);
54 }
55 }
56 }
57 return data;
58 }
59
60 private boolean actuallyUsed(List usages) {
61 for (Iterator j = usages.iterator(); j.hasNext();) {
62 NameOccurrence occ = (NameOccurrence) j.next();
63 if (occ.isOnLeftHandSide()) {
64 continue;
65 } else {
66 return true;
67 }
68 }
69 return false;
70 }
71 }