package synthesijer.jcfrontend; import openjdk.com.sun.tools.javac.tree.JCTree; import openjdk.com.sun.tools.javac.tree.JCTree.JCArrayAccess; import openjdk.com.sun.tools.javac.tree.JCTree.JCAssign; import openjdk.com.sun.tools.javac.tree.JCTree.JCAssignOp; import openjdk.com.sun.tools.javac.tree.JCTree.JCBinary; import openjdk.com.sun.tools.javac.tree.JCTree.JCConditional; import openjdk.com.sun.tools.javac.tree.JCTree.JCExpression; import openjdk.com.sun.tools.javac.tree.JCTree.JCFieldAccess; import openjdk.com.sun.tools.javac.tree.JCTree.JCIdent; import openjdk.com.sun.tools.javac.tree.JCTree.JCLiteral; import openjdk.com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import openjdk.com.sun.tools.javac.tree.JCTree.JCNewArray; import openjdk.com.sun.tools.javac.tree.JCTree.JCNewClass; import openjdk.com.sun.tools.javac.tree.JCTree.JCParens; import openjdk.com.sun.tools.javac.tree.JCTree.JCTypeCast; import openjdk.com.sun.tools.javac.tree.JCTree.JCUnary; import openjdk.com.sun.tools.javac.tree.JCTree.Visitor; import synthesijer.SynthesijerUtils; import synthesijer.ast.Expr; import synthesijer.ast.Op; import synthesijer.ast.Scope; import synthesijer.ast.Type; import synthesijer.ast.expr.ArrayAccess; import synthesijer.ast.expr.AssignExpr; import synthesijer.ast.expr.AssignOp; import synthesijer.ast.expr.BinaryExpr; import synthesijer.ast.expr.CondExpr; import synthesijer.ast.expr.FieldAccess; import synthesijer.ast.expr.Ident; import synthesijer.ast.expr.Literal; import synthesijer.ast.expr.MethodInvocation; import synthesijer.ast.expr.NewArray; import synthesijer.ast.expr.NewClassExpr; import synthesijer.ast.expr.ParenExpr; import synthesijer.ast.expr.TypeCast; import synthesijer.ast.expr.UnaryExpr; import synthesijer.ast.type.ArrayType; import synthesijer.ast.type.ComponentType; public class JCExprVisitor extends Visitor{ public final Scope scope; private Expr expr; public JCExprVisitor(Scope scope){ this.scope = scope; } public Expr getExpr(){ return expr; } public void visitIdent(JCIdent that){ Ident tmp = new Ident(scope); tmp.setIdent(that.toString()); expr = tmp; } private Expr stepIn(JCExpression expr){ JCExprVisitor visitor = new JCExprVisitor(scope); expr.accept(visitor); return visitor.getExpr(); } public void visitBinary(JCBinary that){ //System.out.println(that); BinaryExpr tmp = new BinaryExpr(scope); Expr lhs = stepIn(that.lhs); tmp.setLhs(lhs); Expr rhs = stepIn(that.rhs); setForceTypeCast(lhs, rhs); tmp.setRhs(rhs); tmp.setOp(Op.getOp(that.operator.name.toString())); expr = tmp; } public void visitUnary(JCUnary that){ /* System.out.println("unary:" + that.toString()); System.out.println("op:" + that.getOperator().name); if(that.toString().startsWith(that.getOperator().name.toString())){ System.out.println("prefix"); }else if(that.toString().endsWith(that.getOperator().name.toString())){ System.out.println("postfix"); } */ boolean postfix = false; if(that.toString().endsWith(that.getOperator().name.toString())){ postfix = true; } UnaryExpr tmp = new UnaryExpr(scope); tmp.setOp(Op.getOp(that.operator.name.toString())); tmp.setArg(stepIn(that.arg)); tmp.setPostfix(postfix); expr = tmp; } public void visitApply(JCMethodInvocation that){ MethodInvocation tmp = new MethodInvocation(scope); tmp.setMethod(stepIn(that.getMethodSelect())); for(JCExpression param: that.args){ tmp.addParameter(stepIn(param)); } expr = tmp; } public void visitSelect(JCFieldAccess that){ FieldAccess tmp = new FieldAccess(scope); tmp.setSelected(stepIn(that.selected)); Ident id = new Ident(scope); id.setIdent(that.name.toString()); tmp.setIdent(id); expr = tmp; } public void visitLiteral(JCLiteral that){ Literal tmp = new Literal(scope); switch(that.getKind()){ case INT_LITERAL: tmp.setValue((int)(that.getValue())); break; case BOOLEAN_LITERAL: tmp.setValue((boolean)(that.getValue())); break; case CHAR_LITERAL: tmp.setValue((char)(that.getValue())); break; case DOUBLE_LITERAL: tmp.setValue((double)(that.getValue())); break; case FLOAT_LITERAL: tmp.setValue((float)(that.getValue())); break; case LONG_LITERAL: tmp.setValue((long)(that.getValue())); break; case STRING_LITERAL: tmp.setValue((String)(that.getValue())); break; case NULL_LITERAL: tmp.setNull(); break; default: tmp.setUndefined(); break; } expr = tmp; } private void setForceTypeCast(Expr lhs, Expr rhs){ if(rhs instanceof Literal == false) return; Type ltype, rtype; ltype = lhs.getType(); if(ltype instanceof ComponentType == true) return; // TODO while(ltype instanceof ArrayType){ ltype = ((ArrayType)ltype).getElemType(); } rtype = rhs.getType(); if(ltype == rtype) return; //SynthesijerUtils.dump(lhs.getClass()); //System.out.printf("JCExprVisitor: RHS is casted into %s from %s\n", ltype, rtype); //((Literal)rhs).castType(ltype); } public void visitAssign(JCAssign that){ AssignExpr tmp = new AssignExpr(scope); tmp.setLhs(stepIn(that.lhs)); tmp.setRhs(stepIn(that.rhs)); setForceTypeCast(tmp.getLhs(), tmp.getRhs()); expr = tmp; } public void visitAssignop(JCAssignOp that){ AssignOp tmp = new AssignOp(scope); tmp.setLhs(stepIn(that.lhs)); tmp.setRhs(stepIn(that.rhs)); tmp.setOp(Op.getOp(that.operator.name.toString())); expr = tmp; } public void visitNewArray(JCNewArray that){ NewArray tmp = new NewArray(scope); for(JCExpression dim: that.dims){ tmp.addDimExpr(stepIn(dim)); } if(that.elems != null){ // ad-hoc: to support array initialization for(JCExpression expr: that.elems){ tmp.addElem(stepIn(expr)); } if(that.dims.size() == 0 && that.elems.size() > 0){ Literal d = new Literal(scope); d.setValue(that.elems.size()); tmp.addDimExpr(d); // SynthesijerUtils.warn("In " + scope.getModule().getName()); // SynthesijerUtils.warn("Initialization with new expression is not supported."); // SynthesijerUtils.warn("Initialization values, " + that + " are not used."); } } expr = tmp; } public void visitIndexed(JCArrayAccess that){ ArrayAccess tmp = new ArrayAccess(scope); { tmp.setIndexed(stepIn(that.indexed)); } { tmp.setIndex(stepIn(that.index)); } expr = tmp; } public void visitTypeCast(JCTypeCast that){ TypeCast tmp = new TypeCast(scope); tmp.setExpr(stepIn(that.expr)); tmp.setTargetType(TypeBuilder.genType(that.getType())); expr = tmp; } public void visitParens(JCParens that){ ParenExpr tmp = new ParenExpr(scope); tmp.setExpr(stepIn(that.expr)); expr = tmp; } public void visitNewClass(JCNewClass that){ NewClassExpr tmp = new NewClassExpr(scope); tmp.setClassName(that.constructor.owner.toString()); for(JCExpression arg: that.args){ tmp.addParam(stepIn(arg)); } expr = tmp; } public void visitConditional(JCConditional that){ CondExpr tmp = new CondExpr(scope); tmp.setCond(stepIn(that.cond)); tmp.setTruePart(stepIn(that.truepart)); tmp.setFalsePart(stepIn(that.falsepart)); expr = tmp; } public void visitTree(JCTree t){ SynthesijerUtils.error("[JCExprVisitor] The following is unexpected in this context."); SynthesijerUtils.dump(t); } }