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.ast.ASTCompilationUnit;
8 import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
9 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
10 import net.sourceforge.pmd.symboltable.NameOccurrence;
11 import net.sourceforge.pmd.symboltable.Scope;
12 import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
13
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19
20 public class UnusedLocalVariableRule extends AbstractRule {
21
22 private Set visited = new HashSet();
23
24 public Object visit(ASTCompilationUnit acu, Object data) {
25 visited.clear();
26 return super.visit(acu, data);
27 }
28
29 public Object visit(ASTVariableDeclaratorId node, Object data) {
30 if (node.jjtGetParent().jjtGetParent() instanceof ASTLocalVariableDeclaration) {
31 Scope scope = node.getScope();
32 if (visited.contains(scope)) {
33 return data;
34 } else {
35 visited.add(scope);
36 }
37 Map locals = scope.getVariableDeclarations();
38 for (Iterator i = locals.keySet().iterator(); i.hasNext();) {
39 VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
40
41
42
43 if (decl.isArray()) {
44 continue;
45 }
46 List usages = (List) locals.get(decl);
47 if (!actuallyUsed(usages)) {
48 addViolation(data, decl.getNode(), decl.getImage());
49 }
50 }
51 }
52 return data;
53 }
54
55 private boolean actuallyUsed(List usages) {
56 for (Iterator j = usages.iterator(); j.hasNext();) {
57 NameOccurrence occ = (NameOccurrence) j.next();
58 if (occ.isOnLeftHandSide()) {
59 continue;
60 } else {
61 return true;
62 }
63 }
64 return false;
65 }
66 }