package synthesijer.jcfrontend;
import openjdk.com.sun.tools.javac.tree.JCTree;
import openjdk.com.sun.tools.javac.tree.JCTree.JCBlock;
import openjdk.com.sun.tools.javac.tree.JCTree.JCBreak;
import openjdk.com.sun.tools.javac.tree.JCTree.JCCase;
import openjdk.com.sun.tools.javac.tree.JCTree.JCContinue;
import openjdk.com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
import openjdk.com.sun.tools.javac.tree.JCTree.JCExpression;
import openjdk.com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import openjdk.com.sun.tools.javac.tree.JCTree.JCForLoop;
import openjdk.com.sun.tools.javac.tree.JCTree.JCIf;
import openjdk.com.sun.tools.javac.tree.JCTree.JCReturn;
import openjdk.com.sun.tools.javac.tree.JCTree.JCSkip;
import openjdk.com.sun.tools.javac.tree.JCTree.JCStatement;
import openjdk.com.sun.tools.javac.tree.JCTree.JCSwitch;
import openjdk.com.sun.tools.javac.tree.JCTree.JCSynchronized;
import openjdk.com.sun.tools.javac.tree.JCTree.JCTry;
import openjdk.com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import openjdk.com.sun.tools.javac.tree.JCTree.JCWhileLoop;
import openjdk.com.sun.tools.javac.tree.JCTree.Visitor;
import synthesijer.SynthesijerUtils;
import synthesijer.ast.Expr;
import synthesijer.ast.Module;
import synthesijer.ast.Scope;
import synthesijer.ast.Statement;
import synthesijer.ast.Type;
import synthesijer.ast.statement.BlockStatement;
import synthesijer.ast.statement.BreakStatement;
import synthesijer.ast.statement.ContinueStatement;
import synthesijer.ast.statement.DoWhileStatement;
import synthesijer.ast.statement.ExprStatement;
import synthesijer.ast.statement.ForStatement;
import synthesijer.ast.statement.IfStatement;
import synthesijer.ast.statement.ReturnStatement;
import synthesijer.ast.statement.SkipStatement;
import synthesijer.ast.statement.SwitchStatement;
import synthesijer.ast.statement.TryStatement;
import synthesijer.ast.statement.VariableDecl;
import synthesijer.ast.statement.WhileStatement;
public class JCStmtVisitor extends Visitor{
public final Scope scope;
private Statement stmt;
public JCStmtVisitor(Scope scope){
this.scope = scope;
}
public Statement getStatement(){
return stmt;
}
private Statement stepIn(JCTree that, Scope scope){
JCStmtVisitor visitor = new JCStmtVisitor(scope);
that.accept(visitor);
return visitor.getStatement();
}
private Expr stepIn(JCExpression that, Scope scope){
JCExprVisitor visitor = new JCExprVisitor(scope);
that.accept(visitor);
return visitor.getExpr();
}
private BlockStatement wrapBlockStatement(Statement stmt){
if(stmt instanceof BlockStatement){
return (BlockStatement)stmt;
}else{
BlockStatement block = new BlockStatement(stmt.getScope());
block.addStatement(stmt);
return block;
}
}
public void visitIf(JCIf that){
IfStatement tmp = new IfStatement(scope);
tmp.setCondition(stepIn(that.cond, scope));
tmp.setThenPart(wrapBlockStatement(stepIn(that.thenpart, scope)));
if(that.elsepart != null){
tmp.setElsePart(wrapBlockStatement(stepIn(that.elsepart, scope)));
}
stmt = tmp;
}
public void visitForLoop(JCForLoop that){
ForStatement tmp = new ForStatement(scope);
for(JCStatement s: that.init){
//tmp.addInitialize(stepIn(s, scope));
tmp.addInitialize(stepIn(s, tmp));
}
tmp.setCondition(stepIn(that.cond, tmp));
for(JCStatement s: that.step){
tmp.addUpdate(stepIn(s, tmp));
}
tmp.setBody(wrapBlockStatement(stepIn(that.body, tmp)));
stmt = tmp;
}
public void visitWhileLoop(JCWhileLoop that){
WhileStatement tmp = new WhileStatement(scope);
tmp.setCondition(stepIn(that.cond, scope));
tmp.setBody(wrapBlockStatement(stepIn(that.body, scope)));
stmt = tmp;
}
public void visitDoLoop(JCDoWhileLoop that){
DoWhileStatement tmp = new DoWhileStatement(scope);
tmp.setCondition(stepIn(that.cond, scope));
tmp.setBody(wrapBlockStatement(stepIn(that.body, scope)));
stmt = tmp;
}
public void visitBlock(JCBlock that){
BlockStatement tmp = new BlockStatement(scope);
for(JCStatement s: that.getStatements()){
JCStmtVisitor visitor = new JCStmtVisitor(scope);
s.accept(visitor);
tmp.addStatement(visitor.getStatement());
}
stmt = tmp;
}
public void visitReturn(JCReturn that){
ReturnStatement tmp = new ReturnStatement(scope);
if(that.expr != null){
JCExprVisitor visitor = new JCExprVisitor(scope);
that.expr.accept(visitor);
tmp.setExpr(visitor.getExpr());
}
stmt = tmp;
}
public void visitExec(JCExpressionStatement that){
JCExprVisitor visitor = new JCExprVisitor(scope);
that.expr.accept(visitor);
stmt = new ExprStatement(scope, visitor.getExpr());
}
public void visitBreak(JCBreak that){
stmt = new BreakStatement(scope);
}
public void visitContinue(JCContinue that){
stmt = new ContinueStatement(scope);
}
public void visitSkip(JCSkip that){
stmt = new SkipStatement(scope);
}
public void visitTry(JCTry that){
TryStatement tmp = new TryStatement(scope);
JCStmtVisitor visitor = new JCStmtVisitor(scope);
that.body.accept(visitor);
tmp.setBody(visitor.getStatement());
stmt = tmp;
}
public void visitSynchronized(JCSynchronized that){
visitBlock(that.body);
}
public void visitSwitch(JCSwitch that){
SwitchStatement tmp = new SwitchStatement(scope);
tmp.setSelector(stepIn(that.selector, scope));
for(JCCase c: that.cases){
SwitchStatement.Elem elem;
if(c.pat != null){
elem = tmp.newElement(stepIn(c.pat, scope));
}else{
elem = tmp.getDefaultElement();
}
for(JCStatement s: c.stats){
elem.addStatement(stepIn(s, scope));
}
}
stmt = tmp;
}
public void visitVarDef(JCVariableDecl that) {
String name = that.getName().toString();
Type type = TypeBuilder.genType(that.getType());
Expr init;
if(that.init != null){
JCExprVisitor visitor = new JCExprVisitor(scope);
that.init.accept(visitor);
init = visitor.getExpr();
}else{
init = null;
}
VariableDecl tmp = new VariableDecl(scope, name, type, init);
if(JCFrontendUtils.isGlobalConstant(that.mods)){
tmp.setGlobalConstant(true);
}
if(JCFrontendUtils.isPrivate(that.mods) == false && scope instanceof Module){
tmp.setPublic(true);
}
if(JCFrontendUtils.isVolatile(that.mods)){
tmp.setVolatile(true);
}
if(JCFrontendUtils.isAnnotatedBy(that.mods.annotations, "Debug")){
tmp.setDebug(true);
}
scope.addVariableDecl(tmp);
stmt = tmp;
}
public void visitTree(JCTree t){
SynthesijerUtils.error("[JCStmtVisitor] The following is unexpected in this context.");
SynthesijerUtils.dump(t);
}
}