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