http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3724c2ff/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
----------------------------------------------------------------------
diff --git
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
deleted file mode 100644
index 4f9d5f2..0000000
---
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/vf2js/JSVF2JSEmitter.java
+++ /dev/null
@@ -1,1950 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.flex.compiler.internal.codegen.js.vf2js;
-
-import java.io.FilterWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-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;
-import org.apache.flex.compiler.codegen.js.goog.IJSGoogDocEmitter;
-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.IParameterDefinition;
-import org.apache.flex.compiler.definitions.ITypeDefinition;
-import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
-import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
-import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
-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.codegen.js.utils.EmitterUtils;
-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.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;
-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;
-import org.apache.flex.compiler.tree.as.IForLoopNode;
-import org.apache.flex.compiler.tree.as.IFunctionCallNode;
-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.IKeywordNode;
-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.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 'vf2js' JavaScript production.
- *
- * @author Erik de Bruin
- */
-public class JSVF2JSEmitter extends JSGoogEmitter implements IJSVF2JSEmitter
-{
-
- public JSVF2JSEmitter(FilterWriter out)
- {
- super(out);
- }
-
- @Override
- protected String getIndent(int numIndent)
- {
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < numIndent; i++)
- sb.append(JSFlexJSEmitterTokens.INDENT.getToken());
- return sb.toString();
- }
-
- @Override
- protected void emitMemberName(IDefinitionNode node)
- {
- write(node.getName());
- }
-
- @Override
- public void emitClass(IClassNode node)
- {
- IClassDefinition definition = node.getDefinition();
- getModel().setCurrentClass(definition);
-
- project = getWalker().getProject();
-
- IFunctionDefinition ctorDefinition = definition.getConstructor();
-
- // Static-only (Singleton) classes may not have a constructor
- if (ctorDefinition != null)
- {
- IFunctionNode ctorNode = (IFunctionNode) ctorDefinition.getNode();
- if (ctorNode != null)
- {
- // constructor
- emitMethod(ctorNode);
- write(ASEmitterTokens.SEMICOLON);
- }
- else
- {
- String qname = parseQualifiedName(definition);
- if (qname != null && !qname.equals(""))
- {
- write(qname);
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- write(ASEmitterTokens.FUNCTION);
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.PAREN_CLOSE);
- write(ASEmitterTokens.SPACE);
- write(ASEmitterTokens.BLOCK_OPEN);
- writeNewline();
- write(ASEmitterTokens.BLOCK_CLOSE);
- write(ASEmitterTokens.SEMICOLON);
- }
- }
- }
-
- IDefinitionNode[] dnodes = node.getAllMemberNodes();
- for (IDefinitionNode dnode : dnodes)
- {
- if (dnode.getNodeID() == ASTNodeID.VariableID)
- {
- writeNewline();
- writeNewline();
- writeNewline();
- emitField((IVariableNode) dnode);
- write(ASEmitterTokens.SEMICOLON);
- }
- else if (dnode.getNodeID() == ASTNodeID.FunctionID)
- {
- if (!((IFunctionNode) dnode).isConstructor())
- {
- writeNewline();
- writeNewline();
- writeNewline();
- emitMethod((IFunctionNode) dnode);
- write(ASEmitterTokens.SEMICOLON);
- }
- }
- else if (dnode.getNodeID() == ASTNodeID.GetterID
- || dnode.getNodeID() == ASTNodeID.SetterID)
- {
- writeNewline();
- writeNewline();
- writeNewline();
- emitAccessors((IAccessorNode) dnode);
- write(ASEmitterTokens.SEMICOLON);
- }
- }
- }
-
- @Override
- public void emitInterface(IInterfaceNode node)
- {
- ICompilerProject project = getWalker().getProject();
-
- getDocEmitter().emitInterfaceDoc(node, project);
-
- String qname = parseQualifiedName(node);
- if (qname != null && !qname.equals(""))
- {
- write(qname);
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- write(ASEmitterTokens.FUNCTION);
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.PAREN_CLOSE);
- write(ASEmitterTokens.SPACE);
- write(ASEmitterTokens.BLOCK_OPEN);
- writeNewline();
- write(ASEmitterTokens.BLOCK_CLOSE);
- write(ASEmitterTokens.SEMICOLON);
- }
-
- final IDefinitionNode[] members = node.getAllMemberDefinitionNodes();
- for (IDefinitionNode mnode : members)
- {
- boolean isAccessor = mnode.getNodeID() == ASTNodeID.GetterID
- || mnode.getNodeID() == ASTNodeID.SetterID;
-
- writeNewline();
- writeNewline();
- writeNewline();
-
- getDocEmitter().emitInterfaceMemberDoc(mnode, project);
-
- write(qname);
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(JSEmitterTokens.PROTOTYPE);
- write(ASEmitterTokens.MEMBER_ACCESS);
- if (isAccessor)
- {
- writeGetSetPrefix(mnode.getNodeID() == ASTNodeID.GetterID);
- }
- write(parseQualifiedName(mnode));
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- write(ASEmitterTokens.FUNCTION);
- emitParameters(((IFunctionNode)
mnode).getParametersContainerNode());
- write(ASEmitterTokens.SPACE);
- write(ASEmitterTokens.BLOCK_OPEN);
- write(ASEmitterTokens.BLOCK_CLOSE);
- write(ASEmitterTokens.SEMICOLON);
- }
- }
-
- @Override
- public void emitFunctionBlockHeader(IFunctionNode node)
- {
- 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 (EmitterUtils.hasBody(node) && !isStatic && !isLocal)
- emitSelfReference(node);
-
- emitRestParameterCodeBlock(node);
-
- emitDefaultParameterCodeBlock(node);
-
- if (node.isConstructor())
- {
- emitVarNonLiteralAssignments();
- }
-
- if (node.isConstructor() && hasSuperClass(node)
- && !EmitterUtils.hasSuperCall(node.getScopedNode()))
- emitSuperCall(node, JSSessionModel.CONSTRUCTOR_FULL);
- }
-
- private void emitVarNonLiteralAssignments()
- {
- // (erikdebruin): If the initial value of a variable is set using
- // a method, JS needs this initialization to be done
- // in the constructor
- IClassNode cdnode = (IClassNode)
getModel().getCurrentClass().getNode();
- IDefinitionNode[] dnodes = cdnode.getAllMemberNodes();
- for (IDefinitionNode dnode : dnodes)
- {
- if (dnode.getNodeID() == ASTNodeID.VariableID)
- {
- IVariableNode vnode = (IVariableNode) dnode;
- IExpressionNode avnode = vnode.getAssignedValueNode();
- if (avnode != null && !(avnode instanceof ILiteralNode)
- && !(avnode instanceof IEmbedNode))
- {
- writeNewline("", true);
- if (vnode.hasModifier(ASModifier.STATIC))
- {
- write(parseQualifiedName(cdnode));
- }
- else
- {
- write(ASEmitterTokens.THIS);
- }
- write(ASEmitterTokens.MEMBER_ACCESS);
- writeToken(vnode.getName());
- writeToken(ASEmitterTokens.EQUAL);
- getWalker().walk(avnode);
- indentPop();
- writeNewline(ASEmitterTokens.SEMICOLON);
- }
- }
- }
- }
-
- @Override
- public void emitVarDeclaration(IVariableNode node)
- {
- if (!(node instanceof ChainedVariableNode))
- {
- // (erikdebruin): check for 'var i:int = 0, j:int = 0' containers
- IASNode pnode = node.getParent();
- if (!(pnode instanceof IVariableExpressionNode)
- || node.getChild(0) instanceof IKeywordNode)
- {
- emitMemberKeyword(node);
- }
- }
-
- IExpressionNode avnode = node.getAssignedValueNode();
- if (avnode != null)
- {
- IDefinition def = avnode.resolveType(getWalker().getProject());
-
- String opcode = avnode.getNodeID().getParaphrase();
- if (opcode != "AnonymousFunction")
- getDocEmitter().emitVarDoc(node, def,
getWalker().getProject());
- }
- else
- {
- getDocEmitter().emitVarDoc(node, null, getWalker().getProject());
- }
-
- emitDeclarationName(node);
- if (avnode != null && !(avnode instanceof IEmbedNode))
- {
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- emitAssignedValue(avnode);
- }
-
- if (!(node instanceof ChainedVariableNode))
- {
- // 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);
- }
- }
- }
- }
-
- @Override
- public void emitMemberKeyword(IDefinitionNode node)
- {
- if (node instanceof IFunctionNode)
- {
- writeToken(ASEmitterTokens.FUNCTION);
- }
- else if (node instanceof IVariableNode)
- {
- writeToken(ASEmitterTokens.VAR);
- }
- }
-
- @Override
- public void emitField(IVariableNode node)
- {
- IDefinition definition = EmitterUtils.getClassDefinition(node);
-
- IDefinition def = null;
- IExpressionNode enode =
node.getVariableTypeNode();//getAssignedValueNode();
- if (enode != null)
- {
- if (project == null)
- project = getWalker().getProject();
-
- def = enode.resolveType(project);
- }
-
- getDocEmitter().emitFieldDoc(node, def, project);
-
- IDefinition ndef = node.getDefinition();
-
- 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(parseQualifiedName(definition)
- + ASEmitterTokens.MEMBER_ACCESS.getToken() + root
- + node.getName());
-
- IExpressionNode vnode = node.getAssignedValueNode();
- if (vnode != null && vnode instanceof ILiteralNode)
- {
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- getWalker().walk(vnode);
- }
-
- if (!(node instanceof ChainedVariableNode))
- {
- int len = node.getChildCount();
- for (int i = 0; i < len; i++)
- {
- IASNode child = node.getChild(i);
- if (child instanceof ChainedVariableNode)
- {
- writeNewline(ASEmitterTokens.SEMICOLON);
- writeNewline();
- emitField((IVariableNode) child);
- }
- }
- }
- if (node.getNodeID() == ASTNodeID.BindableVariableID)
- {
- // [Bindable]
- writeNewline(ASEmitterTokens.SEMICOLON.getToken());
- writeNewline();
- writeNewline("/**");
- writeNewline("@export");
- writeNewline(" */");
- writeNewline(parseQualifiedName(definition)
- + 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("@export");
- writeNewline(" */");
- writeNewline(parseQualifiedName(definition)
- + 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 emitAccessors(IAccessorNode node)
- {
- if (node.getNodeID() == ASTNodeID.GetterID)
- {
- emitGetAccessor((IGetterNode) node);
- }
- else if (node.getNodeID() == ASTNodeID.SetterID)
- {
- emitSetAccessor((ISetterNode) node);
- }
- }
-
- @Override
- public void emitMethod(IFunctionNode node)
- {
- FunctionNode fn = (FunctionNode) node;
- fn.parseFunctionBody(getProblems());
-
- ICompilerProject project = getWalker().getProject();
-
- getDocEmitter().emitMethodDoc(node, project);
-
- boolean isConstructor = node.isConstructor();
-
- String qname = parseQualifiedName(getTypeDefinition(node));
- if (qname != null && !qname.equals(""))
- {
- write(qname);
- if (!isConstructor)
- {
- write(ASEmitterTokens.MEMBER_ACCESS);
- if (!fn.hasModifier(ASModifier.STATIC))
- {
- write(JSEmitterTokens.PROTOTYPE);
- write(ASEmitterTokens.MEMBER_ACCESS);
- }
- }
- }
-
- if (!isConstructor)
- emitMemberName(node);
-
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.EQUAL);
- write(ASEmitterTokens.FUNCTION);
-
- emitParameters(node.getParametersContainerNode());
-
- boolean hasSuperClass = hasSuperClass(node);
-
- if (isConstructor && node.getScopedNode().getChildCount() == 0)
- {
- write(ASEmitterTokens.SPACE);
- write(ASEmitterTokens.BLOCK_OPEN);
- emitVarNonLiteralAssignments();
- if (hasSuperClass)
- {
- emitSuperCall(node, JSSessionModel.CONSTRUCTOR_EMPTY);
- writeNewline();
- }
- write(ASEmitterTokens.BLOCK_CLOSE);
- }
-
- if (!isConstructor || node.getScopedNode().getChildCount() > 0)
- emitMethodScope(node.getScopedNode());
-
- if (isConstructor && hasSuperClass)
- {
- writeNewline(ASEmitterTokens.SEMICOLON);
- write(JSGoogEmitterTokens.GOOG_INHERITS);
- write(ASEmitterTokens.PAREN_OPEN);
- write(qname);
- writeToken(ASEmitterTokens.COMMA);
- String sname = parseQualifiedName(getSuperClassDefinition(node,
- project));
- if (sname.equals(IASLanguageConstants.Object))
- sname = IASLanguageConstants.Class;
- write(sname);
- write(ASEmitterTokens.PAREN_CLOSE);
- }
- }
-
- protected boolean hasSuperClass(IDefinitionNode node)
- {
- ICompilerProject project = getWalker().getProject();
- IClassDefinition superClassDefinition = getSuperClassDefinition(node,
- project);
-
- if (superClassDefinition == null)
- return false;
-
- String qname = parseQualifiedName(superClassDefinition);
-
- // ToDo (erikdebruin): need this to get the JS version of the SDK in
- // shape?
- boolean useClassAsSuperClass = !qname
- .equals(IASLanguageConstants.Object);
- if (!useClassAsSuperClass)
- {
- if (parseQualifiedName(node).equals("mx.core.EmbeddedFontRegistry")
- || parseQualifiedName(node).equals(
- "mx.managers.HistoryManagerImpl")
- || parseQualifiedName(node).equals(
- "mx.core.TextFieldFactory"))
- {
- useClassAsSuperClass = true;
- }
- }
-
- return superClassDefinition != null && useClassAsSuperClass;
- }
-
- @Override
- public void emitFunctionCall(IFunctionCallNode node)
- {
- IASNode cnode = node.getChild(0);
-
- if (cnode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
- cnode = cnode.getChild(0);
-
- 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();
-
- def = node.getNameNode().resolve(project);
-
- 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(parseQualifiedName(def));
- else
- // I think we still need this for "new someVarOfTypeClass"
- getWalker().walk(node.getNameNode());
- emitArguments(node.getArgumentsNode());
- }
- 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());
- emitArguments(node.getArgumentsNode());
- }
- else
- {
- emitIsAs(node.getArgumentNodes()[0], node.getNameNode(),
- ASTNodeID.Op_AsID, true);
- }
- }
- else
- {
- emitSuperCall(node, JSSessionModel.SUPER_FUNCTION_CALL);
- }
- }
-
-
//--------------------------------------------------------------------------
-
- @Override
- protected void emitSelfReference(IFunctionNode node)
- {
- // we don't want 'var self = this;' in FlexJS
- }
-
- private boolean writeThis(IIdentifierNode node)
- {
- if (node instanceof NonResolvingIdentifierNode)
- return false;
-
- IClassNode classNode = (IClassNode) node
- .getAncestorOfType(IClassNode.class);
-
- IDefinition nodeDef = node.resolve(project);
-
- IASNode parentNode = node.getParent();
- ASTNodeID parentNodeId = parentNode.getNodeID();
-
- IASNode firstChild = parentNode.getChild(0);
- IClassDefinition thisClass = getModel().getCurrentClass();
-
- boolean identifierIsMemberAccess = parentNodeId ==
ASTNodeID.MemberAccessExpressionID;
-
- if (classNode == null) // script in MXML and AS interface definitions
- {
- if (nodeDef instanceof ParameterDefinition)
- return false;
-
- if (nodeDef instanceof VariableDefinition)
- {
- 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();
-
- 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
- {
- if (nodeDef != null && !nodeDef.isInternal()
- && isClassMember(nodeDef, classNode))
- {
- 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;
-
- if (nodeDef instanceof IParameterDefinition)
- return false;
-
- return !identifierIsLocalFunction;
- }
- }
- }
-
- return false;
- }
-
- private boolean isClassMember(IDefinition nodeDef, IClassNode classNode)
- {
- TypeScope cscope = (TypeScope) classNode.getDefinition()
- .getContainedScope();
-
- Set<INamespaceDefinition> nsSet = cscope.getNamespaceSet(project);
- Collection<IDefinition> defs = new HashSet<IDefinition>();
-
- cscope.getAllPropertiesForMemberAccess((CompilerProject) project, defs,
- nsSet);
-
- Iterator<IDefinition> visiblePropertiesIterator = defs.iterator();
- while (visiblePropertiesIterator.hasNext())
- {
- if (parseQualifiedName(nodeDef).equals(
- parseQualifiedName(visiblePropertiesIterator.next())))
- return true;
- }
-
- return false;
- }
-
- private boolean isSameClass(IDefinition pdef, IDefinition thisClass,
- ICompilerProject project)
- {
- if (pdef == thisClass)
- return true;
-
- IDefinition cdef = ((ClassDefinition) thisClass)
- .resolveBaseClass(project);
- while (cdef != null)
- {
- // 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 = 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()
- && nodeDef.getParent() != null)
- {
- String sname = parseQualifiedName(nodeDef.getParent());
- 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(parseQualifiedName(cnode));
- 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(parseQualifiedName(nodeDef));
- 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(parseQualifiedName(nodeDef));
- 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 == JSSessionModel.CONSTRUCTOR_EMPTY)
- {
- indentPush();
- writeNewline();
- indentPop();
- }
- else if (type == JSSessionModel.SUPER_FUNCTION_CALL)
- {
- if (fnode == null)
- fnode = (IFunctionNode) fcnode
- .getAncestorOfType(IFunctionNode.class);
- }
-
- if (fnode != null && fnode.isConstructor() && !hasSuperClass(fnode))
- return;
-
- IClassNode cnode = (IClassNode) node
- .getAncestorOfType(IClassNode.class);
-
- if (cnode == null)
- return;
-
- // (erikdebruin): Catch when a 'super' call does NOT match the
enclosing
- // function call. The GCC only allows '.base()' calls
- // to matching super methods, so we need to use
- // 'goog.base' for these ...
- boolean isCallToOtherSuperMethod = false;
- try
- {
- IExpressionNode d = fcnode.getNameNode();
- if (d != null && d instanceof IMemberAccessExpressionNode)
- {
- IIdentifierNode b = (IIdentifierNode)
((IMemberAccessExpressionNode) d)
- .getRightOperandNode();
-
- isCallToOtherSuperMethod = b != null
- && !b.getName().equals(fnode.getName());
- }
- }
- catch (Exception e)
- { /* Eat it! */
- }
-
- if (isCallToOtherSuperMethod)
- {
- write(ASEmitterTokens.THIS);
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(JSGoogEmitterTokens.SUPERCLASS);
- write(ASEmitterTokens.MEMBER_ACCESS);
- }
- else
- {
- write(parseQualifiedName(cnode));
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(JSGoogEmitterTokens.GOOG_BASE);
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.THIS);
- }
-
- if (fnode != null && fnode.isConstructor())
- {
- writeToken(ASEmitterTokens.COMMA);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(JSGoogEmitterTokens.GOOG_CONSTRUCTOR);
- write(ASEmitterTokens.SINGLE_QUOTE);
- }
-
- if (fnode != null && !fnode.isConstructor())
- {
- if (!isCallToOtherSuperMethod)
- {
- writeToken(ASEmitterTokens.COMMA);
- write(ASEmitterTokens.SINGLE_QUOTE);
- }
-
- 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());
-
- if (!isCallToOtherSuperMethod)
- {
- write(ASEmitterTokens.SINGLE_QUOTE);
- }
- else
- {
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(JSGoogEmitterTokens.GOOG_CALL);
- write(ASEmitterTokens.PAREN_OPEN);
- write(ASEmitterTokens.THIS);
- }
- }
-
- IASNode[] anodes = null;
- boolean writeArguments = false;
- if (fcnode != null)
- {
- anodes = fcnode.getArgumentNodes();
-
- writeArguments = anodes.length > 0;
- }
- 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)
- {
- int len = anodes.length;
- for (int i = 0; i < len; i++)
- {
- writeToken(ASEmitterTokens.COMMA);
-
- getWalker().walk(anodes[i]);
- }
- }
-
- write(ASEmitterTokens.PAREN_CLOSE);
-
- if (type == JSSessionModel.CONSTRUCTOR_FULL)
- {
- write(ASEmitterTokens.SEMICOLON);
- writeNewline();
- }
- else if (type == JSSessionModel.CONSTRUCTOR_EMPTY)
- {
- write(ASEmitterTokens.SEMICOLON);
- }
- }
-
- @Override
- protected void emitDefaultParameterCodeBlock(IFunctionNode node)
- {
- IParameterNode[] pnodes = node.getParameterNodes();
- if (pnodes.length == 0)
- return;
-
- Map<Integer, IParameterNode> defaults = EmitterUtils
- .getDefaults(pnodes);
-
- if (defaults != null)
- {
- final StringBuilder code = new StringBuilder();
-
- if (!EmitterUtils.hasBody(node))
- {
- indentPush();
- write(JSFlexJSEmitterTokens.INDENT);
- }
-
- List<IParameterNode> parameters = new ArrayList<IParameterNode>(
- defaults.values());
-
- for (int i = 0, n = parameters.size(); i < n; i++)
- {
- IParameterNode pnode = parameters.get(i);
-
- if (pnode != null)
- {
- code.setLength(0);
-
- /* x = typeof y !== 'undefined' ? y : z;\n */
- code.append(pnode.getName());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(ASEmitterTokens.EQUAL.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(ASEmitterTokens.TYPEOF.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(pnode.getName());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(ASEmitterTokens.STRICT_NOT_EQUAL.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
- code.append(ASEmitterTokens.UNDEFINED.getToken());
- code.append(ASEmitterTokens.SINGLE_QUOTE.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(ASEmitterTokens.TERNARY.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(pnode.getName());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(ASEmitterTokens.COLON.getToken());
- code.append(ASEmitterTokens.SPACE.getToken());
- code.append(pnode.getDefaultValue());
- code.append(ASEmitterTokens.SEMICOLON.getToken());
-
- write(code.toString());
-
- if (i == n - 1 && !EmitterUtils.hasBody(node))
- indentPop();
-
- writeNewline();
- }
- }
- }
- }
-
- @Override
- public void emitBinaryOperator(IBinaryOperatorNode node)
- {
- 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());
-
- write(ASEmitterTokens.SPACE);
- writeToken(ASEmitterTokens.INSTANCEOF);
-
- IDefinition dnode = (node.getRightOperandNode()).resolve(project);
- if (dnode != null)
- write(parseQualifiedName(dnode));
- else
- getWalker().walk(node.getRightOperandNode());
- }
- else
- {
- IExpressionNode leftSide = node.getLeftOperandNode();
-
- 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;
-
- IDefinition def = null;
- if (property instanceof IIdentifierNode)
- def = ((IIdentifierNode) property).resolve(getWalker()
- .getProject());
-
- boolean isSuper = false;
- if (leftSide.getNodeID() == ASTNodeID.MemberAccessExpressionID)
- {
- IASNode cnode = leftSide.getChild(0);
- ASTNodeID cId = cnode.getNodeID();
-
- 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)
- {
- emitSuperCall(node, "");
- }
- else
- {
- 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);
- }
- }
- }
-
- private void emitIsAs(IExpressionNode left, IExpressionNode right,
- ASTNodeID id, boolean coercion)
- {
- 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(left);
- writeToken(ASEmitterTokens.COMMA);
-
- IDefinition dnode = (right).resolve(project);
- if (dnode != null)
- write(parseQualifiedName(dnode));
- else
- getWalker().walk(right);
-
- if (coercion)
- {
- writeToken(ASEmitterTokens.COMMA);
- write(ASEmitterTokens.TRUE);
- }
-
- write(ASEmitterTokens.PAREN_CLOSE);
- }
-
- @Override
- public void emitMemberAccessExpression(IMemberAccessExpressionNode node)
- {
- IASNode leftNode = node.getLeftOperandNode();
- IASNode rightNode = node.getRightOperandNode();
-
- 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 (!(leftNode instanceof ILanguageIdentifierNode &&
((ILanguageIdentifierNode) leftNode)
- .getKind() ==
ILanguageIdentifierNode.LanguageIdentifierKind.THIS))
- {
- 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
- {
- write(ASEmitterTokens.THIS);
- write(node.getOperator().getOperatorText());
- }
-
- }
-
- if (continueWalk)
- getWalker().walk(node.getRightOperandNode());
- }
-
- private static ITypeDefinition getTypeDefinition(IDefinitionNode node)
- {
- ITypeNode tnode = (ITypeNode) node.getAncestorOfType(ITypeNode.class);
- return (ITypeDefinition) tnode.getDefinition();
- }
-
- private static IClassDefinition getSuperClassDefinition(
- IDefinitionNode node, ICompilerProject project)
- {
- IClassDefinition parent = (IClassDefinition) node.getDefinition()
- .getParent();
- IClassDefinition superClass = parent.resolveBaseClass(project);
- return superClass;
- }
-
- @Override
- protected void emitObjectDefineProperty(IAccessorNode node)
- {
- FunctionNode fn = (FunctionNode) node;
- fn.parseFunctionBody(getProblems());
-
- 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();
-
- getDocEmitter().emitMethodDoc(fn, project);
- write(parseQualifiedName(type));
- if (!node.hasModifier(ASModifier.STATIC))
- {
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(JSEmitterTokens.PROTOTYPE);
- }
-
- write(ASEmitterTokens.MEMBER_ACCESS);
- writeGetSetPrefix(node instanceof IGetterNode);
- writeToken(node.getName());
- writeToken(ASEmitterTokens.EQUAL);
- write(ASEmitterTokens.FUNCTION);
- emitParameters(node.getParametersContainerNode());
- //writeNewline();
- emitMethodScope(node.getScopedNode());
- }
-
- private void writeGetSetPrefix(boolean isGet)
- {
- if (isGet)
- write(ASEmitterTokens.GET);
- else
- write(ASEmitterTokens.SET);
- write("_");
- }
-
- @Override
- public IJSGoogDocEmitter getDocEmitter()
- {
- return new JSVF2JSDocEmitter(this);
- }
-
- @Override
- public void emitPackageHeader(IPackageDefinition definition)
- {
- IASScope containedScope = definition.getContainedScope();
- ITypeDefinition type =
findType(containedScope.getAllLocalDefinitions());
- if (type == null)
- return;
-
- writeNewline("/**");
- writeNewline(" * " + parseQualifiedName(type));
- 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(parseQualifiedName(type));
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(ASEmitterTokens.PAREN_CLOSE);
- writeNewline(ASEmitterTokens.SEMICOLON);
- writeNewline();
- }
-
- @Override
- public void emitPackageHeaderContents(IPackageDefinition definition)
- {
- PackageScope containedScope = (PackageScope) definition
- .getContainedScope();
-
- ITypeDefinition type =
findType(containedScope.getAllLocalDefinitions());
- if (type == null)
- return;
-
- if (project == null)
- project = getWalker().getProject();
-
- FlexJSProject flexProject = (FlexJSProject) project;
- ASProjectScope projectScope = flexProject.getScope();
- ICompilationUnit cu = projectScope
- .getCompilationUnitForDefinition(type);
- ArrayList<String> requiresList = flexProject.getRequires(cu);
- ArrayList<String> interfacesList = flexProject.getInterfaces(cu);
-
- String cname = parseQualifiedName(type);
- ArrayList<String> writtenInstances = new ArrayList<String>();
- writtenInstances.add(cname); // make sure we don't add ourselves
-
- boolean emitsRequires = false;
- if (requiresList != null)
- {
- Collections.sort(requiresList);
- 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;
- }
- }
- }
-
- boolean emitsInterfaces = false;
- if (interfacesList != null)
- {
- Collections.sort(interfacesList);
- 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);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
- write(ASEmitterTokens.SINGLE_QUOTE);
- write(ASEmitterTokens.PAREN_CLOSE);
- writeNewline(ASEmitterTokens.SEMICOLON);
- }
-
- if (emitsRequires || emitsInterfaces || isMainCU)
- {
- writeNewline();
- }
-
- writeNewline();
- writeNewline();
- }
-
- @Override
- public void emitPackageFooter(IPackageDefinition definition)
- {
- IASScope containedScope = definition.getContainedScope();
- ITypeDefinition type =
findType(containedScope.getAllLocalDefinitions());
- if (type == null)
- return;
-
- ITypeNode tnode = findTypeNode(definition.getNode());
- if (tnode != null)
- {
- /*
- * Metadata
- *
- * @type {Object.<string, Array.<Object>>}
- */
- writeNewline();
- writeNewline();
- writeNewline();
- getDocEmitter().begin();
- writeNewline(" * Metadata");
- writeNewline(" *");
- writeNewline(" * @type {Object.<string, Array.<Object>>}");
- getDocEmitter().end();
-
- // a.B.prototype.AFJS_CLASS_INFO = { };
- write(parseQualifiedName(type));
- 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(parseQualifiedName(tnode));
- 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)
- {
- 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(parseQualifiedName(enode.resolve(project)));
- 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++;
-
- 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();
-
- }
-
- /*
- @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();
-
- }
-
- @Override
- public void emitIterationFlow(IIterationFlowNode node)
- {
- // 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)
- {
- write(ASEmitterTokens.SPACE);
- getWalker().walk(lnode);
- }
- }
- */
-
- @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))
- {
- 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('"'))
- {
- 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);
- }
- }
-
- @Override
- public void emitE4XFilter(IMemberAccessExpressionNode node)
- {
- // ToDo (erikdebruin): implement E4X replacement !?!
- write(ASEmitterTokens.SINGLE_QUOTE);
- write("E4XFilter");
- write(ASEmitterTokens.SINGLE_QUOTE);
- }
-
- @Override
- public void emitContainer(IContainerNode node)
- {
- int nodeCount = node.getChildCount();
- for (int i = 0; i < nodeCount; i++)
- {
- getWalker().walk(node.getChild(i));
-
- if (i < nodeCount - 1)
- writeToken(ASEmitterTokens.COMMA);
- }
- }
-
- private String parseQualifiedName(IDefinitionNode def)
- {
- return parseQualifiedNameString(def.getQualifiedName());
- }
-
- private String parseQualifiedName(IDefinition def)
- {
- return parseQualifiedNameString(def.getQualifiedName());
- }
-
- private String parseQualifiedNameString(String qNameString)
- {
- // ToDo (erikdebruin): Ugly hacks for VF2JS ...
- if (qNameString.equals(IASLanguageConstants._int))
- {
- qNameString = qNameString.toUpperCase();
- }
-
- if (qNameString.equals("byte"))
- {
- qNameString = "$" + qNameString;
- }
-
- return qNameString;
- }
-
-}