UnusedFormalParameterRule.java
01 /**
02  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03  */
04 package net.sourceforge.pmd.lang.java.rule.unusedcode;
05 
06 import java.util.List;
07 import java.util.Map;
08 
09 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()) {
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 && !((ASTClassOrInterfaceDeclarationparent).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 }