Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
file stats: LOC: 145   Methods: 4
NCLOC: 116   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
UselessOverridingMethod.java 81.8% 88.2% 100% 86.2%
coverage coverage
 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  17 public Object visit(ASTClassOrInterfaceDeclaration clz, Object data) {
 31  17 if (clz.isInterface()) {
 32  1 return data;
 33    }
 34  16 return super.visit(clz, data);
 35    }
 36   
 37  15 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  15 if (node.isAbstract() || node.isFinal() || node.isNative() || node.isSynchronized()) {
 42  3 return super.visit(node, data);
 43    }
 44   
 45  12 ASTBlock block = node.getBlock();
 46  12 if (block == null) {
 47  0 return super.visit(node, data);
 48    }
 49    //Only process functions with one BlockStatement
 50  12 if (block.jjtGetNumChildren() != 1 || block.findChildrenOfType(ASTStatement.class).size() != 1)
 51  0 return super.visit(node, data);
 52   
 53  12 ASTStatement statement = (ASTStatement) block.jjtGetChild(0).jjtGetChild(0);
 54  12 if (statement.jjtGetChild(0).jjtGetNumChildren() == 0) {
 55  1 return data; // skips empty return statements
 56    }
 57  11 SimpleNode statementGrandChild = (SimpleNode) statement.jjtGetChild(0).jjtGetChild(0);
 58  11 ASTPrimaryExpression primaryExpression;
 59   
 60  11 if (statementGrandChild instanceof ASTPrimaryExpression)
 61  8 primaryExpression = (ASTPrimaryExpression) statementGrandChild;
 62    else {
 63  3 List primaryExpressions = findFirstDegreeChildrenOfType(statementGrandChild, ASTPrimaryExpression.class);
 64  3 if (primaryExpressions.size() != 1)
 65  1 return super.visit(node, data);
 66  2 primaryExpression = (ASTPrimaryExpression) primaryExpressions.get(0);
 67    }
 68   
 69  10 ASTPrimaryPrefix primaryPrefix = (ASTPrimaryPrefix) findFirstDegreeChildrenOfType(primaryExpression, ASTPrimaryPrefix.class).get(0);
 70  10 if (!primaryPrefix.usesSuperModifier())
 71  0 return super.visit(node, data);
 72   
 73  10 ASTMethodDeclarator methodDeclarator = (ASTMethodDeclarator) findFirstDegreeChildrenOfType(node, ASTMethodDeclarator.class).get(0);
 74  10 if (!primaryPrefix.hasImageEqualTo(methodDeclarator.getImage()))
 75  0 return super.visit(node, data);
 76   
 77    //Process arguments
 78  10 ASTPrimarySuffix primarySuffix = (ASTPrimarySuffix) findFirstDegreeChildrenOfType(primaryExpression, ASTPrimarySuffix.class).get(0);
 79  10 ASTArguments arguments = (ASTArguments) primarySuffix.jjtGetChild(0);
 80  10 ASTFormalParameters formalParameters = (ASTFormalParameters) methodDeclarator.jjtGetChild(0);
 81  10 if (formalParameters.jjtGetNumChildren() != arguments.jjtGetNumChildren())
 82  1 return super.visit(node, data);
 83   
 84  9 if (arguments.jjtGetNumChildren() == 0) //No arguments to check
 85  2 addViolation(data, node, getMessage());
 86    else {
 87  7 ASTArgumentList argumentList = (ASTArgumentList) arguments.jjtGetChild(0);
 88  7 for (int i = 0; i < argumentList.jjtGetNumChildren(); i++) {
 89  8 Node ExpressionChild = argumentList.jjtGetChild(i).jjtGetChild(0);
 90  8 if (!(ExpressionChild instanceof ASTPrimaryExpression) || ExpressionChild.jjtGetNumChildren() != 1)
 91  2 return super.visit(node, data); //The arguments are not simply passed through
 92   
 93  6 ASTPrimaryExpression argumentPrimaryExpression = (ASTPrimaryExpression) ExpressionChild;
 94  6 ASTPrimaryPrefix argumentPrimaryPrefix = (ASTPrimaryPrefix) argumentPrimaryExpression.jjtGetChild(0);
 95  6 if (argumentPrimaryPrefix.jjtGetNumChildren() == 0) {
 96  1 return super.visit(node, data); //The arguments are not simply passed through (using "this" for instance)
 97    }
 98  5 Node argumentPrimaryPrefixChild = argumentPrimaryPrefix.jjtGetChild(0);
 99  5 if (!(argumentPrimaryPrefixChild instanceof ASTName))
 100  0 return super.visit(node, data); //The arguments are not simply passed through
 101   
 102  5 if (formalParameters.jjtGetNumChildren() < i + 1) {
 103  1 return super.visit(node, data); // different number of args
 104    }
 105   
 106  4 ASTName argumentName = (ASTName) argumentPrimaryPrefixChild;
 107  4 ASTFormalParameter formalParameter = (ASTFormalParameter) formalParameters.jjtGetChild(i);
 108  4 ASTVariableDeclaratorId variableId = (ASTVariableDeclaratorId) findFirstDegreeChildrenOfType(formalParameter, ASTVariableDeclaratorId.class).get(0);
 109  4 if (!argumentName.hasImageEqualTo(variableId.getImage())) {
 110  1 return super.visit(node, data); //The arguments are not simply passed through
 111    }
 112   
 113    }
 114  2 addViolation(data, node, getMessage()); //All arguments are passed through directly
 115    }
 116  4 return super.visit(node, data);
 117    }
 118   
 119  37 public List findFirstDegreeChildrenOfType(SimpleNode n, Class targetType) {
 120  37 List l = new ArrayList();
 121  37 lclFindChildrenOfType(n, targetType, l);
 122  37 return l;
 123    }
 124   
 125  37 private void lclFindChildrenOfType(Node node, Class targetType, List results) {
 126  37 if (node.getClass().equals(targetType)) {
 127  0 results.add(node);
 128    }
 129   
 130  37 if (node instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node).isNested()) {
 131  0 return;
 132    }
 133   
 134  37 if (node instanceof ASTClassOrInterfaceBodyDeclaration && ((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
 135  0 return;
 136    }
 137   
 138  37 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
 139  81 Node child = node.jjtGetChild(i);
 140  81 if (child.getClass().equals(targetType)) {
 141  36 results.add(child);
 142    }
 143    }
 144    }
 145    }