View Javadoc

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                  // TODO this misses some cases
41                  // need to add DFAish code to determine if an array
42                  // is initialized locally or gotten from somewhere else
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  }