Add README file intended to lower the barrier to entry for the next
[checker-flow-ng.git] / GenerateControlFlow.java
blob5cb23b9882c753aea5ae4411bf90d5982fbd8420
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() {
11 super();
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);
24 return 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);
60 return 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);
79 scan(member, null);
80 // TODO s/null/previous/?
82 return 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);
111 return join;
114 public ControlFlowNode visitContinue(ContinueTree tree, ControlFlowNode previous) {
115 return null; // TODO replace
118 public ControlFlowNode visitDoWhileLoop(DoWhileLoopTree tree, ControlFlowNode previous) {
119 // TODO reimplement
120 return null; // TODO replace
123 public ControlFlowNode visitEmptyStatement(EmptyStatementTree tree, ControlFlowNode previous) {
124 return 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);
140 return split;
143 public ControlFlowNode visitErroneous(ErroneousTree tree, ControlFlowNode previous) {
144 // TODO Yeah, right.
145 return null;
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);
169 return 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);
180 return rv;
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);
201 return 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);
225 return rv;
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();
240 return rv;
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);
248 return 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);
284 return 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);
333 return dummy;
336 public ControlFlowNode visitWildcard(WildcardTree tree, ControlFlowNode previous) {
337 return null; // TODO replace