/******************************************************************************* * 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.compiler.internal.egl2mof; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Stack; import org.eclipse.edt.compiler.core.ast.ArrayType; import org.eclipse.edt.compiler.core.ast.FieldAccess; import org.eclipse.edt.compiler.core.ast.LiteralExpression; import org.eclipse.edt.compiler.core.ast.NameType; import org.eclipse.edt.compiler.core.ast.Node; import org.eclipse.edt.compiler.core.ast.ParenthesizedExpression; import org.eclipse.edt.compiler.core.ast.QualifiedName; import org.eclipse.edt.compiler.core.ast.SettingsBlock; import org.eclipse.edt.compiler.core.ast.SimpleName; import org.eclipse.edt.mof.EObject; import org.eclipse.edt.mof.egl.ArrayAccess; import org.eclipse.edt.mof.egl.ArrayLiteral; import org.eclipse.edt.mof.egl.AsExpression; 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.BytesLiteral; import org.eclipse.edt.mof.egl.ConstructorInvocation; import org.eclipse.edt.mof.egl.Container; import org.eclipse.edt.mof.egl.DecimalLiteral; import org.eclipse.edt.mof.egl.DeclarationExpression; import org.eclipse.edt.mof.egl.Delegate; import org.eclipse.edt.mof.egl.DelegateInvocation; import org.eclipse.edt.mof.egl.DynamicAccess; import org.eclipse.edt.mof.egl.Element; import org.eclipse.edt.mof.egl.Enumeration; import org.eclipse.edt.mof.egl.EnumerationEntry; import org.eclipse.edt.mof.egl.Expression; import org.eclipse.edt.mof.egl.ExternalType; import org.eclipse.edt.mof.egl.Field; import org.eclipse.edt.mof.egl.FloatingPointLiteral; import org.eclipse.edt.mof.egl.Function; import org.eclipse.edt.mof.egl.FunctionInvocation; import org.eclipse.edt.mof.egl.FunctionMember; import org.eclipse.edt.mof.egl.FunctionParameter; import org.eclipse.edt.mof.egl.FunctionPart; import org.eclipse.edt.mof.egl.FunctionStatement; import org.eclipse.edt.mof.egl.IntegerLiteral; import org.eclipse.edt.mof.egl.Interface; import org.eclipse.edt.mof.egl.InvocationExpression; import org.eclipse.edt.mof.egl.IsAExpression; import org.eclipse.edt.mof.egl.IsNotExpression; import org.eclipse.edt.mof.egl.LHSExpr; import org.eclipse.edt.mof.egl.Library; import org.eclipse.edt.mof.egl.LocalVariableDeclarationStatement; import org.eclipse.edt.mof.egl.Member; import org.eclipse.edt.mof.egl.MemberAccess; import org.eclipse.edt.mof.egl.MemberName; import org.eclipse.edt.mof.egl.Name; import org.eclipse.edt.mof.egl.NewExpression; import org.eclipse.edt.mof.egl.NullLiteral; import org.eclipse.edt.mof.egl.NumericLiteral; import org.eclipse.edt.mof.egl.ObjectExpression; import org.eclipse.edt.mof.egl.ObjectExpressionEntry; import org.eclipse.edt.mof.egl.Part; import org.eclipse.edt.mof.egl.PartName; import org.eclipse.edt.mof.egl.Program; import org.eclipse.edt.mof.egl.QualifiedFunctionInvocation; import org.eclipse.edt.mof.egl.Service; import org.eclipse.edt.mof.egl.SetValuesExpression; import org.eclipse.edt.mof.egl.Statement; import org.eclipse.edt.mof.egl.StatementBlock; import org.eclipse.edt.mof.egl.StringLiteral; import org.eclipse.edt.mof.egl.StructPart; import org.eclipse.edt.mof.egl.SubstringAccess; import org.eclipse.edt.mof.egl.SuperExpression; import org.eclipse.edt.mof.egl.TernaryExpression; import org.eclipse.edt.mof.egl.ThisExpression; import org.eclipse.edt.mof.egl.Type; import org.eclipse.edt.mof.egl.UnaryExpression; import org.eclipse.edt.mof.egl.utils.IRUtils; import org.eclipse.edt.mof.egl.utils.TypeUtils; import org.eclipse.edt.mof.serialization.IEnvironment; abstract class Egl2MofExpression extends Egl2MofStatement { private Stack<Expression> sveStack = new Stack<Expression>(); private Stack<Type> sveTypeStack = new Stack<Type>(); private Stack<LHSExpr> localStack = new Stack<LHSExpr>(); Egl2MofExpression(IEnvironment env) { super(env); } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.AsExpression expr) { AsExpression asExpr = factory.createAsExpression(); stack.push(asExpr); setElementInformation(expr, asExpr); expr.getExpression().accept(this); asExpr.setObjectExpr((Expression)stack.pop()); Type eType = (Type)mofTypeFor(expr.resolveType()); asExpr.setEType(eType); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.ArrayAccess node) { node.getArray().accept(this); Expression arrayExpression = (Expression)stack.pop(); Expression lastAC = null; for (int i = 0; i < node.getIndices().size(); i++) { org.eclipse.edt.compiler.core.ast.Expression indexExpr = (org.eclipse.edt.compiler.core.ast.Expression) node.getIndices().get(i); indexExpr.accept(this); Expression index = (Expression)stack.pop(); Type exprType = indexExpr.resolveType(); if (exprType == null) { ArrayAccess ax = factory.createArrayAccess(); ax.setIndex(index); ax.setArray(arrayExpression); lastAC = ax; } else { boolean isDynamicAccess = TypeUtils.isTextType((Type)mofTypeFor(exprType)); if (isDynamicAccess) { DynamicAccess ax = factory.createDynamicAccess(); ax.setAccess(index); ax.setExpression(arrayExpression); lastAC = ax; } else { ArrayAccess ax = factory.createArrayAccess(); ax.setIndex(IRUtils.createAsExpression(index, (Type)getMofSerializable(Type_EGLInt))); ax.setArray(arrayExpression); lastAC = ax; } } } setElementInformation(node, lastAC); stack.push(lastAC); return false; } public boolean visit(org.eclipse.edt.compiler.core.ast.ArrayLiteral node) { List<Expression> entries = new ArrayList<Expression>(); for(org.eclipse.edt.compiler.core.ast.Expression expr : node.getExpressions()) { expr.accept(this); entries.add((Expression)stack.pop()); } ArrayLiteral lit = factory.createArrayLiteral(); lit.getEntries().addAll(entries); setElementInformation(node, lit); stack.push(lit); return false; } public boolean visit(org.eclipse.edt.compiler.core.ast.ObjectExpression node) { List<ObjectExpressionEntry> entries = new ArrayList<ObjectExpressionEntry>(); for (org.eclipse.edt.compiler.core.ast.ObjectExpressionEntry entry : (List<org.eclipse.edt.compiler.core.ast.ObjectExpressionEntry>)node.getEntries()) { ObjectExpressionEntry entryIR = factory.createObjectExpressionEntry(); entryIR.setId(entry.getId()); entry.getExpression().accept(this); entryIR.setExpression((Expression) stack.pop()); entries.add(entryIR); } ObjectExpression objExpr = factory.createObjectExpression(); objExpr.getEntries().addAll(entries); setElementInformation(node,objExpr); stack.push(objExpr); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.Assignment assignment) { Assignment expr = factory.createAssignment(); expr.setOperator(assignment.getOperator().toString()); setElementInformation(assignment, expr); stack.push(expr); assignment.getLeftHandSide().accept(this); expr.setLHS((LHSExpr)eStackPop()); assignment.getRightHandSide().accept(this); expr.setRHS((Expression)eStackPop()); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.BinaryExpression binExpr) { BinaryExpression expr = factory.createBinaryExpression(); setElementInformation(binExpr, expr); stack.push(expr); binExpr.getFirstExpression().accept(this); Expression arg1 = (Expression)eStackPop(); binExpr.getSecondExpression().accept(this); Expression arg2 = (Expression)eStackPop(); expr.setLHS(arg1); expr.setRHS(arg2); expr.setOperator(binExpr.getOperator().toString()); // // Handle implicit cast operation if necessary // IRUtils.makeCompatible(expr); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.TernaryExpression ternaryExpr) { TernaryExpression expr = factory.createTernaryExpression(); setElementInformation(ternaryExpr, expr); stack.push(expr); ternaryExpr.getFirstExpr().accept(this); Expression arg1 = (Expression)eStackPop(); ternaryExpr.getSecondExpr().accept(this); Expression arg2 = (Expression)eStackPop(); ternaryExpr.getThirdExpr().accept(this); Expression arg3 = (Expression)eStackPop(); expr.setFirst(arg1); expr.setSecond(arg2); expr.setThird(arg3); expr.setOperator("?"); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.BooleanLiteral literal) { BooleanLiteral lit = factory.createBooleanLiteral(); lit.setValue(literal.getValue()); setElementInformation(literal, lit); stack.push(lit); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.BytesLiteral literal) { BytesLiteral lit = factory.createBytesLiteral(); lit.setValue(literal.getValue()); setElementInformation(literal, lit); stack.push(lit); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.FloatLiteral literal) { FloatingPointLiteral lit = factory.createFloatingPointLiteral(); if (literal.getLiteralKind() == LiteralExpression.SMALLFLOAT_LITERAL) { lit.setType(IRUtils.getEGLPrimitiveType(Type_Smallfloat)); } else { lit.setType(IRUtils.getEGLPrimitiveType(Type_Float)); } lit.setValue(literal.getValue()); setElementInformation(literal, lit); stack.push(lit); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.DecimalLiteral literal) { DecimalLiteral lit = factory.createDecimalLiteral(); lit.setValue(literal.getValue()); setElementInformation(literal, lit); stack.push(lit); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.FieldAccess fieldAccess) { Type type = (Type)mofTypeFor(fieldAccess.getPrimary().resolveType()); if (TypeUtils.isDynamicType(type)) { DynamicAccess expr = factory.createDynamicAccess(); setElementInformation(fieldAccess, expr); StringLiteral index = factory.createStringLiteral(); index.setValue(fieldAccess.getCaseSensitiveID()); expr.setAccess(index); stack.push(expr); fieldAccess.getPrimary().accept(this); expr.setExpression((Expression)stack.pop()); } else { MemberAccess expr = factory.createMemberAccess(); expr.setId(fieldAccess.getCaseSensitiveID()); setElementInformation(fieldAccess, expr); stack.push(expr); fieldAccess.getPrimary().accept(this); expr.setQualifier((Expression)eStackPop()); } return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.FunctionInvocation node) { InvocationExpression fi; Type typeBinding = node.getTarget().resolveType(); List<FunctionParameter> functionParmBindings; if (typeBinding instanceof Delegate) { functionParmBindings = ((Delegate)typeBinding).getParameters(); fi = factory.createDelegateInvocation(); fi.setId(((Delegate) typeBinding).getCaseSensitiveName()); node.getTarget().accept(this); ((DelegateInvocation)fi).setExpression((Expression)stack.pop()); } else { Element targetBinding = (Element)node.getTarget().resolveElement(); Function functionBinding = null; Part declarer = null; if (targetBinding instanceof Function) { functionBinding = (Function) targetBinding; functionParmBindings = functionBinding.getParameters(); declarer = (Part)functionBinding.getContainer(); } else { functionParmBindings = new ArrayList<FunctionParameter>(); } boolean isStatic = functionBinding != null && (functionBinding.isStatic() || functionBinding.getContainer() instanceof Library); if (node.getTarget() instanceof org.eclipse.edt.compiler.core.ast.ThisExpression || node.getTarget() instanceof org.eclipse.edt.compiler.core.ast.SuperExpression) { // Constructor invocation. fi = factory.createConstructorInvocation(); fi.setId("constructor"); Expression expr; if (node.getTarget() instanceof org.eclipse.edt.compiler.core.ast.ThisExpression) { expr = factory.createThisExpression(); ((ThisExpression)expr).setThisObject((Part)currentPart); } else { expr = factory.createSuperExpression(); ((SuperExpression)expr).setThisObject((Part)currentPart); } ((ConstructorInvocation)fi).setExpression(expr); } else if (node.getTarget() instanceof SimpleName && !isStatic) { if (functionBinding == null || isSuperTypeMember(functionBinding)) { // Qualify with this to get QualifiedFunctionInvocation which will do dynamic lookup fi = factory.createQualifiedFunctionInvocation(); fi.setId(node.getTarget().getCanonicalString()); ThisExpression thisExpr = factory.createThisExpression(); thisExpr.setThisObject((Part)currentPart); ((QualifiedFunctionInvocation)fi).setQualifier(thisExpr); } else { Member mbr = (Member)getEObjectFor(functionBinding); String id=null; if (mbr instanceof FunctionMember) { id = ((FunctionMember)mbr).getCaseSensitiveName(); } else { if(functionBinding != null) { id = functionBinding.getCaseSensitiveName(); } } fi = factory.createFunctionInvocation(); fi.setId(id); ((FunctionInvocation)fi).setTarget(mbr); } } else { if (isStatic && node.getTarget() instanceof org.eclipse.edt.compiler.core.ast.Name) { if (mofTypeFor(declarer) == currentPart) { Member mbr = (Member)getEObjectFor(functionBinding); String id=null; if (mbr instanceof FunctionMember) { id = ((FunctionMember)mbr).getCaseSensitiveName(); } else { if(functionBinding != null) { id = functionBinding.getCaseSensitiveName(); } } fi = factory.createFunctionInvocation(); fi.setId(id); ((FunctionInvocation)fi).setTarget(mbr); } else { fi = factory.createQualifiedFunctionInvocation(); fi.setId(functionBinding.getCaseSensitiveName()); PartName partName = factory.createPartName(); partName.setId(declarer.getCaseSensitiveName()); partName.setPackageName(declarer.getCaseSensitivePackageName()); setElementInformation(node.getTarget(), partName); ((QualifiedFunctionInvocation)fi).setQualifier(partName); } } else { if (node.getTarget() instanceof FieldAccess) { FieldAccess fa = (FieldAccess) node.getTarget(); if (fa.getPrimary() instanceof org.eclipse.edt.compiler.core.ast.ThisExpression || fa.getPrimary() instanceof org.eclipse.edt.compiler.core.ast.SuperExpression) { if (functionBinding == null || isSuperTypeMember(functionBinding)) { // Qualify with this to get QualifiedFunctionInvocation which will do dynamic lookup fi = factory.createQualifiedFunctionInvocation(); fi.setId(functionBinding.getCaseSensitiveName()); if (fa.getPrimary() instanceof org.eclipse.edt.compiler.core.ast.SuperExpression) { SuperExpression superExpr = factory.createSuperExpression(); superExpr.setThisObject((Part)currentPart); ((QualifiedFunctionInvocation)fi).setQualifier(superExpr); } else { ThisExpression thisExpr = factory.createThisExpression(); thisExpr.setThisObject((Part)currentPart); ((QualifiedFunctionInvocation)fi).setQualifier(thisExpr); } } else { Member mbr = (Member)getEObjectFor(functionBinding); String id=null; if (mbr instanceof FunctionMember) { id = ((FunctionMember)mbr).getCaseSensitiveName(); } else { if(functionBinding != null) { id = functionBinding.getCaseSensitiveName(); } } fi = factory.createFunctionInvocation(); fi.setId(id); ((FunctionInvocation)fi).setTarget(mbr); } } else { fi = factory.createQualifiedFunctionInvocation(); if (functionBinding == null) { fi.setId(node.getTarget().getCaseSensitiveID()); } else { fi.setId(functionBinding.getCaseSensitiveName()); } fa.getPrimary().accept(this); ((QualifiedFunctionInvocation)fi).setQualifier((Expression)stack.pop()); } } else { if (node.getTarget() instanceof QualifiedName) { fi = factory.createQualifiedFunctionInvocation(); QualifiedName name = (QualifiedName)node.getTarget(); fi.setId(name.getCaseSensitiveIdentifier()); name.getQualifier().accept(this); ((QualifiedFunctionInvocation)fi).setQualifier((Expression)stack.pop()); } else { //Catch error cases fi = factory.createFunctionInvocation(); fi.setId(node.getTarget().getCanonicalString()); } } } } } int index = 0; for (Iterator<org.eclipse.edt.compiler.core.ast.Expression> iter = node.getArguments().iterator(); iter.hasNext();) { org.eclipse.edt.compiler.core.ast.Expression argExpr = iter.next(); argExpr.accept(this); Expression expr = (Expression)stack.pop(); // TODO: find out why this is being done this way // if (isFormatFunction && index == 2 && expr instanceof org.eclipse.edt.mof.egl.api.StringLiteral) { // org.eclipse.edt.mof.egl.api.StringLiteral lit = (org.eclipse.edt.mof.egl.api.StringLiteral) expr; // lit.setValue(new TimeStampAndIntervalPatternFixer(lit.getValue()).toString()); // } // if passing any type to anything other than an any, must change // the arg to an AsExpression...only need to do this if the parm is an input type...do not need // to massage the arguments for output parms FunctionParameter parm = null; if (functionParmBindings.size() > 0) { if (functionParmBindings.size() > index) { parm = functionParmBindings.get(index); } else { parm = functionParmBindings.get(functionParmBindings.size() - 1); } } fi.getArguments().add(expr); index++; } setElementInformation(node, fi); stack.push(fi); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.IntegerLiteral literal) { IntegerLiteral lit = factory.createIntegerLiteral(); switch (literal.getLiteralKind()) { case LiteralExpression.BIGINT_LITERAL: lit.setType(IRUtils.getEGLPrimitiveType(Type_Bigint)); break; case LiteralExpression.SMALLINT_LITERAL: lit.setType(IRUtils.getEGLPrimitiveType(Type_Smallint)); break; case LiteralExpression.INTEGER_LITERAL: default: lit.setType(IRUtils.getEGLPrimitiveType(Type_Int)); break; } lit.setValue(literal.getValue()); setElementInformation(literal, lit); stack.push(lit); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.IsAExpression expr) { IsAExpression isaExpr = factory.createIsAExpression(); setElementInformation(expr, isaExpr); stack.push(isaExpr); expr.getExpression().accept(this); isaExpr.setObjectExpr((Expression)stack.pop()); Type type = (Type)mofTypeFor(expr.getType().resolveType()); isaExpr.setEType(type); return false; } @Override public boolean visit(ParenthesizedExpression parenExpr) { return true; } private Name createNameForPart(Type binding) { if (binding instanceof StructPart || binding instanceof ExternalType || binding instanceof Enumeration || binding instanceof Program || binding instanceof Interface || binding instanceof Service) { // Is only a proper reference to a part if given part type is allowed to have // field references to the part itself (static reference) as opposed to field // of an instance. SimpleName AST values may be referencing a Part in the case // where the reference is to a global variable outside the scope of a TopLevelFunction // that is being compiled independently PartName name = factory.createPartName(); String packageName; packageName = ((Part)binding).getCaseSensitivePackageName(); name.setPackageName(packageName); name.setId(((Part)binding).getCaseSensitiveName()); return name; } else { return factory.createDanglingReference(); } } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.SimpleName node) { Object binding = node.resolveElement(); // Since there was no binding this is an invalid name if (binding == null) { Name invalid; if (currentPart instanceof FunctionPart) { invalid = factory.createDanglingReference(); } else { invalid = factory.createInvalidName(); } invalid.setId(node.getCanonicalName()); setElementInformation(node, invalid); stack.push(invalid); return false; } Name name = null; if (binding instanceof Part) { name = createNameForPart((Part)binding); name.setId(((Part)binding).getCaseSensitiveName()); } else if(binding instanceof Member){ name = factory.createMemberName(); if(((Member)binding).getContainer() == null && TypeUtils.isDynamicType(((Member) binding).getType())){ name.setId(node.getCaseSensitiveIdentifier()); } else{ name.setId(((Member)binding).getCaseSensitiveName()); } } Element qualifier = null; if(binding instanceof Member && isInOtherLibrary(((Member)binding).getContainer())){ qualifier = ((Member)binding).getContainer(); } else if(binding instanceof EnumerationEntry){ qualifier = ((Member)binding).getContainer(); } if (qualifier != null) { if (qualifier instanceof Part) { name = (Name)addQualifier(createNameForPart((Part)qualifier), name); } else { Element context = (Element)getEObjectFor(qualifier); name = (Name)addQualifier(context, name); } } if (name instanceof MemberName) { if (isSuperTypeMember(binding)) { ThisExpression thisExpr = factory.createThisExpression(); thisExpr.setThisObject((Part)currentPart); name = (Name)addQualifier(thisExpr, name); } else { EObject result = getEObjectFor(binding); if (result instanceof Member) { Member mbr = (Member)result; ((MemberName)name).setMember(mbr); } } } setElementInformation(node, name); stack.push(name); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.QualifiedName name) { Object element = name.resolveElement(); if (element instanceof Member && ((Member)element).getContainer() == null && TypeUtils.isDynamicType(((Member)element).getType())) { DynamicAccess expr = factory.createDynamicAccess(); setElementInformation(name, expr); StringLiteral index = factory.createStringLiteral(); index.setValue(name.getCaseSensitiveIdentifier()); expr.setAccess(index); stack.push(expr); name.getQualifier().accept(this); expr.setExpression((Expression)stack.pop()); } else { MemberAccess nameExpr = factory.createMemberAccess(); setElementInformation(name, nameExpr); stack.push(nameExpr); nameExpr.setId(name.getCaseSensitiveIdentifier()); Object qualBinding = name.getQualifier().resolveElement(); if (qualBinding instanceof Part){ nameExpr.setQualifier(createNameForPart((Part)qualBinding)); } else { name.getQualifier().accept(this); nameExpr.setQualifier((Expression)stack.pop()); } } return false; } private boolean isInOtherLibrary(Container binding){ return (binding instanceof Library && !mofTypeFor((Library)binding).equals(currentPart)); } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.NullLiteral literal) { NullLiteral lit = factory.createNullLiteral(); setElementInformation(literal, lit); stack.push(lit); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.StringLiteral literal) { StringLiteral lit = factory.createStringLiteral(); lit.setValue(literal.getValue()); lit.setIsHex(literal.isHex()); setElementInformation(literal, lit); stack.push(lit); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.IsNotExpression isNotExpression) { IsNotExpression expr = factory.createIsNotExpression(); setElementInformation(isNotExpression, expr); stack.push(expr); isNotExpression.getFirstExpression().accept(this); expr.setExpr((Expression)stack.pop()); expr.setOperation(isNotExpression.getOperator().toString()); SimpleName mnemonic = (SimpleName)isNotExpression.getSecondExpression(); expr.setMnemonic(mnemonic.getIdentifier()); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.NewExpression newExpression) { NewExpression expr = factory.createNewExpression(); Type type = newExpression.resolveType(); if (type == null) { stack.push(expr); return false; } EObject obj = mofTypeFor(type); if (!(obj instanceof Type)) { stack.push(expr); return false; } Type mofType = (Type)obj; expr.setId(type.getTypeSignature()); setElementInformation(newExpression, expr); if(newExpression.getType() instanceof NameType){ for(org.eclipse.edt.compiler.core.ast.Expression argument : ((NameType)newExpression.getType()).getArguments()){ argument.accept(this); expr.getArguments().add((Expression)stack.pop()); } } if (newExpression.getType().isArrayType()) { processNewArray(newExpression.getType(), expr); } if (newExpression.getSettingsBlock() != null && newExpression.getSettingsBlock().getSettings().size() > 0) { SetValuesExpression sve = processSettings(expr, newExpression, mofType, newExpression.getSettingsBlock()); setElementInformation(newExpression, sve); stack.push(sve); } else { stack.push(expr); } return false; } private void processNewArray(org.eclipse.edt.compiler.core.ast.Type type, NewExpression expr) { if (type.isArrayType()) { ArrayType arrType = ((ArrayType)type); processNewArray(arrType.getElementType(), expr); if (arrType.hasInitialSize()) { arrType.getInitialSize().accept(this); expr.getArguments().add((Expression)stack.pop()); } else { IntegerLiteral lit = factory.createIntegerLiteral(); lit.setType(IRUtils.getEGLPrimitiveType(Type_Int)); lit.setValue("0"); setElementInformation(type, lit); expr.getArguments().add(lit); } } } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.SetValuesExpression setValuesExpression) { setValuesExpression.getExpression().accept(this); Type targetType = null; if (setValuesExpression.getExpression().resolveType() != null) { EObject obj = mofTypeFor(setValuesExpression.getExpression().resolveType()); if (obj instanceof Type) { targetType = (Type) obj; } } SetValuesExpression sve = processSettings((Expression)stack.pop(), setValuesExpression.getExpression(), targetType, setValuesExpression.getSettingsBlock()); setElementInformation(setValuesExpression, sve); stack.push(sve); return false; } private SetValuesExpression processSettings(Expression target, org.eclipse.edt.compiler.core.ast.Expression targetNode, Type targetType, SettingsBlock settings) { if (!localStack.isEmpty() && target instanceof LHSExpr) { if (!sveTypeStack.isEmpty() && TypeUtils.isDynamicType(sveTypeStack.peek())) { //If the previous type was a dynamic type (like dictionary), we need to create a dynamic //access to use DynamicAccess da = factory.createDynamicAccess(); setElementInformation(settings, da); LHSExpr newLHS = setAccessForDynamicAccess(da, target); da.setExpression(localStack.peek()); target = newLHS; } else { target = addQualifier(localStack.peek(), (LHSExpr)target); } } sveStack.push(target); sveTypeStack.push(targetType); SetValuesExpression sve = factory.createSetValuesExpression(); sve.setTarget(target); StatementBlock block = factory.createStatementBlock(); setElementInformation(settings, block); // Can assume no annotations MemberName localRef = null; Field decl = null; if (!(target instanceof LHSExpr)) { LocalVariableDeclarationStatement local = factory.createLocalVariableDeclarationStatement(); DeclarationExpression declExpr = factory.createDeclarationExpression(); decl = factory.createField(); decl.setName("eze$SettingTarget" + sveStack.size()); decl.setType(targetType); setElementInformation(targetNode, decl); declExpr.getFields().add(decl); local.setExpression(declExpr); setElementInformation(targetNode, local); Assignment assignExpr = factory.createAssignment(); localRef = factory.createMemberName(); localRef.setId(decl.getCaseSensitiveName()); localRef.setMember(decl); // Push new reference to temp onto the stack localStack.push(localRef); assignExpr.setLHS(localRef); assignExpr.setRHS(target); StatementBlock initializer = factory.createStatementBlock(); AssignmentStatement stmt = createAssignmentStatement(assignExpr); setElementInformation(targetNode, stmt); initializer.getStatements().add(stmt); setElementInformation(targetNode, initializer); decl.setInitializerStatements(initializer); decl.setContainer(initializer.getContainer()); block.getStatements().add(local); } else { localStack.push((LHSExpr)target); } for (Node setting : (List<Node>)settings.getSettings()) { setting.accept(this); Expression setexpr = (Expression)stack.pop(); LHSExpr ref = null; if (decl == null) { // No temp was created so use the actual target // but clone it because it should be a different // instance of the expression when used in another place ref = (LHSExpr)target; } else { ref = factory.createMemberName(); ((MemberName)ref).setId(decl.getCaseSensitiveName()); ((MemberName)ref).setMember(decl); } if (setexpr instanceof Assignment) { Assignment assign = (Assignment)setexpr; if (TypeUtils.isDynamicType(targetType)) { DynamicAccess da = factory.createDynamicAccess(); setElementInformation(setting, da); LHSExpr newLHS = setAccessForDynamicAccess(da, assign.getLHS()); da.setExpression(ref); assign.setLHS(newLHS); } else { LHSExpr lhs = addQualifier(ref, assign.getLHS()); assign.setLHS(lhs); } AssignmentStatement stmt = createAssignmentStatement(assign); setElementInformation(setting, stmt); block.getStatements().add(stmt); } else if (setexpr instanceof SetValuesExpression && !(setting instanceof org.eclipse.edt.compiler.core.ast.NewExpression)) { SetValuesExpression ex = (SetValuesExpression)setexpr; //move the statements from the setValues block into this block for (Statement stmt : ex.getSettings().getStatements()) { block.getStatements().add(stmt); } } else { QualifiedFunctionInvocation func = factory.createQualifiedFunctionInvocation(); setElementInformation(setting, func); func.setQualifier(ref); func.setId("appendElement"); func.getArguments().add(setexpr); FunctionStatement stmt = factory.createFunctionStatement(); stmt.setExpr(func); setElementInformation(setting, stmt); block.getStatements().add(stmt); } } sve.setSettings(block); sveStack.pop(); sveTypeStack.pop(); localStack.pop(); return sve; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.SubstringAccess substringAccess) { SubstringAccess access = factory.createSubstringAccess(); setElementInformation(substringAccess, access); stack.push(access); substringAccess.getExpr().accept(this); access.setStart((Expression)stack.pop()); substringAccess.getExpr2().accept(this); access.setEnd((Expression)stack.pop()); substringAccess.getPrimary().accept(this); access.setStringExpression((Expression)stack.pop()); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.SuperExpression superExpression) { SuperExpression expr = factory.createSuperExpression(); expr.setThisObject((Part)currentPart); setElementInformation(superExpression, expr); stack.push(expr); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.ThisExpression thisExpression) { ThisExpression expr = factory.createThisExpression(); Element binding = (Element)thisExpression.resolveElement(); if (binding == null) { binding = thisExpression.resolveType(); } Element obj = (Element)getEObjectFor(binding); expr.setThisObject(obj); setElementInformation(thisExpression, expr); stack.push(expr); return false; } @Override public boolean visit(org.eclipse.edt.compiler.core.ast.UnaryExpression unaryExpression) { unaryExpression.getExpression().accept(this); Expression subExpr = (Expression)stack.pop(); //If the operator is a +, do not create a unary expression, just pass on the subexpr if (unaryExpression.getOperator() == org.eclipse.edt.compiler.core.ast.UnaryExpression.Operator.PLUS) { stack.push(subExpr); return false; } boolean isMinus = (unaryExpression.getOperator() == org.eclipse.edt.compiler.core.ast.UnaryExpression.Operator.MINUS); if (subExpr instanceof NumericLiteral && isMinus) { ((NumericLiteral)subExpr).setIsNegated(!((NumericLiteral)subExpr).isNegated()); stack.push(subExpr); } else { UnaryExpression expr = factory.createUnaryExpression(); setElementInformation(unaryExpression, expr); stack.push(expr); expr.setExpression(subExpr); expr.setOperator(unaryExpression.getOperator().toString()); } return false; } private boolean isSuperTypeMember(Object binding) { if (binding == null) return false; StructPart part = null; if (binding instanceof Member && ((Member)binding).getContainer() instanceof StructPart) { part = (StructPart)mofTypeFor((Type)((Member)binding).getContainer()); } else if (binding instanceof Member) { return isSuperTypeMember(((Member)binding).getContainer()); } StructPart current = (StructPart)currentBindingLevelPart; return part != null && !current.equals(part) && current.isSubtypeOf(part); } }