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.ASTClassOrInterfaceDeclaration;
8   import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
9   import net.sourceforge.pmd.ast.ASTMethodDeclaration;
10  import net.sourceforge.pmd.ast.Node;
11  import net.sourceforge.pmd.ast.SimpleNode;
12  import net.sourceforge.pmd.symboltable.NameOccurrence;
13  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
14  
15  import java.util.List;
16  import java.util.Map;
17  
18  public class UnusedFormalParameterRule extends AbstractRule {
19  
20      public Object visit(ASTConstructorDeclaration node, Object data) {
21          check(node, data);
22          return data;
23      }
24  
25      public Object visit(ASTMethodDeclaration node, Object data) {
26          if (!node.isPrivate() && !hasProperty("checkall")) {
27              return data;
28          }
29          if (!node.isNative()) {
30              check(node, data);
31          }
32          return data;
33      }
34  
35      private void check(SimpleNode node, Object data) {
36          Node parent = node.jjtGetParent().jjtGetParent().jjtGetParent();
37          if (parent instanceof ASTClassOrInterfaceDeclaration && !((ASTClassOrInterfaceDeclaration) parent).isInterface()) {
38              Map<VariableNameDeclaration, List<NameOccurrence>> vars = node.getScope().getVariableDeclarations();
39              for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry: vars.entrySet()) {
40                  VariableNameDeclaration nameDecl = entry.getKey();
41                  if (actuallyUsed(nameDecl, entry.getValue())) {
42                      continue;
43                  }
44                  addViolation(data, node, new Object[]{node instanceof ASTMethodDeclaration ? "method" : "constructor", nameDecl.getImage()});
45              }
46          }
47      }
48  
49      private boolean actuallyUsed(VariableNameDeclaration nameDecl, List<NameOccurrence> usages) {
50          for (NameOccurrence occ: usages) {
51              if (occ.isOnLeftHandSide()) {
52                  if (nameDecl.isArray() && occ.getLocation().jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) {
53                      // array element access
54                      return true;
55                  }
56                  continue;
57              } else {
58                  return true;
59              }
60          }
61          return false;
62      }
63  
64  
65  }