Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 243 |  | Methods: | 14
| NCLOC: | 196 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
StatementAndBraceFinder.java | 81.9% | 86.8% | 92.9% | 85.6% |

1 |  | /*
2 |  | * Created on 11.07.2004
3 |  | */
4 |  | package net.sourceforge.pmd.dfa;
5 |  |
6 |  | import net.sourceforge.pmd.ast.*;
7 |  |
8 |  | /**
9 |  | * @author raik
10 |  | * <p/>
11 |  | * Sublayer of DataFlowFacade. Finds all data flow nodes and stores the
12 |  | * type information (@see StackObject). At last it uses this information to
13 |  | * link the nodes.
14 |  | */
15 |  | public class StatementAndBraceFinder extends JavaParserVisitorAdapter {
16 |  |
17 |  | private Structure dataFlow;
18 |  |
19 | 46 | public void buildDataFlowFor(SimpleJavaNode node) {
20 | 46 | if (!(node instanceof ASTMethodDeclaration) && !(node instanceof ASTConstructorDeclaration)) {
21 | 1 | throw new RuntimeException("Can't build a data flow for anything other than a method or a constructor");
22 |  | }
23 |  |
24 | 45 | this.dataFlow = new Structure();
25 | 45 | this.dataFlow.createStartNode(node.getBeginLine());
26 | 45 | this.dataFlow.createNewNode(node);
27 |  |
28 | 45 | node.jjtAccept(this, dataFlow);
29 |  |
30 | 45 | this.dataFlow.createEndNode(node.getEndLine());
31 |  |
32 | 45 | Linker linker = new Linker(dataFlow.getBraceStack(), dataFlow.getContinueBreakReturnStack());
33 | 45 | try {
34 | 45 | linker.computePaths();
35 |  | } catch (LinkerException e) {
36 | 0 | e.printStackTrace();
37 |  | } catch (SequenceException e) {
38 | 0 | e.printStackTrace();
39 |  | }
40 |  | }
41 |  |
42 | 70 | public Object visit(ASTStatementExpression node, Object data) {
43 | 70 | if (!(data instanceof Structure)) {
44 | 0 | return data;
45 |  | }
46 | 70 | Structure dataFlow = (Structure) data;
47 | 70 | dataFlow.createNewNode(node);
48 | 70 | return super.visit(node, data);
49 |  | }
50 |  |
51 | 42 | public Object visit(ASTVariableDeclarator node, Object data) {
52 | 42 | if (!(data instanceof Structure)) {
53 | 0 | return data;
54 |  | }
55 | 42 | Structure dataFlow = (Structure) data;
56 | 42 | dataFlow.createNewNode(node);
57 | 42 | return super.visit(node, data);
58 |  | }
59 |  |
60 | 132 | public Object visit(ASTExpression node, Object data) {
61 | 132 | if (!(data instanceof Structure)) {
62 | 0 | return data;
63 |  | }
64 | 132 | Structure dataFlow = (Structure) data;
65 |  |
66 |  | // TODO what about throw stmts?
67 | 132 | if (node.jjtGetParent() instanceof ASTIfStatement) {
68 | 27 | dataFlow.createNewNode(node); // START IF
69 | 27 | dataFlow.pushOnStack(NodeType.IF_EXPR, dataFlow.getLast());
70 | 105 | } else if (node.jjtGetParent() instanceof ASTWhileStatement) {
71 | 3 | dataFlow.createNewNode(node); // START WHILE
72 | 3 | dataFlow.pushOnStack(NodeType.WHILE_EXPR, dataFlow.getLast());
73 | 102 | } else if (node.jjtGetParent() instanceof ASTSwitchStatement) {
74 | 3 | dataFlow.createNewNode(node); // START SWITCH
75 | 3 | dataFlow.pushOnStack(NodeType.SWITCH_START, dataFlow.getLast());
76 | 99 | } else if (node.jjtGetParent() instanceof ASTForStatement) {
77 | 21 | dataFlow.createNewNode(node); // FOR EXPR
78 | 21 | dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
79 | 78 | } else if (node.jjtGetParent() instanceof ASTDoStatement) {
80 | 3 | dataFlow.createNewNode(node); // DO EXPR
81 | 3 | dataFlow.pushOnStack(NodeType.DO_EXPR, dataFlow.getLast());
82 |  | }
83 |  |
84 | 132 | return super.visit(node, data);
85 |  | }
86 |  |
87 | 21 | public Object visit(ASTForInit node, Object data) {
88 | 21 | if (!(data instanceof Structure)) {
89 | 0 | return data;
90 |  | }
91 | 21 | Structure dataFlow = (Structure) data;
92 | 21 | super.visit(node, data);
93 | 21 | dataFlow.pushOnStack(NodeType.FOR_INIT, dataFlow.getLast());
94 | 21 | this.addForExpressionNode(node, dataFlow);
95 | 21 | return data;
96 |  | }
97 |  |
98 | 1 | public Object visit(ASTLabeledStatement node, Object data) {
99 | 1 | dataFlow.createNewNode(node);
100 | 1 | dataFlow.pushOnStack(NodeType.LABEL_STATEMENT, dataFlow.getLast());
101 | 1 | return super.visit(node, data);
102 |  | }
103 |  |
104 | 21 | public Object visit(ASTForUpdate node, Object data) {
105 | 21 | if (!(data instanceof Structure)) {
106 | 0 | return data;
107 |  | }
108 | 21 | Structure dataFlow = (Structure) data;
109 | 21 | this.addForExpressionNode(node, dataFlow);
110 | 21 | super.visit(node, data);
111 | 21 | dataFlow.pushOnStack(NodeType.FOR_UPDATE, dataFlow.getLast());
112 | 21 | return data;
113 |  | }
114 |  |
115 |  | // ----------------------------------------------------------------------------
116 |  | // BRANCH OUT
117 |  |
118 | 178 | public Object visit(ASTStatement node, Object data) {
119 | 178 | if (!(data instanceof Structure)) {
120 | 0 | return data;
121 |  | }
122 | 178 | Structure dataFlow = (Structure) data;
123 |  |
124 | 178 | if (node.jjtGetParent() instanceof ASTForStatement) {
125 | 26 | this.addForExpressionNode(node, dataFlow);
126 | 26 | dataFlow.pushOnStack(NodeType.FOR_BEFORE_FIRST_STATEMENT, dataFlow.getLast());
127 | 152 | } else if (node.jjtGetParent() instanceof ASTDoStatement) {
128 | 3 | dataFlow.pushOnStack(NodeType.DO_BEFORE_FIRST_STATEMENT, dataFlow.getLast());
129 | 3 | dataFlow.createNewNode((SimpleNode) node.jjtGetParent());
130 |  | }
131 |  |
132 | 178 | super.visit(node, data);
133 |  |
134 | 178 | if (node.jjtGetParent() instanceof ASTIfStatement) {
135 | 38 | ASTIfStatement st = (ASTIfStatement) node.jjtGetParent();
136 | 38 | if (!st.hasElse()) {
137 | 16 | dataFlow.pushOnStack(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, dataFlow.getLast());
138 | 22 | } else if (st.hasElse() && !st.jjtGetChild(1).equals(node)) {
139 | 11 | dataFlow.pushOnStack(NodeType.ELSE_LAST_STATEMENT, dataFlow.getLast());
140 |  | } else {
141 | 11 | dataFlow.pushOnStack(NodeType.IF_LAST_STATEMENT, dataFlow.getLast());
142 |  | }
143 | 140 | } else if (node.jjtGetParent() instanceof ASTWhileStatement) {
144 | 3 | dataFlow.pushOnStack(NodeType.WHILE_LAST_STATEMENT, dataFlow.getLast());
145 | 137 | } else if (node.jjtGetParent() instanceof ASTForStatement) {
146 | 26 | dataFlow.pushOnStack(NodeType.FOR_END, dataFlow.getLast());
147 | 111 | } else if (node.jjtGetParent() instanceof ASTLabeledStatement) {
148 | 1 | dataFlow.pushOnStack(NodeType.LABEL_LAST_STATEMENT, dataFlow.getLast());
149 |  | }
150 | 178 | return data;
151 |  | }
152 |  |
153 | 3 | public Object visit(ASTSwitchStatement node, Object data) {
154 | 3 | if (!(data instanceof Structure)) {
155 | 0 | return data;
156 |  | }
157 | 3 | Structure dataFlow = (Structure) data;
158 | 3 | super.visit(node, data);
159 | 3 | dataFlow.pushOnStack(NodeType.SWITCH_END, dataFlow.getLast());
160 | 3 | return data;
161 |  | }
162 |  |
163 | 5 | public Object visit(ASTSwitchLabel node, Object data) {
164 | 5 | if (!(data instanceof Structure)) {
165 | 0 | return data;
166 |  | }
167 | 5 | Structure dataFlow = (Structure) data;
168 |  | //super.visit(node, data);
169 | 5 | if (node.jjtGetNumChildren() == 0) {
170 | 2 | dataFlow.pushOnStack(NodeType.SWITCH_LAST_DEFAULT_STATEMENT, dataFlow.getLast());
171 |  | } else {
172 | 3 | dataFlow.pushOnStack(NodeType.CASE_LAST_STATEMENT, dataFlow.getLast());
173 |  | }
174 | 5 | return data;
175 |  | }
176 |  |
177 | 5 | public Object visit(ASTBreakStatement node, Object data) {
178 | 5 | if (!(data instanceof Structure)) {
179 | 0 | return data;
180 |  | }
181 | 5 | Structure dataFlow = (Structure) data;
182 | 5 | dataFlow.createNewNode(node);
183 | 5 | dataFlow.pushOnStack(NodeType.BREAK_STATEMENT, dataFlow.getLast());
184 | 5 | return super.visit(node, data);
185 |  | }
186 |  |
187 |  |
188 | 1 | public Object visit(ASTContinueStatement node, Object data) {
189 | 1 | if (!(data instanceof Structure)) {
190 | 0 | return data;
191 |  | }
192 | 1 | Structure dataFlow = (Structure) data;
193 | 1 | dataFlow.createNewNode(node);
194 | 1 | dataFlow.pushOnStack(NodeType.CONTINUE_STATEMENT, dataFlow.getLast());
195 | 1 | return super.visit(node, data);
196 |  | }
197 |  |
198 | 0 | public Object visit(ASTReturnStatement node, Object data) {
199 | 0 | if (!(data instanceof Structure)) {
200 | 0 | return data;
201 |  | }
202 | 0 | Structure dataFlow = (Structure) data;
203 | 0 | dataFlow.createNewNode(node);
204 | 0 | dataFlow.pushOnStack(NodeType.RETURN_STATEMENT, dataFlow.getLast());
205 | 0 | return super.visit(node, data);
206 |  | }
207 |  |
208 |  | /*
209 |  | * The method handles the special "for" loop. It creates always an
210 |  | * expression node even if the loop looks like for(;;).
211 |  | * */
212 | 68 | private void addForExpressionNode(SimpleNode node, Structure dataFlow) {
213 | 68 | ASTForStatement parent = (ASTForStatement) node.jjtGetParent();
214 | 68 | boolean hasExpressionChild = false;
215 | 68 | boolean hasForInitNode = false;
216 | 68 | boolean hasForUpdateNode = false;
217 |  |
218 | 68 | for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
219 | 249 | if (parent.jjtGetChild(i) instanceof ASTExpression)
220 | 59 | hasExpressionChild = true;
221 | 190 | else if (parent.jjtGetChild(i) instanceof ASTForUpdate)
222 | 61 | hasForUpdateNode = true;
223 | 129 | else if (parent.jjtGetChild(i) instanceof ASTForInit)
224 | 61 | hasForInitNode = true;
225 |  | }
226 | 68 | if (!hasExpressionChild) {
227 | 9 | if (node instanceof ASTForInit) {
228 | 2 | dataFlow.createNewNode(node);
229 | 2 | dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
230 | 7 | } else if (node instanceof ASTForUpdate) {
231 | 2 | if (!hasForInitNode) {
232 | 1 | dataFlow.createNewNode(node);
233 | 1 | dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
234 |  | }
235 | 5 | } else if (node instanceof ASTStatement) {
236 | 5 | if (!hasForInitNode && !hasForUpdateNode) {
237 | 2 | dataFlow.createNewNode(node);
238 | 2 | dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
239 |  | }
240 |  | }
241 |  | }
242 |  | }
243 |  | }