Clover Coverage Report - PMD-3.8
Coverage timestamp: Wed Oct 14 2009 06:14:43 CDT
../../../../img/srcFileCovDistChart8.png 34% of files have more coverage
85   199   34   5
30   162   0.4   8.5
17     2  
2    
 
  CyclomaticComplexity       Line # 33 81 29 69.7% 0.6967213
  CyclomaticComplexity.Entry       Line # 35 4 5 90% 0.9
 
  (4)
 
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.ASTBlockStatement;
8    import net.sourceforge.pmd.ast.ASTCatchStatement;
9    import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
10    import net.sourceforge.pmd.ast.ASTConditionalAndExpression;
11    import net.sourceforge.pmd.ast.ASTConditionalExpression;
12    import net.sourceforge.pmd.ast.ASTConditionalOrExpression;
13    import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
14    import net.sourceforge.pmd.ast.ASTDoStatement;
15    import net.sourceforge.pmd.ast.ASTEnumDeclaration;
16    import net.sourceforge.pmd.ast.ASTForStatement;
17    import net.sourceforge.pmd.ast.ASTIfStatement;
18    import net.sourceforge.pmd.ast.ASTMethodDeclaration;
19    import net.sourceforge.pmd.ast.ASTMethodDeclarator;
20    import net.sourceforge.pmd.ast.ASTSwitchLabel;
21    import net.sourceforge.pmd.ast.ASTSwitchStatement;
22    import net.sourceforge.pmd.ast.ASTWhileStatement;
23    import net.sourceforge.pmd.ast.Node;
24    import net.sourceforge.pmd.ast.SimpleNode;
25   
26    import java.util.Stack;
27   
28    /**
29    * @author Donald A. Leckie
30    * @version $Revision: 1.13 $, $Date: 2006/10/02 12:22:20 $
31    * @since January 14, 2003
32    */
 
33    public class CyclomaticComplexity extends AbstractRule {
34   
 
35    private static class Entry {
36    private SimpleNode node;
37    private int decisionPoints = 1;
38    public int highestDecisionPoints;
39    public int methodCount;
40   
 
41  8 toggle private Entry(SimpleNode node) {
42  8 this.node = node;
43    }
44   
 
45  10 toggle public void bumpDecisionPoints() {
46  10 decisionPoints++;
47    }
48   
 
49  3 toggle public void bumpDecisionPoints(int size) {
50  3 decisionPoints += size;
51    }
52   
 
53  7 toggle public int getComplexityAverage() {
54  7 return ((double) methodCount == 0) ? 1 : (int) (Math.rint((double) decisionPoints / (double) methodCount));
55    }
56    }
57   
58    private Stack entryStack = new Stack();
59   
 
60  5 toggle public Object visit(ASTIfStatement node, Object data) {
61  5 ((Entry) entryStack.peek()).bumpDecisionPoints();
62  5 super.visit(node, data);
63  5 return data;
64    }
65   
 
66  0 toggle public Object visit(ASTCatchStatement node, Object data) {
67  0 ((Entry) entryStack.peek()).bumpDecisionPoints();
68  0 super.visit(node, data);
69  0 return data;
70    }
71   
 
72  1 toggle public Object visit(ASTForStatement node, Object data) {
73  1 ((Entry) entryStack.peek()).bumpDecisionPoints();
74  1 super.visit(node, data);
75  1 return data;
76    }
77   
 
78  0 toggle public Object visit(ASTDoStatement node, Object data) {
79  0 ((Entry) entryStack.peek()).bumpDecisionPoints();
80  0 super.visit(node, data);
81  0 return data;
82    }
83   
 
84  1 toggle public Object visit(ASTSwitchStatement node, Object data) {
85  1 Entry entry = (Entry) entryStack.peek();
86  1 int childCount = node.jjtGetNumChildren();
87  1 int lastIndex = childCount - 1;
88  13 for (int n = 0; n < lastIndex; n++) {
89  12 Node childNode = node.jjtGetChild(n);
90  12 if (childNode instanceof ASTSwitchLabel) {
91    // default is generally not considered a decision (same as "else")
92  4 ASTSwitchLabel sl = (ASTSwitchLabel) childNode;
93  4 if (!sl.isDefault()) {
94  3 childNode = node.jjtGetChild(n + 1);
95  3 if (childNode instanceof ASTBlockStatement) {
96  3 entry.bumpDecisionPoints();
97    }
98    }
99    }
100    }
101  1 super.visit(node, data);
102  1 return data;
103    }
104   
 
105  1 toggle public Object visit(ASTWhileStatement node, Object data) {
106  1 ((Entry) entryStack.peek()).bumpDecisionPoints();
107  1 super.visit(node, data);
108  1 return data;
109    }
110   
 
111  0 toggle public Object visit(ASTConditionalExpression node, Object data) {
112  0 ((Entry) entryStack.peek()).bumpDecisionPoints();
113  0 super.visit(node, data);
114  0 return data;
115    }
116   
 
117  0 toggle public Object visit(ASTConditionalAndExpression node, Object data) {
118  0 ((Entry) entryStack.peek()).bumpDecisionPoints(node.jjtGetNumChildren() - 1);
119  0 super.visit(node, data);
120  0 return data;
121    }
122   
 
123  0 toggle public Object visit(ASTConditionalOrExpression node, Object data) {
124  0 ((Entry) entryStack.peek()).bumpDecisionPoints(node.jjtGetNumChildren() - 1);
125  0 super.visit(node, data);
126  0 return data;
127    }
128   
 
129  4 toggle public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
130  4 if (node.isInterface()) {
131  0 return data;
132    }
133   
134  4 entryStack.push(new Entry(node));
135  4 super.visit(node, data);
136  4 Entry classEntry = (Entry) entryStack.pop();
137  4 if ((classEntry.getComplexityAverage() >= getIntProperty("reportLevel")) || (classEntry.highestDecisionPoints >= getIntProperty("reportLevel"))) {
138  3 addViolation(data, node, new String[]{"class", node.getImage(), String.valueOf(classEntry.getComplexityAverage()) + " (Highest = " + String.valueOf(classEntry.highestDecisionPoints) + ")"});
139    }
140  4 return data;
141    }
142   
 
143  3 toggle public Object visit(ASTMethodDeclaration node, Object data) {
144  3 entryStack.push(new Entry(node));
145  3 super.visit(node, data);
146  3 Entry methodEntry = (Entry) entryStack.pop();
147  3 int methodDecisionPoints = methodEntry.decisionPoints;
148  3 Entry classEntry = (Entry) entryStack.peek();
149  3 classEntry.methodCount++;
150  3 classEntry.bumpDecisionPoints(methodDecisionPoints);
151   
152  3 if (methodDecisionPoints > classEntry.highestDecisionPoints) {
153  3 classEntry.highestDecisionPoints = methodDecisionPoints;
154    }
155   
156  3 ASTMethodDeclarator methodDeclarator = null;
157  6 for (int n = 0; n < node.jjtGetNumChildren(); n++) {
158  6 Node childNode = node.jjtGetChild(n);
159  6 if (childNode instanceof ASTMethodDeclarator) {
160  3 methodDeclarator = (ASTMethodDeclarator) childNode;
161  3 break;
162    }
163    }
164   
165  3 if (methodEntry.decisionPoints >= getIntProperty("reportLevel")) {
166  2 addViolation(data, node, new String[]{"method", (methodDeclarator == null) ? "" : methodDeclarator.getImage(), String.valueOf(methodEntry.decisionPoints)});
167    }
168   
169  3 return data;
170    }
171   
 
172  0 toggle public Object visit(ASTEnumDeclaration node, Object data) {
173  0 entryStack.push(new Entry(node));
174  0 super.visit(node, data);
175  0 Entry classEntry = (Entry) entryStack.pop();
176  0 if ((classEntry.getComplexityAverage() >= getIntProperty("reportLevel")) || (classEntry.highestDecisionPoints >= getIntProperty("reportLevel"))) {
177  0 addViolation(data, node, new String[]{"class", node.getImage(), String.valueOf(classEntry.getComplexityAverage()) + "(Highest = " + String.valueOf(classEntry.highestDecisionPoints) + ")"});
178    }
179  0 return data;
180    }
181   
 
182  1 toggle public Object visit(ASTConstructorDeclaration node, Object data) {
183  1 entryStack.push(new Entry(node));
184  1 super.visit(node, data);
185  1 Entry constructorEntry = (Entry) entryStack.pop();
186  1 int constructorDecisionPointCount = constructorEntry.decisionPoints;
187  1 Entry classEntry = (Entry) entryStack.peek();
188  1 classEntry.methodCount++;
189  1 classEntry.decisionPoints += constructorDecisionPointCount;
190  1 if (constructorDecisionPointCount > classEntry.highestDecisionPoints) {
191  1 classEntry.highestDecisionPoints = constructorDecisionPointCount;
192    }
193  1 if (constructorEntry.decisionPoints >= getIntProperty("reportLevel")) {
194  1 addViolation(data, node, new String[]{"constructor", classEntry.node.getImage(), String.valueOf(constructorDecisionPointCount)});
195    }
196  1 return data;
197    }
198   
199    }