diff --git a/build/build.properties b/build/build.properties index 7185a85..7c361f7 100644 --- a/build/build.properties +++ b/build/build.properties @@ -1 +1 @@ -compiler.version=0.2.6.2 +compiler.version=0.2.6.4 diff --git a/src/main/java/randori/compiler/common/VersionInfo.java b/src/main/java/randori/compiler/common/VersionInfo.java index cba0ec9..e51e893 100644 --- a/src/main/java/randori/compiler/common/VersionInfo.java +++ b/src/main/java/randori/compiler/common/VersionInfo.java @@ -36,7 +36,7 @@ public class VersionInfo public static final String RANDORI_BUILD = "1"; public static final String RANDORI_BUILD_VERSION = "1"; - public static final String RANDORI_COMPILER_VERSION = "0.2.6.2"; + public static final String RANDORI_COMPILER_VERSION = "0.2.6.5_renaun"; public static final String RANDORI_COMPILER_NAME = "randori"; public static final String LIB_VERSION_1_0 = "1.0"; diff --git a/src/main/java/randori/compiler/internal/codegen/as/ASBlockWalker.java b/src/main/java/randori/compiler/internal/codegen/as/ASBlockWalker.java index 2458b3b..ee68ed4 100644 --- a/src/main/java/randori/compiler/internal/codegen/as/ASBlockWalker.java +++ b/src/main/java/randori/compiler/internal/codegen/as/ASBlockWalker.java @@ -450,15 +450,15 @@ public void visitLiteral(ILiteralNode node) || node.getLiteralType() == LiteralType.NUMBER || node.getLiteralType() == LiteralType.REGEXP || node.getLiteralType() == LiteralType.STRING - || node.getLiteralType() == LiteralType.VOID) + || node.getLiteralType() == LiteralType.VOID + || node.getLiteralType() == LiteralType.XML) { emitter.emitLiteral(node); } else if (node.getLiteralType() == LiteralType.ARRAY || node.getLiteralType() == LiteralType.OBJECT || node.getLiteralType() == LiteralType.VECTOR - || node.getLiteralType() == LiteralType.XMLLIST - || node.getLiteralType() == LiteralType.XML) + || node.getLiteralType() == LiteralType.XMLLIST) { emitter.emitLiteralContainer((ILiteralContainerNode) node); } @@ -518,7 +518,7 @@ public void visitBinaryOperator(IBinaryOperatorNode node) @Override public void visitUnaryOperator(IUnaryOperatorNode node) { - debug("visitUnaryOperator()"); + debug("visitUnaryOperator()" + node.getOperator().getOperatorText()); emitter.emitUnaryOperator(node); } @@ -619,7 +619,7 @@ public void visitLanguageIdentifierNode(ILanguageIdentifierNode node) // //-------------------------------------------------------------------------- - protected void debug(String message) + public void debug(String message) { if (isDebug) { diff --git a/src/main/java/randori/compiler/internal/codegen/js/RandoriEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/RandoriEmitter.java index f95983b..fd2bae3 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/RandoriEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/RandoriEmitter.java @@ -78,6 +78,7 @@ import randori.compiler.internal.utils.MetaDataUtils.MetaData.Mode; import randori.compiler.internal.utils.RandoriUtils; +import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase; /** * The base ship... * @@ -270,6 +271,7 @@ public void emitClass(IClassNode node) } writeNewline(";"); + // REE footer.emitNewInherit(node); } } @@ -282,7 +284,6 @@ public void emitClass(IClassNode node) for (IDefinitionNode member : members) { IDefinition definition = member.getDefinition(); - if (member.getNodeID() == ASTNodeID.FunctionID) { if (((IFunctionDefinition) definition).isConstructor()) @@ -642,6 +643,7 @@ public void emitMethodScope(IFunctionNode node) @Override public void emitUnaryOperator(IUnaryOperatorNode node) { + if (node.getNodeID() == ASTNodeID.Op_PreIncrID || node.getNodeID() == ASTNodeID.Op_PreDecrID || node.getNodeID() == ASTNodeID.Op_BitwiseNotID @@ -674,6 +676,26 @@ else if (node.getNodeID() == ASTNodeID.Op_TypeOfID) getWalker().walk(node.getOperandNode()); write(")"); } + // E4X @name change to .attribute('name') + else if (node.getNodeID() == ASTNodeID.Op_AtID) + { + if (node instanceof ExpressionNodeBase ) + { + // Ensure we're not in a with scope or part of a filter expression. + final ExpressionNodeBase expressionNode = (ExpressionNodeBase)node; + if (expressionNode.inFilter()) + { + getWalker().walk(node.getOperandNode()); + return; + } + } + + write("attribute('"); + getWalker().walk(node.getOperandNode()); + write("')"); + + //write(node.getOperator().getOperatorText()); + } } private void emitPostAssignment(IUnaryOperatorNode node, String operator) diff --git a/src/main/java/randori/compiler/internal/codegen/js/SessionModel.java b/src/main/java/randori/compiler/internal/codegen/js/SessionModel.java index 7dc5542..7abd575 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/SessionModel.java +++ b/src/main/java/randori/compiler/internal/codegen/js/SessionModel.java @@ -25,11 +25,7 @@ import java.util.HashMap; import java.util.List; -import org.apache.flex.compiler.definitions.IClassDefinition; -import org.apache.flex.compiler.definitions.IDefinition; -import org.apache.flex.compiler.definitions.IFunctionDefinition; -import org.apache.flex.compiler.definitions.IScopedDefinition; -import org.apache.flex.compiler.definitions.IVariableDefinition; +import org.apache.flex.compiler.definitions.*; import org.apache.flex.compiler.definitions.metadata.IMetaTag; import org.apache.flex.compiler.internal.scopes.TypeScope; import org.apache.flex.compiler.tree.as.IASNode; @@ -47,6 +43,8 @@ */ public class SessionModel implements ISessionModel { + private HashMap getterSetterProperties = new HashMap(); + private HashMap runtimeDependencies = new HashMap(); private HashMap staticDependencies = new HashMap(); @@ -132,6 +130,20 @@ public void setInScope(boolean value) // Dependencies //-------------------------------------------------------------------------- + + public void addGetterSetter(IAccessorDefinition definition) + { + if (getterSetterProperties.containsKey(definition.getQualifiedName())) + return; + + getterSetterProperties.put(definition.getQualifiedName(), definition); + } + + public Collection getGetterSetter() + { + return getterSetterProperties.values(); + } + @Override public void addDependency(IScopedDefinition definition, IASNode node) { diff --git a/src/main/java/randori/compiler/internal/codegen/js/emitter/BinaryOperatorEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/emitter/BinaryOperatorEmitter.java index 4787439..b9a7029 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/emitter/BinaryOperatorEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/emitter/BinaryOperatorEmitter.java @@ -22,21 +22,18 @@ import org.apache.flex.compiler.definitions.IAccessorDefinition; import org.apache.flex.compiler.definitions.IDefinition; import org.apache.flex.compiler.definitions.IFunctionDefinition; +import org.apache.flex.compiler.definitions.ITypeDefinition; +import org.apache.flex.compiler.internal.tree.as.BinaryOperatorAssignmentNode; +import org.apache.flex.compiler.internal.tree.as.IdentifierNode; import org.apache.flex.compiler.projects.ICompilerProject; import org.apache.flex.compiler.tree.ASTNodeID; -import org.apache.flex.compiler.tree.as.IBinaryOperatorNode; -import org.apache.flex.compiler.tree.as.IExpressionNode; -import org.apache.flex.compiler.tree.as.IIdentifierNode; -import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode; +import org.apache.flex.compiler.tree.as.*; import randori.compiler.codegen.js.IRandoriEmitter; import randori.compiler.codegen.js.ISubEmitter; -import randori.compiler.internal.utils.ASNodeUtils; -import randori.compiler.internal.utils.DefinitionNameUtils; -import randori.compiler.internal.utils.ExpressionUtils; -import randori.compiler.internal.utils.MetaDataUtils; -import randori.compiler.internal.utils.RandoriUtils; +import randori.compiler.internal.utils.*; +import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase; /** * Handles the production of the {@link IBinaryOperatorNode}. * @@ -54,6 +51,20 @@ public BinaryOperatorEmitter(IRandoriEmitter emitter) @Override public void emit(IBinaryOperatorNode node) { + // THIS IS HARD CODED "filter" but maybe needs to be dynamic at some point + // "filter" is applied to E4X expressions and is implemented in JXONTree + boolean isFilter = false; + if (node instanceof ExpressionNodeBase) + { + // Ensure we're not in a with scope or part of a filter expression. + final ExpressionNodeBase expressionNode = (ExpressionNodeBase)node; + if (expressionNode.inFilter() && expressionNode.hasParenthesis()) + { + isFilter = true; + write("filter"); + } + } + ICompilerProject project = getEmitter().getWalker().getProject(); IExpressionNode left = node.getLeftOperandNode(); @@ -62,6 +73,30 @@ public void emit(IBinaryOperatorNode node) IExpressionNode right = node.getRightOperandNode(); IDefinition rhsDefinition = right.resolve(project); + // This is a special case for array assessor on flash.utils.ByteArray + // when an assignment is being made. Array assessor for retrieving data is separate + if (left.getNodeID() == ASTNodeID.ArrayIndexExpressionID + && node.getOperator().getOperatorText() == "=") + { + IDynamicAccessNode arrayNode = (IDynamicAccessNode)left; + IDefinition definition = arrayNode.getLeftOperandNode().resolve(project); + if (definition != null && arrayNode.getLeftOperandNode() instanceof IdentifierNode && definition.getTypeReference() != null + && definition.getTypeReference().getName().indexOf("ByteArray") > -1) + { + //System.out.println("**** ASSIGNMENT WITH ARRAY ASSESSOR ****"); + // TODO Check for ByteArray builtin + getModel().setInAssignment(false); + getEmitter().getWalker().walk(arrayNode.getLeftOperandNode()); + write(".setValueByPosition("); + getEmitter().getWalker().walk(arrayNode.getRightOperandNode()); + write(","); + // TODO not sure if need to do same checks as below + getEmitter().getWalker().walk(right); + write(")"); + return; + } + } + // Compound statements if (ExpressionUtils.isCompoundAssignment(node, lhsDefinition)) { @@ -71,11 +106,24 @@ public void emit(IBinaryOperatorNode node) if (ASNodeUtils.hasParenOpen(node)) write("("); + if (isFilter) + write("'"); // if on the left side with '=' , we are in setter mode getModel().setInAssignment(ExpressionUtils.isInAssignment(node)); getModel().setAssign(node); + // Case where right is another BinaryOperatorAssignment + if (right instanceof BinaryOperatorAssignmentNode) + { + emitBinaryRightAssignment(rhsDefinition, right); + writeNewline(";"); + + // Need to reset to this parent node + getModel().setInAssignment(ExpressionUtils.isInAssignment(node)); + getModel().setAssign(node); + } + getEmitter().getWalker().walk(left); if (!MetaDataUtils.isNative(lhsDefinition) @@ -100,11 +148,34 @@ && getModel().isInAssignment() boolean wasAssignment = getModel().isInAssignment(); getModel().setInAssignment(false); + // Right was another Binary Assignment so we just need the getter to set this left side + // TODO this is still potentially prone to side affects in the getter functions + if (right instanceof BinaryOperatorAssignmentNode) + getEmitter().getWalker().walk(((IBinaryOperatorNode)right).getLeftOperandNode()); + else + emitBinaryRightAssignment(rhsDefinition, right); + + if (!MetaDataUtils.isNative(lhsDefinition) && wasAssignment + && lhsDefinition instanceof IAccessorDefinition) + { + writeIfNotNative(")", lhsDefinition); + } + + if (isFilter) + write("'"); + if (ASNodeUtils.hasParenClose(node)) + write(")"); + } + + private void emitBinaryRightAssignment(IDefinition rhsDefinition, IExpressionNode right) + { + if (rhsDefinition instanceof IFunctionDefinition && right instanceof IIdentifierNode) { + // this is not a right hand function call, just a reff to accessor or function - write(IRandoriEmitter.STATIC_DELEGATE_NAME); + String pre = "this"; String parentQName = DefinitionNameUtils.toExportQualifiedName( rhsDefinition.getParent(), getProject()); @@ -113,23 +184,21 @@ && getModel().isInAssignment() pre = parentQName; } String name = getEmitter().stringifyNode(right); - if (name.contains("get_")) - { - name = "get_"; - } - else if (name.contains("set_")) + if (name.contains("get_") + || name.contains("set_")) { - name = "set_"; + getEmitter().getWalker().walk(right); } else { name = ""; + write(IRandoriEmitter.STATIC_DELEGATE_NAME); + write("(" + pre + ", "); + write(pre); + write("."); + write(name + rhsDefinition.getBaseName()); + write(")"); } - write("(" + pre + ", "); - write(pre); - write("."); - write(name + rhsDefinition.getBaseName()); - write(")"); } // else if (rhsDefinition instanceof IVariableDefinition // && right instanceof IIdentifierNode) @@ -154,15 +223,6 @@ else if (name.contains("set_")) } RandoriUtils.addBinaryRightDependency(right, getModel(), getProject()); - - if (!MetaDataUtils.isNative(lhsDefinition) && wasAssignment - && lhsDefinition instanceof IAccessorDefinition) - { - writeIfNotNative(")", lhsDefinition); - } - - if (ASNodeUtils.hasParenClose(node)) - write(")"); } private void emitCompoundAssignment(IBinaryOperatorNode node, diff --git a/src/main/java/randori/compiler/internal/codegen/js/emitter/DynamicAccessEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/emitter/DynamicAccessEmitter.java index dff0a5c..dd99890 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/emitter/DynamicAccessEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/emitter/DynamicAccessEmitter.java @@ -19,10 +19,16 @@ package randori.compiler.internal.codegen.js.emitter; +import org.apache.flex.compiler.definitions.IDefinition; +import org.apache.flex.compiler.internal.scopes.ASScope; +import org.apache.flex.compiler.internal.tree.as.IdentifierNode; +import org.apache.flex.compiler.projects.ICompilerProject; import org.apache.flex.compiler.tree.as.IDynamicAccessNode; import randori.compiler.codegen.js.IRandoriEmitter; import randori.compiler.codegen.js.ISubEmitter; +import randori.compiler.internal.utils.DefinitionNameUtils; +import randori.compiler.internal.utils.ExpressionUtils; /** * Handles the production of the {@link IDynamicAccessNode}. @@ -42,7 +48,17 @@ public DynamicAccessEmitter(IRandoriEmitter emitter) public void emit(IDynamicAccessNode node) { getModel().setInAssignment(false); - + ICompilerProject project = getEmitter().getWalker().getProject(); + IDefinition definition = node.getLeftOperandNode().resolve(project); + if (definition != null && node.getLeftOperandNode() instanceof IdentifierNode && definition.getTypeReference() != null + && definition.getTypeReference().getName().indexOf("ByteArray") > -1) + { + getEmitter().getWalker().walk(node.getLeftOperandNode()); + write(".getValueByPosition("); + getEmitter().getWalker().walk(node.getRightOperandNode()); + write(")"); + return; + } getEmitter().getWalker().walk(node.getLeftOperandNode()); write("["); getEmitter().getWalker().walk(node.getRightOperandNode()); diff --git a/src/main/java/randori/compiler/internal/codegen/js/emitter/FieldEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/emitter/FieldEmitter.java index 9106cff..5906db3 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/emitter/FieldEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/emitter/FieldEmitter.java @@ -20,12 +20,14 @@ package randori.compiler.internal.codegen.js.emitter; import org.apache.flex.compiler.definitions.IVariableDefinition; +import org.apache.flex.compiler.definitions.metadata.IMetaTag; import org.apache.flex.compiler.tree.as.IEmbedNode; import org.apache.flex.compiler.tree.as.IExpressionNode; import org.apache.flex.compiler.tree.as.IVariableNode; import randori.compiler.codegen.js.IRandoriEmitter; import randori.compiler.codegen.js.ISubEmitter; +import randori.compiler.internal.codegen.js.utils.GenericEmitUtils; import randori.compiler.internal.utils.RandoriUtils; /** @@ -48,11 +50,26 @@ public void emit(IVariableNode node) { IVariableDefinition definition = (IVariableDefinition) node .getDefinition(); + // Handle case where [Embed] or [Factory] metadata is present String prefix = RandoriUtils.toFieldPrefix(definition, getWalker() .getProject()); write(prefix); - emitAssignedValue(node.getAssignedValueNode()); + + IMetaTag embedTag = definition.getMetaTagByName("Embed"); + IMetaTag factoryTag = definition.getMetaTagByName("Factory"); + if (factoryTag != null) + { + + write(" "); + write("="); + write(" "); + GenericEmitUtils.emitEmbedFactory(factoryTag, embedTag, definition, getEmitter()); + } + else + { + emitAssignedValue(node.getAssignedValueNode()); + } } private void emitAssignedValue(IExpressionNode node) diff --git a/src/main/java/randori/compiler/internal/codegen/js/emitter/FooterEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/emitter/FooterEmitter.java index e841e71..2f98ba6 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/emitter/FooterEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/emitter/FooterEmitter.java @@ -21,12 +21,7 @@ import java.util.Collection; -import org.apache.flex.compiler.definitions.IClassDefinition; -import org.apache.flex.compiler.definitions.IFunctionDefinition; -import org.apache.flex.compiler.definitions.IParameterDefinition; -import org.apache.flex.compiler.definitions.IScopedDefinition; -import org.apache.flex.compiler.definitions.ITypeDefinition; -import org.apache.flex.compiler.definitions.IVariableDefinition; +import org.apache.flex.compiler.definitions.*; import org.apache.flex.compiler.definitions.metadata.IMetaTag; import org.apache.flex.compiler.tree.as.IClassNode; import org.apache.flex.compiler.tree.as.IScopedDefinitionNode; @@ -34,6 +29,7 @@ import randori.compiler.codegen.js.IRandoriEmitter; import randori.compiler.codegen.js.ISubEmitter; +import randori.compiler.internal.codegen.js.SessionModel; import randori.compiler.internal.utils.DefinitionUtils; import randori.compiler.internal.utils.MetaDataUtils; import randori.compiler.internal.utils.RandoriUtils; @@ -69,6 +65,9 @@ public FooterEmitter(IRandoriEmitter emitter) @Override public void emit(IClassNode node) { + emitGetterSetter(node, ((SessionModel)getEmitter().getModel() ) + .getGetterSetter()); + emitInherit(node); emitClassName(node); emitDependencies(node, "Runtime", getEmitter().getModel() @@ -79,6 +78,41 @@ public void emit(IClassNode node) emitLast(node); } + public void emitNewInherit(IClassNode node) + { + // $Inherit(foo.bar.Baz, foo.bar.SuperClass); + if (node.getBaseClassName() == null) + return; + + final String baseClassName = toBaseQualifiedName(node.getDefinition()); + if (baseClassName.equals("Object")) + return; + + final String qualifiedName = MetaDataUtils.getExportQualifiedName(node + .getDefinition()); + + //System.out.println("###**### " + node.getContainingScope().getScope()); + + + IClassDefinition bclass = node.getDefinition().resolveBaseClass( + getProject()); + if (bclass != null && bclass.getNode() != null) + getEmitter().getModel().addDependency((IScopedDefinition)bclass, bclass.getNode()); + //node.getContainingScope().getScope() + //getEmitter().getModel(). + + // NEED TO PUT "baseClassName" IN STATIC DEPENDENCIES ???? + //write(INHERIT_NAME); + //write("("); + writeNewline(); + write(qualifiedName); + write(".prototype = new "); + + write(baseClassName); + writeNewline("();"); + writeNewline(); + } + void emitInherit(IClassNode node) { // $Inherit(foo.bar.Baz, foo.bar.SuperClass); @@ -115,6 +149,35 @@ void emitClassName(IClassNode node) writeNewline(); } + void emitGetterSetter(IClassNode node, + Collection getterSetterProperties) + { + // foo.bar.Baz.get[name]Dependencies = function () { + // var p; + // return []; + // }; + + final String qualifiedName = MetaDataUtils.getExportQualifiedName(node + .getDefinition()); + + if (getterSetterProperties.size() > 0) + { + for (IAccessorDefinition type : getterSetterProperties) + { + if (!type.isStatic()) + { + String name = MetaDataUtils.getAccessorName( + (IAccessorDefinition) type, getProject()); + writeNewline("Object.defineProperty(" + qualifiedName + ".prototype, '" + name + "', {" ); + writeNewline(" get: function() { return this.get_"+name+"(); },"); + writeNewline(" set: function(value) { return this.set_"+name+"(value); }"); + writeNewline("});"); + } + } + } + writeNewline(); + } + void emitDependencies(IScopedDefinitionNode node, String name, Collection dependencies) { diff --git a/src/main/java/randori/compiler/internal/codegen/js/emitter/FunctionCallEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/emitter/FunctionCallEmitter.java index 437b921..3ac8171 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/emitter/FunctionCallEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/emitter/FunctionCallEmitter.java @@ -105,9 +105,22 @@ public void emit(IFunctionCallNode node) } else if (definition instanceof IClassDefinition) { + // TODO Think about giving a warning if ((IIdentifierNode)node.getNameNode()).getName() == "int" case + String castName = ((IIdentifierNode)node.getNameNode()).getName() + ""; // cast Foo(bar); just walk the value in parens - walkParameters(node); - return; + if (castName.equals("int")) + { + write("~~"); + write("("); + walkParameters(node); + write(")"); + return; + } + else + { + walkParameters(node); + return; + } } else if (fnode.getNameNode() instanceof IMemberAccessExpressionNode) { diff --git a/src/main/java/randori/compiler/internal/codegen/js/emitter/IdentifierEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/emitter/IdentifierEmitter.java index ac05d81..3269dd5 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/emitter/IdentifierEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/emitter/IdentifierEmitter.java @@ -70,7 +70,6 @@ public void emit(IIdentifierNode node) } IDefinition definition = node.resolve(getProject()); - if (definition instanceof IAccessorDefinition) { emitIdentifierAccessor(node, (IAccessorDefinition) definition); @@ -107,12 +106,14 @@ private void emitIdentifierClass(IIdentifierNode node, // figure out Class.FOO static var and qualify it if (node.getParent() instanceof IMemberAccessExpressionNode) { + IMemberAccessExpressionNode mnode = (IMemberAccessExpressionNode) node .getParent(); if (mnode.getRightOperandNode() instanceof IIdentifierNode) { IDefinition rightDef = mnode.getRightOperandNode().resolve( getProject()); + if (rightDef instanceof IVariableDefinition) { IVariableDefinition vdef = (IVariableDefinition) rightDef; @@ -243,10 +244,10 @@ private void emitIdentifierAccessor(IIdentifierNode node, { if (!MetaDataUtils.isNative(definition)) { + String baseName = MetaDataUtils.getAccessorName(definition, getProject()); String headName = getAccessorName(definition, node, getProject()); - if (getModel().skipOperator()) { // TODO make sure this logic is correct; if (Window.console != null) { @@ -283,7 +284,6 @@ else if (node.getParent().getNodeID() == ASTNodeID.MemberAccessExpressionID // definition.getNode(), getProject()); // write(headName + "."); // } - if (getModel().isInAssignment() && ExpressionUtils.isRight(getModel().getAssign(), node)) { @@ -312,8 +312,10 @@ else if (node.getParent().getNodeID() == ASTNodeID.MemberAccessExpressionID private void emitIdentifierFunction(IIdentifierNode node, IFunctionDefinition definition) { - if (definition.isStatic() && definition.getNode() != null) + if (definition.isStatic() && definition.getNode() != null + && !(node.getParent() instanceof IMemberAccessExpressionNode)) { + String qualifiedName = DefinitionNameUtils.toExportQualifiedName( definition, getProject()); write(qualifiedName); diff --git a/src/main/java/randori/compiler/internal/codegen/js/emitter/MethodEmitter.java b/src/main/java/randori/compiler/internal/codegen/js/emitter/MethodEmitter.java index a79f050..27125d4 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/emitter/MethodEmitter.java +++ b/src/main/java/randori/compiler/internal/codegen/js/emitter/MethodEmitter.java @@ -30,6 +30,7 @@ import org.apache.flex.compiler.definitions.IVariableDefinition; import org.apache.flex.compiler.definitions.metadata.IMetaTag; import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute; +import org.apache.flex.compiler.internal.definitions.metadata.MetaTagAttribute; import org.apache.flex.compiler.internal.tree.as.FunctionNode; import org.apache.flex.compiler.tree.as.IASNode; import org.apache.flex.compiler.tree.as.IClassNode; @@ -39,6 +40,8 @@ import randori.compiler.codegen.js.IRandoriEmitter; import randori.compiler.codegen.js.ISubEmitter; +import randori.compiler.internal.codegen.js.SessionModel; +import randori.compiler.internal.codegen.js.utils.GenericEmitUtils; import randori.compiler.internal.utils.DefinitionUtils; import randori.compiler.internal.utils.MetaDataUtils; import randori.compiler.internal.utils.RandoriUtils; @@ -116,6 +119,13 @@ public void emit(IFunctionNode node) write(prefix); write(" = function"); + // REE GETTER/SETTER Object.define + if (definition instanceof IAccessorDefinition) + { + SessionModel sm = (SessionModel)getEmitter().getModel(); + sm.addGetterSetter((IAccessorDefinition)definition); + } + getEmitter().emitParamters(node); getEmitter().emitMethodScope(node); } @@ -194,13 +204,8 @@ protected void emitConstructorFieldInitializers( //int i = 0; for (IVariableDefinition field : fields) { - IMetaTag tag = field.getMetaTagByName("Embed"); - if (tag != null) - { - emitEmbed(field); - writeNewline(";"); - continue; - } + + if (field instanceof IAccessorDefinition) continue; // constants do not get initialized @@ -209,10 +214,22 @@ protected void emitConstructorFieldInitializers( if (DefinitionUtils.isVariableAParameter(field, definition.getParameters())) continue; + + write("this."); write(field.getBaseName()); write(" = "); + + IMetaTag embedTag = field.getMetaTagByName("Embed"); + IMetaTag factoryTag = field.getMetaTagByName("Factory"); + if (embedTag != null || factoryTag != null) + { + GenericEmitUtils.emitEmbedFactory(factoryTag, embedTag, field, getEmitter()); + writeNewline(";"); + continue; + } + String value = DefinitionUtils.returnInitialVariableValue( (IVariableNode) field.getNode(), getEmitter()); @@ -223,66 +240,4 @@ protected void emitConstructorFieldInitializers( // write(";"); } } - - private void emitEmbed(IVariableDefinition field) - { - IMetaTag factoryTag = field.getMetaTagByName("Factory"); - IMetaTag embedTag = field.getMetaTagByName("Embed"); - - write("this."); - write(field.getBaseName()); - write(" = "); - - String factory = factoryTag.getAttributeValue("factoryClass"); - String type = factoryTag.getAttributeValue("type"); - - write(factory); - write("("); - - write("\""); - write(type); - write("\""); - write(", "); - - IMetaTagAttribute[] atts1 = factoryTag.getAllAttributes(); - IMetaTagAttribute[] atts2 = embedTag.getAllAttributes(); - - // write properties - List list = new ArrayList(); - for (IMetaTagAttribute att : atts1) - { - if (!att.getKey().equals("factoryClass") - && !att.getKey().equals("type")) - { - list.add(att); - } - } - - for (IMetaTagAttribute att : atts2) - { - //if (!att.getKey().equals("source")) - //{ - list.add(att); - // } - } - - write("{"); - int i = 0; - final int len = list.size(); - for (IMetaTagAttribute attribute : list) - { - write(attribute.getKey()); - write(":"); - write("\""); - write(attribute.getValue()); - write("\""); - if (i < len - 1) - write(", "); - i++; - } - write("}"); - - write(")"); - - } } diff --git a/src/main/java/randori/compiler/internal/codegen/js/utils/GenericEmitUtils.java b/src/main/java/randori/compiler/internal/codegen/js/utils/GenericEmitUtils.java index 7bb6d7f..982ad9f 100644 --- a/src/main/java/randori/compiler/internal/codegen/js/utils/GenericEmitUtils.java +++ b/src/main/java/randori/compiler/internal/codegen/js/utils/GenericEmitUtils.java @@ -19,24 +19,26 @@ package randori.compiler.internal.codegen.js.utils; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - +import org.apache.commons.lang3.StringEscapeUtils; import org.apache.flex.compiler.constants.IASKeywordConstants; import org.apache.flex.compiler.definitions.IFunctionDefinition; import org.apache.flex.compiler.definitions.IParameterDefinition; +import org.apache.flex.compiler.definitions.IVariableDefinition; +import org.apache.flex.compiler.definitions.metadata.IMetaTag; +import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute; +import org.apache.flex.compiler.internal.definitions.metadata.MetaTagAttribute; import org.apache.flex.compiler.projects.ICompilerProject; -import org.apache.flex.compiler.tree.as.IExpressionNode; -import org.apache.flex.compiler.tree.as.IFunctionCallNode; -import org.apache.flex.compiler.tree.as.IFunctionNode; -import org.apache.flex.compiler.tree.as.IParameterNode; - +import org.apache.flex.compiler.tree.as.*; import randori.compiler.codegen.as.IASEmitter; +import randori.compiler.codegen.js.IRandoriEmitter; import randori.compiler.internal.utils.DefinitionUtils; import randori.compiler.internal.utils.ExpressionUtils; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + /** * @author Michael Schmalle */ @@ -200,4 +202,72 @@ public static final void emitDefaultParameterCodeBlock(IFunctionNode node, } } } + + + public static final void emitEmbedFactory(IMetaTag factoryTag, IMetaTag embedTag, IVariableDefinition field, + IASEmitter emitter) + { + if (factoryTag == null) + return; + String factory = factoryTag.getAttributeValue("factoryClass"); + String type = factoryTag.getAttributeValue("type"); + + + emitter.write(factory); + emitter.write("("); + + emitter.write("\""); + emitter.write(type); + emitter.write("\""); + emitter.write(", "); + + IMetaTagAttribute[] atts1 = factoryTag.getAllAttributes(); + + // write properties + List list = new ArrayList(); + for (IMetaTagAttribute att : atts1) + { + if (!att.getKey().equals("factoryClass") + && !att.getKey().equals("type")) + { + list.add(att); + } + } + if (embedTag != null) + { + IMetaTagAttribute[] atts2 = embedTag.getAllAttributes(); + for (IMetaTagAttribute att : atts2) + { + //if (!att.getKey().equals("source")) + //{ + list.add(att); + // } + } + } + else + { + // Use the value as the source + String value = DefinitionUtils.returnInitialVariableValue( + (IVariableNode) field.getNode(), (IRandoriEmitter) emitter); + list.add(new MetaTagAttribute("source", StringEscapeUtils.escapeJava(value))); + } + + emitter.write("{"); + int i = 0; + final int len = list.size(); + for (IMetaTagAttribute attribute : list) + { + emitter.write(attribute.getKey()); + emitter.write(":"); + emitter.write("\""); + emitter.write(attribute.getValue()); + emitter.write("\""); + if (i < len - 1) + emitter.write(", "); + i++; + } + emitter.write("}"); + + emitter.write(")"); + } } diff --git a/src/main/java/randori/compiler/internal/utils/DefinitionUtils.java b/src/main/java/randori/compiler/internal/utils/DefinitionUtils.java index 2f7a5bc..fceb03d 100644 --- a/src/main/java/randori/compiler/internal/utils/DefinitionUtils.java +++ b/src/main/java/randori/compiler/internal/utils/DefinitionUtils.java @@ -138,6 +138,7 @@ public static final String toBaseClassQualifiedName( } IReference reference = typeNode.getDefinition().getBaseClassReference(); + List imports = resolveImports(typeNode.getDefinition()); String qualifiedName = toQualifiedName(reference); if (qualifiedName.indexOf(".") != -1) diff --git a/src/main/java/randori/compiler/internal/visitor/as/ASNodeSwitch.java b/src/main/java/randori/compiler/internal/visitor/as/ASNodeSwitch.java index 803d2c5..925efaa 100644 --- a/src/main/java/randori/compiler/internal/visitor/as/ASNodeSwitch.java +++ b/src/main/java/randori/compiler/internal/visitor/as/ASNodeSwitch.java @@ -72,6 +72,8 @@ import randori.compiler.visitor.as.IASNodeStrategy; import randori.compiler.visitor.as.IASNodeVisitor; +import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase; + /** * The {@link ASNodeSwitch} class is an {@link IASNodeStrategy} implementation * that handles {@link IASNode} types based on the node interface type. @@ -100,6 +102,7 @@ public ASNodeSwitch(IASNodeVisitor visitor) @Override public void handle(IASNode node) { + //System.out.println("ASNodeSwitch::handle NodeID: " + node.getNodeID()); // TODO (mschmalle) Still working on the switch, its complication in the expressions switch (node.getNodeID()) {