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
54 return true;
55 }
56 continue;
57 } else {
58 return true;
59 }
60 }
61 return false;
62 }
63
64
65 }