Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 96 |  | Methods: | 4
| NCLOC: | 79 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
UnusedPrivateMethodRule.java | 95.5% | 97.5% | 100% | 97% |

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.ASTInitializer;
10 |  | import net.sourceforge.pmd.ast.ASTMethodDeclaration;
11 |  | import net.sourceforge.pmd.ast.ASTMethodDeclarator;
12 |  | import net.sourceforge.pmd.ast.AccessNode;
13 |  | import net.sourceforge.pmd.ast.SimpleNode;
14 |  | import net.sourceforge.pmd.symboltable.ClassScope;
15 |  | import net.sourceforge.pmd.symboltable.MethodNameDeclaration;
16 |  | import net.sourceforge.pmd.symboltable.NameOccurrence;
17 |  |
18 |  | import java.util.HashSet;
19 |  | import java.util.Iterator;
20 |  | import java.util.List;
21 |  | import java.util.Map;
22 |  | import java.util.Set;
23 |  |
24 |  | public class UnusedPrivateMethodRule extends AbstractRule {
25 |  |
26 |  |
27 | 19 | public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
28 | 19 | if (node.isInterface()) {
29 | 0 | return data;
30 |  | }
31 |  |
32 | 19 | Map methods = ((ClassScope) node.getScope()).getMethodDeclarations();
33 | 19 | for (Iterator i = findUnique(methods).iterator(); i.hasNext();) {
34 | 34 | MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
35 | 34 | List occs = (List) methods.get(mnd);
36 | 34 | if (!privateAndNotExcluded(mnd)) {
37 | 17 | continue;
38 |  | }
39 | 17 | if (occs.isEmpty()) {
40 | 3 | addViolation(data, mnd.getNode(), mnd.getImage() + mnd.getParameterDisplaySignature());
41 |  | } else {
42 | 14 | if (calledFromOutsideItself(occs, mnd)) {
43 | 1 | addViolation(data, mnd.getNode(), mnd.getImage() + mnd.getParameterDisplaySignature());
44 |  | }
45 |  |
46 |  | }
47 |  | }
48 | 19 | return data;
49 |  | }
50 |  |
51 | 19 | private Set findUnique(Map methods) {
52 |  | // some rather hideous hackery here
53 |  | // to work around the fact that PMD does not yet do full type analysis
54 |  | // when it does, delete this
55 | 19 | Set unique = new HashSet();
56 | 19 | Set sigs = new HashSet();
57 | 19 | for (Iterator i = methods.keySet().iterator(); i.hasNext();) {
58 | 36 | MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
59 | 36 | String sig = mnd.getImage() + mnd.getParameterCount();
60 | 36 | if (!sigs.contains(sig)) {
61 | 34 | unique.add(mnd);
62 |  | }
63 | 36 | sigs.add(sig);
64 |  | }
65 | 19 | return unique;
66 |  | }
67 |  |
68 | 14 | private boolean calledFromOutsideItself(List occs, MethodNameDeclaration mnd) {
69 | 14 | int callsFromOutsideMethod = 0;
70 | 14 | for (Iterator i = occs.iterator(); i.hasNext();) {
71 | 14 | NameOccurrence occ = (NameOccurrence) i.next();
72 | 14 | SimpleNode occNode = occ.getLocation();
73 | 14 | ASTConstructorDeclaration enclosingConstructor = (ASTConstructorDeclaration) occNode.getFirstParentOfType(ASTConstructorDeclaration.class);
74 | 14 | if (enclosingConstructor != null) {
75 | 1 | callsFromOutsideMethod++;
76 | 1 | break; // Do we miss unused private constructors here?
77 |  | }
78 | 13 | ASTInitializer enclosingInitializer = (ASTInitializer) occNode.getFirstParentOfType(ASTInitializer.class);
79 | 13 | if (enclosingInitializer != null) {
80 | 1 | callsFromOutsideMethod++;
81 | 1 | break;
82 |  | }
83 |  |
84 | 12 | ASTMethodDeclaration enclosingMethod = (ASTMethodDeclaration) occNode.getFirstParentOfType(ASTMethodDeclaration.class);
85 | 12 | if ((enclosingMethod == null) || (enclosingMethod != null && !mnd.getNode().jjtGetParent().equals(enclosingMethod))) {
86 | 11 | callsFromOutsideMethod++;
87 |  | }
88 |  | }
89 | 14 | return callsFromOutsideMethod == 0;
90 |  | }
91 |  |
92 | 34 | private boolean privateAndNotExcluded(MethodNameDeclaration mnd) {
93 | 34 | ASTMethodDeclarator node = (ASTMethodDeclarator) mnd.getNode();
94 | 34 | return ((AccessNode) node.jjtGetParent()).isPrivate() && !node.hasImageEqualTo("readObject") && !node.hasImageEqualTo("writeObject") && !node.hasImageEqualTo("readResolve") && !node.hasImageEqualTo("writeReplace");
95 |  | }
96 |  | }