1 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 31 public class CloneMethodMustImplementCloneable extends AbstractRule { 32 33 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { 34 ASTImplementsList impl = (ASTImplementsList) node.getFirstChildOfType(ASTImplementsList.class); 35 if (impl != null && impl.jjtGetParent().equals(node)) { 36 for (int ix = 0; ix < impl.jjtGetNumChildren(); ix++) { 37 ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) impl.jjtGetChild(ix); 38 if (type.getType() == null) { 39 if ("Cloneable".equals(type.getImage())) { 40 return data; 41 } 42 } else if (type.getType().equals(Cloneable .class)) { 43 return data; 44 } else { 45 List implementors = Arrays.asList(type.getType().getInterfaces()); 46 if (implementors.contains(Cloneable .class)) { 47 return data; 48 } 49 } 50 } 51 } 52 if (node.jjtGetNumChildren() != 0 && node.jjtGetChild(0).getClass().equals(ASTExtendsList.class)) { 53 ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) ((SimpleNode) node.jjtGetChild(0)).jjtGetChild(0); 54 Class clazz = type.getType(); 55 if (clazz != null && clazz.equals(Cloneable .class)) { 56 return data; 57 } 58 while (clazz != null && !Object .class.equals(clazz)) { 59 if (Arrays.asList(clazz.getInterfaces()).contains(Cloneable .class)) { 60 return data; 61 } 62 clazz = clazz.getSuperclass(); 63 } 64 } 65 66 return super.visit(node, data); 67 } 68 69 public Object visit(ASTMethodDeclaration node, Object data) { 70 71 if (node.isFinal()) { 72 List blocks = node.findChildrenOfType(ASTBlock.class); 73 if (blocks.size() == 1) { 74 blocks = node.findChildrenOfType(ASTBlockStatement.class); 75 if (blocks.size() == 1) { 76 ASTBlockStatement block = (ASTBlockStatement) blocks.get(0); 77 ASTClassOrInterfaceType type = (ASTClassOrInterfaceType) block.getFirstChildOfType(ASTClassOrInterfaceType.class); 78 if (type != null && type.getType() != null && type.getNthParent(9).equals(node) && type.getType().equals(CloneNotSupportedException .class)) { 79 return data; 80 } else if (type != null && type.getType() == null && "CloneNotSupportedException".equals(type.getImage())) { 81 return data; 82 } 83 } 84 } 85 } 86 return super.visit(node, data); 87 } 88 89 public Object visit(ASTMethodDeclarator node, Object data) { 90 if (!"clone".equals(node.getImage())) { 91 return data; 92 } 93 int countParams = ((ASTFormalParameters) node.jjtGetChild(0)).jjtGetNumChildren(); 94 if (countParams != 0) { 95 return data; 96 } 97 addViolation(data, node); 98 return data; 99 } 100 } | Popular Tags |