/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.ir.compiler.java; import gw.lang.ir.IRClass; import gw.lang.ir.IRElement; import gw.lang.ir.IRExpression; import gw.lang.ir.IRStatement; import gw.lang.ir.IRSymbol; import gw.lang.ir.IRType; import gw.lang.ir.expression.IRArithmeticExpression; import gw.lang.ir.expression.IRArrayLengthExpression; import gw.lang.ir.expression.IRArrayLoadExpression; import gw.lang.ir.expression.IRBooleanLiteral; import gw.lang.ir.expression.IRCastExpression; import gw.lang.ir.expression.IRCharacterLiteral; import gw.lang.ir.expression.IRClassLiteral; import gw.lang.ir.expression.IRCompositeExpression; import gw.lang.ir.expression.IRConditionalAndExpression; import gw.lang.ir.expression.IRConditionalOrExpression; import gw.lang.ir.expression.IREqualityExpression; import gw.lang.ir.expression.IRFieldGetExpression; import gw.lang.ir.expression.IRIdentifier; import gw.lang.ir.expression.IRInstanceOfExpression; import gw.lang.ir.expression.IRMethodCallExpression; import gw.lang.ir.expression.IRNegationExpression; import gw.lang.ir.expression.IRNewArrayExpression; import gw.lang.ir.expression.IRNewExpression; import gw.lang.ir.expression.IRNewMultiDimensionalArrayExpression; import gw.lang.ir.expression.IRNoOpExpression; import gw.lang.ir.expression.IRNotExpression; import gw.lang.ir.expression.IRNullLiteral; import gw.lang.ir.expression.IRNumericLiteral; import gw.lang.ir.expression.IRPrimitiveTypeConversion; import gw.lang.ir.expression.IRRelationalExpression; import gw.lang.ir.expression.IRStringLiteralExpression; import gw.lang.ir.expression.IRTernaryExpression; import gw.lang.ir.statement.IRArrayStoreStatement; import gw.lang.ir.statement.IRAssignmentStatement; import gw.lang.ir.statement.IRBreakStatement; import gw.lang.ir.statement.IRCaseClause; import gw.lang.ir.statement.IRCatchClause; import gw.lang.ir.statement.IRContinueStatement; import gw.lang.ir.statement.IRDoWhileStatement; import gw.lang.ir.statement.IREvalStatement; import gw.lang.ir.statement.IRFieldDecl; import gw.lang.ir.statement.IRFieldSetStatement; import gw.lang.ir.statement.IRForEachStatement; import gw.lang.ir.statement.IRIfStatement; import gw.lang.ir.statement.IRMethodCallStatement; import gw.lang.ir.statement.IRMethodStatement; import gw.lang.ir.statement.IRMonitorLockAcquireStatement; import gw.lang.ir.statement.IRMonitorLockReleaseStatement; import gw.lang.ir.statement.IRNewStatement; import gw.lang.ir.statement.IRNoOpStatement; import gw.lang.ir.statement.IRReturnStatement; import gw.lang.ir.statement.IRStatementList; import gw.lang.ir.statement.IRSwitchStatement; import gw.lang.ir.statement.IRSyntheticStatement; import gw.lang.ir.statement.IRThrowStatement; import gw.lang.ir.statement.IRTryCatchFinallyStatement; import gw.lang.ir.statement.IRWhileStatement; import java.lang.reflect.Modifier; import java.util.List; public class IRJavaCompiler { private StringBuilder _output = new StringBuilder(); private int _indent; public IRJavaCompiler() { } public StringBuilder getOutput() { return _output; } public void compileClassStatement(IRClass irClass) { _output.append("// Compiled from ").append(irClass.getSourceFile()).append("\n"); _output.append(getModifierString(irClass.getModifiers())).append(irClass.getName()); if (irClass.getSuperType() != null) { _output.append(" extends ").append(irClass.getSuperType().getRelativeName()); } if (!irClass.getInterfaces().isEmpty()) { _output.append(" implements ").append(joinTypeNames(irClass.getInterfaces())); _output.append(" "); } _output.append("{\n"); // Inner classes pushIndent(); // Fields for (IRFieldDecl fieldDecl : irClass.getFields()) { compileIRFieldDecl(fieldDecl); } _output.append("\n"); // Methods for (IRMethodStatement methodStatement : irClass.getMethods()) { compileIRMethodStatement(methodStatement); _output.append("\n"); } popIndent(); _output.append("}"); } private void compileIRElement(IRElement element) { if (element instanceof IRStatement) { compileIRStatement((IRStatement) element); } else { compileIRExpression((IRExpression) element); } } private void compileIRStatement(IRStatement statement) { if (statement == null) { return; } if (statement.getOriginalSourceStatement() != null) { appendOriginalSourceComment(statement.getOriginalSourceStatement()); } if (statement instanceof IRAssignmentStatement) { compileIRAssignmentStatement((IRAssignmentStatement) statement); } else if (statement instanceof IRFieldDecl) { compileIRFieldDecl((IRFieldDecl) statement); } else if (statement instanceof IRFieldSetStatement) { compileIRFieldSetStatement((IRFieldSetStatement) statement); } else if (statement instanceof IRIfStatement) { compileIRIfStatement((IRIfStatement) statement); } else if (statement instanceof IRMethodCallStatement) { compileIRMethodCallStatement((IRMethodCallStatement) statement); } else if (statement instanceof IRNewStatement ) { compileIRNewStatement( (IRNewStatement)statement ); } else if (statement instanceof IRMethodStatement) { compileIRMethodStatement( (IRMethodStatement)statement ); } else if (statement instanceof IRNoOpStatement) { compileIRNoOpStatement( (IRNoOpStatement)statement ); } else if (statement instanceof IRReturnStatement) { compileIRReturnStatement( (IRReturnStatement)statement ); } else if (statement instanceof IRStatementList) { compileIRStatementList( (IRStatementList)statement ); } else if (statement instanceof IRArrayStoreStatement) { compileIRArrayStoreStatement( (IRArrayStoreStatement)statement ); } else if (statement instanceof IRThrowStatement) { compileIRThrowStatement( (IRThrowStatement)statement ); } else if (statement instanceof IRTryCatchFinallyStatement) { compileIRTryCatchFinallyStatement( (IRTryCatchFinallyStatement)statement ); } else if (statement instanceof IRSyntheticStatement) { compileIRSyntheticStatement( (IRSyntheticStatement)statement ); } else if (statement instanceof IRWhileStatement) { compileIRWhileStatement( (IRWhileStatement)statement ); } else if (statement instanceof IRDoWhileStatement) { compileIRDoWhileStatement( (IRDoWhileStatement)statement ); } else if (statement instanceof IRForEachStatement) { compileIRForEachStatement( (IRForEachStatement)statement ); } else if (statement instanceof IRSwitchStatement) { compileIRSwitchStatement( (IRSwitchStatement)statement ); } else if (statement instanceof IRBreakStatement) { compileIRBreak( (IRBreakStatement)statement ); } else if (statement instanceof IRContinueStatement) { compileIRContinue( (IRContinueStatement)statement ); } else if (statement instanceof IREvalStatement) { compileIREvalStatement( (IREvalStatement)statement ); } else if (statement instanceof IRMonitorLockAcquireStatement) { compileIRMonitorLockAcquireStatement((IRMonitorLockAcquireStatement) statement); } else if (statement instanceof IRMonitorLockReleaseStatement ) { compileIRMonitorLockReleaseStatement((IRMonitorLockReleaseStatement) statement); } else { throw new IllegalArgumentException("Unrecognized statement of type " + statement.getClass()); } } private void compileIREvalStatement( IREvalStatement statement ) { appendIndent(); _output.append( "eval( " ); compileIRElement( statement.getExpression() ); _output.append( " )" ); } private void compileIRDoWhileStatement(IRDoWhileStatement irDoWhileStatement) { appendIndent(); _output.append("do {\n"); pushIndent(); compileIRElement(irDoWhileStatement.getBody()); popIndent(); appendIndent(); _output.append("} while ("); compileIRElement(irDoWhileStatement.getLoopTest()); _output.append(")\n"); } private void compileIRBreak( IRBreakStatement irBreakStatement ) { appendIndent( ); _output.append( "break;" ); } private void compileIRContinue( IRContinueStatement irBreakStatement ) { appendIndent( ); _output.append( "continue;" ); } private void compileIRMonitorLockAcquireStatement( IRMonitorLockAcquireStatement irMonitorLockAcquireStatement ) { appendIndent( ); _output.append( "synchronized( " ); compileIRElement( irMonitorLockAcquireStatement.getMonitoredObject() ); _output.append( " )" ); } private void compileIRMonitorLockReleaseStatement( IRMonitorLockReleaseStatement irMonitorLockReleaseStatement ) { } private void compileIRSwitchStatement(IRSwitchStatement irSwitchStatement ) { appendIndent(); _output.append("switch("); compileIRElement(irSwitchStatement.getInit()); _output.append(") {\n"); pushIndent(); for (IRCaseClause caseClause : irSwitchStatement.getCases()) { appendIndent(); _output.append("case "); compileIRElement( caseClause.getCondition() ); _output.append(":\n"); pushIndent(); for ( IRStatement statement : caseClause.getStatements() ) { compileIRElement( statement ); } popIndent(); } if (!irSwitchStatement.getDefaultStatements().isEmpty()) { appendIndent(); _output.append("default:\n"); pushIndent(); for (IRStatement statement : irSwitchStatement.getDefaultStatements()) { compileIRElement( statement ); } popIndent(); } popIndent(); appendIndent(); _output.append("}\n"); } private void compileIRForEachStatement(IRForEachStatement irForEachStatement ) { appendIndent( ); _output.append( "/*foreach*/\n" ); for(IRStatement initializer : irForEachStatement.getInitializers()) { appendIndent(); compileIRElement(initializer); _output.append( "\n" ); } if( irForEachStatement.hasIdentifierToNullCheck() ) { appendIndent(); _output.append( "if (" ).append( irForEachStatement.getIdentifierToNullCheck().getSymbol().getName() ).append( " != null) {\n" ); pushIndent(); } appendIndent(); _output.append("while ("); compileIRElement(irForEachStatement.getLoopTest()); _output.append(") {\n"); pushIndent(); for(IRStatement initializer : irForEachStatement.getIncrementors()) { compileIRElement(initializer); _output.append( "\n" ); } compileIRElement(irForEachStatement.getBody()); popIndent(); appendIndent(); _output.append("}\n"); if( irForEachStatement.hasIdentifierToNullCheck() ) { popIndent(); appendIndent(); _output.append( "}\n" ); } } private void compileIRWhileStatement(IRWhileStatement irWhileStatement) { appendIndent(); _output.append("while ("); compileIRElement(irWhileStatement.getLoopTest()); _output.append(") {\n"); pushIndent(); compileIRElement(irWhileStatement.getBody()); popIndent(); appendIndent(); _output.append("}\n"); } private void compileIRSyntheticStatement(IRSyntheticStatement irSyntheticStatement) { appendIndent(); compileIRElement(irSyntheticStatement.getExpression()); _output.append(";\n"); } private void compileIRTryCatchFinallyStatement(IRTryCatchFinallyStatement irTryCatchFinallyStatement) { appendIndent(); _output.append("try {\n"); pushIndent(); compileIRElement(irTryCatchFinallyStatement.getTryBody()); popIndent(); appendIndent(); _output.append("}\n"); for (IRCatchClause catchClause : irTryCatchFinallyStatement.getCatchStatements()) { appendIndent(); _output.append("catch( ").append(catchClause.getIdentifier().getType().getRelativeName()).append(" ").append(catchClause.getIdentifier().getName()).append(") {\n"); pushIndent(); compileIRElement(catchClause.getBody()); popIndent(); appendIndent(); _output.append("}\n"); } if (irTryCatchFinallyStatement.getFinallyBody() != null) { appendIndent(); _output.append("finally {\n"); pushIndent(); compileIRElement(irTryCatchFinallyStatement.getFinallyBody()); popIndent(); appendIndent(); _output.append("}\n"); } } private void compileIRThrowStatement(IRThrowStatement irThrowStatement) { appendIndent(); _output.append("throw "); compileIRElement(irThrowStatement.getException()); _output.append(";\n"); } private void compileIRArrayStoreStatement(IRArrayStoreStatement irArrayStoreStatement) { appendIndent(); compileIRElement(irArrayStoreStatement.getTarget()); _output.append("["); compileIRElement(irArrayStoreStatement.getIndex()); _output.append("] = "); compileIRElement(irArrayStoreStatement.getValue()); _output.append(";\n"); } private void compileIRFieldSetStatement(IRFieldSetStatement irFieldSetStatement) { appendIndent(); if (irFieldSetStatement.getLhs() == null) { _output.append(irFieldSetStatement.getOwnersType().getRelativeName()); } else { compileIRElement(irFieldSetStatement.getLhs()); } _output.append("."); _output.append(irFieldSetStatement.getName()); _output.append(" = "); compileIRElement(irFieldSetStatement.getRhs()); _output.append(";\n"); } private void compileIRIfStatement(IRIfStatement irIfStatement) { appendIndent(); _output.append("if ("); compileIRElement(irIfStatement.getExpression()); _output.append(") {\n"); pushIndent(); compileIRElement(irIfStatement.getIfStatement()); popIndent(); appendIndent(); _output.append("}"); if (irIfStatement.getElseStatement() != null) { _output.append(" else {\n"); pushIndent(); compileIRElement(irIfStatement.getElseStatement()); popIndent(); appendIndent(); _output.append("}"); } _output.append("\n"); } private void compileIRMethodCallStatement(IRMethodCallStatement irMethodCallStatement) { appendIndent(); compileIRElement(irMethodCallStatement.getExpression()); _output.append(";\n"); } private void compileIRNewStatement(IRNewStatement irNewExpr ) { appendIndent(); compileIRElement( irNewExpr.getNewExpression()); _output.append(";\n"); } private void compileIRNoOpStatement(IRNoOpStatement irNoOpStatement) { _output.append("\n"); } private void compileIRReturnStatement(IRReturnStatement irReturnStatement) { appendIndent(); _output.append("return"); if (irReturnStatement.getReturnValue() != null) { _output.append(" "); compileIRElement(irReturnStatement.getReturnValue()); } _output.append(";\n"); } private void compileIRStatementList(IRStatementList irStatementList) { for (IRStatement statement : irStatementList.getStatements()) { compileIRStatement(statement); } } private void compileIRAssignmentStatement(IRAssignmentStatement irAssignmentStatement) { appendIndent(); _output.append(irAssignmentStatement.getSymbol().getName()); _output.append(" = "); compileIRElement(irAssignmentStatement.getValue()); _output.append(";\n"); } private void compileIRExpression(IRExpression expression) { if (expression instanceof IRArithmeticExpression) { compileIRAdditiveExpression((IRArithmeticExpression) expression); } else if (expression instanceof IRArrayLoadExpression) { compileIRArrayLoadExpression((IRArrayLoadExpression) expression); } else if (expression instanceof IRBooleanLiteral) { compileIRBooleanLiteral((IRBooleanLiteral) expression); } else if (expression instanceof IRCompositeExpression) { compileIRCompositeExpression((IRCompositeExpression) expression); } else if (expression instanceof IREqualityExpression) { compileIREqualityExpression((IREqualityExpression) expression); } else if (expression instanceof IRFieldGetExpression) { compileIRFieldGetExpression((IRFieldGetExpression) expression); } else if (expression instanceof IRIdentifier) { compileIRIdentifier((IRIdentifier) expression); } else if (expression instanceof IRMethodCallExpression) { compileIRMethodCallExpression((IRMethodCallExpression) expression); } else if (expression instanceof IRNullLiteral) { compileIRNullLiteral((IRNullLiteral) expression); } else if (expression instanceof IRPrimitiveTypeConversion) { compileIRPrimitiveTypeConversion((IRPrimitiveTypeConversion) expression); } else if (expression instanceof IRTernaryExpression) { compileIRTernaryExpression((IRTernaryExpression) expression); } else if (expression instanceof IRNumericLiteral) { compileIRNumericLiteral((IRNumericLiteral) expression); } else if (expression instanceof IRStringLiteralExpression) { compileIRStringLiteralExpression((IRStringLiteralExpression) expression); } else if (expression instanceof IRNewArrayExpression) { compileIRNewArrayExpression((IRNewArrayExpression) expression); } else if (expression instanceof IRNewMultiDimensionalArrayExpression) { compileIRNewMultiDimenstionalArrayExpression( (IRNewMultiDimensionalArrayExpression)expression ); } else if (expression instanceof IRArrayLengthExpression) { compileIRArrayLengthExpression( (IRArrayLengthExpression)expression ); } else if (expression instanceof IRCastExpression) { compileIRCastExpression( (IRCastExpression)expression ); } else if (expression instanceof IRNewExpression) { compileIRNewExpression( (IRNewExpression)expression ); } else if (expression instanceof IRRelationalExpression) { compileIRRelationalExpression( (IRRelationalExpression)expression ); } else if (expression instanceof IRClassLiteral) { compileIRClassLiteral( (IRClassLiteral)expression ); } else if (expression instanceof IRNegationExpression) { compileIRNegationExpression( (IRNegationExpression)expression ); } else if (expression instanceof IRConditionalOrExpression) { compileIRConditionalOrExpression( (IRConditionalOrExpression)expression ); } else if (expression instanceof IRConditionalAndExpression) { compileIRConditionalAndExpression( (IRConditionalAndExpression)expression ); } else if (expression instanceof IRNotExpression) { compileIRNotExpression( (IRNotExpression)expression ); } else if (expression instanceof IRInstanceOfExpression) { compileIRInstanceOfExpression( (IRInstanceOfExpression)expression ); } else if (expression instanceof IRCharacterLiteral) { compileIRCharacterLiteral((IRCharacterLiteral) expression); } else if (expression instanceof IRNoOpExpression) { // Do nothing } else { throw new IllegalArgumentException("Unrecognized expression of type " + expression.getClass()); } } private void compileIRInstanceOfExpression(IRInstanceOfExpression irInstanceOfExpression) { _output.append("("); compileIRElement( irInstanceOfExpression.getRoot()); _output.append(" instanceof "); _output.append(irInstanceOfExpression.getTestType().getRelativeName()); _output.append(")"); } private void compileIRNotExpression(IRNotExpression irNotExpression) { _output.append("!("); compileIRElement(irNotExpression.getRoot()); _output.append(")"); } private void compileIRConditionalAndExpression(IRConditionalAndExpression irConditionalAndExpression) { _output.append("("); compileIRElement(irConditionalAndExpression.getLhs()); _output.append(" && "); compileIRElement(irConditionalAndExpression.getRhs()); _output.append(")"); } private void compileIRConditionalOrExpression(IRConditionalOrExpression irConditionalOrExpression) { _output.append("("); compileIRElement(irConditionalOrExpression.getLhs()); _output.append(" || "); compileIRElement(irConditionalOrExpression.getRhs()); _output.append(")"); } private void compileIRNegationExpression(IRNegationExpression irNegationExpression) { _output.append("-"); compileIRElement(irNegationExpression.getRoot()); } private void compileIRClassLiteral(IRClassLiteral irClassLiteral) { _output.append(irClassLiteral.getLiteralType().getName()).append(".class"); } private void compileIRRelationalExpression(IRRelationalExpression irRelationalExpression) { String op; switch(irRelationalExpression.getOp()) { case GT: op = " > "; break; case GTE: op = " >= "; break; case LT: op = " < "; break; case LTE: op = " <= "; break; default: throw new IllegalArgumentException("Unexpected operation " + irRelationalExpression.getOp()); } compileIRElement(irRelationalExpression.getLhs()); _output.append( op ); compileIRElement(irRelationalExpression.getRhs()); } private void compileIRNewExpression(IRNewExpression irNewExpression) { _output.append("new " + irNewExpression.getOwnersType().getRelativeName() + "("); for (int i = 0; i < irNewExpression.getArgs().size(); i++) { if (i > 0) { _output.append(", "); } compileIRElement(irNewExpression.getArgs().get(i)); } _output.append(")"); } private void compileIRCastExpression(IRCastExpression irCastExpression) { _output.append("((").append(irCastExpression.getType().getRelativeName()).append(") "); compileIRElement(irCastExpression.getRoot()); _output.append(")"); } private void compileIRNewArrayExpression(IRNewArrayExpression irNewArrayExpression) { _output.append("new ").append(irNewArrayExpression.getComponentType().getRelativeName()).append("["); compileIRElement(irNewArrayExpression.getSizeExpression()); _output.append("]"); } private void compileIRNewMultiDimenstionalArrayExpression(IRNewMultiDimensionalArrayExpression expr ) { _output.append("new ").append( expr.getResultType().getRelativeName()); for( IRExpression e: expr.getSizeExpressions() ) { _output.append( "[" ); compileIRElement( e ); _output.append("]"); } } private void compileIRArrayLengthExpression(IRArrayLengthExpression irNewArrayExpression) { compileIRElement(irNewArrayExpression.getRoot()); _output.append(".length"); } private void compileIRStringLiteralExpression(IRStringLiteralExpression irStringLiteralExpression) { _output.append("\"").append(irStringLiteralExpression.getValue()).append("\""); } private void compileIRCharacterLiteral(IRCharacterLiteral irCharacterLiteral) { _output.append('\''); char literal = irCharacterLiteral.getValue(); if(literal == '\'' || literal == '\\') { _output.append('\\'); } _output.append(literal); _output.append('\''); } private void compileIRNumericLiteral(IRNumericLiteral irNumericLiteral) { _output.append(irNumericLiteral.getValue()); } private void compileIRAdditiveExpression(IRArithmeticExpression irAdditiveExpression) { compileIRElement(irAdditiveExpression.getLhs()); switch(irAdditiveExpression.getOp()) { case Addition: _output.append(" + "); break; case Subtraction: _output.append(" - "); break; case Division: _output.append(" / "); break; case Multiplication: _output.append(" * "); break; case Remainder: _output.append(" % "); break; case ShiftLeft: _output.append(" << "); break; case ShiftRight: _output.append(" >> "); break; case UnsignedShiftRight: _output.append(" >>> "); break; case BitwiseAnd: _output.append(" & "); break; case BitwiseXor: _output.append(" ^ "); break; case BitwiseOr: _output.append(" | "); break; default: throw new IllegalArgumentException("Unexpected operation " + irAdditiveExpression.getOp().toString()); } compileIRElement(irAdditiveExpression.getRhs()); } private void compileIRArrayLoadExpression(IRArrayLoadExpression irArrayLoadExpression) { compileIRElement(irArrayLoadExpression.getRoot()); _output.append("["); compileIRElement(irArrayLoadExpression.getIndex()); _output.append("]"); } private void compileIRBooleanLiteral(IRBooleanLiteral irBooleanLiteral) { _output.append(irBooleanLiteral.getValue()); } private void compileIRCompositeExpression(IRCompositeExpression irCompositeExpression) { _output.append("[[\n"); pushIndent(); for (IRElement element : irCompositeExpression.getElements()) { // Expressions don't do their own indentation. Since the last element will be an expression, we need to do it ourselves // for that last statement. Otherwise, allow the statement compilation to handle it. if (element instanceof IRExpression) { appendIndent(); } compileIRElement(element); } _output.append("\n"); popIndent(); appendIndent(); _output.append("]]"); } private void compileIREqualityExpression(IREqualityExpression irEqualityExpression) { compileIRExpression(irEqualityExpression.getLhs()); _output.append(irEqualityExpression.isEquals() ? " == " : " != "); compileIRExpression(irEqualityExpression.getRhs()); } private void compileIRFieldGetExpression(IRFieldGetExpression irFieldGetExpression) { if (irFieldGetExpression.getLhs() == null) { _output.append(irFieldGetExpression.getOwnersType().getRelativeName()); } else { compileIRElement(irFieldGetExpression.getLhs()); } _output.append("."); _output.append(irFieldGetExpression.getName()); } private void compileIRIdentifier(IRIdentifier irIdentifier) { _output.append(irIdentifier.getSymbol().getName()); } private void compileIRMethodCallExpression(IRMethodCallExpression irMethodCallExpression) { if (irMethodCallExpression.getRoot() == null) { _output.append(irMethodCallExpression.getOwnersType().getRelativeName()); } else { compileIRExpression(irMethodCallExpression.getRoot()); } _output.append("."); _output.append(irMethodCallExpression.getName()); _output.append("("); for (int i = 0; i < irMethodCallExpression.getArgs().size(); i++) { if (i > 0) { _output.append(", "); } compileIRElement(irMethodCallExpression.getArgs().get(i)); } _output.append(")"); } private void compileIRNullLiteral(IRNullLiteral irNullLiteral) { _output.append("null"); } private void compileIRPrimitiveTypeConversion(IRPrimitiveTypeConversion irPrimitiveTypeConversion) { _output.append("(").append(irPrimitiveTypeConversion.getToType().getRelativeName()).append(") "); compileIRElement(irPrimitiveTypeConversion.getRoot()); } private void compileIRTernaryExpression(IRTernaryExpression irTernaryExpression) { _output.append("("); compileIRElement(irTernaryExpression.getTest()); _output.append(" ? "); compileIRElement(irTernaryExpression.getTrueValue()); _output.append(" : "); compileIRElement(irTernaryExpression.getFalseValue()); _output.append(")"); } private void compileIRFieldDecl(IRFieldDecl fieldDecl) { appendIndent(); _output.append(getModifierString(fieldDecl.getModifiers())).append(fieldDecl.getType().getRelativeName()).append(" ").append(fieldDecl.getName()); if (fieldDecl.getValue() != null) { _output.append(" = ").append(fieldDecl.getValue()); } _output.append(";\n"); } private void compileIRMethodStatement(IRMethodStatement methodStatement) { appendIndent(); _output.append(getModifierString(methodStatement.getModifiers())); _output.append(methodStatement.getReturnType().getRelativeName()).append(" "); _output.append(methodStatement.getName()); _output.append("("); _output.append(joinParameters(methodStatement.getParameters())); _output.append(") {\n"); pushIndent(); compileIRStatement(methodStatement.getMethodBody()); popIndent(); appendIndent(); _output.append("}\n"); } static final int BRIDGE = 0x00000040; static final int VARARGS = 0x00000080; static final int SYNTHETIC = 0x00001000; static final int ANNOTATION = 0x00002000; static final int ENUM = 0x00004000; private String getModifierString(int modifiers) { StringBuilder sb = new StringBuilder(); if (Modifier.isPublic(modifiers)) { sb.append("public "); } else if (Modifier.isPrivate(modifiers)) { sb.append("private "); } else if (Modifier.isProtected(modifiers)) { sb.append("protected "); } else { sb.append("internal "); } if (Modifier.isAbstract(modifiers)) { sb.append("abstract "); } if (Modifier.isFinal(modifiers)) { sb.append("final "); } if (Modifier.isInterface(modifiers)) { sb.append("interface "); } if (Modifier.isNative(modifiers)) { sb.append("native "); } if (Modifier.isStatic(modifiers)) { sb.append("static "); } // if (Modifier.isSynchronized(modifiers)) { // sb.append("synchronized "); // } if (Modifier.isTransient(modifiers)) { sb.append("transient "); } if (Modifier.isVolatile(modifiers)) { sb.append("volatile "); } if ((modifiers & BRIDGE) != 0) { sb.append("bridge "); } if ((modifiers & VARARGS) != 0) { sb.append("varargs "); } if ((modifiers & SYNTHETIC) != 0) { sb.append("synthetic "); } if ((modifiers & ANNOTATION) != 0) { sb.append("annotation "); } if ((modifiers & ENUM) != 0) { sb.append("enum "); } return sb.toString(); } private String joinTypeNames(List<IRType> types) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < types.size(); i++) { if (i > 0) { sb.append(", "); } sb.append(types.get(i).getRelativeName()); } return sb.toString(); } private String joinParameters(List<IRSymbol> symbols) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < symbols.size(); i++) { if (i > 0) { sb.append(", "); } sb.append(symbols.get(i).getType().getRelativeName()).append(" ").append(symbols.get(i).getName()); } return sb.toString(); } private void pushIndent() { _indent+=2; } private void popIndent() { _indent-=2; } private void appendIndent() { for (int i = 0; i < _indent; i++) { _output.append(" "); } } private void appendOriginalSourceComment(String originalSource) { // _output.append("\n"); // appendIndent(indent); // _output.append("// "); // // Just append the first line // int lineBreak = originalSource.indexOf('\n'); // if (lineBreak == -1) { // _output.append(originalSource); // } else { // _output.append(originalSource.substring(0, lineBreak)); // } // _output.append("\n"); } }