1 |
| |
2 |
| |
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.ASTMethodDeclarator; |
11 |
| import net.sourceforge.pmd.ast.AccessNode; |
12 |
| import net.sourceforge.pmd.ast.SimpleNode; |
13 |
| import net.sourceforge.pmd.symboltable.ClassScope; |
14 |
| import net.sourceforge.pmd.symboltable.MethodNameDeclaration; |
15 |
| import net.sourceforge.pmd.symboltable.NameOccurrence; |
16 |
| |
17 |
| import java.util.Iterator; |
18 |
| import java.util.List; |
19 |
| import java.util.Map; |
20 |
| |
21 |
| public class UnusedPrivateMethodRule extends AbstractRule { |
22 |
| |
23 |
13
| public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
|
24 |
13
| if (node.isInterface()) {
|
25 |
0
| return data;
|
26 |
| } |
27 |
| |
28 |
13
| Map methods = ((ClassScope)node.getScope()).getMethodDeclarations();
|
29 |
13
| for (Iterator i = methods.keySet().iterator(); i.hasNext();) {
|
30 |
24
| MethodNameDeclaration mnd = (MethodNameDeclaration)i.next();
|
31 |
24
| List occs = (List)methods.get(mnd);
|
32 |
24
| if (!privateAndNotExcluded(mnd)) {
|
33 |
12
| continue;
|
34 |
| } |
35 |
12
| if (occs.isEmpty()) {
|
36 |
3
| addViolation(data, mnd.getNode(), mnd.getImage() + mnd.getParameterDisplaySignature());
|
37 |
| } else { |
38 |
9
| if (calledFromOutsideItself(occs, mnd)) {
|
39 |
1
| addViolation(data, mnd.getNode(), mnd.getImage() + mnd.getParameterDisplaySignature());
|
40 |
| } |
41 |
| |
42 |
| } |
43 |
| } |
44 |
13
| return data;
|
45 |
| } |
46 |
| |
47 |
9
| private boolean calledFromOutsideItself(List occs, MethodNameDeclaration mnd) {
|
48 |
9
| int callsFromOutsideMethod = 0;
|
49 |
9
| for (Iterator i = occs.iterator(); i.hasNext();) {
|
50 |
9
| NameOccurrence occ = (NameOccurrence)i.next();
|
51 |
9
| SimpleNode occNode = occ.getLocation();
|
52 |
9
| ASTConstructorDeclaration enclosingConstructor = (ASTConstructorDeclaration)occNode.getFirstParentOfType(ASTConstructorDeclaration.class);
|
53 |
9
| if (enclosingConstructor != null) {
|
54 |
1
| callsFromOutsideMethod++;
|
55 |
1
| continue;
|
56 |
| } |
57 |
8
| ASTMethodDeclaration enclosingMethod = (ASTMethodDeclaration)occNode.getFirstParentOfType(ASTMethodDeclaration.class);
|
58 |
8
| if (enclosingMethod != null && !mnd.getNode().jjtGetParent().equals(enclosingMethod)) {
|
59 |
7
| callsFromOutsideMethod++;
|
60 |
| } |
61 |
| } |
62 |
9
| return callsFromOutsideMethod == 0;
|
63 |
| } |
64 |
| |
65 |
24
| private boolean privateAndNotExcluded(MethodNameDeclaration mnd) {
|
66 |
24
| ASTMethodDeclarator node = (ASTMethodDeclarator)mnd.getNode();
|
67 |
24
| return ((AccessNode) node.jjtGetParent()).isPrivate() && !node.getImage().equals("readObject") && !node.getImage().equals("writeObject") && !node.getImage().equals("readResolve") && !node.getImage().equals("writeReplace");
|
68 |
| } |
69 |
| } |