1 import com
.sun
.source
.tree
.*;
2 import com
.sun
.source
.util
.*;
3 import java
.util
.Stack
;
5 // TODO Handle exceptions everywhere
7 public class GenerateControlFlow
extends TreePathScanner
<ControlFlowNode
, ControlFlowNode
> {
8 private Stack
<ControlFlowNode
> returnEndpoints
;
10 public GenerateControlFlow() {
12 returnEndpoints
= new Stack
<ControlFlowNode
>();
15 public ControlFlowNode
scan(Tree tree
, ControlFlowNode previous
) {
16 // System.out.println("TOREMOVE in scan");
17 ControlFlowNode rv
= super.scan(tree
, previous
);
19 if (previous
!= null) {
20 rv
.getPredecessors().add(previous
);
21 previous
.setSuccessor(rv
);
27 public ControlFlowNode
visitAnnotation(AnnotationTree tree
, ControlFlowNode previous
) {
28 return null; // TODO replace
31 public ControlFlowNode
visitArrayAccess(ArrayAccessTree tree
, ControlFlowNode previous
) {
32 return scan(tree
.getIndex(), scan(tree
.getExpression(), previous
));
35 public ControlFlowNode
visitArrayType(ArrayTypeTree tree
, ControlFlowNode previous
) {
36 return null; // TODO replace
39 public ControlFlowNode
visitAssert(AssertTree tree
, ControlFlowNode previous
) {
40 return null; // TODO replace
41 //return scan(tree.getCondition(), previous);
42 // TODO: Handle case for detail
45 public ControlFlowNode
visitAssignment(AssignmentTree tree
, ControlFlowNode previous
) {
46 return scan(tree
.getExpression(), previous
);
49 public ControlFlowNode
visitBinary(BinaryTree tree
, ControlFlowNode previous
) {
50 System
.out
.println("TOREMOVE in binary");
51 return scan(tree
.getRightOperand(), scan(tree
.getLeftOperand(), previous
));
54 public ControlFlowNode
visitBlock(BlockTree tree
, ControlFlowNode previous
) {
55 System
.out
.println("TOREMOVE in block");
56 // TODO: Handle case for static blocks
57 ControlFlowNode current
= previous
;
58 for (StatementTree stmt
: tree
.getStatements())
59 current
= scan(stmt
, current
);
63 public ControlFlowNode
visitBreak(BreakTree tree
, ControlFlowNode previous
) {
64 return null; // TODO replace
67 public ControlFlowNode
visitCase(CaseTree tree
, ControlFlowNode previous
) {
68 return null; // TODO replace
71 public ControlFlowNode
visitCatch(CatchTree tree
, ControlFlowNode previous
) {
72 return null; // TODO replace
75 public ControlFlowNode
visitClass(ClassTree tree
, ControlFlowNode previous
) {
76 System
.out
.println("TOREMOVE in class");
77 for (Tree member
: tree
.getMembers()) {
78 if (member
!= null && member
.getKind() == Tree
.Kind
.METHOD
);
80 // TODO s/null/previous/?
85 public ControlFlowNode
visitCompilationUnit(CompilationUnitTree tree
, ControlFlowNode previous
) {
86 return null; // TODO replace
89 public ControlFlowNode
visitCompoundAssignment(CompoundAssignmentTree tree
, ControlFlowNode previous
) {
90 return scan(tree
.getExpression(), previous
);
93 public ControlFlowNode
visitConditionalExpression(ConditionalExpressionTree tree
, ControlFlowNode previous
) {
94 ControlFlowNode condition
= scan(tree
.getCondition(), previous
);
96 ControlFlowNode ifTrue
= scan(tree
.getTrueExpression(), condition
);
97 condition
.setSuccessor(ifTrue
);
99 // We can not use scan; it clobbers the successor, which is bad.
100 // TODO encapsulate this?
101 ControlFlowNode ifFalse
= new ControlFlowNode(tree
.getFalseExpression());
102 ifFalse
.getPredecessors().add(condition
);
103 condition
.setElseSuccessor(ifFalse
);
105 ControlFlowNode join
= new ControlFlowNode(null);
106 join
.getPredecessors().add(ifTrue
);
107 join
.getPredecessors().add(ifFalse
);
108 ifTrue
.setSuccessor(join
);
109 ifFalse
.setSuccessor(join
);
114 public ControlFlowNode
visitContinue(ContinueTree tree
, ControlFlowNode previous
) {
115 return null; // TODO replace
118 public ControlFlowNode
visitDoWhileLoop(DoWhileLoopTree tree
, ControlFlowNode previous
) {
120 return null; // TODO replace
123 public ControlFlowNode
visitEmptyStatement(EmptyStatementTree tree
, ControlFlowNode previous
) {
127 public ControlFlowNode
visitEnhancedForLoop(EnhancedForLoopTree tree
, ControlFlowNode previous
) {
128 // TODO this is likely wrong too
129 ControlFlowNode expression
= scan(tree
.getExpression(), previous
);
130 ControlFlowNode statement
= scan(tree
.getStatement(), expression
);
132 // We can not use scan; it clobbers the successor, which is bad.
133 // TODO encapsulate this?
134 ControlFlowNode split
= new ControlFlowNode(null);
135 split
.getPredecessors().add(statement
);
136 expression
.getPredecessors().add(split
);
137 statement
.setSuccessor(split
);
138 split
.setElseSuccessor(expression
);
143 public ControlFlowNode
visitErroneous(ErroneousTree tree
, ControlFlowNode previous
) {
148 public ControlFlowNode
visitExpressionStatement(ExpressionStatementTree tree
, ControlFlowNode previous
) {
149 return scan(tree
.getExpression(), previous
);
152 public ControlFlowNode
visitForLoop(ForLoopTree tree
, ControlFlowNode previous
) {
153 ControlFlowNode init
= previous
;
154 for (StatementTree stmt
: tree
.getInitializer())
155 init
= scan(stmt
, init
);
156 ControlFlowNode condition
= scan(tree
.getCondition(), init
);
157 ControlFlowNode statement
= scan(tree
.getStatement(), condition
);
158 ControlFlowNode update
= statement
;
159 for (ExpressionStatementTree stmt
: tree
.getUpdate())
160 update
= scan(stmt
, update
);
162 condition
.getPredecessors().add(update
);
163 update
.setSuccessor(condition
);
165 ControlFlowNode dummy
= new ControlFlowNode(null);
166 dummy
.getPredecessors().add(condition
);
167 condition
.setElseSuccessor(dummy
);
172 public ControlFlowNode
visitIdentifier(IdentifierTree tree
, ControlFlowNode previous
) {
173 ControlFlowNode rv
= new ControlFlowNode(tree
);
175 if (previous
!= null) {
176 rv
.getPredecessors().add(previous
);
177 previous
.setSuccessor(previous
);
183 public ControlFlowNode
visitIf(IfTree tree
, ControlFlowNode previous
) {
184 ControlFlowNode condition
= scan(tree
.getCondition(), previous
);
186 ControlFlowNode thenBlock
= scan(tree
.getThenStatement(), condition
);
187 condition
.setSuccessor(thenBlock
);
189 // We can not use scan; it clobbers the successor, which is bad.
190 // TODO encapsulate this?
191 ControlFlowNode elseBlock
= new ControlFlowNode(tree
.getElseStatement());
192 elseBlock
.getPredecessors().add(condition
);
193 condition
.setElseSuccessor(elseBlock
);
195 ControlFlowNode join
= new ControlFlowNode(null);
196 join
.getPredecessors().add(thenBlock
);
197 join
.getPredecessors().add(elseBlock
);
198 thenBlock
.setSuccessor(join
);
199 elseBlock
.setSuccessor(join
);
204 public ControlFlowNode
visitImport(ImportTree tree
, ControlFlowNode previous
) {
205 return null; // TODO replace
208 public ControlFlowNode
visitInstanceOf(InstanceOfTree tree
, ControlFlowNode previous
) {
209 return scan(tree
.getExpression(), previous
);
212 public ControlFlowNode
visitLabeledStatement(LabeledStatementTree tree
, ControlFlowNode previous
) {
213 return null; // TODO replace
216 public ControlFlowNode
visitLiteral(LiteralTree tree
, ControlFlowNode previous
) {
217 System
.out
.println("TOREMOVE in literal");
218 ControlFlowNode rv
= new ControlFlowNode(tree
);
220 if (previous
!= null) {
221 rv
.getPredecessors().add(previous
);
222 previous
.setSuccessor(previous
);
228 public ControlFlowNode
visitMemberSelect(MemberSelectTree tree
, ControlFlowNode previous
) {
229 return scan(tree
.getExpression(), previous
);
232 public ControlFlowNode
visitMethod(MethodTree tree
, ControlFlowNode previous
) {
233 // TODO it's probably a bit more complex than this
235 ControlFlowNode endpoint
= new ControlFlowNode(null);
236 returnEndpoints
.push(endpoint
);
237 ControlFlowNode rv
= scan(tree
.getBody(), previous
);
238 returnEndpoints
.pop();
243 public ControlFlowNode
visitMethodInvocation(MethodInvocationTree tree
, ControlFlowNode previous
) {
244 System
.out
.println("TOREMOVE in method invocation");
245 ControlFlowNode current
= previous
;
246 for (ExpressionTree expr
: tree
.getArguments())
247 current
= scan(expr
, current
);
251 public ControlFlowNode
visitModifiers(ModifiersTree tree
, ControlFlowNode previous
) {
252 return null; // TODO replace
255 public ControlFlowNode
visitNewArray(NewArrayTree tree
, ControlFlowNode previous
) {
256 return null; // TODO replace
259 public ControlFlowNode
visitNewClass(NewClassTree tree
, ControlFlowNode previous
) {
260 return null; // TODO replace
263 public ControlFlowNode
visitOther(Tree tree
, ControlFlowNode previous
) {
264 return null; // TODO replace
267 public ControlFlowNode
visitParameterizedType(ParameterizedTypeTree tree
, ControlFlowNode previous
) {
268 return null; // TODO replace
271 public ControlFlowNode
visitParenthesized(ParenthesizedTree tree
, ControlFlowNode previous
) {
272 return scan(tree
.getExpression(), previous
);
275 public ControlFlowNode
visitPrimitiveType(PrimitiveTypeTree tree
, ControlFlowNode previous
) {
276 return null; // TODO replace
279 public ControlFlowNode
visitReturn(ReturnTree tree
, ControlFlowNode previous
) {
280 ControlFlowNode rv
= scan(tree
.getExpression(), previous
);
281 ControlFlowNode endOfBlock
= returnEndpoints
.peek();
282 rv
.setSuccessor(endOfBlock
);
283 endOfBlock
.getPredecessors().add(rv
);
287 public ControlFlowNode
visitSwitch(SwitchTree tree
, ControlFlowNode previous
) {
288 return null; // TODO replace
289 //ControlFlowNode current = scan(tree.getExpression(), previous);
290 // TODO First thought was to cheat and call it a bunch of if statements, but that
291 // won't work since not all cases have breaks at the end. Looks like we didn't get
292 // out of goto after all :(
295 public ControlFlowNode
visitSynchronized(SynchronizedTree tree
, ControlFlowNode previous
) {
296 return scan(tree
.getBlock(), scan(tree
.getExpression(), previous
));
299 public ControlFlowNode
visitThrow(ThrowTree tree
, ControlFlowNode previous
) {
300 return null; // TODO replace
303 public ControlFlowNode
visitTry(TryTree tree
, ControlFlowNode previous
) {
304 return null; // TODO replace
307 public ControlFlowNode
visitTypeCast(TypeCastTree tree
, ControlFlowNode previous
) {
308 return scan(tree
.getExpression(), previous
);
311 public ControlFlowNode
visitTypeParameter(TypeParameterTree tree
, ControlFlowNode previous
) {
312 return null; // TODO replace
315 public ControlFlowNode
visitUnary(UnaryTree tree
, ControlFlowNode previous
) {
316 return scan(tree
.getExpression(), previous
);
319 public ControlFlowNode
visitVariable(VariableTree tree
, ControlFlowNode previous
) {
320 return null; // TODO replace
323 public ControlFlowNode
visitWhileLoop(WhileLoopTree tree
, ControlFlowNode previous
) {
324 ControlFlowNode condition
= scan(tree
.getCondition(), previous
);
325 ControlFlowNode statement
= scan(tree
.getStatement(), condition
);
326 condition
.getPredecessors().add(statement
);
327 statement
.setSuccessor(condition
);
329 ControlFlowNode dummy
= new ControlFlowNode(null);
330 dummy
.getPredecessors().add(condition
);
331 condition
.setElseSuccessor(dummy
);
336 public ControlFlowNode
visitWildcard(WildcardTree tree
, ControlFlowNode previous
) {
337 return null; // TODO replace