View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule.unusedcode;
5   
6   import java.util.List;
7   import java.util.Map;
8   
9   import net.sourceforge.pmd.lang.ast.Node;
10  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
11  import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
12  import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
13  import net.sourceforge.pmd.lang.java.ast.JavaNode;
14  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
15  import net.sourceforge.pmd.lang.java.symboltable.NameOccurrence;
16  import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
17  import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
18  
19  public class UnusedFormalParameterRule extends AbstractJavaRule {
20      
21      private static final BooleanProperty CHECKALL_DESCRIPTOR = new BooleanProperty("checkAll", "Check all methods, including non-private ones", false, 1.0f);
22      
23      public UnusedFormalParameterRule() {
24  	definePropertyDescriptor(CHECKALL_DESCRIPTOR);
25      }
26  
27      public Object visit(ASTConstructorDeclaration node, Object data) {
28          check(node, data);
29          return data;
30      }
31  
32      public Object visit(ASTMethodDeclaration node, Object data) {
33          if (!node.isPrivate() && !getProperty(CHECKALL_DESCRIPTOR)) {
34              return data;
35          }
36          if (!node.isNative() && !node.isAbstract()) {
37              check(node, data);
38          }
39          return data;
40      }
41  
42      private void check(Node node, Object data) {
43          Node parent = node.jjtGetParent().jjtGetParent().jjtGetParent();
44          if (parent instanceof ASTClassOrInterfaceDeclaration && !((ASTClassOrInterfaceDeclaration) parent).isInterface()) {
45              Map<VariableNameDeclaration, List<NameOccurrence>> vars = ((JavaNode)node).getScope().getVariableDeclarations();
46              for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry: vars.entrySet()) {
47                  VariableNameDeclaration nameDecl = entry.getKey();
48                  if (actuallyUsed(nameDecl, entry.getValue())) {
49                      continue;
50                  }
51                  addViolation(data, nameDecl.getNode(), new Object[]{node instanceof ASTMethodDeclaration ? "method" : "constructor", nameDecl.getImage()});
52              }
53          }
54      }
55  
56      private boolean actuallyUsed(VariableNameDeclaration nameDecl, List<NameOccurrence> usages) {
57          for (NameOccurrence occ: usages) {
58              if (occ.isOnLeftHandSide()) {
59                  if (nameDecl.isArray() && occ.getLocation().jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) {
60                      // array element access
61                      return true;
62                  }
63                  continue;
64              } else {
65                  return true;
66              }
67          }
68          return false;
69      }
70  
71  
72  }