Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 235 |  | Methods: | 13
| NCLOC: | 189 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
StatementAndBraceFinder.java | 81.4% | 86.3% | 92.3% | 85% |

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