You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2014/10/31 09:28:30 UTC
[08/23] Added VF2JS emitting
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e63cc7fd/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
index a0686c8..9b91eb2 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
@@ -21,33 +21,49 @@ package org.apache.flex.compiler.internal.codegen.js.vf2js;
import java.io.FilterWriter;
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
-import org.apache.flex.compiler.codegen.IASGlobalFunctionConstants.BuiltinType;
+import org.apache.flex.compiler.codegen.IASGlobalFunctionConstants;
import org.apache.flex.compiler.codegen.IDocEmitter;
-import org.apache.flex.compiler.codegen.js.goog.IJSGoogDocEmitter;
-import org.apache.flex.compiler.codegen.js.goog.IJSGoogEmitter;
+import org.apache.flex.compiler.codegen.js.vf2js.IJSVF2JSEmitter;
import org.apache.flex.compiler.common.ASModifier;
import org.apache.flex.compiler.common.ModifiersSet;
-import org.apache.flex.compiler.constants.IASLanguageConstants;
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.IFunctionDefinition.FunctionClassification;
+import org.apache.flex.compiler.definitions.INamespaceDefinition;
import org.apache.flex.compiler.definitions.IPackageDefinition;
import org.apache.flex.compiler.definitions.ITypeDefinition;
import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
-import org.apache.flex.compiler.internal.codegen.js.JSEmitter;
import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
-import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitter;
import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
+import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
import org.apache.flex.compiler.internal.definitions.ClassDefinition;
+import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
+import org.apache.flex.compiler.internal.definitions.InterfaceDefinition;
+import org.apache.flex.compiler.internal.definitions.ParameterDefinition;
+import org.apache.flex.compiler.internal.definitions.VariableDefinition;
+import org.apache.flex.compiler.internal.projects.CompilerProject;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.scopes.ASProjectScope;
import org.apache.flex.compiler.internal.scopes.PackageScope;
+import org.apache.flex.compiler.internal.scopes.TypeScope;
+import org.apache.flex.compiler.internal.tree.as.BinaryOperatorAssignmentNode;
import org.apache.flex.compiler.internal.tree.as.ChainedVariableNode;
import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
import org.apache.flex.compiler.internal.tree.as.FunctionNode;
-import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.internal.tree.as.NonResolvingIdentifierNode;
+import org.apache.flex.compiler.internal.tree.as.ParameterNode;
+import org.apache.flex.compiler.internal.tree.as.RegExpLiteralNode;
+import org.apache.flex.compiler.internal.tree.as.UnaryOperatorAtNode;
import org.apache.flex.compiler.projects.ICompilerProject;
import org.apache.flex.compiler.scopes.IASScope;
import org.apache.flex.compiler.tree.ASTNodeID;
@@ -55,7 +71,6 @@ import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.as.IAccessorNode;
import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
import org.apache.flex.compiler.tree.as.IClassNode;
-import org.apache.flex.compiler.tree.as.IContainerNode;
import org.apache.flex.compiler.tree.as.IDefinitionNode;
import org.apache.flex.compiler.tree.as.IEmbedNode;
import org.apache.flex.compiler.tree.as.IExpressionNode;
@@ -65,130 +80,57 @@ import org.apache.flex.compiler.tree.as.IFunctionNode;
import org.apache.flex.compiler.tree.as.IGetterNode;
import org.apache.flex.compiler.tree.as.IIdentifierNode;
import org.apache.flex.compiler.tree.as.IInterfaceNode;
-import org.apache.flex.compiler.tree.as.INamespaceAccessExpressionNode;
+import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
+import org.apache.flex.compiler.tree.as.ILiteralNode;
+import org.apache.flex.compiler.tree.as.ILiteralNode.LiteralType;
+import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
import org.apache.flex.compiler.tree.as.IParameterNode;
-import org.apache.flex.compiler.tree.as.IScopedNode;
import org.apache.flex.compiler.tree.as.ISetterNode;
import org.apache.flex.compiler.tree.as.ITypeNode;
import org.apache.flex.compiler.tree.as.ITypedExpressionNode;
import org.apache.flex.compiler.tree.as.IVariableExpressionNode;
import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.apache.flex.compiler.units.ICompilationUnit;
import org.apache.flex.compiler.utils.ASNodeUtils;
+import org.apache.flex.compiler.utils.NativeUtils;
/**
- * Concrete implementation of the 'goog' JavaScript production.
+ * Concrete implementation of the 'vf2js' JavaScript production.
*
- * @author Michael Schmalle
* @author Erik de Bruin
*/
-public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
+public class JSVF2JSEmitter extends JSGoogEmitter implements IJSVF2JSEmitter
{
- protected static final String CONSTRUCTOR_EMPTY = "emptyConstructor";
- protected static final String CONSTRUCTOR_FULL = "fullConstructor";
- protected static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";
-
- protected List<String> propertyNames = new ArrayList<String>();
-
- protected ICompilerProject project;
-
- protected IJSGoogDocEmitter getDoc()
- {
- return (IJSGoogDocEmitter) getDocEmitter();
- }
-
- @Override
- public IDocEmitter getDocEmitter()
+ public JSVF2JSEmitter(FilterWriter out)
{
- return new JSGoogDocEmitter(this);
+ super(out);
}
- //--------------------------------------------------------------------------
- //
- //--------------------------------------------------------------------------
-
- @Override
- public void emitPackageHeader(IPackageDefinition definition)
- {
- IASScope containedScope = definition.getContainedScope();
- ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
- if (type == null)
- return;
-
- /* goog.provide('x');\n\n */
- write(JSGoogEmitterTokens.GOOG_PROVIDE);
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(type.getQualifiedName());
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(ASEmitterTokens.PAREN_CLOSE);
- writeNewline(ASEmitterTokens.SEMICOLON);
- writeNewline();
- }
+ public IDefinition thisClass;
@Override
- public void emitPackageHeaderContents(IPackageDefinition definition)
+ protected String getIndent(int numIndent)
{
- PackageScope containedScope = (PackageScope) definition
- .getContainedScope();
-
- ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
- if (type == null)
- return;
-
- List<String> list = resolveImports(type);
- for (String imp : list)
- {
- if (imp.indexOf(JSGoogEmitterTokens.AS3.getToken()) != -1)
- continue;
-
- /* goog.require('x');\n */
- write(JSGoogEmitterTokens.GOOG_REQUIRE);
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(imp);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(ASEmitterTokens.PAREN_CLOSE);
- writeNewline(ASEmitterTokens.SEMICOLON);
- }
-
- // (erikdebruin) only write 'closing' line break when there are
- // actually imports...
- if (list.size() > 1
- || (list.size() == 1 && list.get(0).indexOf(
- JSGoogEmitterTokens.AS3.getToken()) == -1))
- {
- writeNewline();
- }
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < numIndent; i++)
+ sb.append(JSFlexJSEmitterTokens.INDENT.getToken());
+ return sb.toString();
}
@Override
- public void emitPackageContents(IPackageDefinition definition)
+ protected void emitMemberName(IDefinitionNode node)
{
- IASScope containedScope = definition.getContainedScope();
- ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
- if (type == null)
- return;
-
- ITypeNode tnode = findTypeNode(definition.getNode());
- if (tnode != null)
- {
- getWalker().walk(tnode); // IClassNode | IInterfaceNode
- }
+ write(node.getName());
}
@Override
- public void emitPackageFooter(IPackageDefinition definition)
+ public void emitClass(IClassNode node)
{
- }
+ thisClass = node.getDefinition();
- //--------------------------------------------------------------------------
- //
- //--------------------------------------------------------------------------
+ project = getWalker().getProject();
- @Override
- public void emitClass(IClassNode node)
- {
IClassDefinition definition = node.getDefinition();
IFunctionDefinition ctorDefinition = definition.getConstructor();
@@ -230,6 +172,7 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
{
writeNewline();
writeNewline();
+ writeNewline();
emitField((IVariableNode) dnode);
write(ASEmitterTokens.SEMICOLON);
}
@@ -239,6 +182,7 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
{
writeNewline();
writeNewline();
+ writeNewline();
emitMethod((IFunctionNode) dnode);
write(ASEmitterTokens.SEMICOLON);
}
@@ -248,6 +192,7 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
{
writeNewline();
writeNewline();
+ writeNewline();
emitAccessors((IAccessorNode) dnode);
write(ASEmitterTokens.SEMICOLON);
}
@@ -277,72 +222,75 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
write(ASEmitterTokens.SEMICOLON);
}
+
final IDefinitionNode[] members = node.getAllMemberDefinitionNodes();
for (IDefinitionNode mnode : members)
{
boolean isAccessor = mnode.getNodeID() == ASTNodeID.GetterID
|| mnode.getNodeID() == ASTNodeID.SetterID;
- if (!isAccessor || !propertyNames.contains(qname))
- {
- writeNewline();
-
- write(qname);
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(JSEmitterTokens.PROTOTYPE);
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(mnode.getQualifiedName());
-
- if (isAccessor && !propertyNames.contains(qname))
- {
- propertyNames.add(qname);
- }
- else
- {
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- write(ASEmitterTokens.FUNCTION);
-
- emitParameters(((IFunctionNode) mnode).getParameterNodes());
-
- write(ASEmitterTokens.SPACE);
- write(ASEmitterTokens.BLOCK_OPEN);
- writeNewline();
- write(ASEmitterTokens.BLOCK_CLOSE);
- }
+ writeNewline();
+ writeNewline();
+ writeNewline();
- write(ASEmitterTokens.SEMICOLON);
+ getDoc().emitInterfaceMemberDoc((IFunctionNode) mnode, project);
+
+ write(qname);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.PROTOTYPE);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ if (isAccessor)
+ {
+ writeGetSetPrefix(mnode.getNodeID() == ASTNodeID.GetterID);
}
+ write(mnode.getQualifiedName());
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.FUNCTION);
+ emitParameters(((IFunctionNode) mnode).getParameterNodes());
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
}
}
@Override
public void emitField(IVariableNode node)
{
- IClassDefinition definition = getClassDefinition(node);
+ IDefinition definition = getClassDefinition(node);
IDefinition def = null;
IExpressionNode enode = node.getVariableTypeNode();//getAssignedValueNode();
if (enode != null)
- def = enode.resolveType(getWalker().getProject());
+ {
+ if (project == null)
+ project = getWalker().getProject();
+
+ def = enode.resolveType(project);
+ }
getDoc().emitFieldDoc(node, def);
- /* x.prototype.y = z */
+ IDefinition ndef = node.getDefinition();
- ModifiersSet modifierSet = node.getDefinition().getModifiers();
+ ModifiersSet modifierSet = ndef.getModifiers();
String root = "";
if (modifierSet != null && !modifierSet.hasModifier(ASModifier.STATIC))
{
root = JSEmitterTokens.PROTOTYPE.getToken();
root += ASEmitterTokens.MEMBER_ACCESS.getToken();
}
+
+ if (definition == null)
+ definition = ndef.getContainingScope().getDefinition();
+
write(definition.getQualifiedName()
+ ASEmitterTokens.MEMBER_ACCESS.getToken() + root
+ node.getName());
IExpressionNode vnode = node.getAssignedValueNode();
- if (vnode != null)
+ if (vnode != null && !(vnode instanceof IEmbedNode))
{
write(ASEmitterTokens.SPACE);
writeToken(ASEmitterTokens.EQUAL);
@@ -363,75 +311,55 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
}
}
}
- }
-
- @Override
- public void emitVarDeclaration(IVariableNode node)
- {
- if (!(node instanceof ChainedVariableNode))
- {
- emitMemberKeyword(node);
- }
-
- IExpressionNode avnode = node.getAssignedValueNode();
- if (avnode != null)
- {
- IDefinition def = avnode.resolveType(getWalker().getProject());
-
- String opcode = avnode.getNodeID().getParaphrase();
- if (opcode != "AnonymousFunction")
- getDoc().emitVarDoc(node, def);
- }
- else
- {
- getDoc().emitVarDoc(node, null);
- }
-
- emitDeclarationName(node);
- if (!(avnode instanceof IEmbedNode))
- emitAssignedValue(avnode);
-
- if (!(node instanceof ChainedVariableNode))
+ if (node.getNodeID() == ASTNodeID.BindableVariableID)
{
- // check for chained variables
- int len = node.getChildCount();
- for (int i = 0; i < len; i++)
- {
- IASNode child = node.getChild(i);
- if (child instanceof ChainedVariableNode)
- {
- writeToken(ASEmitterTokens.COMMA);
- emitVarDeclaration((IVariableNode) child);
- }
- }
+ // [Bindable]
+ writeNewline(ASEmitterTokens.SEMICOLON.getToken());
+ writeNewline();
+ writeNewline("/**");
+ writeNewline("@expose");
+ writeNewline(" */");
+ writeNewline(definition.getQualifiedName()
+ + ASEmitterTokens.MEMBER_ACCESS.getToken() + root
+ + "get_" + node.getName()
+ + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.EQUAL.getToken()
+ + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.FUNCTION.getToken()
+ + ASEmitterTokens.PAREN_OPEN.getToken() + ASEmitterTokens.PAREN_CLOSE.getToken()
+ + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.BLOCK_OPEN.getToken());
+ writeNewline(ASEmitterTokens.RETURN.getToken() + ASEmitterTokens.SPACE.getToken()
+ + ASEmitterTokens.THIS.getToken() + ASEmitterTokens.MEMBER_ACCESS.getToken()
+ + node.getName() + ASEmitterTokens.SEMICOLON.getToken());
+ writeNewline(ASEmitterTokens.BLOCK_CLOSE.getToken() + ASEmitterTokens.SEMICOLON.getToken());
+ writeNewline();
+ writeNewline("/**");
+ writeNewline("@expose");
+ writeNewline(" */");
+ writeNewline(definition.getQualifiedName()
+ + ASEmitterTokens.MEMBER_ACCESS.getToken() + root
+ + "set_" + node.getName()
+ + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.EQUAL.getToken()
+ + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.FUNCTION.getToken()
+ + ASEmitterTokens.PAREN_OPEN.getToken() + "value" + ASEmitterTokens.PAREN_CLOSE.getToken()
+ + ASEmitterTokens.SPACE.getToken() + ASEmitterTokens.BLOCK_OPEN.getToken());
+ writeNewline("if (value != " + ASEmitterTokens.THIS.getToken()
+ + ASEmitterTokens.MEMBER_ACCESS.getToken() + node.getName() + ") {");
+ writeNewline(" var oldValue = "
+ + ASEmitterTokens.THIS.getToken() + ASEmitterTokens.MEMBER_ACCESS.getToken()
+ + node.getName() + ASEmitterTokens.SEMICOLON.getToken());
+ writeNewline(" " + ASEmitterTokens.THIS.getToken() + ASEmitterTokens.MEMBER_ACCESS.getToken()
+ + node.getName() + " = value;");
+ writeNewline(" this.dispatchEvent(org.apache.flex.events.ValueChangeEvent.createUpdateEvent(");
+ writeNewline(" this, \"" + node.getName() + "\", oldValue, value));");
+ writeNewline("}");
+ write(ASEmitterTokens.BLOCK_CLOSE.getToken());
+
+
}
}
@Override
- public void emitGetAccessor(IGetterNode node)
- {
- emitObjectDefineProperty(node);
- }
-
- @Override
- public void emitSetAccessor(ISetterNode node)
- {
- emitObjectDefineProperty(node);
- }
-
protected void emitAccessors(IAccessorNode node)
{
- String qname = node.getQualifiedName();
- if (!propertyNames.contains(qname))
- {
- emitField(node);
- write(ASEmitterTokens.SEMICOLON);
- writeNewline();
- writeNewline();
-
- propertyNames.add(qname);
- }
-
if (node.getNodeID() == ASTNodeID.GetterID)
{
emitGetAccessor((IGetterNode) node);
@@ -446,7 +374,7 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
public void emitMethod(IFunctionNode node)
{
FunctionNode fn = (FunctionNode) node;
- fn.parseFunctionBody(new ArrayList<ICompilerProblem>());
+ fn.parseFunctionBody(getProblems());
ICompilerProject project = getWalker().getProject();
@@ -495,7 +423,7 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
if (isConstructor && hasSuperClass)
{
- writeNewline();
+ writeNewline(ASEmitterTokens.SEMICOLON);
write(JSGoogEmitterTokens.GOOG_INHERITS);
write(ASEmitterTokens.PAREN_OPEN);
write(qname);
@@ -518,16 +446,67 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
ASTNodeID id = cnode.getNodeID();
if (id != ASTNodeID.SuperID)
{
+ ICompilerProject project = null;
+ IDefinition def = null;
+
+ boolean isClassCast = false;
+
if (node.isNewExpression())
{
writeToken(ASEmitterTokens.NEW);
}
+ else
+ {
+ if (project == null)
+ project = getWalker().getProject();
- getWalker().walk(node.getNameNode());
+ def = node.getNameNode().resolve(project);
- write(ASEmitterTokens.PAREN_OPEN);
- walkArguments(node.getArgumentNodes());
- write(ASEmitterTokens.PAREN_CLOSE);
+ isClassCast = (def instanceof ClassDefinition ||
+ def instanceof InterfaceDefinition) &&
+ !(NativeUtils.isJSNative(def.getBaseName()));
+ }
+
+ if (node.isNewExpression())
+ {
+ if (project == null)
+ project = getWalker().getProject();
+
+ def = node.resolveCalledExpression(project);
+ // all new calls to a class should be fully qualified names
+ if (def instanceof ClassDefinition)
+ write(def.getQualifiedName());
+ else
+ // I think we still need this for "new someVarOfTypeClass"
+ getWalker().walk(node.getNameNode());
+ write(ASEmitterTokens.PAREN_OPEN);
+ walkArguments(node.getArgumentNodes());
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ else if (!isClassCast)
+ {
+ if (def != null)
+ {
+ boolean isInt = def.getBaseName().equals(IASGlobalFunctionConstants._int);
+ if (isInt ||
+ def.getBaseName().equals(IASGlobalFunctionConstants.trace) ||
+ def.getBaseName().equals(IASGlobalFunctionConstants.uint))
+ {
+ write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ if (isInt)
+ write(JSFlexJSEmitterTokens.UNDERSCORE);
+ }
+ }
+ getWalker().walk(node.getNameNode());
+ write(ASEmitterTokens.PAREN_OPEN);
+ walkArguments(node.getArgumentNodes());
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ else
+ {
+ emitIsAs(node.getArgumentNodes()[0], node.getNameNode(), ASTNodeID.Op_AsID, true);
+ }
}
else
{
@@ -535,140 +514,361 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
}
}
+ //--------------------------------------------------------------------------
+
@Override
- public void emitIdentifier(IIdentifierNode node)
+ protected void emitSelfReference(IFunctionNode node)
{
- ICompilerProject project = getWalker().getProject();
+ // we don't want 'var self = this;' in FlexJS
+ }
- IClassNode cnode = (IClassNode) node
+ private boolean writeThis(IIdentifierNode node)
+ {
+ if (node instanceof NonResolvingIdentifierNode)
+ return false;
+
+ IClassNode classNode = (IClassNode) node
.getAncestorOfType(IClassNode.class);
- IDefinition def = ((IIdentifierNode) node).resolve(project);
+ IDefinition nodeDef = ((IIdentifierNode) node).resolve(project);
- ITypeDefinition type = ((IIdentifierNode) node).resolveType(project);
+ IASNode parentNode = node.getParent();
+ ASTNodeID parentNodeId = parentNode.getNodeID();
- IASNode pnode = node.getParent();
- ASTNodeID inode = pnode.getNodeID();
+ IASNode firstChild = parentNode.getChild(0);
- boolean writeSelf = false;
- if (cnode != null)
+ boolean identifierIsMemberAccess = parentNodeId == ASTNodeID.MemberAccessExpressionID;
+
+ if (classNode == null) // script in MXML and AS interface definitions
{
- IDefinitionNode[] members = cnode.getAllMemberNodes();
- for (IDefinitionNode mnode : members)
+ if (nodeDef instanceof ParameterDefinition)
+ return false;
+
+ if (nodeDef instanceof VariableDefinition)
{
- if ((type != null && type.getQualifiedName().equalsIgnoreCase(
- IASLanguageConstants.Function))
- || (def != null && def.getQualifiedName()
- .equalsIgnoreCase(mnode.getQualifiedName())))
- {
- if (!(pnode instanceof FunctionNode)
- && inode != ASTNodeID.MemberAccessExpressionID)
- {
- writeSelf = true;
- break;
- }
- else if (inode == ASTNodeID.MemberAccessExpressionID
- && !def.isStatic())
- {
- String tname = type.getQualifiedName();
- writeSelf = !tname.equalsIgnoreCase(cnode
- .getQualifiedName())
- && !tname.equals(IASLanguageConstants.Function);
- break;
- }
- }
+ IDefinition pdef = ((VariableDefinition) nodeDef).getParent();
+
+ if (thisClass == null || !isSameClass(pdef, thisClass, project))
+ return false;
+
+ if (identifierIsMemberAccess)
+ return node == firstChild;
+
+ return parentNodeId == ASTNodeID.ContainerID
+ || !(parentNode instanceof ParameterNode);
}
- }
+ else if (nodeDef instanceof AccessorDefinition)
+ {
+ IDefinition pdef = ((AccessorDefinition) nodeDef).getParent();
- boolean isRunningInTestMode = cnode != null
- && cnode.getQualifiedName().equalsIgnoreCase("FalconTest_A");
- if (writeSelf && !isRunningInTestMode)
- {
- write(JSGoogEmitterTokens.SELF);
- write(ASEmitterTokens.MEMBER_ACCESS);
+ if (thisClass == null || !isSameClass(pdef, thisClass, project))
+ return false;
+
+ if (identifierIsMemberAccess)
+ return node == firstChild;
+
+ return true;
+ }
+ else if (parentNodeId == ASTNodeID.ContainerID
+ && nodeDef instanceof FunctionDefinition)
+ {
+ return ((FunctionDefinition) nodeDef)
+ .getFunctionClassification() == FunctionClassification.CLASS_MEMBER; // for 'goog.bind'
+ }
+ else
+ {
+ return parentNodeId == ASTNodeID.FunctionCallID
+ && !(nodeDef instanceof AccessorDefinition)
+ && !identifierIsMemberAccess;
+ }
}
else
{
- String pname = (type != null) ? type.getPackageName() : "";
- if (cnode != null
- && pname != ""
- && !pname.equalsIgnoreCase(cnode.getPackageName())
- && inode != ASTNodeID.ArgumentID
- && inode != ASTNodeID.VariableID
- && inode != ASTNodeID.TypedExpressionID)
+ if (nodeDef != null
+ && !nodeDef.isInternal()
+ && isClassMember(nodeDef, classNode))
{
- write(pname);
- write(ASEmitterTokens.MEMBER_ACCESS);
+ if (identifierIsMemberAccess)
+ {
+ if (parentNode.getNodeID() == ASTNodeID.MemberAccessExpressionID
+ && parentNode.getChild(0).getNodeID() == ASTNodeID.SuperID
+ && !isSuperCallForOverride(node))
+ {
+ return true;
+ }
+
+ return node == firstChild;
+ }
+ else
+ {
+ boolean identifierIsLocalFunction = nodeDef instanceof FunctionDefinition
+ && !(nodeDef instanceof AccessorDefinition)
+ && ((FunctionDefinition) nodeDef)
+ .getFunctionClassification() == IFunctionDefinition.FunctionClassification.LOCAL;
+
+ return !identifierIsLocalFunction;
+ }
}
}
- super.emitIdentifier(node);
+ return false;
}
- @Override
- public void emitFunctionBlockHeader(IFunctionNode node)
+ private boolean isClassMember(IDefinition nodeDef, IClassNode classNode)
{
- IDefinition def = node.getDefinition();
- boolean isStatic = false;
- if (def != null && def.isStatic())
- isStatic = true;
- boolean isLocal = false;
- if (node.getFunctionClassification() == IFunctionDefinition.FunctionClassification.LOCAL)
- isLocal = true;
- if (hasBody(node) && !isStatic && !isLocal)
- emitSelfReference(node);
+ TypeScope cscope = (TypeScope) classNode.getDefinition()
+ .getContainedScope();
- if (node.isConstructor()
- && hasSuperClass(node) && !hasSuperCall(node.getScopedNode()))
- emitSuperCall(node, CONSTRUCTOR_FULL);
+ Set<INamespaceDefinition> nsSet = cscope.getNamespaceSet(project);
+ Collection<IDefinition> defs = new HashSet<IDefinition>();
- emitRestParameterCodeBlock(node);
+ cscope.getAllPropertiesForMemberAccess((CompilerProject) project, defs,
+ nsSet);
- emitDefaultParameterCodeBlock(node);
- }
+ Iterator<IDefinition> visiblePropertiesIterator = defs.iterator();
+ while (visiblePropertiesIterator.hasNext())
+ {
+ if (nodeDef.getQualifiedName().equals(
+ visiblePropertiesIterator.next().getQualifiedName()))
+ return true;
+ }
- protected void emitSelfReference(IFunctionNode node)
- {
- writeToken(ASEmitterTokens.VAR);
- writeToken(JSGoogEmitterTokens.SELF);
- writeToken(ASEmitterTokens.EQUAL);
- write(ASEmitterTokens.THIS);
- writeNewline(ASEmitterTokens.SEMICOLON);
+ return false;
}
- protected void emitSuperCall(IASNode node, String type)
+ private boolean isSameClass(IDefinition pdef, IDefinition thisClass,
+ ICompilerProject project)
{
- IFunctionNode fnode = (node instanceof IFunctionNode) ? (IFunctionNode) node
- : null;
- IFunctionCallNode fcnode = (node instanceof IFunctionCallNode) ? (FunctionCallNode) node
- : null;
+ if (pdef == thisClass)
+ return true;
- if (type == CONSTRUCTOR_EMPTY)
- {
- indentPush();
- writeNewline();
- indentPop();
- }
- else if (type == SUPER_FUNCTION_CALL)
+ IDefinition cdef = ((ClassDefinition) thisClass).resolveBaseClass(project);
+ while (cdef != null)
{
- if (fnode == null)
- fnode = (IFunctionNode) fcnode
- .getAncestorOfType(IFunctionNode.class);
+ // needs to be a loop
+ if (cdef == pdef)
+ return true;
+ cdef = ((ClassDefinition) cdef).resolveBaseClass(project);
}
+ return false;
+ }
+
+ @Override
+ public void emitIdentifier(IIdentifierNode node)
+ {
+ if (project == null)
+ project = getWalker().getProject();
+
+ IDefinition nodeDef = ((IIdentifierNode) node).resolve(project);
+
+ IASNode parentNode = node.getParent();
+ ASTNodeID parentNodeId = parentNode.getNodeID();
+
+ boolean identifierIsAccessorFunction = nodeDef instanceof AccessorDefinition;
+ boolean identifierIsPlainFunction = nodeDef instanceof FunctionDefinition
+ && !identifierIsAccessorFunction;
+
+ boolean emitName = true;
+
+ if (nodeDef != null
+ && nodeDef.isStatic())
+ {
+ String sname = nodeDef.getParent().getQualifiedName();
+ if (sname.length() > 0)
+ {
+ write(sname);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ }
+ }
+ else if (!NativeUtils.isNative(node.getName()))
+ {
+ // an instance method as a parameter or
+ // a local function
+ boolean useGoogBind = (parentNodeId == ASTNodeID.ContainerID
+ && identifierIsPlainFunction && ((FunctionDefinition) nodeDef)
+ .getFunctionClassification() == FunctionClassification.CLASS_MEMBER)
+ || (identifierIsPlainFunction && ((FunctionDefinition) nodeDef)
+ .getFunctionClassification() == FunctionClassification.LOCAL);
+
+ if (useGoogBind)
+ {
+ write(JSGoogEmitterTokens.GOOG_BIND);
+ write(ASEmitterTokens.PAREN_OPEN);
+ }
+
+ if (writeThis(node))
+ {
+ write(ASEmitterTokens.THIS);
+
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ }
+
+ if (useGoogBind)
+ {
+ write(node.getName());
+
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.PAREN_CLOSE);
+
+ emitName = false;
+ }
+ }
+
+ IDefinition parentDef = (nodeDef != null) ? nodeDef.getParent() : null;
+ boolean isNative = (parentDef != null)
+ && NativeUtils.isNative(parentDef.getBaseName());
+ if ((identifierIsAccessorFunction && !isNative)
+ || (nodeDef instanceof VariableDefinition && ((VariableDefinition) nodeDef)
+ .isBindable()))
+ {
+ IASNode anode = node
+ .getAncestorOfType(BinaryOperatorAssignmentNode.class);
+
+ boolean isAssignment = false;
+ if (anode != null)
+ {
+ IASNode leftNode = anode.getChild(0);
+ if (anode == parentNode)
+ {
+ if (node == leftNode)
+ isAssignment = true;
+ }
+ else
+ {
+ IASNode pnode = parentNode;
+ IASNode thisNode = node;
+ while (anode != pnode)
+ {
+ if (pnode instanceof IMemberAccessExpressionNode)
+ {
+ if (thisNode != pnode.getChild(1))
+ {
+ // can't be an assignment because
+ // we're on the left side of a memberaccessexpression
+ break;
+ }
+ }
+ if (pnode == leftNode)
+ {
+ isAssignment = true;
+ }
+ thisNode = pnode;
+ pnode = pnode.getParent();
+ }
+ }
+ String op = ((IBinaryOperatorNode) anode).getOperator()
+ .getOperatorText();
+ if (op.contains("==") || !op.contains("="))
+ isAssignment = false;
+ }
+
+ if (parentNode.getNodeID() == ASTNodeID.MemberAccessExpressionID
+ && parentNode.getChild(0).getNodeID() == ASTNodeID.SuperID
+ && isSuperCallForOverride(node))
+ {
+ IClassNode cnode = (IClassNode) node
+ .getAncestorOfType(IClassNode.class);
+
+ // ToDo (erikdebruin): add VF2JS conditional -> only use check during full SDK compilation
+ if (cnode == null)
+ return;
+
+ write(cnode.getQualifiedName());
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSGoogEmitterTokens.GOOG_BASE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.THIS);
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ writeGetSetPrefix(!isAssignment);
+ write(nodeDef.getQualifiedName());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ if (isAssignment)
+ {
+ writeToken(ASEmitterTokens.COMMA);
+ }
+ }
+ else if (node instanceof NonResolvingIdentifierNode)
+ {
+ write(node.getName());
+ }
+ else
+ {
+ writeGetSetPrefix(!isAssignment);
+ write(node.getName());
+ write(ASEmitterTokens.PAREN_OPEN);
+ }
+
+ if (anode != null && isAssignment)
+ {
+ getWalker().walk(((BinaryOperatorAssignmentNode) anode)
+ .getRightOperandNode());
+ }
+
+ if (!(node instanceof NonResolvingIdentifierNode))
+ write(ASEmitterTokens.PAREN_CLOSE);
+ }
+ else if (emitName)
+ {
+ if (nodeDef != null)
+ write(nodeDef.getQualifiedName());
+ else
+ write(node.getName());
+ }
+ }
+
+ private boolean isSuperCallForOverride(IIdentifierNode node)
+ {
+ IFunctionNode pfnode = (IFunctionNode) node.
+ getAncestorOfType(FunctionNode.class);
+
+ if (pfnode == null)
+ return false;
+
+ return pfnode.getName().equals(node.getName());
+ }
+
+ //--------------------------------------------------------------------------
+
+ @Override
+ protected void emitSuperCall(IASNode node, String type)
+ {
+ IFunctionNode fnode = (node instanceof IFunctionNode) ? (IFunctionNode) node
+ : null;
+ IFunctionCallNode fcnode = (node instanceof IFunctionCallNode) ? (FunctionCallNode) node
+ : null;
+
+ if (type == CONSTRUCTOR_EMPTY)
+ {
+ indentPush();
+ writeNewline();
+ indentPop();
+ }
+ else if (type == SUPER_FUNCTION_CALL)
+ {
+ if (fnode == null)
+ fnode = (IFunctionNode) fcnode
+ .getAncestorOfType(IFunctionNode.class);
+ }
+
+ if (fnode != null && fnode.isConstructor() && !hasSuperClass(fnode))
+ return;
- if (fnode.isConstructor() && !hasSuperClass(fnode))
- return;
-
IClassNode cnode = (IClassNode) node
.getAncestorOfType(IClassNode.class);
+ // ToDo (erikdebruin): add VF2JS conditional -> only use check during full SDK compilation
+ if (cnode == null)
+ return;
+
write(cnode.getQualifiedName());
write(ASEmitterTokens.MEMBER_ACCESS);
write(JSGoogEmitterTokens.GOOG_BASE);
write(ASEmitterTokens.PAREN_OPEN);
write(ASEmitterTokens.THIS);
- if (fnode.isConstructor())
+ if (fnode != null && fnode.isConstructor())
{
writeToken(ASEmitterTokens.COMMA);
write(ASEmitterTokens.SINGLE_QUOTE);
@@ -680,7 +880,15 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
{
writeToken(ASEmitterTokens.COMMA);
write(ASEmitterTokens.SINGLE_QUOTE);
- write(fnode.getName());
+ if (fnode.getNodeID() == ASTNodeID.GetterID
+ || fnode.getNodeID() == ASTNodeID.SetterID)
+ writeGetSetPrefix(fnode.getNodeID() == ASTNodeID.GetterID);
+
+ // (erikdebruin): write(fnode.getName());
+ IMemberAccessExpressionNode aenode =
+ (IMemberAccessExpressionNode) fcnode.getNameNode();
+ write(((IIdentifierNode) aenode.getRightOperandNode()).getName());
+
write(ASEmitterTokens.SINGLE_QUOTE);
}
@@ -692,12 +900,29 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
writeArguments = anodes.length > 0;
}
- else if (fnode.isConstructor())
+ else if (fnode != null && fnode.isConstructor())
{
anodes = fnode.getParameterNodes();
writeArguments = (anodes != null && anodes.length > 0);
}
+ else if (fnode == null && node instanceof BinaryOperatorAssignmentNode)
+ {
+ BinaryOperatorAssignmentNode bnode = (BinaryOperatorAssignmentNode) node;
+
+ IFunctionNode pnode = (IFunctionNode) bnode.getAncestorOfType(IFunctionNode.class);
+
+ if (pnode.getNodeID() == ASTNodeID.SetterID)
+ {
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ writeGetSetPrefix(false);
+ getWalker().walk(bnode.getLeftOperandNode());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ writeToken(ASEmitterTokens.COMMA);
+ getWalker().walk(bnode.getRightOperandNode());
+ }
+ }
if (writeArguments)
{
@@ -723,6 +948,7 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
}
}
+ @Override
protected void emitDefaultParameterCodeBlock(IFunctionNode node)
{
IParameterNode[] pnodes = node.getParameterNodes();
@@ -738,7 +964,7 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
if (!hasBody(node))
{
indentPush();
- write(ASEmitterTokens.INDENT);
+ write(JSFlexJSEmitterTokens.INDENT);
}
List<IParameterNode> parameters = new ArrayList<IParameterNode>(
@@ -787,141 +1013,187 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
}
}
- private void emitRestParameterCodeBlock(IFunctionNode node)
+ @Override
+ public void emitBinaryOperator(IBinaryOperatorNode node)
{
- IParameterNode[] pnodes = node.getParameterNodes();
+ ASTNodeID id = node.getNodeID();
+ if (id == ASTNodeID.Op_InID
+ || id == ASTNodeID.Op_LogicalAndAssignID
+ || id == ASTNodeID.Op_LogicalOrAssignID)
+ {
+ super.emitBinaryOperator(node);
+ }
+ else if (id == ASTNodeID.Op_IsID || id == ASTNodeID.Op_AsID)
+ {
+ emitIsAs(node.getLeftOperandNode(), node.getRightOperandNode(), id, false);
+ }
+ else if (id == ASTNodeID.Op_InstanceOfID)
+ {
+ getWalker().walk(node.getLeftOperandNode());
- IParameterNode rest = getRest(pnodes);
- if (rest != null)
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.INSTANCEOF);
+
+ IDefinition dnode = (node.getRightOperandNode()).resolve(project);
+ if (dnode != null)
+ write(dnode.getQualifiedName());
+ else
+ getWalker().walk(node.getRightOperandNode());
+ }
+ else
{
- final StringBuilder code = new StringBuilder();
+ IExpressionNode leftSide = node.getLeftOperandNode();
- /* x = Array.prototype.slice.call(arguments, y);\n */
- code.append(rest.getName());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(ASEmitterTokens.EQUAL.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(BuiltinType.ARRAY.getName());
- code.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
- code.append(JSEmitterTokens.PROTOTYPE.getToken());
- code.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
- code.append(JSEmitterTokens.SLICE.getToken());
- code.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
- code.append(JSEmitterTokens.CALL.getToken());
- code.append(ASEmitterTokens.PAREN_OPEN.getToken());
- code.append(JSEmitterTokens.ARGUMENTS.getToken());
- code.append(ASEmitterTokens.COMMA.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(String.valueOf(pnodes.length - 1));
- code.append(ASEmitterTokens.PAREN_CLOSE.getToken());
- code.append(ASEmitterTokens.SEMICOLON.getToken());
-
- write(code.toString());
+ IExpressionNode property = null;
+ int leftSideChildCount = leftSide.getChildCount();
+ if (leftSideChildCount > 0)
+ {
+ IASNode childNode = leftSide.getChild(leftSideChildCount - 1);
+ if (childNode instanceof IExpressionNode)
+ property = (IExpressionNode) childNode;
+ else
+ property = leftSide;
+ }
+ else
+ property = leftSide;
- writeNewline();
- }
- }
+ IDefinition def = null;
+ if (property instanceof IIdentifierNode)
+ def = ((IIdentifierNode) property).resolve(getWalker()
+ .getProject());
- @Override
- public void emitParameter(IParameterNode node)
- {
- getWalker().walk(node.getNameExpressionNode());
- }
+ boolean isSuper = false;
+ if (leftSide.getNodeID() == ASTNodeID.MemberAccessExpressionID)
+ {
+ IASNode cnode = leftSide.getChild(0);
+ ASTNodeID cId = cnode.getNodeID();
- @Override
- protected void emitAssignedValue(IExpressionNode node)
- {
- if (node != null)
- {
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- if (node.getNodeID() == ASTNodeID.ClassReferenceID)
+ isSuper = cId == ASTNodeID.SuperID;
+ }
+
+ String op = node.getOperator().getOperatorText();
+ boolean isAssignment = !(op.contains("==") || !op.contains("="));
+
+ if (def instanceof AccessorDefinition && isAssignment)
+ {
+ getWalker().walk(leftSide);
+ }
+ else if (isSuper)
{
- IDefinition definition = node.resolve(getWalker().getProject());
- write(definition.getQualifiedName());
+ emitSuperCall(node, "");
}
else
{
- getWalker().walk(node);
+ if (ASNodeUtils.hasParenOpen(node))
+ write(ASEmitterTokens.PAREN_OPEN);
+
+ getWalker().walk(leftSide);
+
+ if (node.getNodeID() != ASTNodeID.Op_CommaID)
+ write(ASEmitterTokens.SPACE);
+
+ writeToken(node.getOperator().getOperatorText());
+
+ getWalker().walk(node.getRightOperandNode());
+
+ if (ASNodeUtils.hasParenClose(node))
+ write(ASEmitterTokens.PAREN_CLOSE);
}
}
}
- @Override
- public void emitTypedExpression(ITypedExpressionNode node)
- {
- getWalker().walk(node.getCollectionNode());
- }
-
- @Override
- public void emitForEachLoop(IForLoopNode node)
+ private void emitIsAs(IExpressionNode left, IExpressionNode right,
+ ASTNodeID id, boolean coercion)
{
- IContainerNode xnode = (IContainerNode) node.getChild(1);
- IBinaryOperatorNode bnode = (IBinaryOperatorNode) node
- .getConditionalsContainerNode().getChild(0);
- IASNode childNode = bnode.getChild(0);
-
- write(JSGoogEmitterTokens.GOOG_ARRAY_FOREACH);
+ write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ if (id == ASTNodeID.Op_IsID)
+ write(ASEmitterTokens.IS);
+ else
+ write(ASEmitterTokens.AS);
write(ASEmitterTokens.PAREN_OPEN);
- getWalker().walk(bnode.getChild(1));
+ getWalker().walk(left);
writeToken(ASEmitterTokens.COMMA);
- writeToken(ASEmitterTokens.FUNCTION);
- write(ASEmitterTokens.PAREN_OPEN);
- if (childNode instanceof IVariableExpressionNode)
- write(((IVariableNode) childNode.getChild(0)).getName());
+
+ IDefinition dnode = (right).resolve(project);
+ if (dnode != null)
+ write(dnode.getQualifiedName());
else
- write(((IIdentifierNode) childNode).getName());
- writeToken(ASEmitterTokens.PAREN_CLOSE);
- if (isImplicit(xnode))
- write(ASEmitterTokens.BLOCK_OPEN);
- getWalker().walk(node.getStatementContentsNode());
- if (isImplicit(xnode))
+ getWalker().walk(right);
+
+ if (coercion)
{
- writeNewline();
- write(ASEmitterTokens.BLOCK_CLOSE);
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.TRUE);
}
+
write(ASEmitterTokens.PAREN_CLOSE);
}
-
- public JSVF2JSEmitter(FilterWriter out)
+
+ @Override
+ public void emitMemberAccessExpression(IMemberAccessExpressionNode node)
{
- super(out);
- }
+ IASNode leftNode = node.getLeftOperandNode();
+ IASNode rightNode = node.getRightOperandNode();
- protected Map<Integer, IParameterNode> getDefaults(IParameterNode[] nodes)
- {
- Map<Integer, IParameterNode> result = new HashMap<Integer, IParameterNode>();
- int i = 0;
- boolean hasDefaults = false;
- for (IParameterNode node : nodes)
+ if (project == null)
+ project = getWalker().getProject();
+
+ IDefinition def = node.resolve(project);
+ boolean isStatic = false;
+ if (def != null && def.isStatic())
+ isStatic = true;
+
+ boolean continueWalk = true;
+ if (!isStatic)
{
- if (node.hasDefaultValue())
+ if (!(leftNode instanceof ILanguageIdentifierNode && ((ILanguageIdentifierNode) leftNode)
+ .getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.THIS))
{
- hasDefaults = true;
- result.put(i, node);
+ if (rightNode instanceof UnaryOperatorAtNode)
+ {
+ // ToDo (erikdebruin): properly handle E4X
+
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ getWalker().walk(node.getLeftOperandNode());
+ write(ASEmitterTokens.SQUARE_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write("E4XOperator");
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.SQUARE_CLOSE);
+ continueWalk = false;
+ }
+ else if (node.getNodeID() == ASTNodeID.Op_DescendantsID)
+ {
+ // ToDo (erikdebruin): properly handle E4X
+
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ getWalker().walk(node.getLeftOperandNode());
+ write(ASEmitterTokens.SQUARE_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write("E4XSelector");
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.SQUARE_CLOSE);
+ continueWalk = false;
+ }
+ else if (leftNode.getNodeID() != ASTNodeID.SuperID)
+ {
+ getWalker().walk(node.getLeftOperandNode());
+ write(node.getOperator().getOperatorText());
+ }
}
else
{
- result.put(i, null);
+ write(ASEmitterTokens.THIS);
+ write(node.getOperator().getOperatorText());
}
- i++;
- }
-
- if (!hasDefaults)
- return null;
-
- return result;
- }
-
- private IParameterNode getRest(IParameterNode[] nodes)
- {
- for (IParameterNode node : nodes)
- {
- if (node.isRest())
- return node;
+
}
-
- return null;
+
+ if (continueWalk)
+ getWalker().walk(node.getRightOperandNode());
}
private static ITypeDefinition getTypeDefinition(IDefinitionNode node)
@@ -930,13 +1202,6 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
return (ITypeDefinition) tnode.getDefinition();
}
- protected static IClassDefinition getClassDefinition(IDefinitionNode node)
- {
- IClassNode tnode = (IClassNode) node
- .getAncestorOfType(IClassNode.class);
- return (tnode != null) ? tnode.getDefinition() : null;
- }
-
private static IClassDefinition getSuperClassDefinition(
IDefinitionNode node, ICompilerProject project)
{
@@ -946,211 +1211,470 @@ public class JSVF2JSEmitter extends JSEmitter implements IJSGoogEmitter
return superClass;
}
- protected boolean hasSuperClass(IDefinitionNode node)
- {
- ICompilerProject project = getWalker().getProject();
- IClassDefinition superClassDefinition = getSuperClassDefinition(node,
- project);
- // XXX (mschmalle) this is nulling for MXML super class, figure out why
- if (superClassDefinition == null)
- return false;
- String qname = superClassDefinition.getQualifiedName();
- return superClassDefinition != null
- && !qname.equals(IASLanguageConstants.Object);
- }
-
- private boolean hasSuperCall(IScopedNode node)
- {
- for (int i = node.getChildCount() - 1; i > -1; i--)
- {
- IASNode cnode = node.getChild(i);
- if (cnode.getNodeID() == ASTNodeID.FunctionCallID
- && cnode.getChild(0).getNodeID() == ASTNodeID.SuperID)
- return true;
- }
-
- return false;
- }
-
- protected static boolean hasBody(IFunctionNode node)
- {
- IScopedNode scope = node.getScopedNode();
- return scope.getChildCount() > 0;
- }
-
+ @Override
protected void emitObjectDefineProperty(IAccessorNode node)
{
- /*
- Object.defineProperty(
- A.prototype,
- 'foo',
- {get: function() {return -1;},
- configurable: true}
- );
- */
-
FunctionNode fn = (FunctionNode) node;
fn.parseFunctionBody(getProblems());
- // head
- write(JSGoogEmitterTokens.OBJECT);
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(JSEmitterTokens.DEFINE_PROPERTY);
- writeNewline(ASEmitterTokens.PAREN_OPEN, true);
-
- // Type
IFunctionDefinition definition = node.getDefinition();
ITypeDefinition type = (ITypeDefinition) definition.getParent();
+
+ // ToDo (erikdebruin): add VF2JS conditional -> only use check during full SDK compilation
+ if (type == null)
+ return;
+
+ if (project == null)
+ project = getWalker().getProject();
+
+ getDoc().emitMethodDoc(fn, project);
write(type.getQualifiedName());
if (!node.hasModifier(ASModifier.STATIC))
{
write(ASEmitterTokens.MEMBER_ACCESS);
write(JSEmitterTokens.PROTOTYPE);
}
- writeToken(ASEmitterTokens.COMMA);
- writeNewline();
- // name
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(definition.getBaseName());
- write(ASEmitterTokens.SINGLE_QUOTE);
- writeToken(ASEmitterTokens.COMMA);
- writeNewline();
-
- // info object
- // declaration
- write(ASEmitterTokens.BLOCK_OPEN);
- write(node.getNodeID() == ASTNodeID.GetterID ? ASEmitterTokens.GET
- : ASEmitterTokens.SET);
- write(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ writeGetSetPrefix(node instanceof IGetterNode);
+ writeToken(node.getName());
+ writeToken(ASEmitterTokens.EQUAL);
write(ASEmitterTokens.FUNCTION);
emitParameters(node.getParameterNodes());
-
+ //writeNewline();
emitMethodScope(node.getScopedNode());
-
- writeToken(ASEmitterTokens.COMMA);
- write(JSEmitterTokens.CONFIGURABLE);
- write(ASEmitterTokens.COLON);
- write(ASEmitterTokens.TRUE);
- writeNewline(ASEmitterTokens.BLOCK_CLOSE, false);
-
- // tail, no colon; parent container will add it
- write(ASEmitterTokens.PAREN_CLOSE);
}
- //--------------------------------------------------------------------------
- // Operators
- //--------------------------------------------------------------------------
-
- @Override
- public void emitNamespaceAccessExpression(INamespaceAccessExpressionNode node)
+ private void writeGetSetPrefix(boolean isGet)
{
- getWalker().walk(node.getLeftOperandNode());
- write(ASEmitterTokens.MEMBER_ACCESS);
- getWalker().walk(node.getRightOperandNode());
+ if (isGet)
+ write(ASEmitterTokens.GET);
+ else
+ write(ASEmitterTokens.SET);
+ write("_");
}
@Override
- public void emitAsOperator(IBinaryOperatorNode node)
+ public IDocEmitter getDocEmitter()
{
- emitBinaryOperator(node);
+ return new JSVF2JSDocEmitter(this);
}
@Override
- public void emitIsOperator(IBinaryOperatorNode node)
+ public void emitPackageHeader(IPackageDefinition definition)
{
- emitBinaryOperator(node);
+ IASScope containedScope = definition.getContainedScope();
+ ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
+ if (type == null)
+ return;
+
+ writeNewline("/**");
+ writeNewline(" * " + type.getQualifiedName());
+ writeNewline(" *");
+ writeNewline(" * @fileoverview");
+ writeNewline(" *");
+ writeNewline(" * @suppress {checkTypes}");
+ writeNewline(" */");
+ writeNewline();
+
+ /* goog.provide('x');\n\n */
+ write(JSGoogEmitterTokens.GOOG_PROVIDE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(type.getQualifiedName());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ writeNewline();
}
@Override
- public void emitBinaryOperator(IBinaryOperatorNode node)
+ public void emitPackageHeaderContents(IPackageDefinition definition)
{
- if (ASNodeUtils.hasParenOpen(node))
- write(ASEmitterTokens.PAREN_OPEN);
+ PackageScope containedScope = (PackageScope) definition
+ .getContainedScope();
- ASTNodeID id = node.getNodeID();
+ ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
+ if (type == null)
+ return;
- if (id == ASTNodeID.Op_IsID)
+ if (project == null)
+ project = getWalker().getProject();
+
+ FlexJSProject flexProject = (FlexJSProject) project;
+ ASProjectScope projectScope = (ASProjectScope) flexProject.getScope();
+ ICompilationUnit cu = projectScope
+ .getCompilationUnitForDefinition(type);
+ ArrayList<String> requiresList = flexProject.getRequires(cu);
+ ArrayList<String> interfacesList = flexProject.getInterfaces(cu);
+
+ String cname = type.getQualifiedName();
+ ArrayList<String> writtenInstances = new ArrayList<String>();
+ writtenInstances.add(cname); // make sure we don't add ourselves
+
+ boolean emitsRequires = false;
+ if (requiresList != null)
{
- write(ASEmitterTokens.IS);
- write(ASEmitterTokens.PAREN_OPEN);
- getWalker().walk(node.getLeftOperandNode());
- writeToken(ASEmitterTokens.COMMA);
- getWalker().walk(node.getRightOperandNode());
- write(ASEmitterTokens.PAREN_CLOSE);
+ for (String imp : requiresList)
+ {
+ if (imp.indexOf(JSGoogEmitterTokens.AS3.getToken()) != -1)
+ continue;
+
+ if (imp.equals(cname))
+ continue;
+
+ if (NativeUtils.isNative(imp))
+ continue;
+
+ if (writtenInstances.indexOf(imp) == -1)
+ {
+
+ /* goog.require('x');\n */
+ write(JSGoogEmitterTokens.GOOG_REQUIRE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(imp);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+
+ writtenInstances.add(imp);
+
+ emitsRequires = true;
+ }
+ }
}
- else if (id == ASTNodeID.Op_AsID)
+
+ boolean emitsInterfaces = false;
+ if (interfacesList != null)
{
- // (is(a, b) ? a : null)
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.IS);
+ for (String imp : interfacesList)
+ {
+ write(JSGoogEmitterTokens.GOOG_REQUIRE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(imp);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+
+ emitsInterfaces = true;
+ }
+ }
+
+ // erikdebruin: Add missing language feature support, with e.g. 'is' and
+ // 'as' operators. We don't need to worry about requiring
+ // this in every project: ADVANCED_OPTIMISATIONS will NOT
+ // include any of the code if it is not used in the project.
+ boolean isMainCU = flexProject.mainCU != null &&
+ cu.getName().equals(flexProject.mainCU.getName());
+ if (isMainCU)
+ {
+ write(JSGoogEmitterTokens.GOOG_REQUIRE);
write(ASEmitterTokens.PAREN_OPEN);
- getWalker().walk(node.getLeftOperandNode());
- writeToken(ASEmitterTokens.COMMA);
- getWalker().walk(node.getRightOperandNode());
- writeToken(ASEmitterTokens.PAREN_CLOSE);
- writeToken(ASEmitterTokens.TERNARY);
- getWalker().walk(node.getLeftOperandNode());
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.COLON);
- write(ASEmitterTokens.NULL);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+ write(ASEmitterTokens.SINGLE_QUOTE);
write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
}
- else
+
+ if (emitsRequires || emitsInterfaces || isMainCU)
{
- getWalker().walk(node.getLeftOperandNode());
+ writeNewline();
+ }
- if (id != ASTNodeID.Op_CommaID)
- write(ASEmitterTokens.SPACE);
+ writeNewline();
+ writeNewline();
+ }
- // (erikdebruin) rewrite 'a &&= b' to 'a = a && b'
- if (id == ASTNodeID.Op_LogicalAndAssignID
- || id == ASTNodeID.Op_LogicalOrAssignID)
- {
- IIdentifierNode lnode = (IIdentifierNode) node
- .getLeftOperandNode();
+ @Override
+ public void emitPackageFooter(IPackageDefinition definition)
+ {
+ IASScope containedScope = definition.getContainedScope();
+ ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
+ if (type == null)
+ return;
- writeToken(ASEmitterTokens.EQUAL);
- writeToken(lnode.getName());
- write((id == ASTNodeID.Op_LogicalAndAssignID) ? ASEmitterTokens.LOGICAL_AND
- : ASEmitterTokens.LOGICAL_OR);
- }
+ ITypeNode tnode = findTypeNode(definition.getNode());
+ if (tnode != null)
+ {
+ /*
+ * Metadata
+ *
+ * @type {Object.<string, Array.<Object>>}
+ */
+ writeNewline();
+ writeNewline();
+ writeNewline();
+ getDoc().begin();
+ writeNewline(" * Metadata");
+ writeNewline(" *");
+ writeNewline(" * @type {Object.<string, Array.<Object>>}");
+ getDoc().end();
+
+ // a.B.prototype.AFJS_CLASS_INFO = { };
+ write(type.getQualifiedName());
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.PROTOTYPE);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ writeToken(JSFlexJSEmitterTokens.FLEXJS_CLASS_INFO);
+ writeToken(ASEmitterTokens.EQUAL);
+ writeToken(ASEmitterTokens.BLOCK_OPEN);
+
+ // names: [{ name: '', qName: '' }]
+ write(JSFlexJSEmitterTokens.NAMES);
+ writeToken(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SQUARE_OPEN);
+ writeToken(ASEmitterTokens.BLOCK_OPEN);
+ write(JSFlexJSEmitterTokens.NAME);
+ writeToken(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(tnode.getName());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ writeToken(ASEmitterTokens.COMMA);
+ write(JSFlexJSEmitterTokens.QNAME);
+ writeToken(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(tnode.getQualifiedName());
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.SQUARE_CLOSE);
+
+ IExpressionNode[] enodes;
+ if (tnode instanceof IClassNode)
+ enodes = ((IClassNode) tnode).getImplementedInterfaceNodes();
else
+ enodes = ((IInterfaceNode) tnode).getExtendedInterfaceNodes();
+
+ if (enodes.length > 0)
{
- write(node.getOperator().getOperatorText());
+ writeToken(ASEmitterTokens.COMMA);
+
+ // interfaces: [a.IC, a.ID]
+ write(JSFlexJSEmitterTokens.INTERFACES);
+ writeToken(ASEmitterTokens.COLON);
+ write(ASEmitterTokens.SQUARE_OPEN);
+ int i = 0;
+ for (IExpressionNode enode : enodes)
+ {
+ write(enode.resolve(project).getQualifiedName());
+ if (i < enodes.length - 1)
+ writeToken(ASEmitterTokens.COMMA);
+ i++;
+ }
+ write(ASEmitterTokens.SQUARE_CLOSE);
}
write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+ }
+ }
+
+ private int foreachLoopCounter = 0;
+
+ @Override
+ public void emitForEachLoop(IForLoopNode node)
+ {
+ IBinaryOperatorNode bnode = (IBinaryOperatorNode) node
+ .getConditionalsContainerNode().getChild(0);
+ IASNode childNode = bnode.getChild(0);
+
+ String iterName = "foreachiter"
+ + new Integer(foreachLoopCounter).toString();
+ foreachLoopCounter++;
- getWalker().walk(node.getRightOperandNode());
+ write(ASEmitterTokens.FOR);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.VAR);
+ write(ASEmitterTokens.SPACE);
+ write(iterName);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.IN);
+ write(ASEmitterTokens.SPACE);
+ getWalker().walk(bnode.getChild(1));
+ writeToken(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_OPEN);
+ writeNewline();
+ if (childNode instanceof IVariableExpressionNode)
+ {
+ write(ASEmitterTokens.VAR);
+ write(ASEmitterTokens.SPACE);
+ write(((IVariableNode) childNode.getChild(0)).getName());
}
+ else
+ write(((IIdentifierNode) childNode).getName());
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.EQUAL);
+ write(ASEmitterTokens.SPACE);
+ getWalker().walk(bnode.getChild(1));
+ write(ASEmitterTokens.SQUARE_OPEN);
+ write(iterName);
+ write(ASEmitterTokens.SQUARE_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
+ writeNewline();
+ getWalker().walk(node.getStatementContentsNode());
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ writeNewline();
- if (ASNodeUtils.hasParenOpen(node))
- write(ASEmitterTokens.PAREN_CLOSE);
}
- //--------------------------------------------------------------------------
- //
- //--------------------------------------------------------------------------
+ /*
+ @Override
+ public void emitForEachLoop(IForLoopNode node)
+ {
+ IContainerNode xnode = (IContainerNode) node.getChild(1);
+ IBinaryOperatorNode bnode = (IBinaryOperatorNode) node
+ .getConditionalsContainerNode().getChild(0);
+ IASNode childNode = bnode.getChild(0);
+
+ write(ASEmitterTokens.TRY);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ writeNewline();
+
+ write(JSGoogEmitterTokens.GOOG_ARRAY_FOREACH);
+ write(ASEmitterTokens.PAREN_OPEN);
+ getWalker().walk(bnode.getChild(1));
+ writeToken(ASEmitterTokens.COMMA);
+ writeToken(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.PAREN_OPEN);
+ if (childNode instanceof IVariableExpressionNode)
+ write(((IVariableNode) childNode.getChild(0)).getName());
+ else
+ write(((IIdentifierNode) childNode).getName());
+ writeToken(ASEmitterTokens.PAREN_CLOSE);
+ if (isImplicit(xnode))
+ write(ASEmitterTokens.BLOCK_OPEN);
+ getWalker().walk(node.getStatementContentsNode());
+ if (isImplicit(xnode))
+ {
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ }
+ write(ASEmitterTokens.PAREN_CLOSE);
+ writeNewline();
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ writeNewline();
+ write(ASEmitterTokens.CATCH);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write("foreachbreakerror");
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ writeNewline();
+
+ }
- private List<String> resolveImports(ITypeDefinition type)
+ @Override
+ public void emitIterationFlow(IIterationFlowNode node)
{
- ArrayList<String> list = new ArrayList<String>();
- IScopedNode scopeNode = type.getContainedScope().getScopeNode();
- if (scopeNode != null)
+ // look for break in foreach and throw error instead
+ if (node.getKind() == IIterationFlowNode.IterationFlowKind.BREAK)
+ {
+ IASNode pNode = node.getParent();
+ while (pNode != null)
+ {
+ ASTNodeID id = pNode.getNodeID();
+ if (id == ASTNodeID.ForEachLoopID)
+ {
+ write(ASEmitterTokens.THROW);
+ write(ASEmitterTokens.SPACE);
+ write(ASEmitterTokens.NEW);
+ write(ASEmitterTokens.SPACE);
+ write(JSGoogEmitterTokens.ERROR);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
+ return;
+ }
+ else if (id == ASTNodeID.ForLoopID ||
+ id == ASTNodeID.DoWhileLoopID ||
+ id == ASTNodeID.WhileLoopID)
+ break;
+ pNode = pNode.getParent();
+ }
+ }
+ write(node.getKind().toString().toLowerCase());
+ IIdentifierNode lnode = node.getLabelNode();
+ if (lnode != null)
{
- scopeNode.getAllImports(list);
+ write(ASEmitterTokens.SPACE);
+ getWalker().walk(lnode);
}
- else
+ }
+ */
+
+ @Override
+ public void emitTypedExpression(ITypedExpressionNode node)
+ {
+ write(JSGoogEmitterTokens.ARRAY);
+ }
+
+ @Override
+ public void emitLiteral(ILiteralNode node)
+ {
+ boolean isWritten = false;
+
+ String s = node.getValue(true);
+ if (!(node instanceof RegExpLiteralNode))
{
- // MXML
- ClassDefinition cdefinition = (ClassDefinition) type;
- String[] implicitImports = cdefinition.getImplicitImports();
- for (String imp : implicitImports)
+ if (node.getLiteralType() == LiteralType.XML)
+ {
+ // ToDo (erikdebruin): VF2JS -> handle XML output properly...
+
+ write("'" + s + "'");
+
+ isWritten = true;
+ }
+ s = s.replaceAll("\n", "__NEWLINE_PLACEHOLDER__");
+ s = s.replaceAll("\r", "__CR_PLACEHOLDER__");
+ s = s.replaceAll("\t", "__TAB_PLACEHOLDER__");
+ s = s.replaceAll("\f", "__FORMFEED_PLACEHOLDER__");
+ s = s.replaceAll("\b", "__BACKSPACE_PLACEHOLDER__");
+ s = s.replaceAll("\\\\\"", "__QUOTE_PLACEHOLDER__");
+ s = s.replaceAll("\\\\", "__ESCAPE_PLACEHOLDER__");
+ //s = "\'" + s.replaceAll("\'", "\\\\\'") + "\'";
+ s = s.replaceAll("__ESCAPE_PLACEHOLDER__", "\\\\\\\\");
+ s = s.replaceAll("__QUOTE_PLACEHOLDER__", "\\\\\"");
+ s = s.replaceAll("__BACKSPACE_PLACEHOLDER__", "\\\\b");
+ s = s.replaceAll("__FORMFEED_PLACEHOLDER__", "\\\\f");
+ s = s.replaceAll("__TAB_PLACEHOLDER__", "\\\\t");
+ s = s.replaceAll("__CR_PLACEHOLDER__", "\\\\r");
+ s = s.replaceAll("__NEWLINE_PLACEHOLDER__", "\\\\n");
+
+ Character c = s.charAt(0);
+ if (c.equals('"'))
{
- list.add(imp);
+ s = s.substring(1, s.length() - 1);
+ s = s.replaceAll("\"", "\\\\\"");
+ s = "\"" + s + "\"";
}
+ if (s.length() == 3)
+ {
+ c = s.charAt(1);
+ if (c.equals('\\')) {
+ s = "\"\\\\\"";
+ }
+ }
+ }
+
+ if (!isWritten)
+ {
+ write(s);
}
- return list;
}
+
+ @Override
+ public void emitE4XFilter(IMemberAccessExpressionNode node)
+ {
+ // ToDo (erikdebruin): implement E4X replacement !?!
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ write("E4XFilter");
+ write(ASEmitterTokens.SINGLE_QUOTE);
+ }
+
}