1 package net.sourceforge.pmd.lang.java.rule.codesize;
2
3 import net.sourceforge.pmd.lang.ast.Node;
4 import net.sourceforge.pmd.lang.java.ast.ASTBreakStatement;
5 import net.sourceforge.pmd.lang.java.ast.ASTCatchStatement;
6 import net.sourceforge.pmd.lang.java.ast.ASTContinueStatement;
7 import net.sourceforge.pmd.lang.java.ast.ASTDoStatement;
8 import net.sourceforge.pmd.lang.java.ast.ASTFinallyStatement;
9 import net.sourceforge.pmd.lang.java.ast.ASTForInit;
10 import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
11 import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
12 import net.sourceforge.pmd.lang.java.ast.ASTLabeledStatement;
13 import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
14 import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
15 import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
16 import net.sourceforge.pmd.lang.java.ast.ASTStatementExpressionList;
17 import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel;
18 import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
19 import net.sourceforge.pmd.lang.java.ast.ASTSynchronizedStatement;
20 import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement;
21 import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
22 import net.sourceforge.pmd.lang.java.ast.JavaNode;
23 import net.sourceforge.pmd.lang.java.rule.AbstractStatisticalJavaRule;
24 import net.sourceforge.pmd.stat.DataPoint;
25 import net.sourceforge.pmd.util.NumericConstants;
26
27
28
29
30
31
32
33 public abstract class AbstractNcssCountRule extends AbstractStatisticalJavaRule {
34
35 private Class<?> nodeClass;
36
37
38
39
40
41
42
43 protected AbstractNcssCountRule(Class<?> nodeClass) {
44 this.nodeClass = nodeClass;
45 }
46
47 @Override
48 public Object visit(JavaNode node, Object data) {
49 int numNodes = 0;
50
51 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
52 JavaNode n = (JavaNode) node.jjtGetChild(i);
53 Integer treeSize = (Integer) n.jjtAccept(this, data);
54 numNodes += treeSize.intValue();
55 }
56
57 if (this.nodeClass.isInstance(node)) {
58
59 numNodes++;
60 DataPoint point = new DataPoint();
61 point.setNode(node);
62 point.setScore(1.0 * numNodes);
63 point.setMessage(getMessage());
64 addDataPoint(point);
65 }
66
67 return Integer.valueOf(numNodes);
68 }
69
70
71
72
73
74
75
76
77
78
79
80 protected Integer countNodeChildren(Node node, Object data) {
81 Integer nodeCount = null;
82 int lineCount = 0;
83 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
84 nodeCount = (Integer) ((JavaNode) node.jjtGetChild(i)).jjtAccept(this, data);
85 lineCount += nodeCount.intValue();
86 }
87 return ++lineCount;
88 }
89
90 @Override
91 public Object visit(ASTForStatement node, Object data) {
92 return countNodeChildren(node, data);
93 }
94
95 @Override
96 public Object visit(ASTDoStatement node, Object data) {
97 return countNodeChildren(node, data);
98 }
99
100 @Override
101 public Object visit(ASTIfStatement node, Object data) {
102
103 Integer lineCount = countNodeChildren(node, data);
104
105 if (node.hasElse()) {
106 lineCount++;
107 }
108
109 return lineCount;
110 }
111
112 @Override
113 public Object visit(ASTWhileStatement node, Object data) {
114 return countNodeChildren(node, data);
115 }
116
117 @Override
118 public Object visit(ASTBreakStatement node, Object data) {
119 return NumericConstants.ONE;
120 }
121
122 @Override
123 public Object visit(ASTCatchStatement node, Object data) {
124 return countNodeChildren(node, data);
125 }
126
127 @Override
128 public Object visit(ASTContinueStatement node, Object data) {
129 return NumericConstants.ONE;
130 }
131
132 @Override
133 public Object visit(ASTFinallyStatement node, Object data) {
134 return countNodeChildren(node, data);
135 }
136
137 @Override
138 public Object visit(ASTReturnStatement node, Object data) {
139 return countNodeChildren(node, data);
140 }
141
142 @Override
143 public Object visit(ASTSwitchStatement node, Object data) {
144 return countNodeChildren(node, data);
145 }
146
147 @Override
148 public Object visit(ASTSynchronizedStatement node, Object data) {
149 return countNodeChildren(node, data);
150 }
151
152 @Override
153 public Object visit(ASTThrowStatement node, Object data) {
154 return NumericConstants.ONE;
155 }
156
157 @Override
158 public Object visit(ASTStatementExpression node, Object data) {
159
160
161 if (node.jjtGetParent() instanceof ASTStatementExpressionList) {
162 return NumericConstants.ZERO;
163 }
164
165 return NumericConstants.ONE;
166 }
167
168 @Override
169 public Object visit(ASTLabeledStatement node, Object data) {
170 return countNodeChildren(node, data);
171 }
172
173 @Override
174 public Object visit(ASTLocalVariableDeclaration node, Object data) {
175
176
177 if (node.jjtGetParent() instanceof ASTForInit) {
178 return NumericConstants.ZERO;
179 }
180
181
182
183
184
185
186
187 return countNodeChildren(node, data);
188 }
189
190 @Override
191 public Object visit(ASTSwitchLabel node, Object data) {
192 return countNodeChildren(node, data);
193 }
194
195 }