Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 100 |  | Methods: | 3
| NCLOC: | 78 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
CloneMethodMustImplementCloneable.java | 55.9% | 78% | 100% | 69.2% |

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 |  | }