- Refactored super calls into emitter.
- Refactored binary operators into emitter.
- Refactored identifier into emitter.


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/cca81f42
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/cca81f42
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/cca81f42

Branch: refs/heads/IDEA-FLEX_JS_COMPILER
Commit: cca81f421eb9a3f5df3a748c5ab3ecc0f2d3d517
Parents: 62b62ec
Author: Michael Schmalle <mschma...@apache.org>
Authored: Sat May 30 19:01:13 2015 -0400
Committer: Frédéric THOMAS <webdoubl...@gmail.com>
Committed: Tue Jun 2 13:40:16 2015 +0100

----------------------------------------------------------------------
 .../codegen/js/flexjs/JSFlexJSEmitter.java      | 475 +------------------
 .../codegen/js/jx/BinaryOperatorEmitter.java    | 271 +++++++++++
 .../codegen/js/jx/IdentifierEmitter.java        | 128 +++++
 .../codegen/js/jx/SuperCallEmitter.java         | 245 ++++++++++
 .../internal/codegen/js/utils/EmitterUtils.java | 125 ++++-
 5 files changed, 785 insertions(+), 459 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/cca81f42/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index 4f5a57e..955e033 100644
--- 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@ -21,15 +21,9 @@ package org.apache.flex.compiler.internal.codegen.js.flexjs;
 
 import java.io.FilterWriter;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
 
 import org.apache.flex.compiler.asdoc.flexjs.ASDocComment;
-import org.apache.flex.compiler.clients.MXMLJSC;
-import org.apache.flex.compiler.clients.MXMLJSC.JSOutputType;
 import org.apache.flex.compiler.codegen.IDocEmitter;
 import org.apache.flex.compiler.codegen.js.flexjs.IJSFlexJSEmitter;
 import org.apache.flex.compiler.common.ASModifier;
@@ -38,39 +32,29 @@ import org.apache.flex.compiler.common.ModifiersSet;
 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.JSEmitterTokens;
-import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
 import 
org.apache.flex.compiler.internal.codegen.js.JSSessionModel.PropertyNodes;
 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.jx.BinaryOperatorEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.ClassEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.FieldEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.FunctionCallEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.IdentifierEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.SuperCallEmitter;
 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.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.ClassNode;
-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.GetterNode;
-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.SetterNode;
 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;
@@ -82,7 +66,6 @@ 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.IFunctionObjectNode;
 import org.apache.flex.compiler.tree.as.IGetterNode;
 import org.apache.flex.compiler.tree.as.IIdentifierNode;
 import org.apache.flex.compiler.tree.as.IInterfaceNode;
@@ -114,7 +97,10 @@ public class JSFlexJSEmitter extends JSGoogEmitter 
implements IJSFlexJSEmitter
     private ClassEmitter classEmitter;
     private FieldEmitter fieldEmitter;
     private FunctionCallEmitter functionCallEmitter;
-
+    private SuperCallEmitter superCallEmitter;
+    private BinaryOperatorEmitter binaryOperatorEmitter;
+    private IdentifierEmitter identifierEmitter;
+    
     public ClassEmitter getClassEmiter()
     {
         return classEmitter;
@@ -127,6 +113,9 @@ public class JSFlexJSEmitter extends JSGoogEmitter 
implements IJSFlexJSEmitter
         classEmitter = new ClassEmitter(this);
         fieldEmitter = new FieldEmitter(this);
         functionCallEmitter = new FunctionCallEmitter(this);
+        superCallEmitter = new SuperCallEmitter(this);
+        binaryOperatorEmitter = new BinaryOperatorEmitter(this);
+        identifierEmitter = new IdentifierEmitter(this);
     }
 
     @Override
@@ -244,207 +233,14 @@ public class JSFlexJSEmitter extends JSGoogEmitter 
implements IJSFlexJSEmitter
             super.emitSelfReference(node);
     }
 
-    private boolean writeThis(IIdentifierNode node)
-    {
-        IClassNode classNode = (IClassNode) node
-                .getAncestorOfType(IClassNode.class);
-
-        IDefinition nodeDef = ((IIdentifierNode) node).resolve(project);
-
-        IASNode parentNode = node.getParent();
-        ASTNodeID parentNodeId = parentNode.getNodeID();
-
-        IASNode firstChild = parentNode.getChild(0);
-
-        final 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)
-                {
-                    return node == firstChild;
-                }
-                else
-                {
-                    boolean identifierIsLocalFunction = nodeDef instanceof 
FunctionDefinition
-                            && !(nodeDef instanceof AccessorDefinition)
-                            && ((FunctionDefinition) nodeDef)
-                                    .getFunctionClassification() == 
IFunctionDefinition.FunctionClassification.LOCAL;
-
-                    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 (nodeDef.getQualifiedName().equals(
-                    visiblePropertiesIterator.next().getQualifiedName()))
-                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 = ((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(formatQualifiedName(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))
-            {
-                IFunctionObjectNode functionObjectNode = (IFunctionObjectNode) 
node
-                        .getParent().getAncestorOfType(
-                                IFunctionObjectNode.class);
-
-                if (functionObjectNode != null)
-                    write(JSGoogEmitterTokens.SELF);
-                else
-                    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 (emitName)
-        {
-            if (nodeDef != null)
-                write(formatQualifiedName(nodeDef.getQualifiedName()));
-            else
-                write(node.getName());
-        }
+        // TODO (mschmalle) remove when project field is removed
+      if (project == null)
+          project = getWalker().getProject();
+        
+        identifierEmitter.emit(node);
     }
 
     
//--------------------------------------------------------------------------
@@ -452,250 +248,13 @@ public class JSFlexJSEmitter extends JSGoogEmitter 
implements IJSFlexJSEmitter
     @Override
     public void emitSuperCall(IASNode node, String type)
     {
-        IFunctionNode fnode = (node instanceof IFunctionNode) ? 
(IFunctionNode) node
-                : null;
-        IFunctionCallNode fcnode = (node instanceof IFunctionCallNode) ? 
(FunctionCallNode) node
-                : null;
-
-        final IClassDefinition thisClass = getModel().getCurrentClass();
-
-        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);
-
-            // ToDo (erikdebruin): add VF2JS conditional -> only use check 
during full SDK compilation
-            if (cnode == null && MXMLJSC.jsOutputType == JSOutputType.VF2JS)
-                return;
-
-            if (fnode != null
-                    && (fnode.getNodeID() == ASTNodeID.GetterID || fnode
-                            .getNodeID() == ASTNodeID.SetterID))
-            {
-                write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
-                write(ASEmitterTokens.MEMBER_ACCESS);
-                if (fnode.getNodeID() == ASTNodeID.GetterID)
-                    write(JSFlexJSEmitterTokens.SUPERGETTER);
-                else
-                    write(JSFlexJSEmitterTokens.SUPERSETTER);
-                write(ASEmitterTokens.PAREN_OPEN);
-                if (cnode == null && thisClass != null)
-                    write(formatQualifiedName(thisClass.getQualifiedName()));
-                else
-                    write(formatQualifiedName(cnode.getQualifiedName()));
-                writeToken(ASEmitterTokens.COMMA);
-                write(ASEmitterTokens.THIS);
-                writeToken(ASEmitterTokens.COMMA);
-                write(ASEmitterTokens.SINGLE_QUOTE);
-                write(fnode.getName());
-                write(ASEmitterTokens.SINGLE_QUOTE);
-
-                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 (node instanceof IFunctionNode
-                        && node instanceof BinaryOperatorAssignmentNode)
-                {
-                    BinaryOperatorAssignmentNode bnode = 
(BinaryOperatorAssignmentNode) node;
-
-                    IFunctionNode pnode = (IFunctionNode) bnode
-                            .getAncestorOfType(IFunctionNode.class);
-
-                    if (pnode.getNodeID() == ASTNodeID.SetterID)
-                    {
-                        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);
-                return;
-            }
-        }
-        super.emitSuperCall(node, type);
+        superCallEmitter.emit(node, type);
     }
 
     @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(formatQualifiedName(dnode.getQualifiedName()));
-            else
-                getWalker().walk(node.getRightOperandNode());
-        }
-        else
-        {
-            IExpressionNode leftSide = node.getLeftOperandNode();
-            if (leftSide.getNodeID() == ASTNodeID.MemberAccessExpressionID)
-            {
-                IASNode lnode = leftSide.getChild(0);
-                IASNode rnode = leftSide.getChild(1);
-                IDefinition rnodeDef = ((IIdentifierNode) rnode)
-                        .resolve(getWalker().getProject());
-                if (lnode.getNodeID() == ASTNodeID.SuperID
-                        && rnodeDef instanceof AccessorDefinition)
-                {
-                    String op = node.getOperator().getOperatorText();
-                    boolean isAssignment = op.contains("=")
-                            && !op.contains("==")
-                            && !(op.startsWith("<") || op.startsWith(">") || op
-                                    .startsWith("!"));
-                    if (isAssignment)
-                    {
-                        write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
-                        write(ASEmitterTokens.MEMBER_ACCESS);
-                        write(JSFlexJSEmitterTokens.SUPERSETTER);
-                        write(ASEmitterTokens.PAREN_OPEN);
-                        IClassNode cnode = (IClassNode) node
-                                .getAncestorOfType(IClassNode.class);
-                        write(formatQualifiedName(cnode.getQualifiedName()));
-                        writeToken(ASEmitterTokens.COMMA);
-                        write(ASEmitterTokens.THIS);
-                        writeToken(ASEmitterTokens.COMMA);
-                        write(ASEmitterTokens.SINGLE_QUOTE);
-                        write(rnodeDef.getBaseName());
-                        write(ASEmitterTokens.SINGLE_QUOTE);
-                        writeToken(ASEmitterTokens.COMMA);
-
-                        if (op.length() > 1) // += and things like that
-                        {
-                            write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
-                            write(ASEmitterTokens.MEMBER_ACCESS);
-                            write(JSFlexJSEmitterTokens.SUPERSETTER);
-                            write(ASEmitterTokens.PAREN_OPEN);
-                            
write(formatQualifiedName(cnode.getQualifiedName()));
-                            writeToken(ASEmitterTokens.COMMA);
-                            write(ASEmitterTokens.THIS);
-                            writeToken(ASEmitterTokens.COMMA);
-                            write(ASEmitterTokens.SINGLE_QUOTE);
-                            write(rnodeDef.getBaseName());
-                            write(ASEmitterTokens.SINGLE_QUOTE);
-                            write(ASEmitterTokens.PAREN_CLOSE);
-                            write(op.substring(0, 1));
-                        }
-
-                        getWalker().walk(node.getRightOperandNode());
-                        write(ASEmitterTokens.PAREN_CLOSE);
-                        return;
-                    }
-                }
-            }
-
-            super.emitBinaryOperator(node);
-            /*
-            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("==") && 
-                                                                               
        !(op.startsWith("<") || 
-                                                                               
                        op.startsWith(">") || 
-                                                                               
                        op.startsWith("!"));
-
-            if (def instanceof AccessorDefinition && isAssignment)
-            {
-               // this will make the set_foo call
-                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);
-            }
-            */
-        }
+        binaryOperatorEmitter.emit(node);
     }
 
     public void emitIsAs(IExpressionNode left, IExpressionNode right,

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/cca81f42/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
new file mode 100644
index 0000000..80ea2c5
--- /dev/null
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
@@ -0,0 +1,271 @@
+/*
+ *
+ *  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.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+import 
org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.tree.as.IIdentifierNode;
+import org.apache.flex.compiler.utils.ASNodeUtils;
+
+public class BinaryOperatorEmitter extends JSSubEmitter implements
+        ISubEmitter<IBinaryOperatorNode>
+{
+
+    public BinaryOperatorEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IBinaryOperatorNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        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)
+        {
+            fjs.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(getProject());
+            if (dnode != null)
+                write(fjs.formatQualifiedName(dnode.getQualifiedName()));
+            else
+                getWalker().walk(node.getRightOperandNode());
+        }
+        else
+        {
+            IExpressionNode leftSide = node.getLeftOperandNode();
+            if (leftSide.getNodeID() == ASTNodeID.MemberAccessExpressionID)
+            {
+                IASNode lnode = leftSide.getChild(0);
+                IASNode rnode = leftSide.getChild(1);
+                IDefinition rnodeDef = ((IIdentifierNode) rnode)
+                        .resolve(getWalker().getProject());
+                if (lnode.getNodeID() == ASTNodeID.SuperID
+                        && rnodeDef instanceof AccessorDefinition)
+                {
+                    String op = node.getOperator().getOperatorText();
+                    boolean isAssignment = op.contains("=")
+                            && !op.contains("==")
+                            && !(op.startsWith("<") || op.startsWith(">") || op
+                                    .startsWith("!"));
+                    if (isAssignment)
+                    {
+                        write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+                        write(ASEmitterTokens.MEMBER_ACCESS);
+                        write(JSFlexJSEmitterTokens.SUPERSETTER);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        IClassNode cnode = (IClassNode) node
+                                .getAncestorOfType(IClassNode.class);
+                        
write(fjs.formatQualifiedName(cnode.getQualifiedName()));
+                        writeToken(ASEmitterTokens.COMMA);
+                        write(ASEmitterTokens.THIS);
+                        writeToken(ASEmitterTokens.COMMA);
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        write(rnodeDef.getBaseName());
+                        write(ASEmitterTokens.SINGLE_QUOTE);
+                        writeToken(ASEmitterTokens.COMMA);
+
+                        if (op.length() > 1) // += and things like that
+                        {
+                            write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+                            write(ASEmitterTokens.MEMBER_ACCESS);
+                            write(JSFlexJSEmitterTokens.SUPERSETTER);
+                            write(ASEmitterTokens.PAREN_OPEN);
+                            write(fjs.formatQualifiedName(cnode
+                                    .getQualifiedName()));
+                            writeToken(ASEmitterTokens.COMMA);
+                            write(ASEmitterTokens.THIS);
+                            writeToken(ASEmitterTokens.COMMA);
+                            write(ASEmitterTokens.SINGLE_QUOTE);
+                            write(rnodeDef.getBaseName());
+                            write(ASEmitterTokens.SINGLE_QUOTE);
+                            write(ASEmitterTokens.PAREN_CLOSE);
+                            write(op.substring(0, 1));
+                        }
+
+                        getWalker().walk(node.getRightOperandNode());
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                        return;
+                    }
+                }
+            }
+
+            super_emitBinaryOperator(node);
+            /*
+            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("==") && 
+                                                    !(op.startsWith("<") || 
+                                                            op.startsWith(">") 
|| 
+                                                            
op.startsWith("!"));
+
+            if (def instanceof AccessorDefinition && isAssignment)
+            {
+                // this will make the set_foo call
+                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 super_emitBinaryOperator(IBinaryOperatorNode node)
+    {
+        if (ASNodeUtils.hasParenOpen(node))
+            write(ASEmitterTokens.PAREN_OPEN);
+
+        ASTNodeID id = node.getNodeID();
+
+        if (id == ASTNodeID.Op_IsID)
+        {
+            write(ASEmitterTokens.IS);
+            write(ASEmitterTokens.PAREN_OPEN);
+            getWalker().walk(node.getLeftOperandNode());
+            writeToken(ASEmitterTokens.COMMA);
+            getWalker().walk(node.getRightOperandNode());
+            write(ASEmitterTokens.PAREN_CLOSE);
+        }
+        else if (id == ASTNodeID.Op_AsID)
+        {
+            // (is(a, b) ? a : null)
+            write(ASEmitterTokens.PAREN_OPEN);
+            write(ASEmitterTokens.IS);
+            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.PAREN_CLOSE);
+        }
+        else
+        {
+            getWalker().walk(node.getLeftOperandNode());
+
+            if (id != ASTNodeID.Op_CommaID)
+                write(ASEmitterTokens.SPACE);
+
+            // (erikdebruin) rewrite 'a &&= b' to 'a = a && b'
+            if (id == ASTNodeID.Op_LogicalAndAssignID
+                    || id == ASTNodeID.Op_LogicalOrAssignID)
+            {
+                IIdentifierNode lnode = (IIdentifierNode) node
+                        .getLeftOperandNode();
+
+                writeToken(ASEmitterTokens.EQUAL);
+                writeToken(lnode.getName());
+                write((id == ASTNodeID.Op_LogicalAndAssignID) ? 
ASEmitterTokens.LOGICAL_AND
+                        : ASEmitterTokens.LOGICAL_OR);
+            }
+            else
+            {
+                write(node.getOperator().getOperatorText());
+            }
+
+            write(ASEmitterTokens.SPACE);
+
+            getWalker().walk(node.getRightOperandNode());
+        }
+
+        if (ASNodeUtils.hasParenOpen(node))
+            write(ASEmitterTokens.PAREN_CLOSE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/cca81f42/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
new file mode 100644
index 0000000..3af251d
--- /dev/null
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
@@ -0,0 +1,128 @@
+/*
+ *
+ *  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.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IDefinition;
+import 
org.apache.flex.compiler.definitions.IFunctionDefinition.FunctionClassification;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+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.FunctionDefinition;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
+import org.apache.flex.compiler.tree.as.IIdentifierNode;
+import org.apache.flex.compiler.utils.NativeUtils;
+
+public class IdentifierEmitter extends JSSubEmitter implements
+        ISubEmitter<IIdentifierNode>
+{
+
+    public IdentifierEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IIdentifierNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        IDefinition nodeDef = ((IIdentifierNode) node).resolve(getProject());
+
+        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(fjs.formatQualifiedName(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 (EmitterUtils.writeThis(getProject(), getModel(), node))
+            {
+                IFunctionObjectNode functionObjectNode = (IFunctionObjectNode) 
node
+                        .getParent().getAncestorOfType(
+                                IFunctionObjectNode.class);
+
+                if (functionObjectNode != null)
+                    write(JSGoogEmitterTokens.SELF);
+                else
+                    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 (emitName)
+        {
+            if (nodeDef != null)
+                write(fjs.formatQualifiedName(nodeDef.getQualifiedName()));
+            else
+                write(node.getName());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/cca81f42/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SuperCallEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SuperCallEmitter.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SuperCallEmitter.java
new file mode 100644
index 0000000..90c3bdb
--- /dev/null
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SuperCallEmitter.java
@@ -0,0 +1,245 @@
+/*
+ *
+ *  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.jx;
+
+import org.apache.flex.compiler.clients.MXMLJSC;
+import org.apache.flex.compiler.clients.MXMLJSC.JSOutputType;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+import 
org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+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.tree.as.BinaryOperatorAssignmentNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IFunctionCallNode;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+
+public class SuperCallEmitter extends JSSubEmitter
+{
+
+    public SuperCallEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+        // TODO Auto-generated constructor stub
+    }
+
+    public void emit(IASNode node, String type)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        IFunctionNode fnode = (node instanceof IFunctionNode) ? 
(IFunctionNode) node
+                : null;
+        IFunctionCallNode fcnode = (node instanceof IFunctionCallNode) ? 
(FunctionCallNode) node
+                : null;
+
+        final IClassDefinition thisClass = getModel().getCurrentClass();
+
+        if (type == JSSessionModel.SUPER_FUNCTION_CALL)
+        {
+            if (fnode == null)
+                fnode = (IFunctionNode) fcnode
+                        .getAncestorOfType(IFunctionNode.class);
+
+            if (fnode != null && fnode.isConstructor()
+                    && !EmitterUtils.hasSuperClass(getProject(), fnode))
+                return;
+
+            IClassNode cnode = (IClassNode) node
+                    .getAncestorOfType(IClassNode.class);
+
+            // ToDo (erikdebruin): add VF2JS conditional -> only use check 
during full SDK compilation
+            if (cnode == null && MXMLJSC.jsOutputType == JSOutputType.VF2JS)
+                return;
+
+            if (fnode != null
+                    && (fnode.getNodeID() == ASTNodeID.GetterID || fnode
+                            .getNodeID() == ASTNodeID.SetterID))
+            {
+                write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+                write(ASEmitterTokens.MEMBER_ACCESS);
+                if (fnode.getNodeID() == ASTNodeID.GetterID)
+                    write(JSFlexJSEmitterTokens.SUPERGETTER);
+                else
+                    write(JSFlexJSEmitterTokens.SUPERSETTER);
+                write(ASEmitterTokens.PAREN_OPEN);
+                if (cnode == null && thisClass != null)
+                    
write(fjs.formatQualifiedName(thisClass.getQualifiedName()));
+                else
+                    write(fjs.formatQualifiedName(cnode.getQualifiedName()));
+                writeToken(ASEmitterTokens.COMMA);
+                write(ASEmitterTokens.THIS);
+                writeToken(ASEmitterTokens.COMMA);
+                write(ASEmitterTokens.SINGLE_QUOTE);
+                write(fnode.getName());
+                write(ASEmitterTokens.SINGLE_QUOTE);
+
+                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 (node instanceof IFunctionNode
+                        && node instanceof BinaryOperatorAssignmentNode)
+                {
+                    BinaryOperatorAssignmentNode bnode = 
(BinaryOperatorAssignmentNode) node;
+
+                    IFunctionNode pnode = (IFunctionNode) bnode
+                            .getAncestorOfType(IFunctionNode.class);
+
+                    if (pnode.getNodeID() == ASTNodeID.SetterID)
+                    {
+                        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);
+                return;
+            }
+        }
+        super_emitSuperCall(node, type);
+    }
+
+    protected void super_emitSuperCall(IASNode node, String type)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        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.isConstructor()
+                && !EmitterUtils.hasSuperClass(getProject(), fnode))
+            return;
+
+        IClassNode cnode = (IClassNode) node
+                .getAncestorOfType(IClassNode.class);
+
+        if (cnode == null)
+        {
+            IDefinition cdef = getModel().getCurrentClass();
+            write(fjs.formatQualifiedName(cdef.getQualifiedName()));
+        }
+        else
+            write(fjs.formatQualifiedName(cnode.getQualifiedName()));
+        write(ASEmitterTokens.MEMBER_ACCESS);
+        write(JSGoogEmitterTokens.GOOG_BASE);
+        write(ASEmitterTokens.PAREN_OPEN);
+        write(ASEmitterTokens.THIS);
+
+        if (fnode.isConstructor())
+        {
+            writeToken(ASEmitterTokens.COMMA);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(JSGoogEmitterTokens.GOOG_CONSTRUCTOR);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+        }
+
+        if (fnode != null && !fnode.isConstructor())
+        {
+            writeToken(ASEmitterTokens.COMMA);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(fnode.getName());
+            write(ASEmitterTokens.SINGLE_QUOTE);
+        }
+
+        IASNode[] anodes = null;
+        boolean writeArguments = false;
+        if (fcnode != null)
+        {
+            anodes = fcnode.getArgumentNodes();
+
+            writeArguments = anodes.length > 0;
+        }
+        else if (fnode.isConstructor())
+        {
+            anodes = fnode.getParameterNodes();
+
+            writeArguments = (anodes != null && anodes.length > 0);
+        }
+
+        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);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/cca81f42/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
index 9f6a99d..69acf2d 100644
--- 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
@@ -20,19 +20,35 @@
 package org.apache.flex.compiler.internal.codegen.js.utils;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 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.INamespaceDefinition;
 import org.apache.flex.compiler.definitions.ITypeDefinition;
+import 
org.apache.flex.compiler.definitions.IFunctionDefinition.FunctionClassification;
+import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
+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.ParameterDefinition;
+import org.apache.flex.compiler.internal.definitions.VariableDefinition;
+import org.apache.flex.compiler.internal.projects.CompilerProject;
+import org.apache.flex.compiler.internal.scopes.TypeScope;
+import org.apache.flex.compiler.internal.tree.as.ParameterNode;
 import org.apache.flex.compiler.projects.ICompilerProject;
 import org.apache.flex.compiler.tree.ASTNodeID;
 import org.apache.flex.compiler.tree.as.IASNode;
 import org.apache.flex.compiler.tree.as.IClassNode;
 import org.apache.flex.compiler.tree.as.IDefinitionNode;
 import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IIdentifierNode;
 import org.apache.flex.compiler.tree.as.IScopedNode;
 
 /**
@@ -119,11 +135,118 @@ public class EmitterUtils
         }
         return list;
     }
-    
+
     public static IClassDefinition getClassDefinition(IDefinitionNode node)
     {
         IClassNode tnode = (IClassNode) node
                 .getAncestorOfType(IClassNode.class);
         return (tnode != null) ? tnode.getDefinition() : null;
     }
+
+    public static boolean writeThis(ICompilerProject project,
+            JSSessionModel model, IIdentifierNode node)
+    {
+        IClassNode classNode = (IClassNode) node
+                .getAncestorOfType(IClassNode.class);
+
+        IDefinition nodeDef = ((IIdentifierNode) node).resolve(project);
+
+        IASNode parentNode = node.getParent();
+        ASTNodeID parentNodeId = parentNode.getNodeID();
+
+        IASNode firstChild = parentNode.getChild(0);
+
+        final IClassDefinition thisClass = model.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(project, nodeDef, classNode))
+            {
+                if (identifierIsMemberAccess)
+                {
+                    return node == firstChild;
+                }
+                else
+                {
+                    boolean identifierIsLocalFunction = nodeDef instanceof 
FunctionDefinition
+                            && !(nodeDef instanceof AccessorDefinition)
+                            && ((FunctionDefinition) nodeDef)
+                                    .getFunctionClassification() == 
IFunctionDefinition.FunctionClassification.LOCAL;
+
+                    return !identifierIsLocalFunction;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public static boolean isClassMember(ICompilerProject project,
+            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 (nodeDef.getQualifiedName().equals(
+                    visiblePropertiesIterator.next().getQualifiedName()))
+                return true;
+        }
+
+        return false;
+    }
 }

Reply via email to