flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cd...@apache.org
Subject [46/51] [partial] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - - Check-In of the migrated project to make error analysis easier
Date Wed, 13 Apr 2016 18:56:38 GMT
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
new file mode 100644
index 0000000..875d1d2
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
@@ -0,0 +1,1540 @@
+/*
+ *
+ *  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.as;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.flex.compiler.codegen.IDocEmitter;
+import org.apache.flex.compiler.codegen.IEmitter;
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.IImportTarget;
+import org.apache.flex.compiler.common.ModifiersSet;
+import org.apache.flex.compiler.constants.IASKeywordConstants;
+import org.apache.flex.compiler.definitions.IDefinition;
+import org.apache.flex.compiler.definitions.IFunctionDefinition;
+import org.apache.flex.compiler.definitions.IPackageDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.definitions.IVariableDefinition;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.internal.tree.as.ChainedVariableNode;
+import org.apache.flex.compiler.internal.tree.as.ContainerNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.internal.tree.as.LabeledStatementNode;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+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.ICatchNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IConditionalNode;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+import org.apache.flex.compiler.tree.as.IContainerNode.ContainerType;
+import org.apache.flex.compiler.tree.as.IDefinitionNode;
+import org.apache.flex.compiler.tree.as.IDynamicAccessNode;
+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.IIfNode;
+import org.apache.flex.compiler.tree.as.IImportNode;
+import org.apache.flex.compiler.tree.as.IInterfaceNode;
+import org.apache.flex.compiler.tree.as.IIterationFlowNode;
+import org.apache.flex.compiler.tree.as.IKeywordNode;
+import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
+import org.apache.flex.compiler.tree.as.ILiteralContainerNode;
+import org.apache.flex.compiler.tree.as.ILiteralNode;
+import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
+import org.apache.flex.compiler.tree.as.INamespaceAccessExpressionNode;
+import org.apache.flex.compiler.tree.as.INamespaceNode;
+import org.apache.flex.compiler.tree.as.INumericLiteralNode;
+import org.apache.flex.compiler.tree.as.IObjectLiteralValuePairNode;
+import org.apache.flex.compiler.tree.as.IOperatorNode;
+import org.apache.flex.compiler.tree.as.IPackageNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.IReturnNode;
+import org.apache.flex.compiler.tree.as.IScopedNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+import org.apache.flex.compiler.tree.as.IStatementNode;
+import org.apache.flex.compiler.tree.as.ISwitchNode;
+import org.apache.flex.compiler.tree.as.ITerminalNode;
+import org.apache.flex.compiler.tree.as.ITernaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IThrowNode;
+import org.apache.flex.compiler.tree.as.ITryNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.tree.as.ITypedExpressionNode;
+import org.apache.flex.compiler.tree.as.IUnaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IUseNamespaceNode;
+import org.apache.flex.compiler.tree.as.IVariableExpressionNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.apache.flex.compiler.tree.as.IWhileLoopNode;
+import org.apache.flex.compiler.tree.as.IWithNode;
+import org.apache.flex.compiler.tree.metadata.IMetaTagNode;
+import org.apache.flex.compiler.utils.ASNodeUtils;
+import org.apache.flex.compiler.visitor.IBlockWalker;
+import org.apache.flex.compiler.visitor.as.IASBlockWalker;
+
+/**
+ * The base implementation for an ActionScript emitter.
+ * 
+ * @author Michael Schmalle
+ */
+public class ASEmitter implements IASEmitter, IEmitter
+{
+    private final FilterWriter out;
+
+    private boolean bufferWrite;
+
+    protected boolean isBufferWrite()
+    {
+        return bufferWrite;
+    }
+
+    public void setBufferWrite(boolean value)
+    {
+        bufferWrite = value;
+    }
+
+    private StringBuilder builder;
+
+    protected StringBuilder getBuilder()
+    {
+        return builder;
+    }
+
+    protected void setBuilder(StringBuilder sb)
+    {
+        builder = sb;
+    }
+    
+    protected void flushBuilder()
+    {
+        setBufferWrite(false);
+        write(builder.toString());
+        builder.setLength(0);
+    }
+
+    // (mschmalle) think about how this should be implemented, we can add our
+    // own problems to this, they don't just have to be parse problems
+    public List<ICompilerProblem> getProblems()
+    {
+        return walker.getErrors();
+    }
+
+    private int currentIndent = 0;
+
+    protected int getCurrentIndent()
+    {
+        return currentIndent;
+    }
+
+    protected void writeIndent()
+    {
+        write(ASEmitterTokens.INDENT);
+    }
+
+    private IASBlockWalker walker;
+
+    @Override
+    public IBlockWalker getWalker()
+    {
+        return walker;
+    }
+
+    @Override
+    public void setWalker(IBlockWalker value)
+    {
+        walker = (IASBlockWalker) value;
+    }
+
+    @Override
+    public IDocEmitter getDocEmitter()
+    {
+        return null;
+    }
+
+    @Override
+    public void setDocEmitter(IDocEmitter value)
+    {
+    }
+    
+    private int currentLine = 0;
+
+    protected int getCurrentLine()
+    {
+        return currentLine;
+    }
+
+    private int currentColumn = 0;
+
+    protected int getCurrentColumn()
+    {
+        return currentColumn;
+    }
+
+    public ASEmitter(FilterWriter out)
+    {
+        this.out = out;
+        builder = new StringBuilder();
+    }
+
+    @Override
+    public String postProcess(String output)
+    {
+    	return output;
+    }
+    
+    @Override
+    public void write(IEmitterTokens value)
+    {
+        write(value.getToken());
+    }
+
+    @Override
+    public void write(String value)
+    {
+        try
+        {
+            int newLineCount = value.length() - value.replace("\n", "").length();
+            currentLine += newLineCount;
+            if (newLineCount > 0)
+            {
+                currentColumn = value.length() - value.lastIndexOf("\n") - 1;
+            }
+            else
+            {
+                currentColumn += value.length();
+            }
+            if (!bufferWrite)
+                out.write(value);
+            else
+                builder.append(value);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected String getIndent(int numIndent)
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < numIndent; i++)
+            sb.append(ASEmitterTokens.INDENT.getToken());
+        return sb.toString();
+    }
+
+    @Override
+    public void indentPush()
+    {
+        currentIndent++;
+    }
+
+    @Override
+    public void indentPop()
+    {
+        currentIndent--;
+    }
+
+    @Override
+    public void writeNewline()
+    {
+        write(ASEmitterTokens.NEW_LINE);
+        write(getIndent(currentIndent));
+    }
+
+    @Override
+    public void writeNewline(IEmitterTokens value)
+    {
+        writeNewline(value.getToken());
+    }
+
+    @Override
+    public void writeNewline(String value)
+    {
+        write(value);
+        writeNewline();
+    }
+
+    @Override
+    public void writeNewline(IEmitterTokens value, boolean pushIndent)
+    {
+        writeNewline(value.getToken(), pushIndent);
+    }
+
+    @Override
+    public void writeNewline(String value, boolean pushIndent)
+    {
+        if (pushIndent)
+            indentPush();
+        else
+            indentPop();
+        write(value);
+        writeNewline();
+    }
+
+    public void writeSymbol(String value)
+    {
+        write(value);
+    }
+
+    @Override
+    public void writeToken(IEmitterTokens value)
+    {
+        writeToken(value.getToken());
+    }
+
+    @Override
+    public void writeToken(String value)
+    {
+        write(value);
+        write(ASEmitterTokens.SPACE);
+    }
+
+    //--------------------------------------------------------------------------
+    // IPackageNode
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitImport(IImportNode node)
+    {
+        IImportTarget target = node.getImportTarget();
+        writeToken(ASEmitterTokens.IMPORT);
+        write(target.toString());
+    }
+
+    @Override
+    public void emitPackageHeader(IPackageDefinition definition)
+    {
+        write(ASEmitterTokens.PACKAGE);
+
+        IPackageNode node = definition.getNode();
+        String name = node.getQualifiedName();
+        if (name != null && !name.equals(""))
+        {
+            write(ASEmitterTokens.SPACE);
+            getWalker().walk(node.getNameExpressionNode());
+        }
+
+        write(ASEmitterTokens.SPACE);
+        write(ASEmitterTokens.BLOCK_OPEN);
+    }
+
+    @Override
+    public void emitPackageHeaderContents(IPackageDefinition definition)
+    {
+    }
+
+    @Override
+    public void emitPackageContents(IPackageDefinition definition)
+    {
+        IPackageNode node = definition.getNode();
+        ITypeNode tnode = EmitterUtils.findTypeNode(node);
+        if (tnode != null)
+        {
+            indentPush();
+            writeNewline();
+            getWalker().walk(tnode); // IClassNode | IInterfaceNode
+        }
+    }
+
+    @Override
+    public void emitPackageFooter(IPackageDefinition definition)
+    {
+        indentPop();
+        writeNewline();
+        write(ASEmitterTokens.BLOCK_CLOSE);
+    }
+
+    //--------------------------------------------------------------------------
+    // 
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitClass(IClassNode node)
+    {
+        writeToken(node.getNamespace());
+
+        if (node.hasModifier(ASModifier.FINAL))
+        {
+            writeToken(ASEmitterTokens.FINAL);
+        }
+        else if (node.hasModifier(ASModifier.DYNAMIC))
+        {
+            writeToken(ASEmitterTokens.DYNAMIC);
+        }
+
+        writeToken(ASEmitterTokens.CLASS);
+        getWalker().walk(node.getNameExpressionNode());
+        write(ASEmitterTokens.SPACE);
+
+        IExpressionNode bnode = node.getBaseClassExpressionNode();
+        if (bnode != null)
+        {
+            writeToken(ASEmitterTokens.EXTENDS);
+            getWalker().walk(bnode);
+            write(ASEmitterTokens.SPACE);
+        }
+
+        IExpressionNode[] inodes = node.getImplementedInterfaceNodes();
+        final int ilen = inodes.length;
+        if (ilen != 0)
+        {
+            writeToken(ASEmitterTokens.IMPLEMENTS);
+            for (int i = 0; i < ilen; i++)
+            {
+                getWalker().walk(inodes[i]);
+                if (i < ilen - 1)
+                {
+                    writeToken(ASEmitterTokens.COMMA);
+                }
+            }
+            write(ASEmitterTokens.SPACE);
+        }
+
+        write(ASEmitterTokens.BLOCK_OPEN);
+
+        // fields, methods, namespaces
+        final IDefinitionNode[] members = node.getAllMemberNodes();
+        if (members.length > 0)
+        {
+            indentPush();
+            writeNewline();
+
+            final int len = members.length;
+            int i = 0;
+            for (IDefinitionNode mnode : members)
+            {
+                getWalker().walk(mnode);
+                if (mnode.getNodeID() == ASTNodeID.VariableID)
+                {
+                    write(ASEmitterTokens.SEMICOLON);
+                    if (i < len - 1)
+                        writeNewline();
+                }
+                else if (mnode.getNodeID() == ASTNodeID.FunctionID)
+                {
+                    if (i < len - 1)
+                        writeNewline();
+                }
+                else if (mnode.getNodeID() == ASTNodeID.GetterID
+                        || mnode.getNodeID() == ASTNodeID.SetterID)
+                {
+                    if (i < len - 1)
+                        writeNewline();
+                }
+                i++;
+            }
+
+            indentPop();
+        }
+
+        writeNewline();
+        write(ASEmitterTokens.BLOCK_CLOSE);
+    }
+
+    @Override
+    public void emitInterface(IInterfaceNode node)
+    {
+        writeToken(node.getNamespace());
+
+        writeToken(ASEmitterTokens.INTERFACE);
+        getWalker().walk(node.getNameExpressionNode());
+        write(ASEmitterTokens.SPACE);
+
+        IExpressionNode[] inodes = node.getExtendedInterfaceNodes();
+        final int ilen = inodes.length;
+        if (ilen != 0)
+        {
+            writeToken(ASEmitterTokens.EXTENDS);
+            for (int i = 0; i < ilen; i++)
+            {
+                getWalker().walk(inodes[i]);
+                if (i < ilen - 1)
+                {
+                    writeToken(ASEmitterTokens.COMMA);
+                }
+            }
+            write(ASEmitterTokens.SPACE);
+        }
+
+        write(ASEmitterTokens.BLOCK_OPEN);
+
+        final IDefinitionNode[] members = node.getAllMemberDefinitionNodes();
+        if (members.length > 0)
+        {
+            indentPush();
+            writeNewline();
+
+            final int len = members.length;
+            int i = 0;
+            for (IDefinitionNode mnode : members)
+            {
+                getWalker().walk(mnode);
+                write(ASEmitterTokens.SEMICOLON);
+                if (i < len - 1)
+                    writeNewline();
+                i++;
+            }
+
+            indentPop();
+        }
+
+        writeNewline();
+        write(ASEmitterTokens.BLOCK_CLOSE);
+    }
+
+    //--------------------------------------------------------------------------
+    // 
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitVarDeclaration(IVariableNode node)
+    {
+        if (!(node instanceof ChainedVariableNode))
+        {
+            emitMemberKeyword(node);
+        }
+
+        emitDeclarationName(node);
+        emitType(node.getVariableTypeNode());
+        
+        IExpressionNode avnode = node.getAssignedValueNode();
+        if (avnode != null)
+        {
+            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);
+                }
+            }
+        }
+
+        // the client such as IASBlockWalker is responsible for the 
+        // semi-colon and newline handling
+    }
+
+    //--------------------------------------------------------------------------
+    // 
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitFieldDocumentation(IVariableNode node)
+    {
+    }
+
+    @Override
+    public void emitField(IVariableNode node)
+    {
+        emitFieldDocumentation(node);
+
+        IVariableDefinition definition = (IVariableDefinition) node
+                .getDefinition();
+
+        if (!(node instanceof ChainedVariableNode))
+        {
+            emitNamespaceIdentifier(node);
+            emitModifiers(definition);
+            emitMemberKeyword(node);
+        }
+
+        emitMemberName(node);
+        emitType(node.getVariableTypeNode());
+
+        IExpressionNode avnode = node.getAssignedValueNode();
+        if (avnode != null)
+        {
+            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);
+                    emitField((IVariableNode) child);
+                }
+            }
+        }
+
+        // the client such as IASBlockWalker is responsible for the 
+        // semi-colon and newline handling
+    }
+
+    //--------------------------------------------------------------------------
+    // 
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitMethodDocumentation(IFunctionNode node)
+    {
+    }
+
+    @Override
+    public void emitMethod(IFunctionNode node)
+    {
+        // see below, this is temp, I don't want a bunch of duplicated code
+        // at them moment, subclasses can refine anyways, we are generalizing
+        if (node instanceof IGetterNode)
+        {
+            emitGetAccessorDocumentation((IGetterNode) node);
+        }
+        else if (node instanceof ISetterNode)
+        {
+            emitSetAccessorDocumentation((ISetterNode) node);
+        }
+        else
+        {
+            emitMethodDocumentation(node);
+        }
+
+        FunctionNode fn = (FunctionNode) node;
+        fn.parseFunctionBody(getProblems());
+
+        IFunctionDefinition definition = node.getDefinition();
+
+        emitNamespaceIdentifier(node);
+        emitModifiers(definition);
+        emitMemberKeyword(node);
+
+        // I'm cheating right here, I haven't "seen" the light
+        // on how to properly and efficiently deal with accessors since they are SO alike
+        // I don't want to lump them in with methods because implementations in the
+        // future need to know the difference without loopholes
+        if (node instanceof IAccessorNode)
+        {
+            emitAccessorKeyword(((IAccessorNode) node).getAccessorKeywordNode());
+        }
+
+        emitMemberName(node);
+        emitParameters(node.getParametersContainerNode());
+        emitType(node.getReturnTypeNode());
+        if (node.getParent().getParent().getNodeID() == ASTNodeID.ClassID)
+        {
+            emitMethodScope(node.getScopedNode());
+        }
+
+        // the client such as IASBlockWalker is responsible for the 
+        // semi-colon and newline handling
+    }
+
+    @Override
+    public void emitGetAccessorDocumentation(IGetterNode node)
+    {
+    }
+
+    @Override
+    public void emitGetAccessor(IGetterNode node)
+    {
+        // just cheat for now, IGetterNode is a IFunctionNode
+        emitMethod(node);
+    }
+
+    @Override
+    public void emitSetAccessorDocumentation(ISetterNode node)
+    {
+    }
+
+    @Override
+    public void emitSetAccessor(ISetterNode node)
+    {
+        // just cheat for now, ISetterNode is a IFunctionNode
+        emitMethod(node);
+    }
+
+    @Override
+    public void emitLocalNamedFunction(IFunctionNode node)
+    {
+        FunctionNode fnode = (FunctionNode) node;
+        write(ASEmitterTokens.FUNCTION);
+        write(ASEmitterTokens.SPACE);
+        write(fnode.getName());
+        emitParameters(fnode.getParametersContainerNode());
+        emitType(fnode.getTypeNode());
+        emitFunctionScope(fnode.getScopedNode());
+    }
+
+    @Override
+    public void emitFunctionObject(IFunctionObjectNode node)
+    {
+        FunctionNode fnode = node.getFunctionNode();
+        write(ASEmitterTokens.FUNCTION);
+        emitParameters(fnode.getParametersContainerNode());
+        emitType(fnode.getTypeNode());
+        emitFunctionScope(fnode.getScopedNode());
+    }
+
+    //--------------------------------------------------------------------------
+    // 
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitNamespace(INamespaceNode node)
+    {
+        emitNamespaceIdentifier(node);
+        writeToken(ASEmitterTokens.NAMESPACE);
+        emitMemberName(node);
+        write(ASEmitterTokens.SPACE);
+        writeToken(ASEmitterTokens.EQUAL);
+        getWalker().walk(node.getNamespaceURINode());
+    }
+
+    //--------------------------------------------------------------------------
+    // 
+    //--------------------------------------------------------------------------
+
+    protected void emitNamespaceIdentifier(IDefinitionNode node)
+    {
+        String namespace = node.getNamespace();
+        if (namespace != null
+                && !namespace.equals(IASKeywordConstants.INTERNAL))
+        {
+            writeToken(namespace);
+        }
+    }
+
+    protected void emitModifiers(IDefinition definition)
+    {
+        ModifiersSet modifierSet = definition.getModifiers();
+        if (modifierSet.hasModifiers())
+        {
+            for (ASModifier modifier : modifierSet.getAllModifiers())
+            {
+                writeToken(modifier.toString());
+            }
+        }
+    }
+
+    public void emitMemberKeyword(IDefinitionNode node)
+    {
+        if (node instanceof IFunctionNode)
+        {
+            writeToken(ASEmitterTokens.FUNCTION);
+        }
+        else if (node instanceof IVariableNode)
+        {
+            writeToken(((IVariableNode) node).isConst() ? ASEmitterTokens.CONST
+                    : ASEmitterTokens.VAR);
+        }
+    }
+
+    protected void emitMemberName(IDefinitionNode node)
+    {
+        getWalker().walk(node.getNameExpressionNode());
+    }
+
+    public void emitDeclarationName(IDefinitionNode node)
+    {
+        getWalker().walk(node.getNameExpressionNode());
+    }
+
+    public void emitParameters(IContainerNode node)
+    {
+        write(ASEmitterTokens.PAREN_OPEN);
+        int len = node.getChildCount();
+        for (int i = 0; i < len; i++)
+        {
+            IParameterNode parameterNode = (IParameterNode) node.getChild(i);
+            getWalker().walk(parameterNode); //emitParameter
+            if (i < len - 1)
+            {
+                writeToken(ASEmitterTokens.COMMA);
+            }
+        }
+        write(ASEmitterTokens.PAREN_CLOSE);
+    }
+
+    @Override
+    public void emitParameter(IParameterNode node)
+    {
+        if (node.isRest())
+        {
+            write(ASEmitterTokens.ELLIPSIS);
+            write(node.getName());
+        }
+        else
+        {
+            getWalker().walk(node.getNameExpressionNode());
+            write(ASEmitterTokens.COLON);
+            getWalker().walk(node.getVariableTypeNode());
+            IExpressionNode anode = node.getAssignedValueNode();
+            if (anode != null)
+            {
+                write(ASEmitterTokens.SPACE);
+                writeToken(ASEmitterTokens.EQUAL);
+                getWalker().walk(anode);
+            }
+        }
+    }
+
+    protected void emitType(IExpressionNode node)
+    {
+        // TODO (mschmalle) node.getVariableTypeNode() will return "*" if undefined, what to use?
+        // or node.getReturnTypeNode()
+        if (node != null)
+        {
+            write(ASEmitterTokens.COLON);
+            getWalker().walk(node);
+        }
+    }
+
+    protected void emitAssignedValue(IExpressionNode node)
+    {
+        if (node == null)
+        {
+            return;
+        }
+        getWalker().walk(node);
+    }
+
+    @Override
+    public void emitFunctionBlockHeader(IFunctionNode node)
+    {
+        // nothing to do in AS
+    }
+
+    public void emitMethodScope(IScopedNode node)
+    {
+        write(ASEmitterTokens.SPACE);
+        getWalker().walk(node);
+    }
+
+    protected void emitAccessorKeyword(IKeywordNode node)
+    {
+        getWalker().walk(node);
+        write(ASEmitterTokens.SPACE);
+    }
+
+    protected void emitFunctionScope(IScopedNode node)
+    {
+        emitMethodScope(node);
+    }
+
+    //--------------------------------------------------------------------------
+    // Statements
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitStatement(IASNode node)
+    {
+        getWalker().walk(node);
+        // XXX (mschmalle) this should be in the after handler?
+        if (node.getParent().getNodeID() != ASTNodeID.LabledStatementID
+        		&& node.getNodeID() != ASTNodeID.ConfigBlockID
+                && !(node instanceof IStatementNode))
+        {
+            write(ASEmitterTokens.SEMICOLON);
+        }
+
+        if (!isLastStatement(node))
+            writeNewline();
+    }
+
+    @Override
+    public void emitIf(IIfNode node)
+    {
+        IConditionalNode conditional = (IConditionalNode) node.getChild(0);
+
+        IContainerNode xnode = (IContainerNode) conditional
+                .getStatementContentsNode();
+
+        writeToken(ASEmitterTokens.IF);
+        //write(SPACE);
+        write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(conditional.getChild(0)); // conditional expression
+        write(ASEmitterTokens.PAREN_CLOSE);
+        if (!isImplicit(xnode))
+            write(ASEmitterTokens.SPACE);
+
+        getWalker().walk(conditional.getChild(1)); // BlockNode
+        IConditionalNode[] nodes = node.getElseIfNodes();
+        if (nodes.length > 0)
+        {
+            for (int i = 0; i < nodes.length; i++)
+            {
+                IConditionalNode enode = nodes[i];
+                IContainerNode snode = (IContainerNode) enode
+                        .getStatementContentsNode();
+
+                final boolean isImplicit = isImplicit(snode);
+                if (isImplicit)
+                    writeNewline();
+                else
+                    write(ASEmitterTokens.SPACE);
+
+                writeToken(ASEmitterTokens.ELSE);
+                writeToken(ASEmitterTokens.IF);
+                write(ASEmitterTokens.PAREN_OPEN);
+                getWalker().walk(enode.getChild(0));
+                write(ASEmitterTokens.PAREN_CLOSE);
+                if (!isImplicit)
+                    write(ASEmitterTokens.SPACE);
+
+                getWalker().walk(enode.getChild(1)); // ConditionalNode
+            }
+        }
+
+        ITerminalNode elseNode = node.getElseNode();
+        if (elseNode != null)
+        {
+            IContainerNode cnode = (IContainerNode) elseNode.getChild(0);
+            // if an implicit if, add a newline with no space
+            final boolean isImplicit = isImplicit(cnode);
+            if (isImplicit)
+                writeNewline();
+            else
+                write(ASEmitterTokens.SPACE);
+            write(ASEmitterTokens.ELSE);
+            if (!isImplicit)
+                write(ASEmitterTokens.SPACE);
+
+            getWalker().walk(elseNode); // TerminalNode
+        }
+    }
+
+    @Override
+    public void emitForEachLoop(IForLoopNode node)
+    {
+        IContainerNode xnode = (IContainerNode) node.getChild(1);
+        writeToken(ASEmitterTokens.FOR);
+        writeToken(ASEmitterTokens.EACH);
+        write(ASEmitterTokens.PAREN_OPEN);
+
+        IContainerNode cnode = node.getConditionalsContainerNode();
+        getWalker().walk(cnode.getChild(0));
+
+        write(ASEmitterTokens.PAREN_CLOSE);
+        if (!isImplicit(xnode))
+            write(ASEmitterTokens.SPACE);
+
+        getWalker().walk(node.getStatementContentsNode());
+    }
+
+    @Override
+    public void emitForLoop(IForLoopNode node)
+    {
+        IContainerNode xnode = (IContainerNode) node.getChild(1);
+
+        writeToken(ASEmitterTokens.FOR);
+        write(ASEmitterTokens.PAREN_OPEN);
+
+        IContainerNode cnode = node.getConditionalsContainerNode();
+        final IASNode node0 = cnode.getChild(0);
+        if (node0.getNodeID() == ASTNodeID.Op_InID)
+        {
+            getWalker().walk(cnode.getChild(0));
+        }
+        else
+        {
+            visitForBody(cnode);
+        }
+
+        write(ASEmitterTokens.PAREN_CLOSE);
+        if (!isImplicit(xnode))
+            write(ASEmitterTokens.SPACE);
+
+        getWalker().walk(node.getStatementContentsNode());
+    }
+
+    @Override
+    public void emitSwitch(ISwitchNode node)
+    {
+        writeToken(ASEmitterTokens.SWITCH);
+        write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(node.getChild(0));
+        writeToken(ASEmitterTokens.PAREN_CLOSE);
+        writeNewline(ASEmitterTokens.BLOCK_OPEN, true);
+
+        IConditionalNode[] cnodes = ASNodeUtils.getCaseNodes(node);
+        ITerminalNode dnode = ASNodeUtils.getDefaultNode(node);
+
+        for (int i = 0; i < cnodes.length; i++)
+        {
+            IConditionalNode casen = cnodes[i];
+            IContainerNode cnode = (IContainerNode) casen.getChild(1);
+            writeToken(ASEmitterTokens.CASE);
+            getWalker().walk(casen.getConditionalExpressionNode());
+            write(ASEmitterTokens.COLON);
+            if (!isImplicit(cnode))
+                write(ASEmitterTokens.SPACE);
+            getWalker().walk(casen.getStatementContentsNode());
+            if (i == cnodes.length - 1 && dnode == null)
+            {
+                indentPop();
+                writeNewline();
+            }
+            else
+                writeNewline();
+        }
+        if (dnode != null)
+        {
+            IContainerNode cnode = (IContainerNode) dnode.getChild(0);
+            write(ASEmitterTokens.DEFAULT);
+            write(ASEmitterTokens.COLON);
+            if (!isImplicit(cnode))
+                write(ASEmitterTokens.SPACE);
+            getWalker().walk(dnode);
+            indentPop();
+            writeNewline();
+        }
+        write(ASEmitterTokens.BLOCK_CLOSE);
+    }
+
+    @Override
+    public void emitWhileLoop(IWhileLoopNode node)
+    {
+        IContainerNode cnode = (IContainerNode) node.getChild(1);
+        writeToken(ASEmitterTokens.WHILE);
+        write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(node.getConditionalExpressionNode());
+        write(ASEmitterTokens.PAREN_CLOSE);
+        if (!isImplicit(cnode))
+            write(ASEmitterTokens.SPACE);
+        getWalker().walk(node.getStatementContentsNode());
+    }
+
+    @Override
+    public void emitDoLoop(IWhileLoopNode node)
+    {
+        IContainerNode cnode = (IContainerNode) node.getChild(0);
+        write(ASEmitterTokens.DO);
+        if (!isImplicit(cnode))
+            write(ASEmitterTokens.SPACE);
+        getWalker().walk(node.getStatementContentsNode());
+        if (!isImplicit(cnode))
+            write(ASEmitterTokens.SPACE);
+        else
+            writeNewline(); // TODO (mschmalle) there is something wrong here, block should NL
+        write(ASEmitterTokens.WHILE);
+        write(ASEmitterTokens.SPACE);
+        write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(node.getConditionalExpressionNode());
+        write(ASEmitterTokens.PAREN_CLOSE);
+        write(ASEmitterTokens.SEMICOLON);
+    }
+
+    @Override
+    public void emitWith(IWithNode node)
+    {
+        IContainerNode cnode = (IContainerNode) node.getChild(1);
+        writeToken(ASEmitterTokens.WITH);
+        write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(node.getTargetNode());
+        write(ASEmitterTokens.PAREN_CLOSE);
+        if (!isImplicit(cnode))
+            write(ASEmitterTokens.SPACE);
+        getWalker().walk(node.getStatementContentsNode());
+    }
+
+    @Override
+    public void emitThrow(IThrowNode node)
+    {
+        writeToken(ASEmitterTokens.THROW);
+        getWalker().walk(node.getThrownExpressionNode());
+    }
+
+    @Override
+    public void emitTry(ITryNode node)
+    {
+        writeToken(ASEmitterTokens.TRY);
+        getWalker().walk(node.getStatementContentsNode());
+        for (int i = 0; i < node.getCatchNodeCount(); i++)
+        {
+            getWalker().walk(node.getCatchNode(i));
+        }
+        ITerminalNode fnode = node.getFinallyNode();
+        if (fnode != null)
+        {
+            write(ASEmitterTokens.SPACE);
+            writeToken(ASEmitterTokens.FINALLY);
+            getWalker().walk(fnode);
+        }
+    }
+
+    @Override
+    public void emitCatch(ICatchNode node)
+    {
+        write(ASEmitterTokens.SPACE);
+        writeToken(ASEmitterTokens.CATCH);
+        write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(node.getCatchParameterNode());
+        writeToken(ASEmitterTokens.PAREN_CLOSE);
+        getWalker().walk(node.getStatementContentsNode());
+    }
+
+    @Override
+    public void emitReturn(IReturnNode node)
+    {
+        write(ASEmitterTokens.RETURN);
+        IExpressionNode rnode = node.getReturnValueNode();
+        if (rnode != null && rnode.getNodeID() != ASTNodeID.NilID)
+        {
+            write(ASEmitterTokens.SPACE);
+            getWalker().walk(rnode);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Expressions
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitFunctionCall(IFunctionCallNode node)
+    {
+        if (node.isNewExpression())
+        {
+            writeToken(ASEmitterTokens.NEW);
+        }
+
+        getWalker().walk(node.getNameNode());
+        
+        emitArguments(node.getArgumentsNode());
+    }
+
+    @Override
+    public void emitArguments(IContainerNode node)
+    {
+        write(ASEmitterTokens.PAREN_OPEN);
+        int len = node.getChildCount();
+        for (int i = 0; i < len; i++)
+        {
+            IExpressionNode argumentNode = (IExpressionNode) node.getChild(i);
+            getWalker().walk(argumentNode);
+            if (i < len - 1)
+            {
+                writeToken(ASEmitterTokens.COMMA);
+            }
+        }
+        write(ASEmitterTokens.PAREN_CLOSE);
+    }
+
+    //--------------------------------------------------------------------------
+    // Operators
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitAsOperator(IBinaryOperatorNode node)
+    {
+        getWalker().walk(node.getLeftOperandNode());
+        write(ASEmitterTokens.SPACE);
+        writeToken(node.getOperator().getOperatorText());
+        getWalker().walk(node.getRightOperandNode());
+    }
+
+    @Override
+    public void emitIsOperator(IBinaryOperatorNode node)
+    {
+        getWalker().walk(node.getLeftOperandNode());
+        write(ASEmitterTokens.SPACE);
+        writeToken(node.getOperator().getOperatorText());
+        getWalker().walk(node.getRightOperandNode());
+    }
+
+    @Override
+    public void emitBinaryOperator(IBinaryOperatorNode node)
+    {
+        if (ASNodeUtils.hasParenOpen(node))
+            write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(node.getLeftOperandNode());
+        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);
+    }
+
+    //--------------------------------------------------------------------------
+    // Utility
+    //--------------------------------------------------------------------------
+
+    protected ITypeNode findTypeNode(IPackageNode node)
+    {
+        IScopedNode scope = node.getScopedNode();
+        for (int i = 0; i < scope.getChildCount(); i++)
+        {
+            IASNode child = scope.getChild(i);
+            if (child instanceof ITypeNode)
+                return (ITypeNode) child;
+        }
+        return null;
+    }
+
+    protected ITypeDefinition findType(Collection<IDefinition> definitions)
+    {
+        for (IDefinition definition : definitions)
+        {
+            if (definition instanceof ITypeDefinition)
+                return (ITypeDefinition) definition;
+        }
+        return null;
+    }
+
+    //--------------------------------------------------------------------------
+    // Static Utility
+    //--------------------------------------------------------------------------
+
+    protected static IFunctionNode getConstructor(IDefinitionNode[] members)
+    {
+        for (IDefinitionNode node : members)
+        {
+            if (node instanceof IFunctionNode)
+            {
+                IFunctionNode fnode = (IFunctionNode) node;
+                if (fnode.isConstructor())
+                    return fnode;
+            }
+        }
+        return null;
+    }
+
+    protected static boolean isLastStatement(IASNode node)
+    {
+        return getChildIndex(node.getParent(), node) == node.getParent()
+                .getChildCount() - 1;
+    }
+
+    // this is not fair that we have to do this if (i < len - 1)
+    private static int getChildIndex(IASNode parent, IASNode node)
+    {
+        final int len = parent.getChildCount();
+        for (int i = 0; i < len; i++)
+        {
+            if (parent.getChild(i) == node)
+                return i;
+        }
+        return -1;
+    }
+
+    protected static final boolean isImplicit(IContainerNode node)
+    {
+        return EmitterUtils.isImplicit(node);
+    }
+
+    protected void visitForBody(IContainerNode node)
+    {
+        final IASNode node0 = node.getChild(0);
+        final IASNode node1 = node.getChild(1);
+        final IASNode node2 = node.getChild(2);
+
+        // initializer
+        if (node0 != null)
+        {
+            getWalker().walk(node0);
+            write(ASEmitterTokens.SEMICOLON);
+            if (node1.getNodeID() != ASTNodeID.NilID)
+                write(ASEmitterTokens.SPACE);
+        }
+        // condition or target
+        if (node1 != null)
+        {
+            getWalker().walk(node1);
+            write(ASEmitterTokens.SEMICOLON);
+            if (node2.getNodeID() != ASTNodeID.NilID)
+                write(ASEmitterTokens.SPACE);
+        }
+        // iterator
+        if (node2 != null)
+        {
+            getWalker().walk(node2);
+        }
+    }
+
+    @Override
+    public void emitLiteral(ILiteralNode node)
+    {
+        write(node.getValue(true));
+    }
+
+    @Override
+    public void emitLiteralContainer(ILiteralContainerNode node)
+    {
+        final ContainerNode cnode = node.getContentsNode();
+        final ContainerType type = cnode.getContainerType();
+        String postFix = "";
+
+        if (type == ContainerType.BRACES)
+        {
+            write(ASEmitterTokens.BLOCK_OPEN);
+            postFix = ASEmitterTokens.BLOCK_CLOSE.getToken();
+        }
+        else if (type == ContainerType.BRACKETS)
+        {
+            write(ASEmitterTokens.SQUARE_OPEN);
+            postFix = ASEmitterTokens.SQUARE_CLOSE.getToken();
+        }
+        else if (type == ContainerType.IMPLICIT)
+        {
+            // nothing to write, move along
+        }
+        else if (type == ContainerType.PARENTHESIS)
+        {
+            write(ASEmitterTokens.PAREN_OPEN);
+            postFix = ASEmitterTokens.PAREN_CLOSE.getToken();
+        }
+
+        final int len = cnode.getChildCount();
+        for (int i = 0; i < len; i++)
+        {
+            IASNode child = cnode.getChild(i);
+            getWalker().walk(child);
+            if (i < len - 1)
+                writeToken(ASEmitterTokens.COMMA);
+        }
+
+        if (postFix != "")
+            write(postFix);
+    }
+
+    @Override
+    public void emitIdentifier(IIdentifierNode node)
+    {
+        write(node.getName());
+    }
+
+    @Override
+    public void emitNumericLiteral(INumericLiteralNode node)
+    {
+        write(node.getNumericValue().toString());
+    }
+
+    @Override
+    public void emitKeyword(IKeywordNode node)
+    {
+        write(node.getNodeID().getParaphrase());
+    }
+
+    @Override
+    public void emitIterationFlow(IIterationFlowNode node)
+    {
+        write(node.getKind().toString().toLowerCase());
+        IIdentifierNode lnode = node.getLabelNode();
+        if (lnode != null)
+        {
+            write(ASEmitterTokens.SPACE);
+            getWalker().walk(lnode);
+        }
+    }
+
+    @Override
+    public void emitMemberAccessExpression(IMemberAccessExpressionNode node)
+    {
+        getWalker().walk(node.getLeftOperandNode());
+        write(node.getOperator().getOperatorText());
+        getWalker().walk(node.getRightOperandNode());
+    }
+
+    @Override
+    public void emitDynamicAccess(IDynamicAccessNode node)
+    {
+        getWalker().walk(node.getLeftOperandNode());
+        write(ASEmitterTokens.SQUARE_OPEN);
+        getWalker().walk(node.getRightOperandNode());
+        write(ASEmitterTokens.SQUARE_CLOSE);
+    }
+
+    @Override
+    public void emitTypedExpression(ITypedExpressionNode node)
+    {
+        getWalker().walk(node.getCollectionNode());
+        write(ASEmitterTokens.MEMBER_ACCESS);
+        write(ASEmitterTokens.LESS_THAN);
+        getWalker().walk(node.getTypeNode());
+        write(ASEmitterTokens.GREATER_THAN);
+    }
+
+    @Override
+    public void emitVariableExpression(IVariableExpressionNode node)
+    {
+        getWalker().walk(node.getTargetVariable());
+    }
+
+    @Override
+    public void emitTernaryOperator(ITernaryOperatorNode node)
+    {
+    	if (ASNodeUtils.hasParenOpen((IOperatorNode) node))
+    		write(ASEmitterTokens.PAREN_OPEN);
+        getWalker().walk(node.getConditionalNode());
+        write(ASEmitterTokens.SPACE);
+        writeToken(ASEmitterTokens.TERNARY);
+        getWalker().walk(node.getLeftOperandNode());
+        write(ASEmitterTokens.SPACE);
+        writeToken(ASEmitterTokens.COLON);
+        getWalker().walk(node.getRightOperandNode());
+        if (ASNodeUtils.hasParenClose((IOperatorNode) node))
+            write(ASEmitterTokens.PAREN_CLOSE);
+    }
+
+    @Override
+    public void emitObjectLiteralValuePair(IObjectLiteralValuePairNode node)
+    {
+        getWalker().walk(node.getNameNode());
+        write(ASEmitterTokens.COLON);
+        getWalker().walk(node.getValueNode());
+    }
+
+    @Override
+    public void emitLabelStatement(LabeledStatementNode node)
+    {
+        writeToken(node.getLabel());
+        writeToken(ASEmitterTokens.COLON);
+        getWalker().walk(node.getLabeledStatement());
+    }
+
+    @Override
+    public void emitNamespaceAccessExpression(
+            INamespaceAccessExpressionNode node)
+    {
+        getWalker().walk(node.getLeftOperandNode());
+        write(node.getOperator().getOperatorText());
+        getWalker().walk(node.getRightOperandNode());
+    }
+
+    @Override
+    public void emitUnaryOperator(IUnaryOperatorNode node)
+    {
+        if (ASNodeUtils.hasParenOpen(node))
+            write(ASEmitterTokens.PAREN_OPEN);
+
+        if (node.getNodeID() == ASTNodeID.Op_PreIncrID
+                || node.getNodeID() == ASTNodeID.Op_PreDecrID
+                || node.getNodeID() == ASTNodeID.Op_BitwiseNotID
+                || node.getNodeID() == ASTNodeID.Op_LogicalNotID
+                || node.getNodeID() == ASTNodeID.Op_SubtractID
+                || node.getNodeID() == ASTNodeID.Op_AddID)
+        {
+            write(node.getOperator().getOperatorText());
+            IExpressionNode opNode = node.getOperandNode();
+            getWalker().walk(opNode);
+        }
+
+        else if (node.getNodeID() == ASTNodeID.Op_PostIncrID
+                || node.getNodeID() == ASTNodeID.Op_PostDecrID)
+        {
+            getWalker().walk(node.getOperandNode());
+            write(node.getOperator().getOperatorText());
+        }
+        else if (node.getNodeID() == ASTNodeID.Op_DeleteID
+                || node.getNodeID() == ASTNodeID.Op_VoidID)
+        {
+            writeToken(node.getOperator().getOperatorText());
+            getWalker().walk(node.getOperandNode());
+        }
+        else if (node.getNodeID() == ASTNodeID.Op_TypeOfID)
+        {
+            write(node.getOperator().getOperatorText());
+            write(ASEmitterTokens.PAREN_OPEN);
+            getWalker().walk(node.getOperandNode());
+            write(ASEmitterTokens.PAREN_CLOSE);
+        }
+
+        if (ASNodeUtils.hasParenClose(node))
+            write(ASEmitterTokens.PAREN_CLOSE);
+    }
+
+    @Override
+    public void emitLanguageIdentifier(ILanguageIdentifierNode node)
+    {
+        if (node.getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.ANY_TYPE)
+        {
+            write(ASEmitterTokens.ANY_TYPE);
+        }
+        else if (node.getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.REST)
+        {
+            write(ASEmitterTokens.ELLIPSIS);
+        }
+        else if (node.getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.SUPER)
+        {
+            write(ASEmitterTokens.SUPER);
+        }
+        else if (node.getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.THIS)
+        {
+            write(ASEmitterTokens.THIS);
+        }
+        else if (node.getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.VOID)
+        {
+            write(ASEmitterTokens.VOID);
+        }
+    }
+
+    @Override
+    public void emitMetaTag(IMetaTagNode node)
+    {
+    }
+
+    @Override
+    public void emitContainer(IContainerNode node)
+    {
+    }
+
+    @Override
+    public void emitE4XFilter(IMemberAccessExpressionNode node)
+    {
+        // ToDo (erikdebruin)
+    }
+
+    @Override
+    public void emitUseNamespace(IUseNamespaceNode node)
+    {
+        // ToDo (erikdebruin)
+    }
+
+    @Override
+    public String stringifyNode(IASNode node)
+    {
+        boolean oldBufferWrite = isBufferWrite();
+        StringBuilder oldBuilder = this.builder;
+        this.builder = new StringBuilder();
+        setBufferWrite(true);
+        getWalker().walk(node);
+        String result = getBuilder().toString();
+        getBuilder().setLength(0);
+        this.builder = oldBuilder;
+        setBufferWrite(oldBufferWrite);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitterTokens.java
new file mode 100644
index 0000000..9296a78
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitterTokens.java
@@ -0,0 +1,203 @@
+/*
+ *
+ *  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.as;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+/**
+ * @author Michael Schmalle
+ * @author Erik de Bruin
+ */
+public enum ASEmitterTokens implements IEmitterTokens
+{
+    DOUBLE_QUOTE("\""), INDENT("\t"), NEW_LINE("\n"), SINGLE_QUOTE("'"), SPACE(
+            " "),
+
+    INTERNAL("internal"), PRIVATE("private"), PROTECTED("protected"),
+
+    ANY_TYPE("*"), UNDEFINED("undefined"),
+
+    //    int EOF = 1;
+    //    int NULL_TREE_LOOKAHEAD = 3;
+    //    int HIDDEN_TOKEN_COMMENT = 4;
+    //    int HIDDEN_TOKEN_SINGLE_LINE_COMMENT = 5;
+    //    int HIDDEN_TOKEN_STAR_ASSIGNMENT = 6;
+    //    int HIDDEN_TOKEN_BUILTIN_NS = 7;
+    //    int HIDDEN_TOKEN_MULTI_LINE_COMMENT = 8;
+    //    int TOKEN_ASDOC_TAG = 9;
+    //    int TOKEN_ASDOC_TEXT = 10;
+    EACH("each"),
+    //    int TOKEN_RESERVED_WORD_CONFIG = 12;
+    //    int TOKEN_KEYWORD_INCLUDE = 13;
+    //    int TOKEN_RESERVED_WORD_GOTO = 14;
+    //    int TOKEN_IDENTIFIER = 15;
+    FINALLY("finally"),
+    CATCH("catch"),
+    //    int TOKEN_LITERAL_STRING = 18;
+    BLOCK_OPEN("{"),
+    BLOCK_CLOSE("}"),
+    //    int TOKEN_NAMESPACE_NAME = 21;
+    //    int TOKEN_OPERATOR_NS_QUALIFIER = 22;
+    //    int TOKEN_NAMESPACE_ANNOTATION = 23;
+    COLON(":"),
+    IMPORT("import"),
+    //    int TOKEN_KEYWORD_USE = 26;
+    NAMESPACE("namespace"),
+    //    int TOKEN_ASDOC_COMMENT = 28;
+    FINAL("final"),
+    DYNAMIC("dynamic"),
+    OVERRIDE("override"),
+    //    int TOKEN_MODIFIER_STATIC = 32;
+    //    int TOKEN_MODIFIER_NATIVE = 33;
+    //    int TOKEN_MODIFIER_VIRTUAL = 34;
+    MEMBER_ACCESS("."),
+    //    int TOKEN_ATTRIBUTE = 36;
+    SQUARE_OPEN("["),
+    PACKAGE("package"),
+    INTERFACE("interface"),
+    EXTENDS("extends"),
+    COMMA(","),
+    CLASS("class"),
+    IMPLEMENTS("implements"),
+    FUNCTION("function"),
+    PAREN_CLOSE(")"),
+    PAREN_OPEN("("),
+    GET("get"),
+    SET("set"),
+    ELLIPSIS("..."),
+    VAR("var"),
+    CONST("const"),
+    //    int TOKEN_OPERATOR_ASSIGNMENT = 52;
+    //    int TOKEN_DIRECTIVE_DEFAULT_XML = 53;
+    SEMICOLON(";"),
+    RETURN("return"),
+    THROW("throw"),
+    FOR("for"),
+    IN("in"),
+    DO("do"),
+    WHILE("while"),
+    //    int TOKEN_KEYWORD_CONTINUE = 61;
+    //    int TOKEN_KEYWORD_BREAK = 62;
+    WITH("with"),
+    TRY("try"),
+    IF("if"),
+    ELSE("else"),
+    SWITCH("switch"),
+    CASE("case"),
+    DEFAULT("default"),
+    SUPER("super"),
+    //    int TOKEN_TYPED_COLLECTION_OPEN = 71;
+    //    int TOKEN_TYPED_COLLECTION_CLOSE = 72;
+    GREATER_THAN(">"),
+    //    int TOKEN_OPERATOR_LOGICAL_AND_ASSIGNMENT = 74;
+    //    int TOKEN_OPERATOR_LOGICAL_OR_ASSIGNMENT = 75;
+    //    int TOKEN_OPERATOR_PLUS_ASSIGNMENT = 76;
+    //    int TOKEN_OPERATOR_MINUS_ASSIGNMENT = 77;
+    //    int TOKEN_OPERATOR_MULTIPLICATION_ASSIGNMENT = 78;
+    //    int TOKEN_OPERATOR_DIVISION_ASSIGNMENT = 79;
+    //    int TOKEN_OPERATOR_MODULO_ASSIGNMENT = 80;
+    //    int TOKEN_OPERATOR_BITWISE_AND_ASSIGNMENT = 81;
+    //    int TOKEN_OPERATOR_BITWISE_OR_ASSIGNMENT = 82;
+    //    int TOKEN_OPERATOR_BITWISE_XOR_ASSIGNMENT = 83;
+    //    int TOKEN_OPERATOR_BITWISE_LEFT_SHIFT_ASSIGNMENT = 84;
+    //    int TOKEN_OPERATOR_BITWISE_RIGHT_SHIFT_ASSIGNMENT = 85;
+    //    int TOKEN_OPERATOR_BITWISE_UNSIGNED_RIGHT_SHIFT_ASSIGNMENT = 86;
+    TERNARY("?"),
+    LOGICAL_OR("||"),
+    LOGICAL_AND("&&"),
+    //    int TOKEN_OPERATOR_BITWISE_OR = 90;
+    //    int TOKEN_OPERATOR_BITWISE_XOR = 91;
+    //    int TOKEN_OPERATOR_BITWISE_AND = 92;
+    EQUAL("="),
+    //    int TOKEN_OPERATOR_NOT_EQUAL = 94;
+    STRICT_EQUAL("==="),
+    STRICT_NOT_EQUAL("!=="),
+    //    int TOKEN_OPERATOR_GREATER_THAN_EQUALS = 97;
+    LESS_THAN("<"),
+    //    int TOKEN_OPERATOR_LESS_THAN_EQUALS = 99;
+    INSTANCEOF("instanceof"),
+    IS("is"),
+    AS("as"),
+    //    int TOKEN_OPERATOR_BITWISE_LEFT_SHIFT = 103;
+    //    int TOKEN_OPERATOR_BITWISE_RIGHT_SHIFT = 104;
+    //    int TOKEN_OPERATOR_BITWISE_UNSIGNED_RIGHT_SHIFT = 105;
+    MINUS("-"),
+    PLUS("+"),
+    //    int TOKEN_OPERATOR_DIVISION = 108;
+    //    int TOKEN_OPERATOR_MODULO = 109;
+    //    int TOKEN_OPERATOR_STAR = 110;
+    //    int TOKEN_KEYWORD_DELETE = 111;
+    //    int TOKEN_OPERATOR_INCREMENT = 112;
+    //    int TOKEN_OPERATOR_DECREMENT = 113;
+    VOID("void"),
+    TYPEOF("typeof"),
+    //    int TOKEN_OPERATOR_BITWISE_NOT = 116;
+    //    int TOKEN_OPERATOR_LOGICAL_NOT = 117;
+    NULL("null"),
+    TRUE("true"),
+    FALSE("false"),
+    THIS("this"),
+    //    int TOKEN_VOID_0 = 122;
+    //    int TOKEN_LITERAL_REGEXP = 123;
+    //    int TOKEN_LITERAL_NUMBER = 124;
+    //    int TOKEN_LITERAL_HEX_NUMBER = 125;
+    SQUARE_CLOSE("]"),
+    //    int TOKEN_TYPED_LITERAL_OPEN = 127;
+    //    int TOKEN_TYPED_LITERAL_CLOSE = 128;
+    //    int TOKEN_E4X_WHITESPACE = 129;
+    //    int TOKEN_E4X_COMMENT = 130;
+    //    int TOKEN_E4X_CDATA = 131;
+    //    int TOKEN_E4X_PROCESSING_INSTRUCTION = 132;
+    //    int TOKEN_E4X_ENTITY = 133;
+    //    int TOKEN_E4X_DECIMAL_ENTITY = 134;
+    //    int TOKEN_E4X_HEX_ENTITY = 135;
+    //    int TOKEN_E4X_TEXT = 136;
+    //    int TOKEN_E4X_STRING = 137;
+    //    int TOKEN_E4X_OPEN_TAG_START = 138;
+    //    int TOKEN_E4X_CLOSE_TAG_START = 139;
+    //    int HIDDEN_TOKEN_E4X = 140;
+    //    int TOKEN_E4X_NAME = 141;
+    //    int TOKEN_E4X_TAG_END = 142;
+    //    int TOKEN_E4X_EMPTY_TAG_END = 143;
+    //    int TOKEN_E4X_XMLNS = 144;
+    //    int TOKEN_E4X_NAME_DOT = 145;
+    //    int TOKEN_E4X_DOTTED_NAME_PART = 146;
+    //    int TOKEN_E4X_EQUALS = 147;
+    //    int TOKEN_LITERAL_XMLLIST = 148;
+    //    int TOKEN_E4X_XMLLIST_CLOSE = 149;
+    //    int TOKEN_E4X_BINDING_OPEN = 150;
+    //    int TOKEN_E4X_BINDING_CLOSE = 151;
+    NEW("new"),
+    ATSIGN("@"),
+    //    int TOKEN_OPERATOR_DESCENDANT_ACCESS = 154;
+    ;
+
+    private String token;
+
+    private ASEmitterTokens(String value)
+    {
+        token = value;
+    }
+
+    public String getToken()
+    {
+        return token;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASFilterWriter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASFilterWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASFilterWriter.java
new file mode 100644
index 0000000..c9fe02e
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASFilterWriter.java
@@ -0,0 +1,42 @@
+/*
+ *
+ *  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.as;
+
+import java.io.FilterWriter;
+import java.io.Writer;
+
+/**
+ * @author Michael Schmalle
+ */
+public class ASFilterWriter extends FilterWriter
+{
+
+    public ASFilterWriter(Writer out)
+    {
+        super(out);
+    }
+
+    @Override
+    public String toString()
+    {
+        return out.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASWriter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASWriter.java
new file mode 100644
index 0000000..87634b7
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASWriter.java
@@ -0,0 +1,97 @@
+/*
+ *
+ *  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.as;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.codegen.as.IASWriter;
+import org.apache.flex.compiler.internal.codegen.js.JSSharedData;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.projects.IASProject;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.visitor.as.IASBlockWalker;
+
+public class ASWriter implements IASWriter
+{
+    private IASProject project;
+
+    private List<ICompilerProblem> problems;
+
+    private ICompilationUnit compilationUnit;
+
+    @SuppressWarnings("unused")
+    private boolean enableDebug;
+
+    /**
+     * Create a JSApplication writer.
+     * 
+     * @param application the JSApplication model to be encoded
+     * @param useCompression use ZLIB compression if true
+     */
+    public ASWriter(IASProject project, List<ICompilerProblem> problems,
+            ICompilationUnit compilationUnit, boolean enableDebug)
+    {
+        this.project = project;
+        this.problems = problems;
+        this.compilationUnit = compilationUnit;
+        this.enableDebug = enableDebug;
+    }
+
+    @Override
+    public void close() throws IOException
+    {
+        //outputBuffer.close();
+    }
+
+    @Override
+    public void writeTo(OutputStream out)
+    {
+        ASFilterWriter writer = JSSharedData.backend
+                .createWriterBuffer(project);
+        IASEmitter emitter = JSSharedData.backend.createEmitter(writer);
+        IASBlockWalker walker = JSSharedData.backend.createWalker(project,
+                problems, emitter);
+
+        walker.visitCompilationUnit(compilationUnit);
+
+        System.out.println(writer.toString());
+
+        try
+        {
+            out.write(writer.toString().getBytes());
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public int writeTo(File out) throws FileNotFoundException, IOException
+    {
+        return 0;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java
new file mode 100644
index 0000000..957d352
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java
@@ -0,0 +1,166 @@
+/*
+ *
+ *  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.externals.emit;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.flex.compiler.internal.codegen.externals.reference.BaseReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ConstantReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.FunctionReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+public class ReferenceEmitter
+{
+    private ReferenceModel model;
+
+    public ReferenceEmitter(ReferenceModel model)
+    {
+        this.model = model;
+    }
+
+    public void emit() throws IOException
+    {
+        final File asRoot = model.getConfiguration().getAsRoot();
+        if (!asRoot.exists())
+            asRoot.mkdirs();
+
+        emitClasses();
+        emitInterfaces();
+        emitTypedefs();
+        emitFunctions();
+        emitConstants();
+    }
+
+    protected void emitInterfaces() throws IOException
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (ClassReference reference : model.getClasses())
+        {
+            if (model.isExcludedClass(reference) != null)
+                continue;
+
+            if (!reference.isInterface())
+                continue;
+
+            if (model.getConfiguration().isExternalExtern(reference))
+                continue;
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(model.getConfiguration().getAsInterfaceRoot());
+            FileUtils.write(sourceFile, sb.toString());
+
+            sb.setLength(0);
+        }
+    }
+
+    protected void emitClasses() throws IOException
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (ClassReference reference : model.getClasses())
+        {
+            if (model.isExcludedClass(reference) != null)
+                continue;
+
+            if (reference.isInterface())
+                continue;
+
+            if (model.getConfiguration().isExternalExtern(reference))
+                continue;
+            
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(model.getConfiguration().getAsClassRoot());
+            FileUtils.write(sourceFile, sb.toString());
+
+            sb.setLength(0);
+        }
+    }
+
+    protected void emitTypedefs() throws IOException
+    {
+        final StringBuilder sb = new StringBuilder();
+        // TODO figure out how to resolve/emit @typedef
+        for (ClassReference reference : model.getTypedefs())
+        {
+            if (model.isExcludedClass(reference) != null)
+                continue;
+
+            if (model.getConfiguration().isExternalExtern(reference))
+                continue;
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(model.getConfiguration().getAsTypeDefRoot());
+            FileUtils.write(sourceFile, sb.toString());
+
+            sb.setLength(0);
+        }
+    }
+
+    protected void emitFunctions() throws IOException
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (FunctionReference reference : model.getFunctions())
+        {
+            if (model.getConfiguration().isExternalExtern(reference))
+                continue;
+            
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(model.getConfiguration().getAsFunctionRoot());
+            FileUtils.write(sourceFile, sb.toString());
+
+            sb.setLength(0);
+        }
+    }
+
+    protected void emitConstants() throws IOException
+    {
+        final StringBuilder sb = new StringBuilder();
+        for (ConstantReference reference : model.getConstants())
+        {
+            if (model.getConfiguration().isExternalExtern(reference))
+                continue;
+            
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(model.getConfiguration().getAsConstantRoot());
+            FileUtils.write(sourceFile, sb.toString());
+
+            sb.setLength(0);
+        }
+    }
+
+    public void emit(BaseReference reference, StringBuilder sb)
+    {
+        reference.emit(sb);
+    }
+
+    public String emit(BaseReference reference)
+    {
+        final StringBuilder sb = new StringBuilder();
+        reference.emit(sb);
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java
new file mode 100644
index 0000000..a9734de
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java
@@ -0,0 +1,71 @@
+/*
+ *
+ *  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.externals.pass;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+import org.apache.flex.compiler.internal.codegen.externals.utils.DebugLogUtils;
+
+import com.google.javascript.jscomp.AbstractCompiler;
+import com.google.javascript.jscomp.CompilerPass;
+import com.google.javascript.jscomp.NodeTraversal;
+import com.google.javascript.jscomp.NodeTraversal.Callback;
+import com.google.javascript.rhino.Node;
+
+public abstract class AbstractCompilerPass implements CompilerPass, Callback
+{
+    protected ReferenceModel model;
+    protected AbstractCompiler compiler;
+
+    protected boolean logEnabled;
+    protected boolean errEnabled;
+
+    public AbstractCompilerPass(ReferenceModel model, AbstractCompiler compiler)
+    {
+        this.model = model;
+        this.compiler = compiler;
+    }
+
+    @Override
+    public void process(Node externs, Node root)
+    {
+        //NodeTraversal.traverse(compiler, root, this);
+        NodeTraversal.traverseRoots(compiler, this, externs, root);
+    }
+
+    protected void log(Node n)
+    {
+        DebugLogUtils.err(n);
+    }
+
+    protected void err(Node n)
+    {
+        DebugLogUtils.err(n);
+    }
+
+    protected void log(String message)
+    {
+        DebugLogUtils.log(message);
+    }
+
+    protected void err(String message)
+    {
+        DebugLogUtils.err(message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
new file mode 100644
index 0000000..8379af9
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
@@ -0,0 +1,150 @@
+/*
+ *
+ *  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.externals.pass;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.javascript.jscomp.AbstractCompiler;
+import com.google.javascript.jscomp.NodeTraversal;
+import com.google.javascript.rhino.Node;
+
+public class AddMemberPass extends AbstractCompilerPass
+{
+
+    public AddMemberPass(ReferenceModel model, AbstractCompiler compiler)
+    {
+        super(model, compiler);
+    }
+
+    @Override
+    public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n,
+            Node parent)
+    {
+        return n.isBlock() || n.isScript();
+    }
+
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent)
+    {
+        for (Node child : n.children())
+        {
+            //log(child);
+
+            if (child.isExprResult())
+            {
+                Node first = child.getFirstChild();
+
+                if (first.isVar())
+                {
+                    // visitVar(t, n);
+                }
+                else if (first.isFunction())
+                {
+                    // visitFunction(t, n);
+                }
+                else if (first.isAssign())
+                {
+                    if (first.getFirstChild().isGetProp()
+                            && first.getLastChild().isFunction())
+                    {
+                        // instance or static method
+                        visitMethod(t, first);
+                    }
+                    else
+                    {
+                        // DOMException.INDEX_SIZE_ERR = 1;
+                        // The first child of the assign is the GetProp node,
+                        // if later you need the value, either change this or check
+                        // for a parent assign node when creating the FieldReference
+                        // which the value would be n.getLastChild()
+                        // XXX visitStaticField(t, n);
+                        //System.err.println(n.toStringTree());
+                    }
+                }
+                else if (first.isGetProp())
+                {
+                    visitGetProp(t, first);
+                }
+            }
+        }
+    }
+
+    // n == ASSIGN
+    private void visitMethod(NodeTraversal t, Node n)
+    {
+        String qName = n.getFirstChild().getQualifiedName();
+
+        if (n.getFirstChild().isGetProp())
+        {
+            int protoType = qName.indexOf(".prototype.");
+            if (protoType != -1)
+            {
+                String className = qName.substring(0, protoType);
+                String memberName = qName.substring(protoType + 11,
+                        qName.length());
+                //log("Prototype:: className [" + className
+                //        + "] memberName [" + memberName + "]");
+                model.addMethod(n, className, memberName);
+            }
+            else
+            {
+                String className = qName.substring(0, qName.lastIndexOf("."));
+                String memberName = qName.substring(qName.lastIndexOf(".") + 1,
+                        qName.length());
+                //log("className [" + className + "] memberName ["
+                //        + memberName + "]");
+                model.addStaticMethod(n, className, memberName);
+            }
+        }
+        else if (n.getFirstChild().isName())
+        {
+            err("visitMethod() non impl");
+            log(n);
+        }
+    }
+
+    private void visitGetProp(NodeTraversal t, Node n)
+    {
+        String qualifiedName = n.getQualifiedName();
+
+        log("visitGetProp [" + qualifiedName + "]");
+
+        int protoType = qualifiedName.indexOf(".prototype.");
+        if (protoType != -1)
+        {
+            String className = qualifiedName.substring(0, protoType);
+            String memberName = qualifiedName.substring(protoType + 11,
+                    qualifiedName.length());
+            //log("Prototype:: className [" + className
+            //        + "] memberName [" + memberName + "]");
+            model.addField(n, className, memberName);
+        }
+        else
+        {
+            String className = qualifiedName.substring(0,
+                    qualifiedName.lastIndexOf("."));
+            String memberName = qualifiedName.substring(
+                    qualifiedName.lastIndexOf(".") + 1, qualifiedName.length());
+            //log("className [" + className + "] memberName ["
+            //        + memberName + "]");
+            model.addStaticField(n, className, memberName);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectImportsPass.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectImportsPass.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectImportsPass.java
new file mode 100644
index 0000000..d934610
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectImportsPass.java
@@ -0,0 +1,188 @@
+/*
+ *
+ *  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.externals.pass;
+
+import java.util.List;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.*;
+
+import com.google.javascript.jscomp.AbstractCompiler;
+import com.google.javascript.jscomp.NodeTraversal;
+import com.google.javascript.rhino.Node;
+
+/**
+ * @author: Frederic Thomas Date: 05/07/2015 Time: 18:16
+ */
+public class CollectImportsPass extends AbstractCompilerPass
+{
+    public CollectImportsPass(final ReferenceModel model, AbstractCompiler compiler)
+    {
+        super(model, compiler);
+    }
+
+    @Override
+    public void process(Node externs, Node root)
+    {
+        for (ClassReference reference : model.getClasses())
+        {
+            collectClassImports(reference);
+        }
+
+        for (FunctionReference reference : model.getFunctions())
+        {
+            collectFunctionImports(reference);
+        }
+    }
+
+    private void collectClassImports(ClassReference reference)
+    {
+        final MethodReference constructor = reference.getConstructor();
+        final List<ClassReference> superClasses = reference.getSuperClasses();
+        final List<ClassReference> interfaces = reference.getInterfaces();
+        final List<ClassReference> extendedInterfaces = reference.getExtendedInterfaces();
+        final List<FieldReference> fields = reference.getAllFields();
+        final List<MethodReference> methods = reference.getAllMethods();
+
+        for (ClassReference superClass : superClasses)
+        {
+            if (model.isExcludedClass(superClass) == null)
+            {
+                addClassImport(reference, superClass);
+            }
+        }
+
+        for (ClassReference _interface : interfaces)
+        {
+            if (model.isExcludedClass(_interface) == null)
+            {
+                addClassImport(reference, _interface);
+            }
+        }
+
+        for (ClassReference _interface : extendedInterfaces)
+        {
+            if (model.isExcludedClass(_interface) == null)
+            {
+                addClassImport(reference, _interface);
+            }
+        }
+
+        for (FieldReference field : fields)
+        {
+            if (field.isExcluded() == null)
+            {
+                addClassImport(reference, getType(field));
+            }
+        }
+
+        if (constructor != null)
+        {
+            for (ParameterReference parameterReference : constructor.getParameters())
+            {
+                addClassImport(reference, getType(parameterReference));
+            }
+        }
+
+        for (MethodReference method : methods)
+        {
+            if (method.isExcluded() == null)
+            {
+                addClassImport(reference, getReturnType(method));
+
+                for (ParameterReference parameterReference : method.getParameters())
+                {
+                    addClassImport(reference, getType(parameterReference));
+                }
+            }
+        }
+    }
+
+    private void addClassImport(final ClassReference thisReference, final ClassReference referenceToImport)
+    {
+        if (canImport(referenceToImport))
+        {
+            final String thisPackageName = thisReference.getPackageName();
+            final String importPackageName = referenceToImport.getPackageName();
+
+            if (!importPackageName.equals(thisPackageName))
+            {
+                thisReference.addImport(referenceToImport);
+            }
+        }
+    }
+
+    private void collectFunctionImports(final FunctionReference function)
+    {
+        if (function.isExcluded() == null)
+        {
+            ClassReference returnType = getReturnType(function);
+
+            if (canImport(returnType))
+            {
+                function.addImport(returnType);
+            }
+
+            for (ParameterReference parameterReference : function.getParameters())
+            {
+                ClassReference type = getType(parameterReference);
+
+                if (canImport(type))
+                {
+                    function.addImport(type);
+                }
+            }
+        }
+    }
+
+    private ClassReference getType(final FieldReference field)
+    {
+        return model.getClassReference(field.toTypeString());
+    }
+
+    private ClassReference getReturnType(final MethodReference method)
+    {
+        return model.getClassReference(method.transformReturnString());
+    }
+
+    private ClassReference getReturnType(final FunctionReference function)
+    {
+        return model.getClassReference(function.transformReturnString());
+    }
+
+    private ClassReference getType(final ParameterReference parameter)
+    {
+        return model.getClassReference(parameter.getQualifiedName());
+    }
+
+    private boolean canImport(ClassReference reference)
+    {
+        return reference != null && reference.isQualifiedName() && model.isExcludedClass(reference) == null;
+    }
+
+    @Override
+    public boolean shouldTraverse(final NodeTraversal nodeTraversal, final Node n, final Node parent) {
+        return false;
+    }
+
+    @Override
+    public void visit(final NodeTraversal t, final Node n, final Node parent)
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java
new file mode 100644
index 0000000..8ddde76
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java
@@ -0,0 +1,165 @@
+/*
+ *
+ *  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.externals.pass;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.javascript.jscomp.AbstractCompiler;
+import com.google.javascript.jscomp.NodeTraversal;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+
+public class CollectTypesPass extends AbstractCompilerPass
+{
+    public CollectTypesPass(ReferenceModel model, AbstractCompiler compiler)
+    {
+        super(model, compiler);
+    }
+
+    @Override
+    public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n,
+            Node parent)
+    {
+        return n.isBlock() || n.isScript();
+    }
+
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent)
+    {
+        for (Node child : n.children())
+        {
+            if (child.isVar())
+            {
+                visitVar(child);
+            }
+            else if (child.isFunction())
+            {
+                visitFunction(child);
+            }
+            else if (child.isExprResult())
+            {
+                visitExprResult(child);
+            }
+        }
+    }
+
+    private void visitExprResult(Node child)
+    {
+        JSDocInfo comment = null;
+
+        Node container = child.getFirstChild();
+        if (container.isAssign())
+        {
+            comment = container.getJSDocInfo();
+
+            Node left = container.getFirstChild();
+            Node right = container.getLastChild();
+
+            if (left.isName() && right.isFunction())
+            {
+                if (comment.isConstructor() || comment.isInterface())
+                {
+                    // Foo = function () {};
+                    model.addClass(container, left.getString());
+                }
+
+            }
+            else if (left.isGetProp() && right.isFunction())
+            {
+                boolean isConstructor = comment != null
+                        && (comment.isConstructor() || comment.isInterface());
+                // foo.bar.Baz = function () {};
+                if (isConstructor)
+                {
+                    model.addClass(container, left.getQualifiedName());
+                }
+            }
+        }
+    }
+
+    private void visitFunction(Node child)
+    {
+        JSDocInfo comment = child.getJSDocInfo();
+
+        boolean isConstructor = comment != null
+                && (comment.isConstructor() || comment.isInterface());
+
+        if (isConstructor)
+        {
+            // function Goo () {};
+            model.addClass(child, child.getFirstChild().getString());
+        }
+        else
+        {
+            model.addFunction(child, child.getFirstChild().getString());
+        }
+    }
+
+    private void visitVar(Node child)
+    {
+        JSDocInfo comment = child.getJSDocInfo();
+
+        Node first = child.getFirstChild();
+        if (first.isName())
+        {
+            Node subFirst = first.getFirstChild();
+            if (subFirst != null && subFirst.isObjectLit())
+            {
+                if (comment.hasEnumParameterType())
+                {
+
+                }
+                else
+                {
+                    //System.out.println(first.getFirstChild().toStringTree());
+                    //log("Encountered namespace [" + first.getQualifiedName() + "]");
+                    model.addNamespace(child, first.getQualifiedName());
+                }
+            }
+            else if (subFirst != null && subFirst.isFunction())
+            {
+                boolean isConstructor = comment != null
+                        && (comment.isConstructor() || comment.isInterface());
+                // foo.bar.Baz = function () {};
+                if (isConstructor)
+                {
+                    model.addClass(child, first.getString());
+                }
+            }
+            else
+            {
+                boolean isConstructor = comment != null
+                        && (comment.getTypedefType() != null);
+                // * @typedef
+                // var foo;
+                if (isConstructor)
+                {
+                    // model.addClass(child, first.getString());
+                    model.addTypeDef(child, first.getString());
+                }
+                else if (comment != null && comment.isConstant())
+                {
+                    //System.out.println(child.toStringTree());
+                    model.addConstant(child, first.getString());
+                }
+            }
+        }
+    }
+}


Mime
View raw message