/******************************************************************************* * Copyright © 2011, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.gen.javascript.templates; import org.eclipse.edt.compiler.core.IEGLConstants; import org.eclipse.edt.gen.Label; import org.eclipse.edt.gen.javascript.Context; import org.eclipse.edt.mof.codegen.api.TabbedWriter; import org.eclipse.edt.mof.egl.ArrayAccess; import org.eclipse.edt.mof.egl.Assignment; import org.eclipse.edt.mof.egl.AssignmentStatement; import org.eclipse.edt.mof.egl.BinaryExpression; import org.eclipse.edt.mof.egl.BooleanLiteral; import org.eclipse.edt.mof.egl.DeclarationExpression; import org.eclipse.edt.mof.egl.Field; import org.eclipse.edt.mof.egl.ForStatement; import org.eclipse.edt.mof.egl.IfStatement; import org.eclipse.edt.mof.egl.IntegerLiteral; import org.eclipse.edt.mof.egl.LHSExpr; import org.eclipse.edt.mof.egl.LocalVariableDeclarationStatement; import org.eclipse.edt.mof.egl.MemberName; import org.eclipse.edt.mof.egl.MofConversion; import org.eclipse.edt.mof.egl.StatementBlock; import org.eclipse.edt.mof.egl.utils.IRUtils; import org.eclipse.edt.mof.egl.utils.TypeUtils; public class ForStatementTemplate extends JavaScriptTemplate { public void genStatementBody(ForStatement stmt, Context ctx, TabbedWriter out) { if (stmt.getDeclarationExpression() != null) { out.println("{"); ctx.invoke(genDeclarationExpression, stmt, ctx, out); } // do we have a simple or complex for statement boolean hasSideEffects = (stmt.getCounterVariable() != null && (org.eclipse.edt.gen.CommonUtilities.hasSideEffects(stmt.getCounterVariable(), ctx) || stmt .getCounterVariable() instanceof ArrayAccess)) || (stmt.getFromExpression() != null && org.eclipse.edt.gen.CommonUtilities.hasSideEffects(stmt.getFromExpression(), ctx)) || (stmt.getToExpression() != null && org.eclipse.edt.gen.CommonUtilities.hasSideEffects(stmt.getToExpression(), ctx)) || (stmt.getDeltaExpression() != null && org.eclipse.edt.gen.CommonUtilities.hasSideEffects(stmt.getDeltaExpression(), ctx)); if (hasSideEffects) { // we need to process this as a complex for statement // create the initial statement block StatementBlock statementBlockInit = factory.createStatementBlock(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) statementBlockInit.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); // we need to create an assignment statement for the initial expression AssignmentStatement assignmentStatementInit = factory.createAssignmentStatement(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentStatementInit.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentStatementInit.setContainer(statementBlockInit.getContainer()); Assignment assignmentInit = factory.createAssignment(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentInit.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentStatementInit.setAssignment(assignmentInit); assignmentInit.setLHS((LHSExpr) stmt.getCounterVariable()); if (stmt.getFromExpression() != null) assignmentInit.setRHS(stmt.getFromExpression()); else { IntegerLiteral integerLiteralInit = factory.createIntegerLiteral(); integerLiteralInit.setType(IRUtils.getEGLPrimitiveType(MofConversion.Type_Int)); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) integerLiteralInit.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); integerLiteralInit.setValue("1"); assignmentInit.setRHS(integerLiteralInit); } statementBlockInit.getStatements().add(assignmentStatementInit); ctx.invoke(genStatementNoBraces, statementBlockInit, ctx, out); out.println("while (true) {"); // create the conditional statement block StatementBlock statementBlockCond = factory.createStatementBlock(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) statementBlockCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); // create a boolean flag String temporaryCond = ctx.nextTempName(); LocalVariableDeclarationStatement localDeclarationCond = factory.createLocalVariableDeclarationStatement(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) localDeclarationCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); localDeclarationCond.setContainer(stmt.getContainer()); DeclarationExpression declarationExpressionCond = factory.createDeclarationExpression(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) declarationExpressionCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); Field fieldCond = factory.createField(); fieldCond.setName(temporaryCond); fieldCond.setType(TypeUtils.Type_BOOLEAN); // we need to create the member access MemberName nameExpressionCond = factory.createMemberName(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) nameExpressionCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); nameExpressionCond.setMember(fieldCond); nameExpressionCond.setId(fieldCond.getCaseSensitiveName()); // add the field to the declaration expression declarationExpressionCond.getFields().add(fieldCond); // connect the declaration expression to the local declaration localDeclarationCond.setExpression(declarationExpressionCond); statementBlockCond.getStatements().add(localDeclarationCond); // we need to create an if statement for the conditional expression BinaryExpression binaryExpressionCond = factory.createBinaryExpression(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) binaryExpressionCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); binaryExpressionCond.setLHS(stmt.getCounterVariable()); binaryExpressionCond.setRHS(stmt.getToExpression()); if (stmt.isIncrement()) binaryExpressionCond.setOperator("<="); else binaryExpressionCond.setOperator(">="); IfStatement ifStatementCond = factory.createIfStatement(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) ifStatementCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); ifStatementCond.setContainer(stmt.getContainer()); ifStatementCond.setCondition(binaryExpressionCond); // create the true and false statement blocks StatementBlock trueStatementBlockCond = factory.createStatementBlock(); trueStatementBlockCond.setContainer(ifStatementCond.getContainer()); ifStatementCond.setTrueBranch(trueStatementBlockCond); statementBlockCond.getStatements().add(ifStatementCond); // create the boolean literal for true BooleanLiteral booleanLiteralCond = factory.createBooleanLiteral(); booleanLiteralCond.setBooleanValue(true); // we need to create a boolean assignment statement AssignmentStatement assignmentStatementCond = factory.createAssignmentStatement(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentStatementCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentStatementCond.setContainer(trueStatementBlockCond.getContainer()); Assignment assignmentCond = factory.createAssignment(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentStatementCond.setAssignment(assignmentCond); assignmentCond.setLHS(nameExpressionCond); assignmentCond.setRHS(booleanLiteralCond); trueStatementBlockCond.getStatements().add(assignmentStatementCond); ctx.invoke(genStatementNoBraces, statementBlockCond, ctx, out); // now add the logic for the block execution out.println("if (!" + temporaryCond + ") break;"); Label label = new Label(ctx, Label.LABEL_TYPE_FOR); label.setFlag(temporaryCond); ctx.pushLabelStack(label); if (ctx.getAttribute(stmt, org.eclipse.edt.gen.Constants.SubKey_statementNeedsLabel) != null && ((Boolean) ctx.getAttribute(stmt, org.eclipse.edt.gen.Constants.SubKey_statementNeedsLabel)).booleanValue()) out.print(label.getName() + ": "); out.print("do "); ctx.invoke(genStatement, stmt.getBody(), ctx, out); out.println("while (false);"); // it is possible that an exit statement was used and it set this flag out.println("if (!" + temporaryCond + ") break;"); // create the increment statement block StatementBlock statementBlockIncr = factory.createStatementBlock(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) statementBlockIncr.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); // we need to create a increment assignment statement AssignmentStatement assignmentStatementIncr = factory.createAssignmentStatement(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentStatementIncr.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentStatementIncr.setContainer(stmt.getContainer()); Assignment assignmentIncr = factory.createAssignment(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentIncr.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentStatementIncr.setAssignment(assignmentIncr); if (stmt.getDeltaExpression() != null) assignmentIncr.setRHS(stmt.getDeltaExpression()); else { IntegerLiteral integerLiteralIncr = factory.createIntegerLiteral(); integerLiteralIncr.setType(IRUtils.getEGLPrimitiveType(MofConversion.Type_Int)); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) integerLiteralIncr.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); integerLiteralIncr.setValue("1"); assignmentIncr.setRHS(integerLiteralIncr); } if (stmt.isIncrement()) assignmentIncr.setOperator("+="); else assignmentIncr.setOperator("-="); assignmentIncr.setLHS((LHSExpr) stmt.getCounterVariable()); statementBlockIncr.getStatements().add(assignmentStatementIncr); ctx.invoke(genStatementNoBraces, statementBlockIncr, ctx, out); out.println("}"); } else { // we need to process this as a simple for statement Label label = new Label(ctx, Label.LABEL_TYPE_FOR); ctx.pushLabelStack(label); if (ctx.getAttribute(stmt, org.eclipse.edt.gen.Constants.SubKey_statementNeedsLabel) != null && ((Boolean) ctx.getAttribute(stmt, org.eclipse.edt.gen.Constants.SubKey_statementNeedsLabel)).booleanValue()) out.print(label.getName() + ": "); out.print("for ("); // we need to create an assignment statement for the initial expression Assignment assignmentInit = factory.createAssignment(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentInit.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentInit.setLHS((LHSExpr) stmt.getCounterVariable()); if (stmt.getFromExpression() != null) assignmentInit.setRHS(stmt.getFromExpression()); else { IntegerLiteral integerLiteralInit = factory.createIntegerLiteral(); integerLiteralInit.setType(IRUtils.getEGLPrimitiveType(MofConversion.Type_Int)); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) integerLiteralInit.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); integerLiteralInit.setValue("1"); assignmentInit.setRHS(integerLiteralInit); } ctx.invoke(genExpression, assignmentInit, ctx, out); out.print("; "); // now generate the condition BinaryExpression binaryExpressionCond = factory.createBinaryExpression(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) binaryExpressionCond.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); binaryExpressionCond.setLHS(stmt.getCounterVariable()); binaryExpressionCond.setRHS(stmt.getToExpression()); if (stmt.isIncrement()) binaryExpressionCond.setOperator("<="); else binaryExpressionCond.setOperator(">="); ctx.invoke(genExpression, binaryExpressionCond, ctx, out); out.print("; "); // now generate the increment BinaryExpression binaryExpressionIncr = factory.createBinaryExpression(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) binaryExpressionIncr.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); binaryExpressionIncr.setLHS(stmt.getCounterVariable()); if (stmt.getDeltaExpression() != null) binaryExpressionIncr.setRHS(stmt.getDeltaExpression()); else { IntegerLiteral integerLiteralIncr = factory.createIntegerLiteral(); integerLiteralIncr.setType(IRUtils.getEGLPrimitiveType(MofConversion.Type_Int)); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) integerLiteralIncr.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); integerLiteralIncr.setValue("1"); binaryExpressionIncr.setRHS(integerLiteralIncr); } if (stmt.isIncrement()) binaryExpressionIncr.setOperator("+"); else binaryExpressionIncr.setOperator("-"); Assignment assignmentIncr = factory.createAssignment(); if (stmt.getAnnotation(IEGLConstants.EGL_LOCATION) != null) assignmentIncr.addAnnotation(stmt.getAnnotation(IEGLConstants.EGL_LOCATION)); assignmentIncr.setRHS(binaryExpressionIncr); assignmentIncr.setLHS((LHSExpr) stmt.getCounterVariable()); ctx.invoke(genExpression, assignmentIncr, ctx, out); // finish the for statement out.print(") "); // now process the statement block ctx.invoke(genStatement, stmt.getBody(), ctx, out); } // if we had a declaration, clean up if (stmt.getDeclarationExpression() != null) out.println("}"); // now remove the label from the stack ctx.popLabelStack(); } public void genDeclarationExpression(ForStatement stmt, Context ctx, TabbedWriter out) { ctx.invoke(genDeclarationExpression, stmt.getDeclarationExpression(), ctx, out); } public void genStatementEnd(ForStatement stmt, Context ctx, TabbedWriter out) { // we don't want a semi-colon } }