KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > rules > UselessOverridingMethod


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 JavaDoc;
26 import java.util.List JavaDoc;
27
28 public class UselessOverridingMethod extends AbstractRule {
29
30     public Object JavaDoc visit(ASTClassOrInterfaceDeclaration clz, Object JavaDoc data) {
31         if (clz.isInterface()) {
32             return data;
33         }
34         return super.visit(clz, data);
35     }
36
37     public Object JavaDoc visit(ASTMethodDeclaration node, Object JavaDoc 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
if (node.isAbstract() || node.isFinal() || node.isNative() || node.isSynchronized()) {
42             return super.visit(node, data);
43         }
44
45         ASTBlock block = node.getBlock();
46         if (block == null) {
47             return super.visit(node, data);
48         }
49         //Only process functions with one BlockStatement
50
if (block.jjtGetNumChildren() != 1 || block.findChildrenOfType(ASTStatement.class).size() != 1)
51             return super.visit(node, data);
52
53         ASTStatement statement = (ASTStatement) block.jjtGetChild(0).jjtGetChild(0);
54         if (statement.jjtGetChild(0).jjtGetNumChildren() == 0) {
55             return data; // skips empty return statements
56
}
57         SimpleNode statementGrandChild = (SimpleNode) statement.jjtGetChild(0).jjtGetChild(0);
58         ASTPrimaryExpression primaryExpression;
59
60         if (statementGrandChild instanceof ASTPrimaryExpression)
61             primaryExpression = (ASTPrimaryExpression) statementGrandChild;
62         else {
63             List primaryExpressions = findFirstDegreeChildrenOfType(statementGrandChild, ASTPrimaryExpression.class);
64             if (primaryExpressions.size() != 1)
65                 return super.visit(node, data);
66             primaryExpression = (ASTPrimaryExpression) primaryExpressions.get(0);
67         }
68
69         ASTPrimaryPrefix primaryPrefix = (ASTPrimaryPrefix) findFirstDegreeChildrenOfType(primaryExpression, ASTPrimaryPrefix.class).get(0);
70         if (!primaryPrefix.usesSuperModifier())
71             return super.visit(node, data);
72
73         ASTMethodDeclarator methodDeclarator = (ASTMethodDeclarator) findFirstDegreeChildrenOfType(node, ASTMethodDeclarator.class).get(0);
74         if (!primaryPrefix.hasImageEqualTo(methodDeclarator.getImage()))
75             return super.visit(node, data);
76
77         //Process arguments
78
ASTPrimarySuffix primarySuffix = (ASTPrimarySuffix) findFirstDegreeChildrenOfType(primaryExpression, ASTPrimarySuffix.class).get(0);
79         ASTArguments arguments = (ASTArguments) primarySuffix.jjtGetChild(0);
80         ASTFormalParameters formalParameters = (ASTFormalParameters) methodDeclarator.jjtGetChild(0);
81         if (formalParameters.jjtGetNumChildren() != arguments.jjtGetNumChildren())
82             return super.visit(node, data);
83
84         if (arguments.jjtGetNumChildren() == 0) //No arguments to check
85
addViolation(data, node, getMessage());
86         else {
87             ASTArgumentList argumentList = (ASTArgumentList) arguments.jjtGetChild(0);
88             for (int i = 0; i < argumentList.jjtGetNumChildren(); i++) {
89                 Node ExpressionChild = argumentList.jjtGetChild(i).jjtGetChild(0);
90                 if (!(ExpressionChild instanceof ASTPrimaryExpression) || ExpressionChild.jjtGetNumChildren() != 1)
91                     return super.visit(node, data); //The arguments are not simply passed through
92

93                 ASTPrimaryExpression argumentPrimaryExpression = (ASTPrimaryExpression) ExpressionChild;
94                 ASTPrimaryPrefix argumentPrimaryPrefix = (ASTPrimaryPrefix) argumentPrimaryExpression.jjtGetChild(0);
95                 if (argumentPrimaryPrefix.jjtGetNumChildren() == 0) {
96                     return super.visit(node, data); //The arguments are not simply passed through (using "this" for instance)
97
}
98                 Node argumentPrimaryPrefixChild = argumentPrimaryPrefix.jjtGetChild(0);
99                 if (!(argumentPrimaryPrefixChild instanceof ASTName))
100                     return super.visit(node, data); //The arguments are not simply passed through
101

102                 if (formalParameters.jjtGetNumChildren() < i + 1) {
103                     return super.visit(node, data); // different number of args
104
}
105
106                 ASTName argumentName = (ASTName) argumentPrimaryPrefixChild;
107                 ASTFormalParameter formalParameter = (ASTFormalParameter) formalParameters.jjtGetChild(i);
108                 ASTVariableDeclaratorId variableId = (ASTVariableDeclaratorId) findFirstDegreeChildrenOfType(formalParameter, ASTVariableDeclaratorId.class).get(0);
109                 if (!argumentName.hasImageEqualTo(variableId.getImage())) {
110                     return super.visit(node, data); //The arguments are not simply passed through
111
}
112
113             }
114             addViolation(data, node, getMessage()); //All arguments are passed through directly
115
}
116         return super.visit(node, data);
117     }
118
119     public List findFirstDegreeChildrenOfType(SimpleNode n, Class JavaDoc targetType) {
120         List l = new ArrayList JavaDoc();
121         lclFindChildrenOfType(n, targetType, l);
122         return l;
123     }
124
125     private void lclFindChildrenOfType(Node node, Class JavaDoc targetType, List results) {
126         if (node.getClass().equals(targetType)) {
127             results.add(node);
128         }
129
130         if (node instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node).isNested()) {
131             return;
132         }
133
134         if (node instanceof ASTClassOrInterfaceBodyDeclaration && ((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
135             return;
136         }
137
138         for (int i = 0; i < node.jjtGetNumChildren(); i++) {
139             Node child = node.jjtGetChild(i);
140             if (child.getClass().equals(targetType)) {
141                 results.add(child);
142             }
143         }
144     }
145 }
146
Popular Tags