Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 139 |  | Methods: | 4
| NCLOC: | 110 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
UselessOverridingMethod.java | 82.5% | 89.1% | 100% | 87% |

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.ASTArgumentList;
8 |  | import net.sourceforge.pmd.ast.ASTArguments;
9 |  | import net.sourceforge.pmd.ast.ASTBlock;
10 |  | import net.sourceforge.pmd.ast.ASTClassOrInterfaceBodyDeclaration;
11 |  | import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
12 |  | import net.sourceforge.pmd.ast.ASTFormalParameter;
13 |  | import net.sourceforge.pmd.ast.ASTFormalParameters;
14 |  | import net.sourceforge.pmd.ast.ASTMethodDeclaration;
15 |  | import net.sourceforge.pmd.ast.ASTMethodDeclarator;
16 |  | import net.sourceforge.pmd.ast.ASTName;
17 |  | import net.sourceforge.pmd.ast.ASTPrimaryExpression;
18 |  | import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
19 |  | import net.sourceforge.pmd.ast.ASTPrimarySuffix;
20 |  | import net.sourceforge.pmd.ast.ASTStatement;
21 |  | import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
22 |  | import net.sourceforge.pmd.ast.Node;
23 |  | import net.sourceforge.pmd.ast.SimpleNode;
24 |  |
25 |  | import java.util.ArrayList;
26 |  | import java.util.List;
27 |  |
28 |  | public class UselessOverridingMethod extends AbstractRule {
29 |  |
30 | 13 | public Object visit(ASTClassOrInterfaceDeclaration clz, Object data) {
31 | 13 | if (clz.isInterface()) {
32 | 1 | return data;
33 |  | }
34 | 12 | return super.visit(clz, data);
35 |  | }
36 |  |
37 | 12 | public Object visit(ASTMethodDeclaration node, Object data) {
38 |  | // Can skip abstract methods and methods whose only purpose is to
39 |  | // guarantee that the inherited method is not changed by finalizing
40 |  | // them.
41 | 12 | if (node.isAbstract() || node.isFinal() || node.isNative()) {
42 | 1 | return super.visit(node, data);
43 |  | }
44 |  |
45 | 11 | ASTBlock block = node.getBlock();
46 |  | //Only process functions with one BlockStatement
47 | 11 | if (block.jjtGetNumChildren() != 1 || block.findChildrenOfType(ASTStatement.class).size() != 1)
48 | 0 | return super.visit(node, data);
49 |  |
50 | 11 | ASTStatement statement = (ASTStatement) block.jjtGetChild(0).jjtGetChild(0);
51 | 11 | if (statement.jjtGetChild(0).jjtGetNumChildren() == 0) {
52 | 1 | return data; // skips empty return statements
53 |  | }
54 | 10 | SimpleNode statementGrandChild = (SimpleNode) statement.jjtGetChild(0).jjtGetChild(0);
55 | 10 | ASTPrimaryExpression primaryExpression;
56 |  |
57 | 10 | if (statementGrandChild instanceof ASTPrimaryExpression)
58 | 7 | primaryExpression = (ASTPrimaryExpression) statementGrandChild;
59 |  | else {
60 | 3 | List primaryExpressions = findFirstDegreeChildrenOfType(statementGrandChild, ASTPrimaryExpression.class);
61 | 3 | if (primaryExpressions.size() != 1)
62 | 1 | return super.visit(node, data);
63 | 2 | primaryExpression = (ASTPrimaryExpression) primaryExpressions.get(0);
64 |  | }
65 |  |
66 | 9 | ASTPrimaryPrefix primaryPrefix = (ASTPrimaryPrefix) findFirstDegreeChildrenOfType(primaryExpression, ASTPrimaryPrefix.class).get(0);
67 | 9 | if (!primaryPrefix.usesSuperModifier())
68 | 0 | return super.visit(node, data);
69 |  |
70 | 9 | ASTMethodDeclarator methodDeclarator = (ASTMethodDeclarator) findFirstDegreeChildrenOfType(node, ASTMethodDeclarator.class).get(0);
71 | 9 | if (!primaryPrefix.getImage().equals(methodDeclarator.getImage()))
72 | 0 | return super.visit(node, data);
73 |  |
74 |  | //Process arguments
75 | 9 | ASTPrimarySuffix primarySuffix = (ASTPrimarySuffix) findFirstDegreeChildrenOfType(primaryExpression, ASTPrimarySuffix.class).get(0);
76 | 9 | ASTArguments arguments = (ASTArguments) primarySuffix.jjtGetChild(0);
77 | 9 | ASTFormalParameters formalParameters = (ASTFormalParameters) methodDeclarator.jjtGetChild(0);
78 | 9 | if (formalParameters.jjtGetNumChildren() != arguments.jjtGetNumChildren())
79 | 1 | return super.visit(node, data);
80 |  |
81 | 8 | if (arguments.jjtGetNumChildren() == 0) //No arguments to check
82 | 2 | addViolation(data, node, getMessage());
83 |  | else {
84 | 6 | ASTArgumentList argumentList = (ASTArgumentList) arguments.jjtGetChild(0);
85 | 6 | for (int i = 0; i < argumentList.jjtGetNumChildren(); i++) {
86 | 7 | Node ExpressionChild = argumentList.jjtGetChild(i).jjtGetChild(0);
87 | 7 | if (!(ExpressionChild instanceof ASTPrimaryExpression) || ExpressionChild.jjtGetNumChildren() != 1)
88 | 2 | return super.visit(node, data); //The arguments are not simply passed through
89 |  |
90 | 5 | ASTPrimaryExpression argumentPrimaryExpression = (ASTPrimaryExpression) ExpressionChild;
91 | 5 | ASTPrimaryPrefix argumentPrimaryPrefix = (ASTPrimaryPrefix) argumentPrimaryExpression.jjtGetChild(0);
92 | 5 | Node argumentPrimaryPrefixChild = argumentPrimaryPrefix.jjtGetChild(0);
93 | 5 | if (!(argumentPrimaryPrefixChild instanceof ASTName))
94 | 0 | return super.visit(node, data); //The arguments are not simply passed through
95 |  |
96 | 5 | if (formalParameters.jjtGetNumChildren() < i + 1) {
97 | 1 | return super.visit(node, data); // different number of args
98 |  | }
99 |  |
100 | 4 | ASTName argumentName = (ASTName) argumentPrimaryPrefixChild;
101 | 4 | ASTFormalParameter formalParameter = (ASTFormalParameter) formalParameters.jjtGetChild(i);
102 | 4 | ASTVariableDeclaratorId variableId = (ASTVariableDeclaratorId) findFirstDegreeChildrenOfType(formalParameter, ASTVariableDeclaratorId.class).get(0);
103 | 4 | if (!argumentName.getImage().equals(variableId.getImage())) {
104 | 1 | return super.visit(node, data); //The arguments are not simply passed through
105 |  | }
106 |  |
107 |  | }
108 | 2 | addViolation(data, node, getMessage()); //All arguments are passed through directly
109 |  | }
110 | 4 | return super.visit(node, data);
111 |  | }
112 |  |
113 | 34 | public List findFirstDegreeChildrenOfType(SimpleNode n, Class targetType) {
114 | 34 | List l = new ArrayList();
115 | 34 | lclFindChildrenOfType(n, targetType, l);
116 | 34 | return l;
117 |  | }
118 |  |
119 | 34 | private void lclFindChildrenOfType(Node node, Class targetType, List results) {
120 | 34 | if (node.getClass().equals(targetType)) {
121 | 0 | results.add(node);
122 |  | }
123 |  |
124 | 34 | if (node instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node).isNested()) {
125 | 0 | return;
126 |  | }
127 |  |
128 | 34 | if (node instanceof ASTClassOrInterfaceBodyDeclaration && ((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
129 | 0 | return;
130 |  | }
131 |  |
132 | 34 | for (int i = 0; i < node.jjtGetNumChildren(); i++) {
133 | 74 | Node child = node.jjtGetChild(i);
134 | 74 | if (child.getClass().equals(targetType)) {
135 | 33 | results.add(child);
136 |  | }
137 |  | }
138 |  | }
139 |  | }