Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
file stats: LOC: 100   Methods: 3
NCLOC: 78   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CloneMethodMustImplementCloneable.java 55.9% 78% 100% 69.2%
coverage coverage
 1    /**
 2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 3    */
 4    package net.sourceforge.pmd.typeresolution.rules;
 5   
 6    import net.sourceforge.pmd.AbstractRule;
 7    import net.sourceforge.pmd.ast.ASTBlock;
 8    import net.sourceforge.pmd.ast.ASTBlockStatement;
 9    import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
 10    import net.sourceforge.pmd.ast.ASTClassOrInterfaceType;
 11    import net.sourceforge.pmd.ast.ASTExtendsList;
 12    import net.sourceforge.pmd.ast.ASTFormalParameters;
 13    import net.sourceforge.pmd.ast.ASTImplementsList;
 14    import net.sourceforge.pmd.ast.ASTMethodDeclaration;
 15    import net.sourceforge.pmd.ast.ASTMethodDeclarator;
 16    import net.sourceforge.pmd.ast.SimpleNode;
 17   
 18    import java.util.Arrays;
 19    import java.util.List;
 20   
 21    /**
 22    * The method clone() should only be implemented if the class implements the
 23    * Cloneable interface with the exception of a final method that only throws
 24    * CloneNotSupportedException. This version uses PMD's type resolution
 25    * facilities, and can detect if the class implements or extends a Cloneable
 26    * class
 27    *
 28    * @author acaplan
 29    *
 30    */
 31    public class CloneMethodMustImplementCloneable extends AbstractRule {
 32   
 33  8 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
 34  8 ASTImplementsList impl = (ASTImplementsList) node.getFirstChildOfType(ASTImplementsList.class);
 35  8 if (impl != null && impl.jjtGetParent().equals(node)) {
 36  3 for (int ix = 0; ix < impl.jjtGetNumChildren(); ix++) {
 37  3 ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) impl.jjtGetChild(ix);
 38  3 if (type.getType() == null) {
 39  3 if ("Cloneable".equals(type.getImage())) {
 40  3 return data;
 41    }
 42  0 } else if (type.getType().equals(Cloneable.class)) {
 43  0 return data;
 44    } else {
 45  0 List implementors = Arrays.asList(type.getType().getInterfaces());
 46  0 if (implementors.contains(Cloneable.class)) {
 47  0 return data;
 48    }
 49    }
 50    }
 51    }
 52  5 if (node.jjtGetNumChildren() != 0 && node.jjtGetChild(0).getClass().equals(ASTExtendsList.class)) {
 53  1 ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) ((SimpleNode) node.jjtGetChild(0)).jjtGetChild(0);
 54  1 Class clazz = type.getType();
 55  1 if (clazz != null && clazz.equals(Cloneable.class)) {
 56  0 return data;
 57    }
 58  1 while (clazz != null && !Object.class.equals(clazz)) {
 59  1 if (Arrays.asList(clazz.getInterfaces()).contains(Cloneable.class)) {
 60  1 return data;
 61    }
 62  0 clazz = clazz.getSuperclass();
 63    }
 64    }
 65   
 66  4 return super.visit(node, data);
 67    }
 68   
 69  3 public Object visit(ASTMethodDeclaration node, Object data) {
 70   
 71  3 if (node.isFinal()) {
 72  1 List blocks = node.findChildrenOfType(ASTBlock.class);
 73  1 if (blocks.size() == 1) {
 74  1 blocks = node.findChildrenOfType(ASTBlockStatement.class);
 75  1 if (blocks.size() == 1) {
 76  1 ASTBlockStatement block = (ASTBlockStatement) blocks.get(0);
 77  1 ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) block.getFirstChildOfType(ASTClassOrInterfaceType.class);
 78  1 if (type != null && type.getType() != null && type.getNthParent(9).equals(node) && type.getType().equals(CloneNotSupportedException.class)) {
 79  0 return data;
 80  1 } else if (type != null && type.getType() == null && "CloneNotSupportedException".equals(type.getImage())) {
 81  1 return data;
 82    }
 83    }
 84    }
 85    }
 86  2 return super.visit(node, data);
 87    }
 88   
 89  2 public Object visit(ASTMethodDeclarator node, Object data) {
 90  2 if (!"clone".equals(node.getImage())) {
 91  0 return data;
 92    }
 93  2 int countParams = ((ASTFormalParameters) node.jjtGetChild(0)).jjtGetNumChildren();
 94  2 if (countParams != 0) {
 95  1 return data;
 96    }
 97  1 addViolation(data, node);
 98  1 return data;
 99    }
 100    }