You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2016/04/13 20:56:38 UTC
[46/51] [partial] git commit: [flex-falcon]
[refs/heads/feature/maven-migration-test] - - Check-In of the migrated
project to make error analysis easier
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());
+ }
+ }
+ }
+ }
+}