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