KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > dfa > StatementAndBraceFinder


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     public void buildDataFlowFor(SimpleJavaNode node) {
20         if (!(node instanceof ASTMethodDeclaration) && !(node instanceof ASTConstructorDeclaration)) {
21             throw new RuntimeException JavaDoc("Can't build a data flow for anything other than a method or a constructor");
22         }
23
24         this.dataFlow = new Structure();
25         this.dataFlow.createStartNode(node.getBeginLine());
26         this.dataFlow.createNewNode(node);
27
28         node.jjtAccept(this, dataFlow);
29
30         this.dataFlow.createEndNode(node.getEndLine());
31
32         Linker linker = new Linker(dataFlow.getBraceStack(), dataFlow.getContinueBreakReturnStack());
33         try {
34             linker.computePaths();
35         } catch (LinkerException e) {
36             e.printStackTrace();
37         } catch (SequenceException e) {
38             e.printStackTrace();
39         }
40     }
41
42     public Object JavaDoc visit(ASTStatementExpression node, Object JavaDoc data) {
43         if (!(data instanceof Structure)) {
44             return data;
45         }
46         Structure dataFlow = (Structure) data;
47         dataFlow.createNewNode(node);
48         return super.visit(node, data);
49     }
50
51     public Object JavaDoc visit(ASTVariableDeclarator node, Object JavaDoc data) {
52         if (!(data instanceof Structure)) {
53             return data;
54         }
55         Structure dataFlow = (Structure) data;
56         dataFlow.createNewNode(node);
57         return super.visit(node, data);
58     }
59
60     public Object JavaDoc visit(ASTExpression node, Object JavaDoc data) {
61         if (!(data instanceof Structure)) {
62             return data;
63         }
64         Structure dataFlow = (Structure) data;
65
66         // TODO what about throw stmts?
67
if (node.jjtGetParent() instanceof ASTIfStatement) {
68             dataFlow.createNewNode(node); // START IF
69
dataFlow.pushOnStack(NodeType.IF_EXPR, dataFlow.getLast());
70         } else if (node.jjtGetParent() instanceof ASTWhileStatement) {
71             dataFlow.createNewNode(node); // START WHILE
72
dataFlow.pushOnStack(NodeType.WHILE_EXPR, dataFlow.getLast());
73         } else if (node.jjtGetParent() instanceof ASTSwitchStatement) {
74             dataFlow.createNewNode(node); // START SWITCH
75
dataFlow.pushOnStack(NodeType.SWITCH_START, dataFlow.getLast());
76         } else if (node.jjtGetParent() instanceof ASTForStatement) {
77             dataFlow.createNewNode(node); // FOR EXPR
78
dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
79         } else if (node.jjtGetParent() instanceof ASTDoStatement) {
80             dataFlow.createNewNode(node); // DO EXPR
81
dataFlow.pushOnStack(NodeType.DO_EXPR, dataFlow.getLast());
82         }
83
84         return super.visit(node, data);
85     }
86
87     public Object JavaDoc visit(ASTForInit node, Object JavaDoc data) {
88         if (!(data instanceof Structure)) {
89             return data;
90         }
91         Structure dataFlow = (Structure) data;
92         super.visit(node, data);
93         dataFlow.pushOnStack(NodeType.FOR_INIT, dataFlow.getLast());
94         this.addForExpressionNode(node, dataFlow);
95         return data;
96     }
97
98     public Object JavaDoc visit(ASTLabeledStatement node, Object JavaDoc data) {
99         dataFlow.createNewNode(node);
100         dataFlow.pushOnStack(NodeType.LABEL_STATEMENT, dataFlow.getLast());
101         return super.visit(node, data);
102     }
103
104     public Object JavaDoc visit(ASTForUpdate node, Object JavaDoc data) {
105         if (!(data instanceof Structure)) {
106             return data;
107         }
108         Structure dataFlow = (Structure) data;
109         this.addForExpressionNode(node, dataFlow);
110         super.visit(node, data);
111         dataFlow.pushOnStack(NodeType.FOR_UPDATE, dataFlow.getLast());
112         return data;
113     }
114
115 // ----------------------------------------------------------------------------
116
// BRANCH OUT
117

118     public Object JavaDoc visit(ASTStatement node, Object JavaDoc data) {
119         if (!(data instanceof Structure)) {
120             return data;
121         }
122         Structure dataFlow = (Structure) data;
123
124         if (node.jjtGetParent() instanceof ASTForStatement) {
125             this.addForExpressionNode(node, dataFlow);
126             dataFlow.pushOnStack(NodeType.FOR_BEFORE_FIRST_STATEMENT, dataFlow.getLast());
127         } else if (node.jjtGetParent() instanceof ASTDoStatement) {
128             dataFlow.pushOnStack(NodeType.DO_BEFORE_FIRST_STATEMENT, dataFlow.getLast());
129             dataFlow.createNewNode((SimpleNode) node.jjtGetParent());
130         }
131
132         super.visit(node, data);
133
134         if (node.jjtGetParent() instanceof ASTIfStatement) {
135             ASTIfStatement st = (ASTIfStatement) node.jjtGetParent();
136             if (!st.hasElse()) {
137                 dataFlow.pushOnStack(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, dataFlow.getLast());
138             } else if (st.hasElse() && !st.jjtGetChild(1).equals(node)) {
139                 dataFlow.pushOnStack(NodeType.ELSE_LAST_STATEMENT, dataFlow.getLast());
140             } else {
141                 dataFlow.pushOnStack(NodeType.IF_LAST_STATEMENT, dataFlow.getLast());
142             }
143         } else if (node.jjtGetParent() instanceof ASTWhileStatement) {
144             dataFlow.pushOnStack(NodeType.WHILE_LAST_STATEMENT, dataFlow.getLast());
145         } else if (node.jjtGetParent() instanceof ASTForStatement) {
146             dataFlow.pushOnStack(NodeType.FOR_END, dataFlow.getLast());
147         } else if (node.jjtGetParent() instanceof ASTLabeledStatement) {
148             dataFlow.pushOnStack(NodeType.LABEL_LAST_STATEMENT, dataFlow.getLast());
149         }
150         return data;
151     }
152
153     public Object JavaDoc visit(ASTSwitchStatement node, Object JavaDoc data) {
154         if (!(data instanceof Structure)) {
155             return data;
156         }
157         Structure dataFlow = (Structure) data;
158         super.visit(node, data);
159         dataFlow.pushOnStack(NodeType.SWITCH_END, dataFlow.getLast());
160         return data;
161     }
162
163     public Object JavaDoc visit(ASTSwitchLabel node, Object JavaDoc data) {
164         if (!(data instanceof Structure)) {
165             return data;
166         }
167         Structure dataFlow = (Structure) data;
168         //super.visit(node, data);
169
if (node.jjtGetNumChildren() == 0) {
170             dataFlow.pushOnStack(NodeType.SWITCH_LAST_DEFAULT_STATEMENT, dataFlow.getLast());
171         } else {
172             dataFlow.pushOnStack(NodeType.CASE_LAST_STATEMENT, dataFlow.getLast());
173         }
174         return data;
175     }
176
177     public Object JavaDoc visit(ASTBreakStatement node, Object JavaDoc data) {
178         if (!(data instanceof Structure)) {
179             return data;
180         }
181         Structure dataFlow = (Structure) data;
182         dataFlow.createNewNode(node);
183         dataFlow.pushOnStack(NodeType.BREAK_STATEMENT, dataFlow.getLast());
184         return super.visit(node, data);
185     }
186
187
188     public Object JavaDoc visit(ASTContinueStatement node, Object JavaDoc data) {
189         if (!(data instanceof Structure)) {
190             return data;
191         }
192         Structure dataFlow = (Structure) data;
193         dataFlow.createNewNode(node);
194         dataFlow.pushOnStack(NodeType.CONTINUE_STATEMENT, dataFlow.getLast());
195         return super.visit(node, data);
196     }
197
198     public Object JavaDoc visit(ASTReturnStatement node, Object JavaDoc data) {
199         if (!(data instanceof Structure)) {
200             return data;
201         }
202         Structure dataFlow = (Structure) data;
203         dataFlow.createNewNode(node);
204         dataFlow.pushOnStack(NodeType.RETURN_STATEMENT, dataFlow.getLast());
205         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     private void addForExpressionNode(SimpleNode node, Structure dataFlow) {
213         ASTForStatement parent = (ASTForStatement) node.jjtGetParent();
214         boolean hasExpressionChild = false;
215         boolean hasForInitNode = false;
216         boolean hasForUpdateNode = false;
217
218         for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
219             if (parent.jjtGetChild(i) instanceof ASTExpression)
220                 hasExpressionChild = true;
221             else if (parent.jjtGetChild(i) instanceof ASTForUpdate)
222                 hasForUpdateNode = true;
223             else if (parent.jjtGetChild(i) instanceof ASTForInit)
224                 hasForInitNode = true;
225         }
226         if (!hasExpressionChild) {
227             if (node instanceof ASTForInit) {
228                 dataFlow.createNewNode(node);
229                 dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
230             } else if (node instanceof ASTForUpdate) {
231                 if (!hasForInitNode) {
232                     dataFlow.createNewNode(node);
233                     dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
234                 }
235             } else if (node instanceof ASTStatement) {
236                 if (!hasForInitNode && !hasForUpdateNode) {
237                     dataFlow.createNewNode(node);
238                     dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast());
239                 }
240             }
241         }
242     }
243 }
244
Popular Tags