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/18 15:32:03 UTC
[14/14] git commit: [flex-falcon]
[refs/heads/feature/maven-migration-test] - Merge branches 'develop' and
'feature/maven-migration-test' of
https://git-wip-us.apache.org/repos/asf/flex-falcon into
feature/maven-migration-test
Merge branches 'develop' and 'feature/maven-migration-test' of https://git-wip-us.apache.org/repos/asf/flex-falcon into feature/maven-migration-test
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/beaf5b63
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/beaf5b63
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/beaf5b63
Branch: refs/heads/feature/maven-migration-test
Commit: beaf5b63a28777f160c801babaef7ce44cf87336
Parents: 316710d e9fd628
Author: Christofer Dutz <ch...@codecentric.de>
Authored: Mon Apr 18 15:31:26 2016 +0200
Committer: Christofer Dutz <ch...@codecentric.de>
Committed: Mon Apr 18 15:31:26 2016 +0200
----------------------------------------------------------------------
.../flex/compiler/codegen/as/IASEmitter.java | 6 +-
.../flex/compiler/codegen/js/IJSEmitter.java | 2 +-
.../codegen/as/ASAfterNodeStrategy.java | 4 +-
.../codegen/as/ASBeforeNodeStrategy.java | 4 +-
.../compiler/internal/codegen/as/ASEmitter.java | 12 ++
.../compiler/internal/codegen/js/JSEmitter.java | 28 ++-
.../internal/codegen/js/JSSubEmitter.java | 4 +-
.../codegen/js/jx/LiteralContainerEmitter.java | 2 +-
.../js/jx/ObjectLiteralValuePairEmitter.java | 6 +-
.../codegen/js/jx/VarDeclarationEmitter.java | 12 +-
.../js/sourcemaps/TestSourceMapExpressions.java | 181 +++++++++++--------
.../js/sourcemaps/TestSourceMapStatements.java | 144 ++++++++++++++-
.../codegen/js/jx/BlockCloseEmitter.java | 43 +++++
.../codegen/js/jx/BlockOpenEmitter.java | 43 +++++
.../compiler/internal/parsing/as/ASParser.g | 4 +-
.../flex/compiler/common/ISourceLocation.java | 10 +
.../flex/compiler/common/SourceLocation.java | 54 ++++++
.../internal/definitions/metadata/MetaTag.java | 12 ++
.../compiler/internal/parsing/TokenBase.java | 44 +++++
.../compiler/internal/tree/as/NodeBase.java | 17 +-
.../internal/tree/as/OperatorNodeBase.java | 2 +
.../flex/compiler/problems/CompilerProblem.java | 12 ++
22 files changed, 547 insertions(+), 99 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java
index bd0d1eb,0000000..2fe9eea
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/as/IASEmitter.java
@@@ -1,369 -1,0 +1,373 @@@
+/*
+ *
+ * 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.codegen.as;
+
+import java.io.Writer;
+
+import org.apache.flex.compiler.codegen.IDocEmitter;
+import org.apache.flex.compiler.codegen.IEmitter;
+import org.apache.flex.compiler.definitions.IPackageDefinition;
+import org.apache.flex.compiler.internal.tree.as.LabeledStatementNode;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IBlockNode;
+import org.apache.flex.compiler.tree.as.ICatchNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+import org.apache.flex.compiler.tree.as.IDynamicAccessNode;
+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.IParameterNode;
+import org.apache.flex.compiler.tree.as.IReturnNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+import org.apache.flex.compiler.tree.as.ISwitchNode;
+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.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.visitor.IASNodeStrategy;
+import org.apache.flex.compiler.visitor.IBlockWalker;
+
+/**
+ * The {@link IASEmitter} interface allows abstraction between the
+ * {@link IASNodeStrategy} and the current output buffer {@link Writer}.
+ *
+ * @author Michael Schmalle
+ */
+public interface IASEmitter extends IEmitter
+{
+ IBlockWalker getWalker();
+
+ void setWalker(IBlockWalker asBlockWalker);
+
+ IDocEmitter getDocEmitter();
+
+ void setDocEmitter(IDocEmitter value);
+
+ String postProcess(String output);
-
++
+ void emitImport(IImportNode node);
+
+ void emitPackageHeader(IPackageDefinition definition);
+
+ void emitPackageHeaderContents(IPackageDefinition definition);
+
+ void emitPackageContents(IPackageDefinition definition);
+
+ void emitPackageFooter(IPackageDefinition definition);
+
+ /**
+ * Emit a Class.
+ *
+ * @param node The {@link IClassNode} class.
+ */
+ void emitClass(IClassNode node);
+
+ /**
+ * Emit an Interface.
+ *
+ * @param node The {@link IInterfaceNode} class.
+ */
+ void emitInterface(IInterfaceNode node);
+
+ /**
+ * Emit a documentation comment for a Class field or constant
+ * {@link IVariableNode}.
+ *
+ * @param node The {@link IVariableNode} class field member.
+ */
+ void emitFieldDocumentation(IVariableNode node);
+
+ /**
+ * Emit a full Class field member.
+ *
+ * @param node The {@link IVariableNode} class field member.
+ */
+ void emitField(IVariableNode node);
+
+ /**
+ * Emit a documentation comment for a Class method {@link IFunctionNode}.
+ *
+ * @param node The {@link IFunctionNode} class method member.
+ */
+ void emitMethodDocumentation(IFunctionNode node);
+
+ /**
+ * Emit a full Class or Interface method member.
+ *
+ * @param node The {@link IFunctionNode} class method member.
+ */
+ void emitMethod(IFunctionNode node);
+
+ /**
+ * Emit a documentation comment for a Class method {@link IGetterNode}.
+ *
+ * @param node The {@link IGetterNode} class accessor member.
+ */
+ void emitGetAccessorDocumentation(IGetterNode node);
+
+ /**
+ * Emit a full Class getter member.
+ *
+ * @param node The {@link IVariableNode} class getter member.
+ */
+ void emitGetAccessor(IGetterNode node);
+
+ /**
+ * Emit a documentation comment for a Class accessor {@link IGetterNode}.
+ *
+ * @param node The {@link ISetterNode} class accessor member.
+ */
+ void emitSetAccessorDocumentation(ISetterNode node);
+
+ /**
+ * Emit a full Class setter member.
+ *
+ * @param node The {@link ISetterNode} class setter member.
+ */
+ void emitSetAccessor(ISetterNode node);
+
+ void emitParameter(IParameterNode node);
+
+ /**
+ * Emit a namespace member.
+ *
+ * @param node The {@link INamespaceNode} class member.
+ */
+ void emitNamespace(INamespaceNode node);
+
+ //--------------------------------------------------------------------------
+ // Statements
+ //--------------------------------------------------------------------------
+
+ /**
+ * Emit a statement found within an {@link IBlockNode}.
+ *
+ * @param node The {@link IASNode} statement.
+ */
+ void emitStatement(IASNode node);
+
+ /**
+ * Emit a <code>if(){}else if(){}else{}</code> statement.
+ *
+ * @param node The {@link IIfNode} node.
+ */
+ void emitIf(IIfNode node);
+
+ /**
+ * Emit a <code>for each</code> statement.
+ *
+ * @param node The {@link IForLoopNode} node.
+ */
+ void emitForEachLoop(IForLoopNode node);
+
+ /**
+ * Emit a <code>for</code> statement.
+ *
+ * @param node The {@link IForLoopNode} node.
+ */
+ void emitForLoop(IForLoopNode node);
+
+ /**
+ * Emit a <code>switch(){}</code> statement.
+ *
+ * @param node The {@link ISwitchNode} node.
+ */
+ void emitSwitch(ISwitchNode node);
+
+ /**
+ * Emit a <code>while(){}</code> statement.
+ *
+ * @param node The {@link IWhileLoopNode} node.
+ */
+ void emitWhileLoop(IWhileLoopNode node);
+
+ /**
+ * Emit a <code>do{}while()</code> statement.
+ *
+ * @param node The {@link IWhileLoopNode} node.
+ */
+ void emitDoLoop(IWhileLoopNode node);
+
+ /**
+ * Emit a <code>with(){}</code> statement.
+ *
+ * @param node The {@link IWithNode} node.
+ */
+ void emitWith(IWithNode node);
+
+ /**
+ * Emit a <code>throw</code> statement.
+ *
+ * @param node The {@link IThrowNode} node.
+ */
+ void emitThrow(IThrowNode node);
+
+ /**
+ * Emit a <code>try{}</code> statement.
+ *
+ * @param node The {@link ITryNode} node.
+ */
+ void emitTry(ITryNode node);
+
+ /**
+ * Emit a <code>catch(){}</code> statement.
+ *
+ * @param node The {@link ICatchNode} node.
+ */
+ void emitCatch(ICatchNode node);
+
+ /**
+ * Emit a <code>foo:{}</code> statement.
+ *
+ * @param node The {@link LabeledStatementNode} node.
+ */
+ void emitLabelStatement(LabeledStatementNode node);
+
+ void emitReturn(IReturnNode node);
+
+ //--------------------------------------------------------------------------
+ // Expressions
+ //--------------------------------------------------------------------------
+
+ /**
+ * Emit a variable declaration found in expression statements within scoped
+ * blocks.
+ *
+ * @param node The {@link IVariableNode} or chain of variable nodes.
+ */
+ void emitVarDeclaration(IVariableNode node);
+
+ /**
+ * Emit an anonymous {@link IFunctionObjectNode}.
+ *
+ * @param node The anonymous {@link IFunctionObjectNode}.
+ */
+ void emitFunctionObject(IFunctionObjectNode node);
+
+ /**
+ * Emit an local named function {@link IFunctionNode}.
+ *
+ * @param node The local named function {@link IFunctionNode}.
+ */
+ void emitLocalNamedFunction(IFunctionNode node);
+
+ /**
+ * Emit a header at the start of a function block.
+ *
+ * @param node The {@link IFunctionNode} node.
+ */
+ void emitFunctionBlockHeader(IFunctionNode node);
+
+ /**
+ * Emit a function call like <code>new Foo()</code> or <code>foo(42)</code>.
+ *
+ * @param node The {@link IFunctionCallNode} node.
+ */
+ void emitFunctionCall(IFunctionCallNode node);
+
+ void emitArguments(IContainerNode node);
+
+ void emitIterationFlow(IIterationFlowNode node);
+
+ void emitNamespaceAccessExpression(INamespaceAccessExpressionNode node);
+
+ void emitMemberAccessExpression(IMemberAccessExpressionNode node);
+
+ void emitVariableExpression(IVariableExpressionNode node);
+
+ void emitDynamicAccess(IDynamicAccessNode node);
+
+ void emitTypedExpression(ITypedExpressionNode node);
+
+ void emitObjectLiteralValuePair(IObjectLiteralValuePairNode node);
+
+ void emitIdentifier(IIdentifierNode node);
+
+ void emitLiteral(ILiteralNode node);
+
+ void emitLiteralContainer(ILiteralContainerNode node);
+
+ void emitNumericLiteral(INumericLiteralNode node);
+
+ //--------------------------------------------------------------------------
+ // Operators
+ //--------------------------------------------------------------------------
+
+ void emitUnaryOperator(IUnaryOperatorNode node);
+
+ void emitAsOperator(IBinaryOperatorNode node);
+
+ void emitIsOperator(IBinaryOperatorNode node);
+
+ /**
+ * Emit an operator statement.
+ *
+ * @param node The {@link IBinaryOperatorNode} or chain of variable nodes.
+ */
+ void emitBinaryOperator(IBinaryOperatorNode node);
+
+ void emitTernaryOperator(ITernaryOperatorNode node);
+
+ //--------------------------------------------------------------------------
+ // Node
+ //--------------------------------------------------------------------------
+
+ void emitKeyword(IKeywordNode node);
+
+ void emitLanguageIdentifier(ILanguageIdentifierNode node);
+
+ void emitMetaTag(IMetaTagNode node);
+
+ void emitContainer(IContainerNode node);
+
+ void emitE4XFilter(IMemberAccessExpressionNode node);
+
+ void emitUseNamespace(IUseNamespaceNode node);
+
++ void emitBlockOpen(IContainerNode node);
++
++ void emitBlockClose(IContainerNode node);
++
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java
index 218b5be,0000000..287b8c8
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/codegen/js/IJSEmitter.java
@@@ -1,85 -1,0 +1,85 @@@
+/*
+ *
+ * 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.codegen.js;
+
+import java.io.Writer;
+import java.util.List;
+
+import com.google.debugging.sourcemap.FilePosition;
+import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.visitor.IASNodeStrategy;
+
+/**
+ * The {@link IJSEmitter} interface allows abstraction between the
+ * {@link IASNodeStrategy} and the current output buffer {@link Writer}.
+ *
+ * @author Michael Schmalle
+ */
+public interface IJSEmitter extends IASEmitter
+{
+ JSSessionModel getModel();
+ List<SourceMapMapping> getSourceMapMappings();
+
+ String formatQualifiedName(String name);
+
+ /**
+ * Adds a node to the source map.
+ */
+ void startMapping(ISourceLocation node);
+
+ /**
+ * Adds a node to the source map using custom line and column values,
+ * instead of the node's own line and column. Useful for starting a mapping
+ * in the middle of the node.
+ */
+ void startMapping(ISourceLocation node, int line, int column);
+
+ /**
+ * Adds a node to the source map after a particular node instead using the
+ * node's own line and column.
+ */
- void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping);
++ void startMapping(ISourceLocation node, ISourceLocation afterNode);
+
+ /**
+ * Commits a mapping to the source map.
+ */
+ void endMapping(ISourceLocation node);
+
+ void pushSourceMapName(ISourceLocation node);
+ void popSourceMapName();
+
+ void emitSourceMapDirective(ITypeNode node);
+
+ void emitClosureStart();
+ void emitClosureEnd(IASNode node);
+
+ class SourceMapMapping
+ {
+ public String sourcePath;
+ public String name;
+ public FilePosition sourceStartPosition;
+ public FilePosition destStartPosition;
+ public FilePosition destEndPosition;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
index 1ac85f7,0000000..b274b57
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
@@@ -1,77 -1,0 +1,77 @@@
+/*
+ *
+ * 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.IEmitter;
+import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+import org.apache.flex.compiler.tree.as.IContainerNode.ContainerType;
+import org.apache.flex.compiler.visitor.IASNodeStrategy;
+
+/**
+ * A concrete implementation of the {@link IASNodeStrategy} that allows
+ * {@link IASNode} processing after the current node handler.
+ * <p>
+ * The class has access to the current {@link IJSEmitter} instance being used to
+ * output source code to the current output buffer.
+ *
+ * @author Michael Schmalle
+ */
+public class ASAfterNodeStrategy implements IASNodeStrategy
+{
+ private final IASEmitter emitter;
+
+ public ASAfterNodeStrategy(IASEmitter emitter)
+ {
+ this.emitter = emitter;
+ }
+
+ @Override
+ public void handle(IASNode node)
+ {
+ if (node.getNodeID() == ASTNodeID.BlockID)
+ {
+ IContainerNode container = (IContainerNode) node;
+ ContainerType type = container.getContainerType();
+ if (type != ContainerType.IMPLICIT
+ && type != ContainerType.SYNTHESIZED)
+ {
+ if (node.getChildCount() != 0)
+ {
+ emitter.indentPop();
- ((IEmitter) emitter).writeNewline();
++ emitter.writeNewline();
+ }
+
- ((IEmitter) emitter).write(ASEmitterTokens.BLOCK_CLOSE);
++ emitter.emitBlockClose(container);
+ }
+ else if (type == ContainerType.IMPLICIT
+ || type == ContainerType.SYNTHESIZED)
+ {
+ if (node.getChildCount() != 0)
+ {
+ emitter.indentPop();
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
index d481573,0000000..d960057
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
@@@ -1,74 -1,0 +1,74 @@@
+/*
+ *
+ * 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.IEmitter;
+import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+import org.apache.flex.compiler.tree.as.IContainerNode.ContainerType;
+import org.apache.flex.compiler.visitor.IASNodeStrategy;
+
+/**
+ * A concrete implementation of the {@link IASNodeStrategy} that allows
+ * {@link IASNode} processing before the current node handler.
+ *
+ * @author Michael Schmalle
+ */
+public class ASBeforeNodeStrategy implements IASNodeStrategy
+{
+ private final IASEmitter emitter;
+
+ public ASBeforeNodeStrategy(IASEmitter emitter)
+ {
+ this.emitter = emitter;
+ }
+
+ @Override
+ public void handle(IASNode node)
+ {
+ if (node.getNodeID() == ASTNodeID.BlockID)
+ {
+ IASNode parent = node.getParent();
+ IContainerNode container = (IContainerNode) node;
+ ContainerType type = container.getContainerType();
+
+ if (parent.getNodeID() != ASTNodeID.LabledStatementID)
+ {
+ if (node.getChildCount() != 0)
+ emitter.indentPush();
+ }
+
+ // switch cases are SYNTHESIZED
+ if (type != ContainerType.IMPLICIT
+ && type != ContainerType.SYNTHESIZED)
+ {
- ((IEmitter) emitter).write(ASEmitterTokens.BLOCK_OPEN);
++ emitter.emitBlockOpen(container);
+ }
+
+ if (parent.getNodeID() != ASTNodeID.LabledStatementID)
+ {
- ((IEmitter) emitter).writeNewline();
++ emitter.writeNewline();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
index 875d1d2,0000000..6f48f8e
mode 100644,000000..100644
--- 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
@@@ -1,1540 -1,0 +1,1552 @@@
+/*
+ *
+ * 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 void emitBlockOpen(IContainerNode node)
++ {
++ write(ASEmitterTokens.BLOCK_OPEN);
++ }
++
++ @Override
++ public void emitBlockClose(IContainerNode node)
++ {
++ write(ASEmitterTokens.BLOCK_CLOSE);
++ }
++
++ @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;
+ }
+}