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:31:50 UTC

[01/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - VarDeclarationEmitter: fixed sourcemap for assignment when type is omitted

Repository: flex-falcon
Updated Branches:
  refs/heads/feature/maven-migration-test 316710d68 -> beaf5b63a


VarDeclarationEmitter: fixed sourcemap for assignment when type is omitted


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

Branch: refs/heads/feature/maven-migration-test
Commit: e36c544cf9ebe6900dfb84ddffd2bdc9bd94733c
Parents: bc19c66
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 14:03:18 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 14:03:18 2016 -0700

----------------------------------------------------------------------
 .../js/sourcemaps/TestSourceMapStatements.java        | 14 ++++++++++++++
 .../internal/codegen/js/jx/VarDeclarationEmitter.java | 12 ++++++++++--
 2 files changed, 24 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e36c544c/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
index 3c25d07..8f4cf77 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
@@ -27,6 +27,20 @@ public class TestSourceMapStatements extends SourceMapTestBase
     }
 
     @Test
+    public void testVarDeclaration_withAssignedValue()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a = 42;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        //var /** @type {*} */ a = 42
+        assertMapping(node, 0, 0, 0, 0, 0, 4);   // var
+        assertMapping(node, 0, 4, 0, 21, 0, 22); // a
+        assertMapping(node, 0, 5, 0, 4, 0, 21);  // (type)
+        assertMapping(node, 0, 5, 0, 22, 0, 25); // =
+        assertMapping(node, 0, 8, 0, 25, 0, 27); // 42
+    }
+
+    @Test
     public void testVarDeclaration_withType()
     {
         IVariableNode node = (IVariableNode) getNode("var a:int;",

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e36c544c/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
index f43b288..911a280 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
@@ -54,7 +54,8 @@ public class VarDeclarationEmitter extends JSSubEmitter implements
         }
 
         IExpressionNode variableTypeNode = node.getVariableTypeNode();
-        if(variableTypeNode.getLine() >= 0)
+        boolean hasVariableType = variableTypeNode.getLine() >= 0;
+        if(hasVariableType)
         {
             startMapping(variableTypeNode,
                     variableTypeNode.getLine(),
@@ -95,7 +96,14 @@ public class VarDeclarationEmitter extends JSSubEmitter implements
         fjs.emitDeclarationName(node);
         if (avnode != null && !(avnode instanceof IEmbedNode))
         {
-            startMapping(node, node.getVariableTypeNode());
+            if (hasVariableType)
+            {
+                startMapping(node, node.getVariableTypeNode());
+            }
+            else
+            {
+                startMapping(node, node.getNameExpressionNode());
+            }
             write(ASEmitterTokens.SPACE);
             writeToken(ASEmitterTokens.EQUAL);
             endMapping(node);


[02/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - compiler.jx.tests: added some tests for if statement source maps

Posted by cd...@apache.org.
compiler.jx.tests: added some tests for if statement source maps


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

Branch: refs/heads/feature/maven-migration-test
Commit: a9a399be7217b2632d41916a6338a0b4e1310ecd
Parents: e36c544
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 14:58:23 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 14:58:23 2016 -0700

----------------------------------------------------------------------
 .../js/sourcemaps/TestSourceMapStatements.java  | 104 +++++++++++++++++++
 1 file changed, 104 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a9a399be/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
index 8f4cf77..5d11227 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
@@ -4,6 +4,7 @@ import org.apache.flex.compiler.driver.IBackend;
 import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
 import org.apache.flex.compiler.internal.test.SourceMapTestBase;
 import org.apache.flex.compiler.tree.as.IForLoopNode;
+import org.apache.flex.compiler.tree.as.IIfNode;
 import org.apache.flex.compiler.tree.as.IVariableNode;
 
 import org.junit.Test;
@@ -178,6 +179,109 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 21, 0, 39, 0, 40); // )
     }
 
+    //----------------------------------
+    // if ()
+    //----------------------------------
+
+    @Test
+    public void testVisitIf_1()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) b++;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        //if (a)\n  b++;
+        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
+        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
+        assertMapping(node, 0, 5, 0, 5, 0, 6);    // )
+    }
+
+    @Test
+    public void testVisitIf_2()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) b++; else c++;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        //if (a)\n  b++;\nelse\n  c++;
+        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
+        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
+        assertMapping(node, 0, 5, 0, 5, 0, 6);    // )
+        assertMapping(node, 0, 12, 2, 0, 2, 4);   // else
+    }
+
+    @Test
+    public void testVisitIf_4()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) b++; else if (c) d++; else if(e) --f;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        //if (a)\n  b++;\nelse if (c)\n  d++;\nelse if (e)\n  --f;
+        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
+        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
+        assertMapping(node, 0, 5, 0, 5, 0, 6);    // )
+        assertMapping(node, 0, 12, 2, 0, 2, 9);   // else if (
+        assertMapping(node, 0, 22, 2, 10, 2, 11); // )
+        assertMapping(node, 0, 29, 4, 0, 4, 9);   // else if (
+        assertMapping(node, 0, 38, 4, 10, 4, 11); // )
+    }
+
+    //----------------------------------
+    // if () { }
+    //----------------------------------
+
+    @Test
+    public void testVisitIf_1a()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) { b++; }", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        //if (a) {\n  b++;\n}
+        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
+        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
+        assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
+    }
+
+    @Test
+    public void testVisitIf_1b()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) { b++; } else { c++; }",
+                IIfNode.class);
+        asBlockWalker.visitIf(node);
+        //if (a) {\n  b++;\n} else {\n  c++;\n}
+        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
+        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
+        assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
+        assertMapping(node, 0, 16, 2, 2, 2, 7);   // else
+    }
+
+    @Test
+    public void testVisitIf_1c()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) { b++; } else if (b) { c++; } else { d++; }",
+                IIfNode.class);
+        asBlockWalker.visitIf(node);
+        //if (a) {\n  b++;\n} else if (b) {\n  c++;\n} else {\n  d++;\n}
+        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
+        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
+        assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
+        assertMapping(node, 0, 16, 2, 2, 2, 11);  // else if(
+        assertMapping(node, 0, 26, 2, 12, 2, 14); // )
+        assertMapping(node, 0, 37, 4, 2, 4, 7);   // else
+    }
+
+    @Test
+    public void testVisitIf_3()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) b++; else if (c) d++; else --e;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        //if (a)\n  b++;\nelse if (c)\n  d++;\nelse\n  --e;
+        assertMapping(node, 0, 0, 0, 0, 0, 4);     // if (
+        assertMapping(node, 0, 4, 0, 4, 0, 5);     // a
+        assertMapping(node, 0, 5, 0, 5, 0, 6);     // )
+        assertMapping(node, 0, 12, 2, 0, 2, 9);    // else if (
+        assertMapping(node, 0, 21, 2, 9, 2, 10);   // c
+        assertMapping(node, 0, 22, 2, 10, 2, 11);  // )
+        assertMapping(node, 0, 29, 4, 0, 4, 4);    // else
+    }
+
     protected IBackend createBackend()
     {
         return new FlexJSBackend();


[12/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

Posted by cd...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/antlr/org/apache/flex/compiler/internal/parsing/as/ASParser.g
----------------------------------------------------------------------
diff --cc compiler/src/main/antlr/org/apache/flex/compiler/internal/parsing/as/ASParser.g
index 34cb240,0000000..4d4936b
mode 100644,000000..100644
--- a/compiler/src/main/antlr/org/apache/flex/compiler/internal/parsing/as/ASParser.g
+++ b/compiler/src/main/antlr/org/apache/flex/compiler/internal/parsing/as/ASParser.g
@@@ -1,3223 -1,0 +1,3223 @@@
 +header
 +{
 +/*
 + *
 + *  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.parsing.as;
 +
 +/*
 + * This file is generated from ASTreeAssembler.g
 + * DO NOT MAKE EDITS DIRECTLY TO THIS FILE.  THEY WILL BE LOST WHEN THE FILE IS GENERATED AGAIN!!!
 + */
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import org.apache.flex.compiler.tree.as.*;
 +import org.apache.flex.compiler.workspaces.IWorkspace;
 +import org.apache.flex.compiler.parsing.IASToken;
 +import org.apache.flex.compiler.parsing.IASToken.ASTokenKind;
 +import org.apache.flex.compiler.tree.as.IContainerNode.ContainerType;
 +import org.apache.flex.compiler.tree.as.ILiteralNode.LiteralType;
 +import org.apache.flex.compiler.internal.tree.as.*;
 +import org.apache.flex.compiler.internal.tree.as.metadata.*;
 +import org.apache.flex.compiler.asdoc.IASParserASDocDelegate;
 +import org.apache.flex.compiler.constants.IASLanguageConstants;
 +import org.apache.flex.compiler.problems.ICompilerProblem;
 +import org.apache.flex.compiler.problems.*;
 +
 +}
 +
 +/**
 + * ActionScript3 parser grammar. It consumes ASTokens and produces IASNode AST.
 + * The number of tokens in a single syntactic predicate can not be greater than
 + * StreamingTokenBuffer.REWIND_BUFFER_SIZE.
 + *
 + * @see <a href="https://zerowing.corp.adobe.com/display/FlashPlayer/ActionScript+Language+Specification">ActionScript Language Syntax Specification</a>
 + */
 +class ASParser extends Parser("org.apache.flex.compiler.internal.parsing.as.BaseASParser");
 + 
 +options
 +{ 
 +	exportVocab = AS;
 +	defaultErrorHandler = false;
 +}	
 +
 +tokens
 +{	
 +	// These hidden tokens are matched by the raw tokenizer but are not sent to the parser.
 +	HIDDEN_TOKEN_COMMENT; 
 +	HIDDEN_TOKEN_SINGLE_LINE_COMMENT; 
 +	HIDDEN_TOKEN_STAR_ASSIGNMENT; 
 +	HIDDEN_TOKEN_BUILTIN_NS;
 +	HIDDEN_TOKEN_MULTI_LINE_COMMENT; 
 +	
 +	// These two tokens are used by code model's ASDoc tokenizer.
 +	TOKEN_ASDOC_TAG; 
 +	TOKEN_ASDOC_TEXT; 
 +	
 +	// These tokens are transformed from reserved words by StreamingASTokenizer.
 +	TOKEN_RESERVED_WORD_EACH; 
 +	TOKEN_RESERVED_WORD_CONFIG;
 +	TOKEN_KEYWORD_INCLUDE;
 +	TOKEN_RESERVED_WORD_GOTO; 
 +}
 +
 +{
 +
 +    /**
 +     * Construct an AS3 parser from a token buffer.
 +     */
 +    public ASParser(IWorkspace workspace, IRepairingTokenBuffer buffer) 
 +    {
 +    	super(workspace, buffer);
 +    	tokenNames = _tokenNames;
 +    }
 +
 +	/**
 +     * Construct an AS3 parser for parsing command line config args
 +     */
 +	public ASParser(IWorkspace workspace, IRepairingTokenBuffer buffer, boolean parsingProjectConfigVariables) 
 +    {
 +    	super(workspace, buffer, parsingProjectConfigVariables);
 +    	tokenNames = _tokenNames;
 +    }
 +}
 +
 +
 +/**
 + * Matches multiple directives. This layer is added to handle parsing error in directives.
 + */
 +fileLevelDirectives[ContainerNode c]
 +    :   (directive[c, NO_END_TOKEN])*
 +    ;
 +    exception catch [RecognitionException parserError] { handleParsingError(parserError);  }
 +
 +/**
 + * Matches a "directive" level input.
 + * The first couple of alternatives gated with semantic predicates are used to
 + * either disambiguate inputs, or to trap erroneous syntax.
 + */
 +directive[ContainerNode c, int endToken]
 +{
 +    final ASToken lt1 = LT(1);
 +    final ASToken lt2 = LT(2);
 +    final int la1 = LA(1);
 +    final int la2 = LA(2);
 +    final int la3 = LA(3);
 +    final int la4 = LA(4);
 +}
 +    :   { la1 == TOKEN_BLOCK_OPEN }? groupDirective[c, endToken]
 +    |   { la1 == TOKEN_RESERVED_WORD_NAMESPACE && la2 == TOKEN_PAREN_OPEN }? statement[c, endToken] 
 +    |   { la1 == TOKEN_IDENTIFIER && la2 == TOKEN_NAMESPACE_ANNOTATION && lt1.getLine() == lt2.getLine() }?
 +        // Skip over the user-defined namespace name and continue.
 +        nsT:TOKEN_IDENTIFIER attributedDefinition[c]
 +        { trapInvalidNamespaceAttribute((ASToken)nsT); }
 +    |   asDocComment
 +    |   importDirective[c]
 +    |   useNamespaceDirective[c] 
 +    |   { la1 == TOKEN_NAMESPACE_NAME && 
 +    	  la2 == TOKEN_OPERATOR_NS_QUALIFIER && 
 +    	  la3 == TOKEN_IDENTIFIER && 
 +    	  la4 == TOKEN_BLOCK_OPEN}?
 +        // ns::var { ... }
 +        groupDirectiveWithConfigVariable[c, endToken]
 +    |   { la1 == TOKEN_NAMESPACE_NAME &&
 +    	  la2 == TOKEN_OPERATOR_NS_QUALIFIER &&
 +    	  la3 == TOKEN_NAMESPACE_ANNOTATION }?
 +        // ns::var private var foo:int;
 +        attributedDefinition[c]  
 +    |   { la1 == TOKEN_NAMESPACE_NAME &&
 +    	  la2 == TOKEN_OPERATOR_NS_QUALIFIER }? 
 +        // "ns::var" or "ns::[x, y]"
 +        statement[c,endToken]
 +    |   { !isFunctionClosure() }? 
 +        attributedDefinition[c]  
 +    |   packageDirective[c]
 +    |   statement[c,endToken]
 +    |   configNamespace[c]  
 +    |   includeDirective
 +    // The following alternatives are error traps
 +    |   fT:TOKEN_KEYWORD_FINALLY   { reportUnexpectedTokenProblem((ASToken)fT); }
 +    |   cT:TOKEN_KEYWORD_CATCH     { reportUnexpectedTokenProblem((ASToken)cT); }
 +    ;
 +    exception catch [RecognitionException ex]
 +    { 
 +    	handleParsingError(ex, endToken);  
 +    	consumeUntilKeywordOrIdentifier(endToken); 
 +    }
 +	
 +/**
 + * Include processing is usually done in the lexer. However, this rule is added
 + * in order to support code model partitioner whose tokenizer is set to not
 + * "follow includes". In a normal AS3 compilation, the parser would never see
 + * the "include" token. 
 + */
 +includeDirective
 +    :   TOKEN_KEYWORD_INCLUDE TOKEN_LITERAL_STRING 
 +    ;
 +    
 +/**
 + * Matches an attributed definition. An "attribute" can be a namespace or a 
 + * modifier.
 + */
 +attributedDefinition[ContainerNode c]	
 +{ 
 +    List<INamespaceDecorationNode> namespaceAttributes = new ArrayList<INamespaceDecorationNode>();
 +    List<ModifierNode> modifiers = new ArrayList<ModifierNode>(); 
 +    INamespaceDecorationNode namespaceAttr = null;
 +    
 +    boolean enabled = isDefinitionEnabled(c);
 +    boolean eval = true;
 +}
 +    :   (eval=configConditionOfDefinition)?
 +        {
 +        	// A configuration condition variable can either be matched by
 +        	// the above rule or be transformed into a LiteralNode of boolean
 +        	// type. If either is evaluated to false, the definition is disabled.
 +        	enabled &= eval;
 +            if (!enabled)
 +			    c = new ContainerNode(); 
 +        }
 +        (attribute[modifiers, namespaceAttributes])* 
 +        {
 +            // Verify that at most one namespace attribute is matched.
 +            verifyNamespaceAttributes(namespaceAttributes);
 +            
 +            if (!namespaceAttributes.isEmpty())
 +               namespaceAttr = namespaceAttributes.get(0);
 +        }
 +        definition[c, namespaceAttr, modifiers]
 +    	exception catch [RecognitionException ex]
 +    	{ 
 +    		handleParsingError(ex);  
 +    	}
 +    ;
 +
 +/**
 + * Matches an attribute such as:
 + * - Modifiers: dynamic, final, native, override, static, virtual.
 + * - Namespace names.
 + * - Reserved namespace names: internal, private, public, protected.
 + *
 + * A definition can have at most one "namespace attribute".
 + * The matched attribute is added to the lists passed in as arguments.
 + */
 +attribute [List<ModifierNode> modifiers, List<INamespaceDecorationNode> namespaceAttributes] 
 +{
 +    ExpressionNodeBase namespaceNode = null; 
 +    ModifierNode modifierNode = null;
 +}
 +    :   modifierNode=modifierAttribute
 +        {   
 +            if (modifierNode != null)
 +                modifiers.add(modifierNode);
 +        }
 +    |   namespaceNode=namespaceModifier 
 +        {
 +            if (namespaceNode instanceof INamespaceDecorationNode)
 +                namespaceAttributes.add((INamespaceDecorationNode) namespaceNode); 
 +        }
 +    ;
 +	
 +	
 +/**
 + * Matches a definition of variable, function, namespace, class or interface.
 + */
 +definition[ContainerNode c, INamespaceDecorationNode ns, List<ModifierNode> modList]
 +    :   variableDefinition[c, ns, modList]
 +    |   functionDefinition[c, ns, modList]
 +    |   namespaceDefinition[c, ns, modList]
 +    |   classDefinition[c, ns, modList]
 +    |   interfaceDefinition[c, ns, modList]
 +    ;
 +	
 +/**
 + * Matches a "group" in a "group directive". 
 + * Entering a "Block" leaves the global context, but entering a "Group" doesn't.
 + */
 +groupDirective[ContainerNode c, int endToken]
 +{ 
 +    BlockNode b = new BlockNode(); 
 +    enterGroup();
 +}
 +    :   openT:TOKEN_BLOCK_OPEN      { b.startAfter(openT); }
 +        (directive[c, endToken])*
 +    	{ if(b.getChildCount() > 0) c.addItem(b); }
 +    	closeT:TOKEN_BLOCK_CLOSE    { b.endBefore(closeT); leaveGroup(); }
 +    ;
 +
 +/**
 + * Matches a config condition such as "CONFIG::debug". This rule only applies 
 + * to blocks gated with configuration variable.
 + *
 + * @return Evaluated result of the configuration variable.
 + */
 +configCondition returns [boolean result]
 +{
 +	result = false;
 +}
 +    :   ns:TOKEN_NAMESPACE_NAME op:TOKEN_OPERATOR_NS_QUALIFIER id:TOKEN_IDENTIFIER
 +        {
 +            result = evaluateConfigurationVariable(new NamespaceIdentifierNode((ASToken)ns), (ASToken) op, new IdentifierNode((ASToken)id));
 +        }
 +    ;
 +    
 +/**
 + * Similar to "configCondition", only that the token type after "::" is 
 + * "TOKEN_NAMESPACE_ANNOTATION". This rule only applies to "attributed 
 + * definitions".
 + */
 +configConditionOfDefinition returns [boolean result]
 +{
 +	result = false;
 +}
 +    :   ns:TOKEN_NAMESPACE_NAME op:TOKEN_OPERATOR_NS_QUALIFIER id:TOKEN_NAMESPACE_ANNOTATION
 +        {
 +            result = evaluateConfigurationVariable(new NamespaceIdentifierNode((ASToken)ns), (ASToken) op, new IdentifierNode((ASToken)id));
 +        }
 +    ;
 +    
 +/**
 + * Matches a group of directives gated with configuration variable.
 + *
 + *     CONFIG::debug {
 + *         trace("debugging code");
 + *     }
 + *
 + * If the configuration variable evaluates to false, the following block will
 + * not be added to the resulting AST.
 + */
 +groupDirectiveWithConfigVariable [ContainerNode c, int endToken]
 +{
 +    boolean b;
 +    ConfigConditionBlockNode block;
 +    final Token lt = LT(1);
 +}
 +    :   b=configCondition   
 +        {
 +        	block = new ConfigConditionBlockNode(b);
 +        	block.startBefore(lt);
 +        	c.addItem(block);
 +        }
 +        groupDirective[block, endToken]
 +    ;
 +	
 +/**
 + * Matches a statement.
 + *
 + * Note that the "SuperStatement" in ASL syntax spec is not explicitly defined.
 + * The "super" statements like <code>super(args);</code> are matched as regular
 + * "call" expressions.
 + */
 +statement[ContainerNode c, int exitCondition]
 +{
 +    final int la1 = LA(1);
 +    final int la2 = LA(2);
 +}
 +    :   breakOrContinueStatement[c]
 +    |   defaultXMLNamespaceStatement[c]
 +    |   gotoStatement[c]                 
 +    |   emptyStatement
 +    |   { la1 == TOKEN_IDENTIFIER && la2 == TOKEN_COLON }? labeledStatement[c, exitCondition]
 +    |   { la1 != TOKEN_SQUARE_OPEN && 
 +    	  la1 != TOKEN_OPERATOR_LESS_THAN && 
 +    	  la1 != TOKEN_BLOCK_OPEN }? expressionStatement[c]
 +    |   forStatement[c]
 +    |   ifStatement[c]
 +    |   meta[c]
 +    |   returnStatement[c]
 +    |   switchStatement[c]
 +    |   throwsStatement[c]
 +    |   tryStatement[c]
 +    |   whileStatement[c]
 +    |   doStatement[c]
 +    |   withStatement[c]
 +    ;
 +    exception catch [RecognitionException ex]
 +    { 
 +        handleParsingError(ex);  
 +        consumeUntilKeywordOrIdentifier(exitCondition); 
 +    }
 +    
 +/**
 + * Matches an "expression statement". The ASL syntax specification says the 
 + * lookahead can not be "[", "{" or "function". Legacy code requires that "<"
 + * be excluded as well.
 + */
 +expressionStatement[ContainerNode c]
 +{ 
 +    ExpressionNodeBase e = null; 
 +    
 +    if (LA(1) == TOKEN_KEYWORD_FUNCTION)
 +    {
 +        // Recover: continue parsing function as an anonymous function.
 +        logSyntaxError(LT(1));
 +    }
 +}
 +    :   e=expression
 +        {
 +            c.addItem(e);
 +            if (!matchOptionalSemicolon())
 +            {
 +                recoverFromExpressionStatementMissingSemicolon(e);
 +            }
 +        }
 +    ;
 +
 +/**
 + * <h1>From ASL syntax spec:</h1>
 + * <quote>
 + * InnerSubstatement is defined in the grammar for the sole purpose of 
 + * specifying side conditions that disambiguate various syntactic ambiguities 
 + * in a context-sensitive manner specified in Section 5.
 + * </quote>
 + *
 + * It is only used in "do statement" and "if statement" to loosen the following
 + * two cases allowed by AS3 but not by ECMA5.
 + *
 + * <code>
 + * do x++ while (x < 10);     // ES5 would require a ; after x++
 + * if (x > 10) x++ else y++;  // ES5 would require a ; after x++
 + * <code>
 + */
 +innerSubstatement[ContainerNode c]
 +    :   substatement[c] { afterInnerSubstatement(); }
 +    ;
 +    
 +/**
 + * Matches a sub-statement. 
 + */
 +substatement[ContainerNode c]
 +    :   (   { LA(1) != TOKEN_BLOCK_OPEN }? statement[c,NO_END_TOKEN]
 +        |   block[c] 
 +        |   variableDefinition[c, null, null]
 +        )
 +        {
 +        	if (c.getContainerType() == ContainerType.SYNTHESIZED)
 +            	c.setContainerType(ContainerType.IMPLICIT);
 +        }
 +    ;
 +
 +/**
 + * Matches a "labeled statement". For example:
 + *
 + *     innerLoop: x++;
 + *
 + */
 +labeledStatement[ContainerNode c, int exitCondition]
 +{
 +	LabeledStatementNode statementNode = null;
 +	ASToken offendingNSToken = null;
 +}
 +    :   labelT:TOKEN_IDENTIFIER TOKEN_COLON 
 +        { 
 +            final NonResolvingIdentifierNode labelNode = 
 +            	new NonResolvingIdentifierNode(
 +                    labelT != null ? labelT.getText() : "",
 +                    labelT);	
 +            statementNode = new LabeledStatementNode(labelNode);
 +            c.addItem(statementNode);
 +        }
 +        (   { LA(1) == TOKEN_RESERVED_WORD_NAMESPACE && LA(2) == TOKEN_IDENTIFIER }?
 +            { offendingNSToken = LT(1); }
 +            namespaceDefinition[c, null, null] 
 +            { trapInvalidSubstatement(offendingNSToken); }
 +        |   substatement[statementNode.getLabeledStatement()]
 +        )
 +    ;
 +		 	
 +/**
 + * Matches a block.
 + */
 +block[ContainerNode b]
 +    :   openT:TOKEN_BLOCK_OPEN      
 +        { 
 +        	b.startAfter(openT); 
 +            b.setContainerType(ContainerType.BRACES);
 +        }
 +        (directive[b, TOKEN_BLOCK_CLOSE])*
 +        closeT:TOKEN_BLOCK_CLOSE    { b.endBefore(closeT); }
 +    ;
 +    exception catch [RecognitionException ex]
 +    { 
 +        handleParsingError(ex);   
 +        consumeUntilKeywordOrIdentifier(TOKEN_BLOCK_CLOSE); 
 +        endContainerAtError(ex, b);
 +    }
 +
 +/**
 + * Matches an import directive.
 + *
 + *     import flash.display.Sprite;
 + *     import flash.events.*;
 + */
 +importDirective[ContainerNode c]
 +{  
 +	ExpressionNodeBase n = null; 
 +	ImportNode i = null; 
 +}
 +    :   importT:TOKEN_KEYWORD_IMPORT 
 +    	{
 +    		i = new ImportNode((ExpressionNodeBase) null);
 +    		i.startBefore(importT);
 +    		i.endAfter(importT); 
 +    		c.addItem(i);
 +    	}
 +    
 +        n=importName
 +    	{
 +     		if(n != null) {
 +     			i.setImportTarget(n);
 +     			i.setEnd(n.getEnd());
 +     			encounteredImport(i);
 +     		} 
 +     		else {
 +     			i.setImportTarget(new IdentifierNode(""));
 +     		}
 +     		matchOptionalSemicolon();
 +    	}
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches "use namespace ns" directive.
 + */
 +useNamespaceDirective[ContainerNode c]
 +{  
 +	ExpressionNodeBase n = null;
 +	UseNamespaceNode u = null;
 +}
 +    :   useT:TOKEN_KEYWORD_USE { u = new UseNamespaceNode(n); u.startBefore(useT); c.addItem(u); }
 +        nsT:TOKEN_RESERVED_WORD_NAMESPACE { u.endAfter(nsT); } n=restrictedName
 +    	{
 +    		u.setTargetNamespace(n);
 +    		u.setEnd(n.getEnd());
 +    		matchOptionalSemicolon();
 +    	}
 +    ;
 +    exception catch [RecognitionException ex] 
 +	{ 
 +		if (u != null && u.getTargetNamespace() == null) 
 +			u.setTargetNamespace(handleMissingIdentifier(ex));
 +		else 
 +			handleParsingError(ex);  
 +	}
 +
 +/**
 + * Matches an ASDoc block.
 + */		 
 +asDocComment 
 +    :   asdocT:TOKEN_ASDOC_COMMENT 
 +		{
 +			asDocDelegate.setCurrentASDocToken(asdocT);
 +		}
 +	;
 +
 +/**
 + * Matches a "modifier attribute" such as "final", "dynamic", "override", 
 + * "static" or "native".
 + */
 +modifierAttribute returns [ModifierNode modifierNode]
 +{ 
 +    modifierNode = null;
 +    final ASToken modifierT = LT(1); 
 +}
 +    :   (   TOKEN_MODIFIER_FINAL
 +        |   TOKEN_MODIFIER_DYNAMIC
 +        |   TOKEN_MODIFIER_OVERRIDE
 +        |   TOKEN_MODIFIER_STATIC
 +        |   TOKEN_MODIFIER_NATIVE
 +        |   TOKEN_MODIFIER_VIRTUAL
 +        )
 +        { modifierNode = new ModifierNode((ASToken) modifierT);	}
 +	;
 +	
 + 
 +/**
 + * Matches a namespace modifier on an "attributed definition".
 + */
 +namespaceModifier returns[ExpressionNodeBase n]
 +{ 
 +    n = null;
 +}
 +    :   nsPart1T:TOKEN_NAMESPACE_ANNOTATION
 +    	{ 
 +        	// If our text token is a member access, then build a normal 
 +        	// identifier. Otherwise, build a NS specific one.
 +        	
 +        	if (LA(1) == TOKEN_OPERATOR_MEMBER_ACCESS) 
 +        	{
 +                n = new IdentifierNode((ASToken)nsPart1T) ;
 +            }
 +            else
 +            {
 +                final NamespaceIdentifierNode nsNode = new NamespaceIdentifierNode((ASToken)nsPart1T); 
 +        		nsNode.setIsConfigNamespace(isConfigNamespace(nsNode));
 +        		n = nsNode;
 +        	}
 +    	}
 +    	(
 +            dotT:TOKEN_OPERATOR_MEMBER_ACCESS
 +            (
 +                nsNameT:TOKEN_NAMESPACE_ANNOTATION
 +        		{
 +        			IdentifierNode id = new IdentifierNode((ASToken)nsNameT);
 +        			n = new FullNameNode(n, (ASToken) dotT, id);
 +        		}
 +        	)
 +    	)*
 +    	{
 +            if (n instanceof FullNameNode) 
 +        	   n = new QualifiedNamespaceExpressionNode((FullNameNode)n);
 +    	}
 +    
 +    ;
 +
 +/**
 + * Matches a "metadata statement".
 + *
 + *     [ExcludeClass()]
 + *     [Bindable]
 + */
 +meta[ContainerNode c]
 +{
 +	ArrayLiteralNode al = new ArrayLiteralNode(); 
 +	final ASToken lt = LT(1);
 +}
 +    :   attributeT:TOKEN_ATTRIBUTE
 +        { 
 +        	// Note that a separate parser is invoked here for metadata.
 +            parseMetadata(attributeT, errors); 
 +            preCheckMetadata(attributeT, c);
 +    	} 
 +	|   { isIncompleteMetadataTagOnDefinition() }?
 +	    TOKEN_SQUARE_OPEN
 +	    // Error trap for "[" before a definition item.
 +	    { logSyntaxError(LT(1)); } 
 +    |   arrayInitializer[al]  
 +        // This is statement-level metadata.
 +        {
 +        	// Synthesize a MetaTagsNode to hold the metadata offsets.
 +            currentAttributes = new MetaTagsNode();
 +            currentAttributes.span(al, al);
 +            preCheckMetadata(lt, c);
 +        }
 +    ;
 + 	exception catch [RecognitionException ex] 
 + 	{ 
 + 		recoverFromMetadataTag(c, al); 
 +	}
 + 	
 +/**
 + * Matches a "config namespace foo" directive.
 + */
 +configNamespace[ContainerNode c]
 +	:   TOKEN_RESERVED_WORD_CONFIG TOKEN_RESERVED_WORD_NAMESPACE configN:TOKEN_IDENTIFIER 
 +		{
 +			NamespaceNode cNode = new ConfigNamespaceNode(new IdentifierNode((ASToken)configN));
 +			addConditionalCompilationNamespace(cNode);
 +            matchOptionalSemicolon();
 +		}
 +	    
 +	;
 +	exception catch [RecognitionException ex]
 +	{ handleParsingError(ex); }
 +
 +/**
 + * Matches a "package" block.
 + *
 + *     package mx.controls { ... }
 + *
 + */
 +packageDirective[ContainerNode c]
 +{ 
 +	PackageNode p = null; 
 +	ExpressionNodeBase name = null; 
 +	BlockNode b = null; 
 +}	
 +    :   packageT:TOKEN_KEYWORD_PACKAGE { enterPackage((ASToken)packageT); }
 +        (name=packageName)?
 +        {
 +        	p = new PackageNode(name != null ? name : IdentifierNode.createEmptyIdentifierNodeAfterToken(packageT), (ASToken)packageT);
 +        	p.startBefore(packageT);
 +        	c.addItem(p);
 +        	b = p.getScopedNode();
 +        }
 +        (   openT:TOKEN_BLOCK_OPEN { b.startAfter(openT); }
 +        	packageContents[b]
 +        )
 +        { leavePackage(); }
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); leavePackage();  }
 +	
 +/**
 + * Matches a package name such as:
 + *     org.apache.flex
 + *
 + * A Whitespace or LineTerminator is allowed around a . in a PackageName. 
 + * For example, the following is a syntactically valid
 + * <pre>
 + * package a .
 + *         b
 + * { }
 + * </pre>
 + * The resulting PackageName value is equivalent to a PackageName without any intervening Whitespace and LineTerminators.
 + */	
 +packageName returns [ExpressionNodeBase n]
 +{ 
 +	n = null; 
 +	ExpressionNodeBase e = null; 
 +}
 + 	:	n=identifier 
 +		(options{greedy=true;}: { LA(2) != TOKEN_OPERATOR_STAR }?
 +			dotT:TOKEN_OPERATOR_MEMBER_ACCESS 
 +			{ 
 +				n = new FullNameNode(n, (ASToken) dotT, null); 
 +			} 
 +			e=identifier
 +			{ 
 +				((FullNameNode)n).setRightOperandNode(e); 
 +			}
 +		)*
 +	;
 +	exception catch [RecognitionException ex] { return handleMissingIdentifier(ex, n); }	
 +	
 +/**
 + * Matches contents in a package block.
 + */
 +packageContents[ContainerNode b]
 +    :   (directive[b, TOKEN_BLOCK_CLOSE])* 
 +    	closeT:TOKEN_BLOCK_CLOSE { b.endBefore(closeT); }
 +    ;
 +    exception catch [RecognitionException ex]
 +	{
 +        if(handleParsingError(ex)) 
 +        {
 +        	//attempt to recover from the error so we can keep parsing within the block
 +            packageContents(b); 
 +        } 
 +        else 
 +        {
 +            endContainerAtError(ex, b); 
 +        } 
 +    }
 +
 +/**
 + * Matches a namespace definition.
 + *
 + *     namespace ns1;
 + */
 +namespaceDefinition[ContainerNode c, INamespaceDecorationNode namespace, List<ModifierNode> modList]
 +{
 +	NamespaceNode n = null; 
 +	IdentifierNode id = null; 
 +	ExpressionNodeBase v = null; 
 +}
 +	:   nsT:TOKEN_RESERVED_WORD_NAMESPACE id=identifier
 +		{
 +			n = new NamespaceNode(id);
 +			n.startBefore(nsT);
 +			storeDecorations(n, c, namespace, modList);
 +            checkNamespaceDefinition(n);
 +		}
 +		(initializer[n])?
 +    	{ 
 +			c.addItem(n);
 +    		matchOptionalSemicolon(); 
 +    	}
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }	
 +
 +/**
 + * Matches an interface definition.
 + *
 + *     interface IFoo extends IBar {...}
 + */
 +interfaceDefinition[ContainerNode c,  INamespaceDecorationNode namespace, List<ModifierNode> modList]
 +{ 	
 +	InterfaceNode interfaceNode = null; 
 +	IdentifierNode intName = null; 
 +	ExpressionNodeBase baseInterfaceName = null; 
 +	BlockNode b = null; 
 +    enterInterfaceDefinition(LT(1));
 +} 
 +    :   intT:TOKEN_KEYWORD_INTERFACE intName=identifier 
 +		{
 +			interfaceNode = new InterfaceNode(intName);
 +			interfaceNode.setInterfaceKeyword((IASToken)intT);
 +			storeDecorations(interfaceNode, c, namespace, modList);
 +			c.addItem(interfaceNode);
 +			
 +			// Recover from invalid interface name.
 +			final int la1 = LA(1);
 +			if (la1 != TOKEN_RESERVED_WORD_EXTENDS && la1 != TOKEN_BLOCK_OPEN)
 +			{
 +			    addProblem(new SyntaxProblem(LT(1)));
 +			    consumeUntilKeywordOr(TOKEN_BLOCK_OPEN);
 +			}
 +		}
 +		
 +		(	extendsT:TOKEN_RESERVED_WORD_EXTENDS
 +			{ interfaceNode.setExtendsKeyword((ASToken)extendsT); }
 +			(	baseInterfaceName=restrictedName
 +				{ 
 +					interfaceNode.addBaseInterface(baseInterfaceName);  
 +					interfaceNode.setEnd(baseInterfaceName.getEnd()); 
 +				}
 + 
 +				(	commaT:TOKEN_COMMA 
 +					{ interfaceNode.endAfter(commaT); }
 +					(	baseInterfaceName=restrictedName
 +						{ 
 +							interfaceNode.addBaseInterface(baseInterfaceName); 
 +							interfaceNode.setEnd(baseInterfaceName.getEnd()); 
 +						}
 +					)
 +				)*
 +			)
 +		)?
 + 
 +		{ 
 + 		  	b = interfaceNode.getScopedNode();
 + 		}
 + 	
 + 		openT:TOKEN_BLOCK_OPEN
 +			{ b.startAfter(openT); }
 +		classOrInterfaceBlock[b]
 + 	;
 + 	exception catch [RecognitionException ex] { handleParsingError(ex);  }
 + 
 +/**
 + * Matches a class definition. For example:
 + *
 + *     class Player extends my_ns::GameObject implements IPlayer { ... }
 + *
 + */
 +classDefinition [ContainerNode c, INamespaceDecorationNode namespace, List<ModifierNode> modList]
 +{ 	
 +    IdentifierNode className = null; 
 +    ExpressionNodeBase superName = null; 
 +    ExpressionNodeBase interfaceName = null;
 +    ClassNode classNode = null;
 +    disableSemicolonInsertion();
 +    enterClassDefinition(LT(1));
 +}
 +    :   classT:TOKEN_KEYWORD_CLASS className=identifier
 +        {
 +            // When class name is empty, it is a synthesized IdentifierNode
 +            // created by the error recovery logic in "identifier" rule.
 +            // In such case, we fast-forward the token stream to the next
 +            // keyword to recover.
 +            if (className.getName().isEmpty())
 +            {
 +                // If the parser recover from "extends", "implements" or "{", 
 +                // we are could continue parsing the class definition, because
 +                // these tokens are the "follow set" of a class name token.
 +                // Otherwise, the next keyword is still a good starting point.
 +                consumeUntilKeywordOr(TOKEN_BLOCK_OPEN);
 +            }
 +            
 +            insideClass = true;
 +            classNode = new ClassNode(className);
 +            classNode.setSourcePath(((IASToken)classT).getSourcePath());
 +            classNode.setClassKeyword((IASToken)classT);
 +            storeDecorations(classNode, c, namespace, modList);
 +            c.addItem(classNode);
 +        }
 +         
 +        (   extendsT:TOKEN_RESERVED_WORD_EXTENDS 
 +            { classNode.setExtendsKeyword((ASToken)extendsT); }
 +            // The rule for super type should be "restrictedName". However, in
 +            // order to trap errors like "class Foo extends Vector.<T>", the
 +            // parser has to allow parameterized type as super name. It's up to
 +            // semantic analysis to report this problem.
 +            superName=type 
 +        	{ 
 +        		classNode.setBaseClass(superName); 
 +        		classNode.setEnd(superName.getEnd()); 
 +        	}
 +            exception catch [RecognitionException ex] { handleParsingError(ex); }
 +        )?
 + 
 +        (   impT: TOKEN_RESERVED_WORD_IMPLEMENTS 
 +            { classNode.setImplementsKeyword((ASToken)impT); }
 +            (   interfaceName=restrictedName
 +                { 
 +                    classNode.addInterface(interfaceName);
 +                    classNode.setEnd(interfaceName.getEnd());
 +                }
 +                (   commaT:TOKEN_COMMA 
 +                    { classNode.endAfter(commaT); }
 +                    interfaceName=restrictedName
 +                    { 
 +                        classNode.addInterface(interfaceName); 
 +                        classNode.setEnd(interfaceName.getEnd()); 
 +                    }
 +                )*
 +                exception catch [RecognitionException ex] { handleParsingError(ex); }
 +            )
 +            exception catch [RecognitionException ex] { handleParsingError(ex);  }
 +        )?
 +		
 +        openT:TOKEN_BLOCK_OPEN
 +        { classNode.getScopedNode().startAfter(openT); }
 +        classOrInterfaceBlock[classNode.getScopedNode()]
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex);  }
 +
 +/**
 + * Matches the content block of a class definition or an interface definition.
 + */
 +classOrInterfaceBlock[BlockNode b]
 + 	{ enableSemicolonInsertion(); }
 +	
 +	:   (directive[b, TOKEN_BLOCK_CLOSE])*
 +		closeT:TOKEN_BLOCK_CLOSE
 +		{ b.endBefore(closeT); }
 +	;
 +	exception catch [RecognitionException ex] 
 +	{ 
 +		if(handleParsingError(ex))  {
 +			classOrInterfaceBlock(b); //attempt to retry
 +		} else {
 +			endContainerAtError(ex, b); 
 +		}
 +	}
 +	
 +/**
 + * Matches an anonymous function (function closure).
 + */
 +functionExpression returns [FunctionObjectNode n]
 +{ 
 +	n = null; 
 +	BlockNode b = null; 
 +	FunctionNode f = null; 
 +	IdentifierNode name=null; 
 +	ContainerNode p = null;
 +}
 + 	:   functionT:TOKEN_KEYWORD_FUNCTION 
 + 	
 + 		// optional function name
 + 		(name=identifier)?
 +		{
 +			if(name == null) 
 +				name = IdentifierNode.createEmptyIdentifierNodeAfterToken(functionT);
 +			f = new FunctionNode((ASToken)functionT, name);
 +			n = new FunctionObjectNode(f);
 +			f.startBefore(functionT);
 +			n.startBefore(functionT);
 +			b = f.getScopedNode();
 +			disableSemicolonInsertion();
 +		}
 + 
 +        // function signature
 +    	lpT:TOKEN_PAREN_OPEN
 +		{
 +			p = f.getParametersContainerNode();
 +			p.startBefore(lpT);
 +		}
 +    	formalParameters[p]
 +    	rpT:TOKEN_PAREN_CLOSE
 + 		{ p.endAfter(rpT); }
 +    	(resultType[f])?
 +     	{ enableSemicolonInsertion(); }	
 +
 +		// non-optional function body     		
 +     	lbT:TOKEN_BLOCK_OPEN
 +		{ b.startAfter(lbT);}
 +     	functionBlock[f, (ASToken)lbT]		
 + 	;
 + 	exception catch [RecognitionException ex] { handleParsingError(ex);  }
 +
 +/**
 + * Matches a function block, excluding the open "{" but including the closing "}".
 + */
 +functionBlock[FunctionNode f, ASToken openT]
 +{ 
 +    final BlockNode b = f.getScopedNode();
 +    b.setContainerType(IContainerNode.ContainerType.BRACES); 
 +    skipFunctionBody(f, openT);
 +}
 +	:   (directive[b, TOKEN_BLOCK_CLOSE])*
 +        rbT:TOKEN_BLOCK_CLOSE
 +	  	{ b.endBefore(rbT); }
 +	;
 +  	exception catch [RecognitionException ex] 
 +	{ 
 +		IASToken prev = buffer.previous();
 +        if (prev.getType() != ASTokenTypes.EOF)
 +            b.endAfter(prev);
 +        else
 +            b.setEnd(b.getStart());
 +		if(handleParsingError(ex))  {
 +			functionBlock(f, openT); //attempt to retry
 +		} 
 +	}
 +
 +/**
 + * Matches an optional function body. It can either be a "block" or a 
 + * "semicolon".
 + */
 +optionalFunctionBody [FunctionNode f]
 +{
 +    BlockNode blockNode = f.getScopedNode();
 +    enableSemicolonInsertion();
 +}
 +    :   { LA(1) == TOKEN_BLOCK_OPEN }? lbT:TOKEN_BLOCK_OPEN 
 +        { blockNode.startAfter(lbT); } 
 +        functionBlock[f, (ASToken)lbT]   
 +    |   { buffer.matchOptionalSemicolon() }? // Matches a function without body.
 +    |   {
 +            final Token lt = LT(1);
 +            blockNode.startBefore(lt);
 +            blockNode.endBefore(lt);
 +
 +            // Report missing left-curly problem if there's no other syntax
 +            // problems in the function definition.
 +            reportFunctionBodyMissingLeftBraceProblem();
 +        } 
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches a function definition. For example:
 + *
 + *     private function myFunction(name:String) : void
 + *     {
 + *         return;
 + *     }
 + *
 + */	
 +functionDefinition[ContainerNode c, INamespaceDecorationNode namespace, List<ModifierNode> modList]
 +{  
 +	IdentifierNode name=null; 
 +    disableSemicolonInsertion();
 +}
 +	:   (   functionT:TOKEN_KEYWORD_FUNCTION 
 +	
 +			// optional accessors:
 +			// Although "get" and "set" can be identifiers as well, here
 +			// they can only be the reserved words, unless it's a function
 +			// called "get()" or "set()". As a result, the parser
 +			// needs to match it in a "greedy" fashion.
 +	        (options{greedy=true;}:
 +	        	{ LA(2) != TOKEN_PAREN_OPEN}? getT:TOKEN_RESERVED_WORD_GET
 +        	|   { LA(2) != TOKEN_PAREN_OPEN}? setT:TOKEN_RESERVED_WORD_SET
 +        	)? 
 +        	
 +        	// non-optional function name:
 +	        name=identifier
 +			//we need to be able to keep going in case we are in the processing of typing a function name
 +			exception catch [RecognitionException ex] { name = handleMissingIdentifier(ex); }
 +		)
 +		{
 +			final FunctionNode n ;
 +			if (getT != null)
 +				n = new GetterNode((ASToken)functionT, (ASToken)getT, name);
 +			else if (setT != null)
 +				n = new SetterNode((ASToken)functionT, (ASToken)setT, name);
 +			else
 +				n = new FunctionNode((ASToken)functionT, name);
 + 
 +			storeDecorations(n, c, namespace, modList);
 +			c.addItem(n);
 +		}
 +		
 +		// function signature:
 +		lpT:TOKEN_PAREN_OPEN
 +		{
 +			final ContainerNode parameters = n.getParametersContainerNode();
 +			parameters.startBefore(lpT);
 + 		}
 +     	formalParameters[parameters]	
 +     	(	rpT:TOKEN_PAREN_CLOSE 
 +     		{ parameters.endAfter(rpT); }
 +     		// error recovery for typing in-progress function definitions
 +     		exception catch [RecognitionException ex] { handleParsingError(ex); }
 +     	)
 +     	(resultType[n])?
 +     	
 +     	optionalFunctionBody[n]
 + 	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches the parameters of a function definition signature (excluding the parenthesis).
 + * 
 + *     arg1:int, arg2:String
 + */
 +formalParameters[ContainerNode c]
 +	: (formal[c] (TOKEN_COMMA formal[c])*)?
 +	;
 +	exception catch [RecognitionException ex] {handleParsingError(ex); }
 +
 +/**
 + * Matches a single parameter in a function definition.
 + */
 +formal[ContainerNode c]
 +	{ ParameterNode p = null; }
 +	
 +	:(p=restParameter | p=parameter)
 +		{ if (p != null) c.addItem(p); }
 +	;
 +
 +/**
 + * Matches the "rest parameters" in a function definition.
 + *
 + *     ...args
 + */
 +restParameter returns [ParameterNode p]
 +	{ p = null; }
 +	
 +	: e:TOKEN_ELLIPSIS p=parameter
 +		{
 +			if (p != null){
 +				// ??? following is an override on default type-specification
 +				// ??? and should be pulled soon as that gets resolved.
 +				if (p.getTypeNode() == null){
 +					p.span(e);
 +				}
 +				p.setIsRestParameter(true);
 +			}
 +		}
 +	;
 +	
 +/**
 + * Matches a parameter in a function definition.
 + */
 +parameter returns [ParameterNode p]
 +{ 
 +	p = null; 
 +	ASToken t = null;
 +	IdentifierNode name = null; 
 +}
 +	:   (   t=varOrConst 
 +    		{
 +    			// const allowed here, var is not...log error, keep going
 +    			if (t.getType() == TOKEN_KEYWORD_VAR) 
 +    				handleParsingError(new RecognitionException()); 
 +    		}
 +        )? 
 +	
 +        name=identifier
 +		{ 
 +			p = new ParameterNode(name); 
 +			if (t != null && t.getType() == TOKEN_KEYWORD_CONST)
 +				p.setKeyword(t);
 +		}
 +		
 +        (resultType[p])?
 +        (initializer[p])?	 
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches keyword "var" or keyword "const".
 + */
 +varOrConst returns[ASToken token]
 +{ 
 +	token = LT(1); 
 +}
 +	:   TOKEN_KEYWORD_VAR 
 +	|   TOKEN_KEYWORD_CONST
 +	;
 +	
 +/**
 + * Matches a result type: either a "void" keyword or a restricted name.
 + *
 + *     :void
 + *     :String
 + *     :int
 + *
 + */
 +resultType [BaseTypedDefinitionNode result]
 +{ 
 +    ExpressionNodeBase t = null; 
 +}
 +    :   colon:TOKEN_COLON 
 +        (   ( t=voidLiteral | t=type )
 +        	exception catch [RecognitionException ex] 
 +            { t = handleMissingIdentifier(ex); }
 +        )    
 +        { 
 +            if(t.getStart() == -1) 
 +                t.startAfter(colon);
 +            	
 +            if (t.getEnd() == -1) 
 +                t.endAfter(colon);
 +            	
 +            result.endAfter(colon);
 +            result.setType((ASToken) colon, t); 
 +        }
 +    ;
 + 	
 +/**
 + * Matches an initializer in a variable/constant definition.
 + */
 +initializer [IInitializableDefinitionNode v]
 +{
 +	ExpressionNodeBase e = null; 
 +}
 +  	:   assignT:TOKEN_OPERATOR_ASSIGNMENT 
 +        e=assignmentRightValue
 + 		{ v.setAssignedValue((IASToken) assignT, e); }
 + 	;	
 + 	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 + 	
 +/**
 + * Matches a variable/constant definition.
 + */
 +variableDefinition[ContainerNode c, INamespaceDecorationNode namespace, List<ModifierNode> modList]
 +{
 +	VariableNode v = null;
 +	ChainedVariableNode v2 = null;
 +	ASToken tok = null;
 +	asDocDelegate.beforeVariable();
 +}
 + 	
 +	:   tok=varOrConst v=singleVariable[(ASToken)tok, namespace]
 +		{
 +			asDocDelegate.afterVariable();	
 +			storeVariableDecorations(v, c, namespace, modList);
 +			if(v instanceof ConfigConstNode) {
 +				addConfigConstNode((ConfigConstNode)v);
 +			} else {
 +				c.addItem(v);
 +			}
 +		}
 +    	// don't allow chain after a config
 +    	(   {!(v instanceof ConfigConstNode)}? 
 +    	    TOKEN_COMMA v2=chainedVariable[c]
 +    		{
 +    		 	if(v2 != null)
 +                {
 +                    v.addChainedVariableNode(v2);
 +                    storeEmbedDecoration(v2, v.getMetaTags());
 +                }
 +    		}
 +    		exception catch [RecognitionException ex] { handleParsingError(ex); }
 +    	)*
 +    	{ matchOptionalSemicolon(); setAllowErrorsInContext(true); }
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); setAllowErrorsInContext(true); }
 +
 +/**
 + * Matches a single variable/constant definition.
 + */
 +singleVariable[IASToken keyword, INamespaceDecorationNode namespace] returns [VariableNode v]
 +{ 
 +	v = null; 
 +	IdentifierNode name = null; 
 +}
 +	:   name=identifier
 +		{ 
 +			if(namespaceIsConfigNamespace(namespace)) {
 +				v = new ConfigConstNode(name);
 +			} else {
 +				v = new VariableNode(name);
 +			}
 +			v.setKeyword(keyword);
 +			v.setIsConst(keyword.getType() == TOKEN_KEYWORD_CONST);
 +			if(name.getStart() == -1) {
 +				name.startAfter(keyword);
 +				name.endAfter(keyword);
 +			}
 +		}
 +		
 +		(resultType[v])? 
 +		(initializer[v])?
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +	
 +/**
 + * Matches a chained variable/constant definition.
 + */     
 +chainedVariable[ContainerNode c] returns [ChainedVariableNode v]
 +{
 +	 v = null; 
 +	 IdentifierNode name = null; 
 +}
 +	:   name=identifier
 +		{ v = new ChainedVariableNode(name); }
 +		
 +		(resultType[v])?
 +		(initializer[v])?
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +	
 +/**
 + * Matches variable definitions in a for loop.
 + */
 +variableDefExpression returns[NodeBase v]
 +{ 
 +	v = null; 
 +	ContainerNode c = null; 
 +	NodeBase v1 = null; 
 +	ASToken varT = null;
 +} 
 +	:   varT=varOrConst v=singleVariableDefExpression[varT, varT.getType() == TOKEN_KEYWORD_CONST]
 +		(   TOKEN_COMMA v1=singleVariableDefExpression[null, varT.getType() == TOKEN_KEYWORD_CONST]
 +			{
 +				if (c == null) {
 +					c = new ContainerNode();
 +					c.setStart(v.getStart());
 +					c.addItem(v);
 +					v = c;
 +				}
 +				c.addItem(v1);
 +				c.setEnd(v1.getEnd());
 +			}
 +		)*
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex);  }
 +		
 +/**
 + * Matches a single variable definition in a for loop.
 + */
 +singleVariableDefExpression[ASToken varToken, boolean isConst] returns [ExpressionNodeBase n]
 +{
 +	n = null;
 +	VariableNode variable = null;
 +	IdentifierNode varName = null; 
 +	ExpressionNodeBase value = null; 
 +}
 +	:   varName=identifier
 +		{ 
 +			variable = new VariableNode(varName);
 +			if(varToken != null)
 +				variable.setKeyword(varToken);
 +			variable.setIsConst(isConst);
 +			n = new VariableExpressionNode(variable);
 +		}
 +		
 +    	(resultType[variable])?
 +    		
 +    	(initializer[variable])?
 +	;
 +
 +/**
 + * Matches a default XML namespace statement. For example:
 + * 
 + *    default xml namespace = "domain";
 + *
 + */
 +defaultXMLNamespaceStatement[ContainerNode c]
 +	{ ExpressionNodeBase e = null; }
 +	
 +	: defT:TOKEN_DIRECTIVE_DEFAULT_XML TOKEN_OPERATOR_ASSIGNMENT e=assignmentExpression
 +		{ 
 +			DefaultXMLNamespaceNode n = new DefaultXMLNamespaceNode(new KeywordNode((IASToken)defT));
 +			c.addItem(n);
 +			n.setExpressionNode(e); 
 +			matchOptionalSemicolon();
 +		}
 +	;
 +
 +/**
 + * Matches an expression in a pair of parenthesis. It's usually used as a
 + * condition expression in {@code if (...)}, {@code while (...)}, etc.
 + *
 + *     (....)
 + */
 +statementParenExpression returns [ExpressionNodeBase e]
 +{
 +	e = null; 
 +}
 +	:   TOKEN_PAREN_OPEN     { disableSemicolonInsertion(); }
 +		e=expression 
 +	    TOKEN_PAREN_CLOSE    { enableSemicolonInsertion(); }
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); enableSemicolonInsertion(); }
 +	
 +		
 +/**
 + * Matches an empty statement which is an explicit semicolon.
 + */
 +emptyStatement
 + 	:   TOKEN_SEMICOLON
 + 	;
 +
 +/**
 + * Matches a "return" statement.
 + */
 +returnStatement[ContainerNode c]
 +{ 
 +	ExpressionNodeBase n = null; 
 +	ExpressionNodeBase e = null;
 +}
 +	:   returnT:TOKEN_KEYWORD_RETURN 
 +		{
 +			n = new ReturnNode((ASToken)returnT);
 +			c.addItem(n);
 +			afterRestrictedToken((ASToken)returnT);
 +		}
 +		
 +		e=optExpression
 +		{ 
 +			((ReturnNode)n).setStatementExpression(e);
 +		}
 +	   { matchOptionalSemicolon(); }
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches a "throw" statement.
 + */
 +throwsStatement[ContainerNode c]
 +{ 
 +	ExpressionNodeBase n = null; 
 +	ExpressionNodeBase e = null;
 +}
 +	:   throwT:TOKEN_KEYWORD_THROW
 +		{
 +			n = new ThrowNode((ASToken)throwT);
 +			c.addItem(n);
 +			afterRestrictedToken((ASToken)throwT);
 +		}
 +	
 +		(   e=expression
 +			{ 
 +				((ThrowNode)n).setStatementExpression(e); 
 +			}
 +			exception catch [RecognitionException ex] { handleParsingError(ex); }
 +		)
 +	   { matchOptionalSemicolon(); }
 +	;
 +	
 +/**
 + * Matches a "for loop" statement.
 + */
 +forStatement[ContainerNode c]
 +{ 
 +    ForLoopNode node = null; 
 +    ContainerNode forContainer = null; 
 +    BlockNode b = null; 
 +    NodeBase fi = null; 
 +    ExpressionNodeBase e = null; 
 +    BinaryOperatorNodeBase inNode = null;
 +}
 +    :   forKeyword:TOKEN_KEYWORD_FOR lparenT:TOKEN_PAREN_OPEN
 +        { 
 +            node = new ForLoopNode((ASToken)forKeyword); 
 +            c.addItem(node);
 +            forContainer = node.getConditionalsContainerNode();
 +            b = node.getContentsNode();
 +            forContainer.startAfter(lparenT); 
 +        }
 +        
 +        { 
 +            expressionMode = ExpressionMode.noIn;
 +        }
 +        fi=forInitializer
 +        {
 +            expressionMode = ExpressionMode.normal;
 +        }
 +        
 +        (   TOKEN_SEMICOLON           { forContainer.addItem(fi); }
 +            forCondition[forContainer] 
 +            TOKEN_SEMICOLON 
 +            forStep[forContainer]
 +        |   in:TOKEN_KEYWORD_IN 
 +            {
 +                final ExpressionNodeBase leftOfIn;
 +                if (fi instanceof ExpressionNodeBase)
 +                {
 +                    leftOfIn = (ExpressionNodeBase) fi;
 +                }
 +                else
 +                {
 +                    // for...in doesn't allow multiple variable definition in the initializer clause
 +                    addProblem(new InvalidForInInitializerProblem(node));
 +                    if (fi instanceof ContainerNode &&
 +                        fi.getChildCount() > 0 &&
 +                        ((ContainerNode)fi).getChild(0) instanceof ExpressionNodeBase)
 +                    {
 +                        // Recover by taking the first variable initializer and
 +                        // drop the rest.
 +                        leftOfIn = (ExpressionNodeBase)((ContainerNode)fi).getChild(0);
 +                    }
 +                    else
 +                    {
 +                        // No valid variable initializer found: recover by adding
 +                        // an empty identifier node.
 +                        leftOfIn = IdentifierNode.createEmptyIdentifierNodeAfterToken((ASToken)lparenT);
 +                    }
 +                }
 +                inNode = BinaryOperatorNodeBase.create((ASToken)in, leftOfIn, null);
 +                forContainer.addItem(inNode);
 +            }
 +            e=optExpression
 +            { inNode.setRightOperandNode(e); }
 +        )?  // Make optional for error handling.
 +        
 +        {
 +            if (forContainer.getChildCount() == 0 && fi != null)
 +                forContainer.addItem(fi);
 +        }
 +        
 +        (   rparenT:TOKEN_PAREN_CLOSE
 +            { 
 +                forContainer.endBefore(rparenT); 
 +            }
 +            exception catch [RecognitionException ex] { handleParsingError(ex); }
 +        )
 +        substatement[b] 
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches the "initializer" part in a for loop.
 + */    
 +forInitializer returns [NodeBase n]
 +{ 
 +	n = null; 
 +}
 +    :   n=variableDefExpression              								
 +    |   n=optExpression
 +    ;
 +    exception catch [RecognitionException ex] {handleParsingError(ex);  }
 +
 +/**
 + * Matches the "condition" part in a for loop.
 + */
 +forCondition[ContainerNode c]
 +{ 
 +	ExpressionNodeBase e = null; 
 +}
 +	:   e=optExpression
 +		{if (e != null) c.addItem(e);}
 +	;
 + 	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 +
 +/**
 + * Matches the "step" part in a for loop.
 + */
 +forStep[ContainerNode c]
 +{ 
 +	ExpressionNodeBase e = null; 
 +}
 +	:    e=optExpression	
 +		{if (e != null) c.addItem(e);}
 +	;
 + 	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 + 
 +/**
 + * Matches a "do...while" statement.
 + */
 +doStatement[ContainerNode c] 
 +{ 
 +	DoWhileLoopNode n = null; 
 +    ExpressionNodeBase e = null; 
 +    BlockNode b = null; 
 +}
 + 	:   doT:TOKEN_KEYWORD_DO
 + 		{
 + 			n = new DoWhileLoopNode((ASToken)doT);
 + 			c.addItem(n);
 + 			b = n.getContentsNode();
 + 		}
 + 		
 +        innerSubstatement[b]
 +        
 +        TOKEN_KEYWORD_WHILE e=statementParenExpression
 + 	 	{ 
 + 	 		n.setConditionalExpression(e); 	
 +	        matchOptionalSemicolon(); 
 +        }
 + 	;
 + 	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 + 	
 +/**
 + * Matches a "while" loop statement.
 + * 
 + *     while (x > 1) { x--; }
 + */
 +whileStatement[ContainerNode c] 
 +{ 
 +	WhileLoopNode n = null; 
 +	ExpressionNodeBase e = null; 
 +	BlockNode b = null; 
 +}
 + 	:   whileT:TOKEN_KEYWORD_WHILE e=statementParenExpression	
 + 		{
 + 			n = new WhileLoopNode((ASToken)whileT);
 + 			n.setConditionalExpression(e);
 + 			c.addItem(n); 
 + 			b = n.getContentsNode();
 + 		}
 + 	
 + 	    substatement[b]
 + 	;
 + 	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 + 	
 + 	
 +/**
 + * Matches a "break statement" or a "continue statement". For example:
 + *
 + *    break;
 + *    break innerLoop;
 + *    continue;
 + *    continue outerLoop;
 + *
 + */
 +breakOrContinueStatement[ContainerNode c]
 +{ 
 +    IdentifierNode id = null; 
 +    IterationFlowNode n = null; 
 +    final ASToken t = LT(1);
 +}
 +    :   ( TOKEN_KEYWORD_CONTINUE | TOKEN_KEYWORD_BREAK ) 
 +    	{ 
 +    		n = new IterationFlowNode(t); 
 +    		c.addItem(n); 
 +    		afterRestrictedToken(t);
 +    	}
 +    	
 +    	// "greedy" mode is required to associate the following ID with the flow control.
 +    	(options{greedy=true;}: 
 +    	   id=identifier 
 +    	   { n.setLabel(id); }	
 +	    )?
 +    	{ matchOptionalSemicolon(); }
 +    ;
 +    exception catch [RecognitionException ex] {handleParsingError(ex); }
 + 	
 +/**
 + * Matches a "goto" statement.
 + */
 +gotoStatement[ContainerNode c]
 +{ 
 +	IdentifierNode id = null; 
 +	IterationFlowNode n = null; 
 +	final ASToken t = LT(1);
 +}
 +    :   TOKEN_RESERVED_WORD_GOTO id=identifier
 +        {
 +    		n = new IterationFlowNode(t); 
 +    		c.addItem(n);
 +    		n.setLabel(id);
 +    		matchOptionalSemicolon();
 +        }
 +    ;
 + 	exception catch [RecognitionException ex] { handleParsingError(ex); }
 + 	
 +/**
 + * Matches a "with" statement.
 + */
 +withStatement[ContainerNode c]
 +{
 +	WithNode n = null; 
 +	ExpressionNodeBase e = null; 
 +	BlockNode b = null; 
 +}
 +	:   withT:TOKEN_KEYWORD_WITH e=statementParenExpression
 +		{ 
 +			n = new WithNode((ASToken)withT); 
 +			n.setConditionalExpression(e);
 +			c.addItem(n);
 +			b = n.getContentsNode(); 
 +		}
 +    	substatement[b]
 +	;
 +
 +/**
 + * Matches a "try...catch...finally" statement.
 + */
 +tryStatement[ContainerNode c] 
 +{ 
 +	TryNode n = null; 
 +	BlockNode b = null; 
 +}
 + 	:   tryT:TOKEN_KEYWORD_TRY
 + 		{
 + 			n = new TryNode((ASToken)tryT);
 + 			b = n.getContentsNode();
 + 			c.addItem(n);
 + 		}
 + 		
 +        block[b]
 +        
 +        (   options { greedy=true;}: 
 +            catchBlock[n]
 +        )*
 +
 +        (   options { greedy=true;}: 
 +            finallyT:TOKEN_KEYWORD_FINALLY
 +            {
 +            	TerminalNode t = new TerminalNode((ASToken)finallyT);
 +            	n.addFinallyBlock(t);
 +            	b = t.getContentsNode();
 +            }
 +            block[b]
 +        )?
 + 	;  
 +
 +/**
 + * Matches the "catch" block in a "try" statement.
 + */
 +catchBlock[TryNode tryNode]
 +{ 
 +	CatchNode n = null; 
 +	ParameterNode arg = null; 
 +	BlockNode b = null; 
 +}
 +	:   catchT:TOKEN_KEYWORD_CATCH TOKEN_PAREN_OPEN 
 +		{ disableSemicolonInsertion(); } 
 +	  
 +	    arg=catchBlockArgument
 +		{ 
 +			n = new CatchNode(arg); 
 +			tryNode.addCatchClause(n);
 +			b = n.getContentsNode();
 +			n.startBefore(catchT); 
 +		}
 +		
 +		(   rpT:TOKEN_PAREN_CLOSE  
 +			{ 
 +				enableSemicolonInsertion();
 +				n.endAfter(rpT);
 +			}
 +			
 + 			exception catch [RecognitionException ex]
 + 			{handleParsingError(ex);  enableSemicolonInsertion(); }
 + 		)
 + 		
 +	    block[b]
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches the argument in the "try...catch(arg)" statement.
 + */
 +catchBlockArgument returns [ParameterNode p]
 +{ 
 +	p = null; 
 +	IdentifierNode name = null; 
 +	ExpressionNodeBase t = null; 
 +}
 +	:   name=identifier
 +		{ p = new ParameterNode(name); }
 +		
 +		(   colonT:TOKEN_COLON
 +			{ p.setType((ASToken)colonT, null); }
 +			t=type
 +			{ p.setType((ASToken)colonT, t); }
 +		)?
 +	;	
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches an "if" statement.
 + */
 +ifStatement[ContainerNode c]
 +{ 
 +	IfNode i = null; 
 +	ExpressionNodeBase cond = null; 
 +	ContainerNode b = null; 
 +	boolean hasElse = false; 
 +}
 +	:   ifT:TOKEN_KEYWORD_IF cond=statementParenExpression  
 +		{
 +			i = new IfNode((ASToken)ifT);
 +			ConditionalNode cNode = new ConditionalNode((ASToken)ifT);			
 +			cNode.setConditionalExpression(cond);
 +			b = cNode.getContentsNode();
 +			i.addBranch(cNode);
 +			c.addItem(i);
 +		}
 +		innerSubstatement[b]
 +	
 +		(options{greedy=true;}: 
 +            hasElse=elsePart[i]
 +			{ if (hasElse == true) return; }
 +		)*
 +	;
 + 	exception catch [RecognitionException ex] { handleParsingError(ex); }
 + 	
 +/**
 + * Matches the optional "else" block of an "if" statement.
 + *
 + * @return true if there is an "else" block.
 + */
 +elsePart[IfNode i] returns [boolean hasElse]
 +{ 
 +	hasElse = false; 
 +	ContainerNode b = null; 
 +	ExpressionNodeBase cond = null; 
 +	ConditionalNode elseIf = null; 
 +}
 +	
 +	:   elseT:TOKEN_KEYWORD_ELSE
 +		(options{greedy=true;}: 
 +            TOKEN_KEYWORD_IF cond=statementParenExpression
 +			{
 +		    	elseIf = new ConditionalNode((ASToken) elseT);
 +		    	elseIf.setConditionalExpression(cond);
 +		    	i.addBranch(elseIf);
 +				b = elseIf.getContentsNode();
 +			}
 +		)?
 +		
 +		{
 +			if (elseIf == null){
 +				hasElse = true;
 +				TerminalNode t = new TerminalNode((ASToken) elseT);
 +				i.addBranch(t);
 +				b = t.getContentsNode();
 +			}
 +		}
 +		substatement[b]
 +	;
 +	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 +	
 +/**
 + * Matches a "switch" statement.
 + */
 +switchStatement[ContainerNode c]
 +{ 
 +	SwitchNode sw = null; 
 +	ExpressionNodeBase e = null; 
 +}
 + 	:   switchT:TOKEN_KEYWORD_SWITCH e=statementParenExpression
 + 		{
 +			sw = new SwitchNode((ASToken)switchT);			
 +			c.addItem(sw);
 +			if(e != null)
 +				sw.setConditionalExpression(e);
 + 		}
 + 
 + 	    cases[sw]
 + 	;
 +
 +/**
 + * Matches the "case" block in a "switch" statement.
 + */
 +cases[SwitchNode sw]
 +{ 
 +	final ContainerNode b = sw.getContentsNode(); 
 +}
 +    :   TOKEN_BLOCK_OPEN caseClauses[b] TOKEN_BLOCK_CLOSE
 +	;
 +
 +/**
 + * Matches the "case" clauses in a "switch" statement.
 + */
 +caseClauses[ContainerNode swb]
 + 	:    (caseClause[swb])*	
 + 	;
 +
 +/**
 + * Matches a single "case" clause in a "switch" statement.
 + */ 	
 +caseClause[ContainerNode swb]
 +{ 
 +	ExpressionNodeBase e = null; 
 +	ContainerNode b = null; 
 +}
 + 	:   caseT:TOKEN_KEYWORD_CASE e=expression colon
 + 		{
 + 			ConditionalNode cond = new ConditionalNode((ASToken) caseT);
 + 			cond.setConditionalExpression(e);
 + 		 	swb.addItem(cond);
 + 		 	b = cond.getContentsNode(); 
 + 		}
 + 		caseStatementList[b]
 + 		
 + 	|   defaultT:TOKEN_KEYWORD_DEFAULT colon 	
 + 		{
 + 			TerminalNode t = new TerminalNode((ASToken)defaultT);
 + 			swb.addItem(t);
 + 			b = t.getContentsNode();
 + 		}
 + 		caseStatementList[b]
 + 	;
 + 	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 +
 +/**
 + * Matches a colon token ":" or recover from a missing colon.
 + */
 +colon
 +	:	TOKEN_COLON
 +	;
 + 	exception catch [RecognitionException ex] { addProblem(unexpectedTokenProblem(LT(1), ASTokenKind.COLON)); }
 +
 +/**
 + * Matches the statements in a "case" clause.
 + */ 	 
 +caseStatementList[ContainerNode b]
 + 	:   (directive[b, TOKEN_BLOCK_CLOSE])*
 + 	;
 + 	exception catch [RecognitionException ex] {handleParsingError(ex);  }
 + 
 +/**
 + * Matches an identifier token. An identifier can come from different token
 + * types such as: 
 + *
 + *   - IDENTIFIER
 + *   - namespace
 + *   - get 
 + *   - set
 + *
 + * This is because in AS3, these elements are not reserved keyword. However they
 + * have special meaning in some syntactic contexts.
 + * See "AS3 syntax spec - 3.5 Keywords and Punctuators" for details.
 + */
 +identifier returns [IdentifierNode n]
 +{ 
 +    n = null;  
 +    final ASToken token = LT(1);
 +}
 +    :   (	TOKEN_IDENTIFIER 
 +    	|	TOKEN_RESERVED_WORD_NAMESPACE 
 +    	|	TOKEN_RESERVED_WORD_GET 
 +    	| 	TOKEN_RESERVED_WORD_SET 
 +    	)
 +		{ n = new IdentifierNode(token); }
 +    ;
 +    exception
 +    catch [NoViableAltException e1] { n = expectingIdentifier(e1); }
 +    catch [RecognitionException e2] { n = handleMissingIdentifier(e2); }
 +    
 +/**
 + * Matches an "import-able" name.
 + *
 + *     flash.display.Sprite;
 + *     flash.events.*;
 + */    
 +importName returns [ExpressionNodeBase n]
 +{ 
 +	n=null; 
 +	ExpressionNodeBase e = null;
 +}
 +	
 +	: 	n=packageName 
 +		(	dot:TOKEN_OPERATOR_MEMBER_ACCESS 
 +			{ 
 +				n = new FullNameNode(n, (ASToken) dot, null); 
 +			} 
 +			e=starLiteral
 +			{
 +				((FullNameNode)n).setRightOperandNode(e);
 +			}
 +		)?
 +	;
 +	exception catch [RecognitionException ex] { return handleMissingIdentifier(ex, n); }
 +
 +/**
 + * Matches a restricted name. For example:
 + *
 + *     my.package.name.Clock;
 + *     private::myPrivateVar;
 + *     UnqualifiedTypeClock;
 + *
 + */
 +restrictedName returns [ExpressionNodeBase nameExpression]
 +{
 +    nameExpression = null;
 + 	IdentifierNode placeHolderRightNode = null;
 +    ASToken opToken = null;
 +    ExpressionNodeBase part = null;
 +}
 +    :   nameExpression=restrictedNamePart
 +    	
 +    	// LL(1) grammar can only branch on the next token. 
 +        // The LA(2) semantic predicate is used to disambiguate:
 +        // 1. "foo.bar" - a restricted name consisting two identifiers
 +        // 2. "foo.(bar)" - a member expression whose left-hand side is an identifier
 +        //                  and the right-hand side is a parenthesis expression
 +        (options { greedy=true; }: { LA(2) != TOKEN_PAREN_OPEN }?
 +            {
 +                opToken = LT(1); 
 +                
 +                // The place-holder node is a safe-net in case parsing the 
 +                // "right" node fails, so that we will still have a balanced
 +                // FullNameNode.
 +                placeHolderRightNode = IdentifierNode.createEmptyIdentifierNodeAfterToken(opToken);
 +                
 +                final ExpressionNodeBase nameLeft = nameExpression;
 +            }
 +            (   TOKEN_OPERATOR_MEMBER_ACCESS 
 +                { nameExpression = new FullNameNode(nameLeft, opToken, placeHolderRightNode); } 
 +            |   TOKEN_OPERATOR_NS_QUALIFIER 
 +                { nameExpression = new NamespaceAccessExpressionNode(nameLeft, opToken, placeHolderRightNode); }
 +            )
 +            
 +            (	{ opToken.getType() == TOKEN_OPERATOR_NS_QUALIFIER && LA(1) == TOKEN_SQUARE_OPEN }?
 +                // matches ns::["var_in_ns"]
 +            	nameExpression=bracketExpression[nameLeft]
 +	        |   part=restrictedNamePart
 +	            { 
 +	            	((BinaryOperatorNodeBase)nameExpression).setRightOperandNode(part);
 +	            	checkForChainedNamespaceQualifierProblem(opToken, part);
 +	        	}
 +        	)
 +        )*
 +    ;
 +	exception catch [RecognitionException ex] 
 +	{  
 +	   if (nameExpression == null)
 +	       nameExpression = handleMissingIdentifier(ex); 
 +       else
 +           consumeParsingError(ex);
 +    }
 +    
 +    
 +/**
 + * Matches the identifier part of a restricted name. For example:
 + * 
 + *     private
 + *     public
 + *     foo
 + *     MyType
 + *
 + */
 +restrictedNamePart returns [IdentifierNode id]
 +{
 +    id = null;
 +    final ASToken lt = LT(1);
 +}
 +    :   id=identifier
 +    |   TOKEN_NAMESPACE_NAME 
 +        { id = new IdentifierNode(lt); }
 +    |   TOKEN_KEYWORD_SUPER
 +        { id = LanguageIdentifierNode.buildSuper(lt); }
 +    ;
 +    // "identifier", "namespace name" and "super" are all "identifiers" to
 +    // the user. So we override the default error handling in order to emit
 +    // "expecting identifier but found ..." syntax problem.
 +    exception catch [NoViableAltException ex] { id = expectingIdentifier(ex); }
 +
 +/**
 + * Keep legacy rule for Falcon-JS.
 + */
 +typedNameOrStar returns [ExpressionNodeBase n]
 +    :    n=type
 +    ;
 +    
 +/**
 + * Matches a type reference.
 + *
 + *     String
 + *     int
 + *     *
 + *     Vector.<Clock>
 + *     foo.bar.Vector.<T>
 + *
 + */
 +type returns [ExpressionNodeBase n]
 +{ 
 +    n = null; 
 +}
 +    :   n=starLiteral
 +    |   n=restrictedName ( n=typeApplication[n] )?
 +    ;	
 +    exception catch [RecognitionException ex] { n = handleMissingIdentifier(ex); }
 +  
 +/**
 + * Matches a "type application" part>
 + *
 + *     .<String>
 + *     .<Clock>
 + *     .<uint>
 + *
 + */
 +typeApplication [ExpressionNodeBase root] returns[TypedExpressionNode n]
 +{ 
 +    n = null; 
 +    ExpressionNodeBase t = null; 
 +    Token closeT = null;
 +    enterTypeApplication(root);
 +}
 +    :   openT:TOKEN_TYPED_COLLECTION_OPEN
 +        t=type
 +        {
 +            n = new TypedExpressionNode(root, t, (ASToken)openT);
 +            closeT = LT(1);
 +        }
 +        ( TOKEN_TYPED_COLLECTION_CLOSE | TOKEN_OPERATOR_GREATER_THAN )
 +        { n.endAfter(closeT); }
 +    ; 
 +    exception catch [RecognitionException ex] { consumeParsingError(ex); } 
 +
 +
 +/**
 + * Matches an optional expression.
 + * @return NilNode or ExpressionNodeBase.
 + */	 		
 +optExpression returns[ExpressionNodeBase e]
 +{ 
 +	e = null; 
 +}
 +	:   (options{greedy=true;}: e=expression)?												
 +		{ if (e == null) e = new NilNode(); }
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +		
 +/**
 + * Matches an expression or a comma-separated expression list.
 + */
 +expression returns [ExpressionNodeBase n]
 +{
 +    n = null; 
 +    ExpressionNodeBase e1 = null; 
 +}
 +    :   n=assignmentExpression 
 +    	(options{greedy=true;}: 
 +            op:TOKEN_COMMA 
 +            e1=assignmentExpression
 +            { n = BinaryOperatorNodeBase.create((ASToken)op,n,e1); }
 +    	)*
 +    ;	
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches an "assignment expression".
 + *
 + * According to ASL sytax spec, the productions for an "assignment expression"
 + * is either a "conditional expression" or a "left-hand side expression" followed
 + * by an "assignment operator" and an "assignment expression". However, since
 + * "assignmentExpression" and "conditionaExpression" is ambiguous at indefinite 
 + * look-ahead distance, this LL(1) grammar can't decide which alternative to
 + * choose. As a result, the implementation is more lenient in that an AST node
 + * for an assignment binary node will be built even the left-hand side expression
 + * is not a valid "LeftHandSideExpression", such as a constant.
 + * 
 + * For example:
 + * <code>100 = "hello";</code>
 + * This statement will be parsed without syntax error, generating tree like:
 + * <pre>
 + *        =
 + *       / \
 + *    100  "hello"
 + * </pre>
 + *
 + * A possible solution to this is to find out the difference between "conditional
 + * expression" and "left-hand side expression", then insert a semantic predicate
 + * before matching a "assignment operator".
 + */
 +assignmentExpression returns [ExpressionNodeBase n]
 +{
 +	n = null; 
 +	ASToken op = null; 
 +	ExpressionNodeBase r = null;
 +}		
 +	:   n=condExpr 
 +		(options{greedy=true;}: 
 +		    op=assignOp 
 +		    r=assignmentRightValue
 +	        { n = BinaryOperatorNodeBase.create(op,n,r); }
 +		)?
 +	;
 +	
 +/**
 + * Matches the right-hand side of an assignment expression.
 + * "public" namespace is allowed as an R-value for backward compatibility.
 + * @see "CMP-335 and ASLSPEC-19"
 + */
 +assignmentRightValue returns [ExpressionNodeBase rightExpr]
 +{
 +	rightExpr = null;
 +}
 +    :   { isNextTokenPublicNamespace() }? p:TOKEN_NAMESPACE_ANNOTATION
 +        { rightExpr = new NamespaceIdentifierNode((ASToken)p); }
 +    |   rightExpr=assignmentExpression  
 +    ;
 +	
 +assignOp returns [ASToken op]
 +{ 
 +	op = LT(1); 
 +}
 +    :   TOKEN_OPERATOR_ASSIGNMENT 
 +    |   TOKEN_OPERATOR_LOGICAL_AND_ASSIGNMENT
 +    |   TOKEN_OPERATOR_LOGICAL_OR_ASSIGNMENT
 +    |   TOKEN_OPERATOR_PLUS_ASSIGNMENT
 +    |   TOKEN_OPERATOR_MINUS_ASSIGNMENT
 +    |   TOKEN_OPERATOR_MULTIPLICATION_ASSIGNMENT
 +    |   TOKEN_OPERATOR_DIVISION_ASSIGNMENT
 +    |   TOKEN_OPERATOR_MODULO_ASSIGNMENT
 +    |   TOKEN_OPERATOR_BITWISE_AND_ASSIGNMENT
 +    |   TOKEN_OPERATOR_BITWISE_OR_ASSIGNMENT
 +    |   TOKEN_OPERATOR_BITWISE_XOR_ASSIGNMENT
 +    |   TOKEN_OPERATOR_BITWISE_LEFT_SHIFT_ASSIGNMENT
 +    |   TOKEN_OPERATOR_BITWISE_RIGHT_SHIFT_ASSIGNMENT
 +    |   TOKEN_OPERATOR_BITWISE_UNSIGNED_RIGHT_SHIFT_ASSIGNMENT
 +    ;
 +
 +/**
 + * Matches a ternary expression such as: 
 + *
 + *     (x > 2) ? "greater" : "smaller"
 + */		
 +condExpr returns [ExpressionNodeBase n]
 +{
 +    n = null; 
 +    ExpressionNodeBase trueExpr = null; 
 +    ExpressionNodeBase falseExpr = null;
 +    TernaryOperatorNode ternary = null;
 +}
 +	:   n=binaryExpr 
 +        (   op:TOKEN_OPERATOR_TERNARY       
 +            {
 +                ternary = new TernaryOperatorNode((ASToken)op,n,null,null);
 +                n = ternary; 
 +            }
 +            trueExpr=assignmentExpression   { ternary.setLeftOperandNode(trueExpr); }
 +            TOKEN_COLON 
 +            falseExpr=assignmentExpression  { ternary.setRightOperandNode(falseExpr); }
 +        )?
 +        exception catch [RecognitionException ex] { handleParsingError(ex); }
 +	;
 +	
 +/**
 + * Binary expression uses operator precedence parser in BaseASParser.
 + */
 +binaryExpr returns [ExpressionNodeBase n]
 +{
 +	n = precedenceParseExpression(4);
 +	if (true)	return n;
 +}
 +	: fakeExpr
 +	;
 +	
 +/**
 + * fakeExpr simulates the set of allowable follow tokens in an expression context, which allows antlr to function.
 + * It is unreachable.
 + */
 +fakeExpr
 +{ 
 +	ExpressionNodeBase n = null; 
 +}
 +	:	n=unaryExpr (options{greedy=true;}: binaryOperators fakeExpr)?
 +	;
 +	
 +/**
 + * Declares all the binary operators.
 + */
 +binaryOperators
 +    :   TOKEN_OPERATOR_LOGICAL_OR 
 +    |   TOKEN_OPERATOR_LOGICAL_AND
 +    |   TOKEN_OPERATOR_BITWISE_OR 
 +    |   TOKEN_OPERATOR_BITWISE_XOR 
 +    |   TOKEN_OPERATOR_BITWISE_AND
 +    |   TOKEN_OPERATOR_EQUAL 
 +    |   TOKEN_OPERATOR_NOT_EQUAL 
 +    |   TOKEN_OPERATOR_STRICT_EQUAL 
 +    |   TOKEN_OPERATOR_STRICT_NOT_EQUAL
 +    |   TOKEN_OPERATOR_GREATER_THAN 
 +    |   TOKEN_OPERATOR_GREATER_THAN_EQUALS
 +    |   TOKEN_OPERATOR_LESS_THAN 
 +    |   TOKEN_OPERATOR_LESS_THAN_EQUALS
 +    |   TOKEN_KEYWORD_INSTANCEOF
 +    |   TOKEN_KEYWORD_IS 
 +    |   TOKEN_KEYWORD_AS 
 +    |   TOKEN_KEYWORD_IN
 +    |   TOKEN_OPERATOR_BITWISE_LEFT_SHIFT 
 +    |   TOKEN_OPERATOR_BITWISE_RIGHT_SHIFT 
 +    |   TOKEN_OPERATOR_BITWISE_UNSIGNED_RIGHT_SHIFT
 +    |   TOKEN_OPERATOR_MINUS 
 +    |   TOKEN_OPERATOR_PLUS
 +    |   TOKEN_OPERATOR_DIVISION 
 +    |   TOKEN_OPERATOR_MODULO 
 +    |   TOKEN_OPERATOR_STAR
 +	;	
 +
 +/**
 + * Matches a "prefix expression".
 + *
 + *     delete x[i]
 + *     ++i
 + *     --i
 + *
 + * The distinction between this rule and "unary expression" makes the parser
 + * more strict about what expressions can follow what tokens.
 + */
 +prefixExpression returns [ExpressionNodeBase n]
 +{
 +	n = null;
 +	final ASToken op = LT(1);
 +}
 +	:	n=postfixExpr
 +	|	(	TOKEN_KEYWORD_DELETE n=postfixExpr 
 +	    |   TOKEN_OPERATOR_INCREMENT n=lhsExpr
 +	    |   TOKEN_OPERATOR_DECREMENT n=lhsExpr
 +	    )
 +        { 
 +	    	if (n == null)
 +	            n = IdentifierNode.createEmptyIdentifierNodeAfterToken(op);
 +	    	n = UnaryOperatorNodeBase.createPrefix(op, n); 
 +    	} 
 +	;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches a "unary expression".
 + *
 + * This rule is called out of the precedence parser in BaseASParser.
 + * If you need to change the name of this rule, you'll also need to update 
 + * the base class.
 + */
 +unaryExpr returns [ExpressionNodeBase n]
 +{ 
 +    n = null; 
 +    ASToken op = null; 
 +}	
 +    :   (   n=prefixExpression 
 +        |   op=unaryOp n=unaryExpr 
 +            { 
 +            	if (n == null)
 +                    n = IdentifierNode.createEmptyIdentifierNodeAfterToken(op);
 +            	n = UnaryOperatorNodeBase.createPrefix(op, n); 
 +        	} 
 +        ) 
 +        (options { greedy = true; }: 
 +            n=propertyAccessExpression[n] 
 +        |   n=arguments[n] 
 +        )*
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches a unary operator.
 + */
 +unaryOp returns [ASToken op]
 +{
 +	op = LT(1); 
 +}
 +    :   TOKEN_KEYWORD_VOID
 +    |   TOKEN_KEYWORD_TYPEOF
 +    |   TOKEN_OPERATOR_PLUS 
 +    |   TOKEN_OPERATOR_MINUS 
 +    |   TOKEN_OPERATOR_BITWISE_NOT 
 +    |   TOKEN_OPERATOR_LOGICAL_NOT
 +    ;
 +	   
 +/**
 + * Matches "Postfix Expression" such as: i++, i--
 + *
 + * Since ECMA semicolon insertion rule requires that if a "++" or "--" is not
 + * on the same line as its left-hand side expression, a semicolon is inserted
 + * before the "--" or "++" token. The side-effect of the inserted semicolon is
 + * to terminate the expression parsing at this point. As a result, we have to
 + * return "null" to stop parsing the expression. An upstream production will
 + * pickup the "--" or "++" by starting a new expression.
 + *
 + * A good test case for such situation would be:
 + *
 + *    var i = 99
 + *    ++i
 + *
 + * A semicolon should be inserted after "99", resulting in two separate ASTs
 + * for "var i=99" and "++i". Otherwise, "var i=99++" is a bad recognition.
 + */
 +postfixExpr returns [ExpressionNodeBase n]
 +{
 +    n = null; 
 +    boolean isSemicolonInserted = false;
 +}
 +	: n=lhsExpr 
 +	  {
 +	      final ASToken nextToken = LT(1); 
 +	      if (nextToken.getType() == ASTokenTypes.TOKEN_OPERATOR_INCREMENT ||
 +	          nextToken.getType() == ASTokenTypes.TOKEN_OPERATOR_DECREMENT)
 +	          isSemicolonInserted = beforeRestrictedToken(nextToken);
 +      }
 +      (   {!isSemicolonInserted}? (options{greedy=true;}: n=postfixOp[n])?
 +      |   // Do nothing if optional semicolon is inserted.
 +          // This empty alternative is required because otherwise a semantic 
 +          // predicate exception will be thrown, leading the code enter error 
 +          // handling, which will create incorrect tree shape.
 +      )
 +	;
 +
 +/**
 + * Matches a "postfix" operator such as: ++, --
 + * The parameter "n" is the expression the postfix operator acts on.
 + * The return value "top" is a UnaryOperatorNode.
 + */ 
 +postfixOp[ExpressionNodeBase n] returns [UnaryOperatorNodeBase top]
 +{
 +    final ASToken op = LT(1); 
 +    top = null;
 +}	
 +	:  ( TOKEN_OPERATOR_INCREMENT 
 +	   | TOKEN_OPERATOR_DECREMENT )
 +       { top = UnaryOperatorNodeBase.createPostfix(op, n); }
 +	;
 +
 +/**
 + * Matches a primary expression.
 + */ 
 +primaryExpression returns [ExpressionNodeBase n]
 +{ 
 +    n = null;  
 +    ASToken token = LT(1);
 +}
 +    :   TOKEN_KEYWORD_NULL
 +        { n = new LiteralNode(token, LiteralType.NULL); }
 +    |   TOKEN_KEYWORD_TRUE
 +        { n = new LiteralNode(token, LiteralType.BOOLEAN); }
 +    |   TOKEN_KEYWORD_FALSE
 +        { n = new LiteralNode(token, LiteralType.BOOLEAN); }
 +    |   TOKEN_KEYWORD_THIS
 +        { n = LanguageIdentifierNode.buildThis(token); }
 +    |   token=numericLiteral
 +        { n = new NumericLiteralNode(token); }
 +    |   TOKEN_LITERAL_STRING
 +        { n = new LiteralNode(token, LiteralType.STRING); }
 +    |   TOKEN_VOID_0
 +        { n = new LiteralNode(token, LiteralType.OBJECT); }
 +    |   TOKEN_LITERAL_REGEXP
 +        { n = new RegExpLiteralNode(token, this); }
 +    |   { n = new ArrayLiteralNode(); } arrayInitializer[(ArrayLiteralNode)n]
 +    |   n=objectLiteralExpression
 +    |   n=xmlInitializer      { leaveXMLLiteral(); }
 +    |   n=xmlListInitializer  { leaveXMLLiteral(); }
 +    |   n=functionExpression 
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +	
 +/**
 + * Matches a numeric literal token.
 + */
 +numericLiteral returns [ASToken op]
 +{ 
 +	op = LT(1); 
 +}
 +    :   TOKEN_LITERAL_NUMBER 
 +    |   TOKEN_LITERAL_HEX_NUMBER
 +	;
 +	
 +/**
 + * Matches an "object literal".
 + */
 +objectLiteralExpression returns [ExpressionNodeBase n]
 +{ 
 +	ObjectLiteralNode o = new ObjectLiteralNode(); 
 +	n = o; 
 +	ContainerNode b = o.getContentsNode(); 
 +	ExpressionNodeBase vp = null;
 +}
 +    :   openT:TOKEN_BLOCK_OPEN           { n.startBefore(openT); }
 +        (   vp=objectLiteralValuePair    { b.addItem(vp); }
 +      	    (   TOKEN_COMMA vp=objectLiteralValuePair
 +    	        { if (vp != null) b.addItem(vp); }
 +     		    exception catch [RecognitionException ex] 
 +     		    { handleParsingError(ex); }
 +      	    )*
 +        )?		
 +        closeT:TOKEN_BLOCK_CLOSE         { n.endAfter(closeT); }  		
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches a "field" in an "object literal".
 + * The "field" can be gated with a "config condition". If the condition is
 + * "false", return "null" value; Otherwise, return the expression node of the
 + * key/value pair.
 + */
 +objectLiteralValuePair returns [ExpressionNodeBase n]
 +{ 
 +	ExpressionNodeBase v = null;  
 +	n = null;            
 +	boolean condition = true;   
 +    ASToken numberT = null;     
 +}
 +    :   (   { isConfigCondition() && LA(4) != TOKEN_COLON && LA(4) != TOKEN_BLOCK_CLOSE }?
 +            condition=configCondition
 +        |   // Skip - no config varaible.
 +        )
 +        
 +        // Field name:
 +        (   nameT:TOKEN_IDENTIFIER
 +        	{ n = new NonResolvingIdentifierNode(nameT != null ? nameT.getText() : "",nameT); }
 +        |   numberT=numericLiteral
 +        	{ n = new NumericLiteralNode(numberT); }
 +        |   stringT:TOKEN_LITERAL_STRING
 +        	{ n = new LiteralNode(LiteralType.STRING, stringT); }
 +        )
 +        
 +        c:TOKEN_COLON 
 +        
 +        // Field value:
 +        v=assignmentExpression 
 +    	{ 
 +    		if (condition)
 +    		    n = new ObjectLiteralValuePairNode((ASToken)c,n,v); 
 +		    else
 +		        n = null;
 +	    }
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex);  }
 + 
 +
 +/**
 + * Matches array literal. For example:
 + *
 + *    []
 + *    ["hello", 3.14, foo]
 + *    [ , x, y]
 + *    [ , ,]
 + *
 + * "Holes" (empty array elements) are allowed. See "arrayElements" rule for details.
 + */ 
 +arrayInitializer [ArrayLiteralNode node] 
 +    {
 +        final ContainerNode contents = node.getContentsNode(); 
 +    }
-     :   open:TOKEN_SQUARE_OPEN            { contents.startBefore(open); }
++    :   open:TOKEN_SQUARE_OPEN            { node.startBefore(open); contents.startAfter(open); }
 +        arrayElements[contents]
-         close:TOKEN_SQUARE_CLOSE          { contents.endAfter(close); }
++        close:TOKEN_SQUARE_CLOSE          { node.endAfter(close); contents.endBefore(close); }
 +    ;	
 +    exception catch [RecognitionException ex] 
 +    { 
 +    	// Do not convert keywords to identifiers.
 +    	// This is for recovering from:
 +    	// [
 +    	// var x:int;
 +    	handleParsingError(ex); 
 +    	// Notify the caller that the array literal failed.
 +    	throw ex; 
 +    }
 +	
 +/**
 + * Matches all the elements in an "arrayInitializer". For example:
 + *
 + *    x,y,z
 + *    x,,
 + *    (empty)
 + *    ,,,,,,
 + *
 + * "Holes" are compiled as "undefined".
 + * Leading "holes" are kept as "undefined" values.
 + * "Holes" in the middle are kept as "undefined" values.
 + * Trailing "holes" are kept as "undefined" values except that the last "hole"
 + * is dropped.
 + *
 + * For example: x=[,,1,,,2,,,] has 2 leading holes, 2 holes in the middle, and 3
 + * holes at the end. All the holes except for the last trailing holes are kept
 + * as undefined values:
 + *
 + * x[0]=undefined
 + * x[1]=undefined
 + * x[2]=1
 + * x[3]=undefined
 + * x[4]=undefined
 + * x[5]=2
 + * x[6]=undefined
 + * x[7]=undefined
 + * (end)
 + *
 + */
 +arrayElements[ContainerNode b]
 +{ 
 +    ExpressionNodeBase e = null;  
 +}
 +    :   ( TOKEN_COMMA { b.addItem(new NilNode()); } )*
 +        (   { LA(1) != TOKEN_SQUARE_CLOSE}?   
 +            	e=arrayElement { b.addItem(e); /*1*/ }
 +                (   TOKEN_COMMA 
 +                    (   { LA(1) != TOKEN_SQUARE_CLOSE && LA(1) != TOKEN_COMMA }? e=arrayElement { b.addItem(e); /*2*/}
 +                    |   { LA(1) != TOKEN_SQUARE_CLOSE && LA(1) == TOKEN_COMMA }? { b.addItem(new NilNode()); }
 +                    |   // Next token is "]" - pass.
 +            	 	)
 +             		exception catch [RecognitionException ex] { handleParsingError(ex); }
 +              	)*
 +      	|    // Next token is "]" - the initializer is a list of commas: [,,,,,]
 +      	)
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches an "array element" in an "array literal". An array element can be 
 + * gated with a config variable. If the config variable is false, the element
 + * will be matched as a "hole" in the array literal.
 + */
 +arrayElement returns [ExpressionNodeBase e]
 +{ 
 +	e = null; 
 +	boolean c = true;  // config variable
 +}
 +    :   (   { isConfigCondition() && LA(4) != TOKEN_COMMA && LA(4) != TOKEN_SQUARE_CLOSE }?
 +            c=configCondition
 +        |   // Skip - no config varaible.
 +        )
 +        e=assignmentExpression
 +        {
 +        	if (!c) 
 +        	{
 +        		final NilNode nilNode = new NilNode(); 
 +        		nilNode.span(e, e);
 +        		e = nilNode;
 +    		}
 +        }
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex);  }
 +	
 +/**
 + * Matches a "vector initializer".
 + */
 +vectorLiteralExpression returns [VectorLiteralNode node] 
 +{ 
 +	node = new VectorLiteralNode(); 
 +	ContainerNode b = node.getContentsNode(); 
 +	ExpressionNodeBase type = null; 
 +}
 +	:   open:TOKEN_TYPED_LITERAL_OPEN      { node.endAfter(open); }
 +	 	type=type                          { node.setCollectionTypeNode(type); }
 +        close:TOKEN_TYPED_LITERAL_CLOSE    { node.endAfter(close); }
 +        openT:TOKEN_SQUARE_OPEN            { b.startAfter(openT); }
 +	 	(vectorLiteralContents[b])?
 +        closeT:TOKEN_SQUARE_CLOSE          { b.endBefore(closeT); }
 +	;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches a "vector element" in a vector initializer.
 + */
 +vectorLiteralContents[ContainerNode b]
 +{ 
 +	ExpressionNodeBase e = null;  
 +}
 +    :   e=arrayElement       { b.addItem(e); }
 +        (   TOKEN_COMMA
 +            {
 +                //  A trailing comma is allowed, but 
 +                //  an intermediate comma is not.
 +                if ( LA(1) != TOKEN_SQUARE_CLOSE ){
 +                    e=arrayElement();
 +                    b.addItem(e); 
 +                }
 +    	 	}
 +            exception catch [RecognitionException ex] { handleParsingError(ex); }
 +      	)*
 +    ;
 +
 +/**
 + * Matches "XML literal expression".
 + */
 +xmlInitializer returns [XMLLiteralNode n]
 +{ 
 +	n = new XMLLiteralNode(); 
 +	final ASToken lt = LT(1);
 +	enterXMLLiteral();
 +}
 +    :   { LA(1) == TOKEN_E4X_COMMENT || 
 +    	  LA(1) == TOKEN_E4X_CDATA || 
 +    	  LA(1) == TOKEN_E4X_PROCESSING_INSTRUCTION 
 +    	}? 
 +        xmlMarkup
 +        { n.appendLiteralToken(lt); }
 +        xmlWhitespace[n]
 +    |   (options { greedy = true; }: xmlElementContent[n] )+
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }	
 +    
 +/**
 + * Match XML whitespace tokens. If {@code ContainerNode} is null, drop the
 + * whitespace tokens.
 + */
 +xmlWhitespace [BaseLiteralContainerNode n]
 +    :   (options { greedy = true; }: 
 +	        ws:TOKEN_E4X_WHITESPACE 
 +            { 
 +            	if (n != null) 
 +            	    n.appendLiteralToken((ASToken)ws); 
 +    	    }
 +        )*
 +	;
 +    
 +/**
 + * Matches an XML comment, XML CDATA or XML PI token.
 + */
 +xmlMarkup
 +    :   TOKEN_E4X_COMMENT
 +    |   TOKEN_E4X_CDATA
 +    |   TOKEN_E4X_PROCESSING_INSTRUCTION
 +    ;    
 +       
 +/**
 + * Matches an E4X token that can be aggregated in "xmlTokenAggregated".
 + * Instead of a full recursive descent parser for XML tags, the base class
 + * uses a tag name stack to check matching tags. A complete parse tree with
 + * XML structure is unnecessary and adds extra overhead to the parser.
 + */
 +xmlToken [BaseLiteralContainerNode n]
 +{
 +	final ASToken t = LT(1);
 +}
 +    :   (   xmlMarkup
 +        |   TOKEN_E4X_WHITESPACE 
 +        |   TOKEN_E4X_ENTITY
 +        |   TOKEN_E4X_DECIMAL_ENTITY
 +        |   TOKEN_E4X_HEX_ENTITY 
 +        |   TOKEN_E4X_TEXT
 +        |   TOKEN_E4X_STRING
 +        )
 +        { n.appendLiteralToken(t); }       
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }	
 +    
 +/**
 + * Matches an XML tag.
 + *
 + *     <foo>
 + *     </foo>
 + *     <foo />
 + *     <{name}>
 + *     <foo name={nameValue}>
 + *     <foo {attrs}>
 + */
 +xmlTag [BaseLiteralContainerNode n]
 +    :   (   openT:TOKEN_E4X_OPEN_TAG_START          // <foo
 +            { 
 +            	xmlTagOpen((ASToken)openT); 
 +                n.appendLiteralToken((ASToken)openT);
 +        	} 
 +        |   closeT:TOKEN_E4X_CLOSE_TAG_START        // </foo
 +            { 
 +            	xmlTagClose((ASToken)closeT); 
 +                n.appendLiteralToken((ASToken)closeT);
 +        	} 
 +        |   openNoNameT:HIDDEN_TOKEN_E4X            // <
 +            { 
 +            	xmlTagOpenBinding((ASToken)openNoNameT); 
 +                n.appendLiteralToken((ASToken)openNoNameT);
 +        	}
 +        	
 +        	// Note about compatibility:
 +        	// x = <  tagName foo="bar" />;
 +        	//      ^
 +        	// Whitespace isn't allowed here according to ASL spec.
 +            // Avik from AS3 spec team confirmed it was a bug that the old ASC allowed it.
 +
 +        	(   xmlContentBlock[n]
 +        	|   nT:TOKEN_E4X_NAME
 +        	    { n.appendLiteralToken((ASToken)nT); }
 +        	)
 +        )
 +        xmlWhitespace[n]
 +        (   ( { isXMLAttribute() }? xmlAttribute[n] 
 +	    | xmlContentBlock[n] )
 +            xmlWhitespace[n]
 +        )*
 +        (   endT:TOKEN_E4X_TAG_END                  // >
 +            { n.appendLiteralToken((ASToken)endT); }
 +        |   emptyEndT:TOKEN_E4X_EMPTY_TAG_END       // />
 +            {
 +            	xmlEmptyTagEnd((ASToken)emptyEndT); 
 +                n.appendLiteralToken((ASToken)emptyEndT);
 +            }
 +        )
 +    ;
 +    
 +/**
 + * Matches an XML attribute.
 + * 
 + *     name="value"
 + *     name='value'
 + *     name={value}
 + *     {name}="value"
 + *     {name}='value'
 + *     {name}={value}
 + */
 +xmlAttribute [BaseLiteralContainerNode n]
 +    :   (   nT:TOKEN_E4X_NAME  
 +            { n.appendLiteralToken((ASToken)nT); }
 +        |   nsT:TOKEN_E4X_XMLNS 
 +            { n.appendLiteralToken((ASToken)nsT); }
 +        |   xmlAttributeBlock[n]
 +        ) 
 +        (   dT:TOKEN_E4X_NAME_DOT 
 +            { n.appendLiteralToken((ASToken)dT); }
 +            dnT:TOKEN_E4X_DOTTED_NAME_PART 
 +            { n.appendLiteralToken((ASToken)dnT); }
 +        )* 
 +        xmlWhitespace[n]
 +        eqT:TOKEN_E4X_EQUALS
 +        { n.appendLiteralToken((ASToken)eqT); }
 +        xmlWhitespace[n]
 +        (options { greedy = true; }:
 +            strT:TOKEN_E4X_STRING
 +            { n.appendLiteralToken((ASToken)strT); }
 +        |   eT:TOKEN_E4X_ENTITY
 +            { n.appendLiteralToken((ASToken)eT); }
 +        |   hexT:TOKEN_E4X_HEX_ENTITY
 +            { n.appendLiteralToken((ASToken)hexT); }
 +        |   xmlContentBlock[n]
 +        )+
 +    ;
 +
 +/**
 + * Matches an expression block in XML literals.
 + *
 + *    <foo>{ this.fooValue }</foo>
 + */
 +xmlElementContent [BaseLiteralContainerNode n]
 +    :   xmlToken[n] 
 +    |   xmlContentBlock[n]
 +    |   xmlTag[n]
 +    ;
 +    
 +/**
 + * Matches an E4X XML list expression.
 + */
 +xmlListInitializer returns [XMLListLiteralNode n]
 +{ 
 +	n = new XMLListLiteralNode(); 
 +	enterXMLLiteral();
 +}
 +    :   xmlListT:TOKEN_LITERAL_XMLLIST 
 +    	{ n.getContentsNode().addItem(new LiteralNode(LiteralType.XML, xmlListT)); }      
 +        ( xmlElementContent[n] )*
 +        closeT: TOKEN_E4X_XMLLIST_CLOSE 
 +    	{ n.getContentsNode().addItem(new LiteralNode(LiteralType.XML, closeT)); }      
 +    	xmlWhitespace[null]
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }	
 +
 +/**
 + * Matches a binding expression in an XML literal.
 + */
 +xmlContentBlock[BaseLiteralContainerNode n]
 +{ 
 +	ExpressionNodeBase e = null; 
 +}
 +    :   TOKEN_E4X_BINDING_OPEN 
 +        e=expression 
 +    	{ 
 +            if(e != null) 
 +                n.getContentsNode().addItem(e); 
 +    	}
 +        TOKEN_E4X_BINDING_CLOSE
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +    
 +
 +/**
 + * Matches a binding expression in an XML literal attribute name.
 + */
 +xmlAttributeBlock[BaseLiteralContainerNode n]
 +{ 
 +	ExpressionNodeBase e = null; 
 +}
 +    :   TOKEN_E4X_BINDING_OPEN 
 +        e=lhsExpr 
 +    	{ 
 +            if(e != null) 
 +                n.getContentsNode().addItem(e); 
 +    	}
 +        TOKEN_E4X_BINDING_CLOSE
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +    
 +
 +/**
 + * Matches a left-hand side (of asssignment) expression.
 + */
 +lhsExpr returns [ExpressionNodeBase n]
 +{
 +	n = null;
 +}
 +    :   (   n=newExpression 
 +        |   n=parenExpression 
 +        |   n=nameExpression 
 +        |   n=primaryExpression 
 +        |   n=xmlAttributeName
 +        )
 +    	(options { greedy = true; }: 
 +            n=propertyAccessExpression[n] 
 +        |   n=arguments[n] 
 +    	)*	
 +    ;
 +	exception catch [RecognitionException ex] { handleParsingError(ex); }
 +	
 +/**
 + * Matches a member expression. See ASL syntax spec for details.
 + */
 +memberExpression returns [ExpressionNodeBase n]
 +    :   (   n=primaryExpression
 +        |   n=parenExpression
 +        |   n=propertyName
 +        |   n=newExpression
 +        )
 +        ( options { greedy = true; }: n=propertyAccessExpression[n] )*
 +    ;
 +
 +/**
 + * Matches a new expression. See ASL syntax spec for details.
 + */			
 +newExpression returns[ExpressionNodeBase n]
 +{ 
 +	n = null; 
 +}
 +	:   newT:TOKEN_KEYWORD_NEW 
 +        (   { LA(1) != TOKEN_KEYWORD_FUNCTION }?
 +        	(   n=vectorLiteralExpression
 +            |   n=memberExpression 
 +            )   
 +            {   
 +                if (n == null) 
 +                	n= handleMissingIdentifier(null); 
 +            	else 
 +            		n = FullNameNode.toMemberAccessExpressionNode(n);
 +				n = new FunctionCallNode((ASToken)newT, n); 
 +			} 
 +            (options{greedy=true;}: n=arguments[n])?
 +        |   n=functionExpression  { n = new FunctionCallNode((ASToken)newT, n); }
 +        )
 +		exception catch [RecognitionException ex] { 
 +			//if we have the 'new' keyword, but no expression, drop in a dummy identifier
 +		    if(newT != null && n == null) {
 +			    IdentifierNode identifier = handleMissingIdentifier(ex);
 +			    if(identifier != null) {
 +			        //if we're here, that means identifier fixup is turned on
 +			        n = new FunctionCallNode((ASToken)newT, identifier);
 +			    }
 +			} else {
 +			    handleParsingError(ex); 
 +			}
 +		}
 +	;
 +
 +/**
 + * Matches an expression with parenthesis.
 + *
 + *     (id)
 + *     (1 + 2)
 + *     (name == "hello")
 + *
 + */
 +parenExpression returns[ExpressionNodeBase n]
 +{
 +    n = null; 
 +} 
 +    :   TOKEN_PAREN_OPEN n=expression TOKEN_PAREN_CLOSE
 +	    { if(n != null) n.setHasParenthesis(true); }
 +    ;
 +    exception catch [RecognitionException ex] { handleParsingError(ex); }
 +
 +/**
 + * Matches a property name in a member expression.
 + */
 +propertyName returns [ExpressionNodeBase n]
 +{
 +    n = null;
 +}
 +    :   n=starLiteral                 // *
 +    |   n=restrictedName              // qualified & unqualified name
 +    |   n=xmlAttributeName            // e4x attribute
 +    ;
 +    
 +/**
 + * This is a non-greedy and non-aggregating version of "restricted name".
 + * It is defined in addition to "propertyName" in order to get correct
 + * precedence in the name expressions and expected tree shapes.
 + */
 +nameExpression returns[ExpressionNodeBase n]
 +	{ n = null; }
 +	
 +	: n=identifier 
 +	| n=starLiteral
 +	| superT:TOKEN_KEYWORD_SUPER
 +		{ n = LanguageIdentifierNode.buildSuper((IASToken)superT); }
 +	| nsT:TOKEN_NAMESPACE_NAME
 +		{ 
 +			n = new NamespaceIdentifierNode((ASToken)nsT); 
 +			((NamespaceIdentifierNode)n).setIsConfigNamespace(isConfigNamespace((NamespaceIdentifie

<TRUNCATED>

[05/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - TestSourceMapStatements: added block open { to tested mappings

Posted by cd...@apache.org.
TestSourceMapStatements: added block open { to tested mappings


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

Branch: refs/heads/feature/maven-migration-test
Commit: c22e5a075e3fc760b68fd273fcfcdb1f3c389f3b
Parents: 6705005
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 15:54:21 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 15:54:21 2016 -0700

----------------------------------------------------------------------
 .../codegen/js/sourcemaps/TestSourceMapStatements.java      | 9 +++++++++
 1 file changed, 9 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c22e5a07/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
index 5d11227..436ee15 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
@@ -127,6 +127,7 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 18, 0, 36, 0, 38); // ;
         assertMapping(node, 0, 27, 0, 45, 0, 47); // ;
         assertMapping(node, 0, 32, 0, 50, 0, 52); // )
+        assertMapping(node, 0, 34, 0, 52, 0, 53); // {
     }
 
     @Test
@@ -153,6 +154,7 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 5, 0, 5, 0, 6); // ;
         assertMapping(node, 0, 6, 0, 6, 0, 7); // ;
         assertMapping(node, 0, 7, 0, 7, 0, 9); // )
+        assertMapping(node, 0, 9, 0, 9, 0, 10); // {
     }
 
     @Test
@@ -165,6 +167,7 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 0, 0, 0, 0, 5);    // for (
         assertMapping(node, 0, 14, 0, 32, 0, 36); // in
         assertMapping(node, 0, 21, 0, 39, 0, 41); // )
+        assertMapping(node, 0, 23, 0, 41, 0, 42); // {
     }
 
     @Test
@@ -235,6 +238,7 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
         assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
         assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
+        assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
     }
 
     @Test
@@ -247,7 +251,9 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
         assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
         assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
+        assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
         assertMapping(node, 0, 16, 2, 2, 2, 7);   // else
+        assertMapping(node, 0, 21, 2, 7, 2, 8);   // {
     }
 
     @Test
@@ -261,9 +267,12 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
         assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
         assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
+        assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
         assertMapping(node, 0, 16, 2, 2, 2, 11);  // else if(
         assertMapping(node, 0, 26, 2, 12, 2, 14); // )
+        assertMapping(node, 0, 28, 2, 14, 2, 15); // {
         assertMapping(node, 0, 37, 4, 2, 4, 7);   // else
+        assertMapping(node, 0, 42, 4, 7, 4, 8);    // {
     }
 
     @Test


[04/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - JSEmitter: overrides emitBlockOpen() and emitBlockClose() so that it can generate source maps

Posted by cd...@apache.org.
JSEmitter: overrides emitBlockOpen() and emitBlockClose() so that it can generate source maps


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

Branch: refs/heads/feature/maven-migration-test
Commit: 6705005c66ea099c9c3e8010731731ac50d931d0
Parents: 8c39361
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 15:42:33 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 15:42:33 2016 -0700

----------------------------------------------------------------------
 .../compiler/internal/codegen/js/JSEmitter.java | 18 ++++++++
 .../codegen/js/jx/BlockCloseEmitter.java        | 43 ++++++++++++++++++++
 .../codegen/js/jx/BlockOpenEmitter.java         | 43 ++++++++++++++++++++
 3 files changed, 104 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6705005c/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
index a50e288..1a73cf6 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
@@ -30,6 +30,8 @@ import org.apache.flex.compiler.common.ISourceLocation;
 import org.apache.flex.compiler.definitions.ITypeDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitter;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.jx.BlockCloseEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.BlockOpenEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.DoWhileLoopEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.DynamicAccessEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.ForLoopEmitter;
@@ -82,6 +84,8 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
 {
     private JSSessionModel model;
     
+    public BlockOpenEmitter blockOpenEmitter;
+    public BlockCloseEmitter blockCloseEmitter;
     public NumericLiteralEmitter numericLiteralEmitter;
     public ParametersEmitter parametersEmitter;
     public ParameterEmitter parameterEmitter;
@@ -126,6 +130,8 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
         model = new JSSessionModel();
         sourceMapMappings = new ArrayList<SourceMapMapping>();
 
+        blockOpenEmitter = new BlockOpenEmitter(this);
+        blockCloseEmitter = new BlockCloseEmitter(this);
         numericLiteralEmitter = new NumericLiteralEmitter(this);
         parametersEmitter = new ParametersEmitter(this);
         parameterEmitter = new ParameterEmitter(this);
@@ -305,6 +311,18 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
         interationFlowEmitter.emit(node);
     }
 
+    @Override
+    public void emitBlockOpen(IContainerNode node)
+    {
+        blockOpenEmitter.emit(node);
+    }
+
+    @Override
+    public void emitBlockClose(IContainerNode node)
+    {
+        blockCloseEmitter.emit(node);
+    }
+
     public void pushSourceMapName(ISourceLocation node)
     {
         boolean isValidMappingScope = node instanceof ITypeNode

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6705005c/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java
new file mode 100644
index 0000000..3099eda
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java
@@ -0,0 +1,43 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+
+public class BlockCloseEmitter extends JSSubEmitter implements
+        ISubEmitter<IContainerNode>
+{
+    public BlockCloseEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IContainerNode node)
+    {
+        startMapping(node);
+        write(ASEmitterTokens.BLOCK_CLOSE);
+        endMapping(node);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6705005c/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockOpenEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockOpenEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockOpenEmitter.java
new file mode 100644
index 0000000..5487d9c
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockOpenEmitter.java
@@ -0,0 +1,43 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+
+public class BlockOpenEmitter extends JSSubEmitter implements
+        ISubEmitter<IContainerNode>
+{
+    public BlockOpenEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IContainerNode node)
+    {
+        startMapping(node, node.getLine(), node.getColumn() - 1);
+        write(ASEmitterTokens.BLOCK_OPEN);
+        endMapping(node);
+    }
+}


[11/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

Posted by cd...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/java/org/apache/flex/compiler/common/ISourceLocation.java
----------------------------------------------------------------------
diff --cc compiler/src/main/java/org/apache/flex/compiler/common/ISourceLocation.java
index 738bdf3,0000000..25f6b6d
mode 100644,000000..100644
--- a/compiler/src/main/java/org/apache/flex/compiler/common/ISourceLocation.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/ISourceLocation.java
@@@ -1,75 -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.common;
 +
 +/**
 + * This interface provides information about where something 
 + * (a token, a tag, an attribute, a node, a definition, etc.)
 + * appears in source code.
 + * <p>
 + * Its primary purpose is for problem reporting.
 + * The start and end offsets are used to highlight
 + * a soruce range in the Flash Builder editor.
 + * The line and column numbers are used by command-line
 + * tools to report problems.
 + */
 +public interface ISourceLocation
 +{
 +    /**
 +     * Indicates an unknown or implicit starting offset, ending offset,
 +     * line number, or column number.
 +     */
 +    static final int UNKNOWN = -1;
 +    
 +    /**
 +     * Gets the normalized source path.
 +     */
 +    String getSourcePath();
 +    
 +    /**
 +     * Gets the local starting offset. It is zero-based.
 +     */
 +    int getStart();
 +
 +    /**
 +     * Gets the local ending offset. It is zero-based.
 +     */
 +    int getEnd();
 +    
 +    /**
 +     * Gets the local line number. It is zero-based.
 +     */
 +    int getLine();
 +    
 +    /**
 +     * Gets the local column number. It is zero-based.
 +     */
 +    int getColumn();
 +    
 +    /**
++     * Gets the local line number at the end. It is zero-based.
++     */
++    int getEndLine();
++
++    /**
++     * Gets the local column number at the end. It is zero-based.
++     */
++    int getEndColumn();
++    
++    /**
 +     * Gets the absolute starting offset. It is zero-based.
 +     */
 +    int getAbsoluteStart();
 +    
 +    /**
 +     * Gets the absolute starting offset. It is zero-based.
 +     */
 +    int getAbsoluteEnd();
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java
----------------------------------------------------------------------
diff --cc compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java
index 88998b7,0000000..0d0e1b0
mode 100644,000000..100644
--- a/compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java
@@@ -1,361 -1,0 +1,415 @@@
 +/*
 + *
 + *  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.common;
 +
 +import org.apache.flex.utils.FilenameNormalization;
 +
 +/**
 + * Common class to store file/location information across all source types
 + * such as AS, CSS etc
 + */
 +public class SourceLocation implements ISourceLocation
 +{
 +    /**
 +     * Constructor for a known source location.
 +     */
 +    public SourceLocation(String sourcePath, int start, int end, int line, int column)
 +    {
 +        this.sourcePath = sourcePath;
 +        this.start = start;
 +        this.end = end;
 +        this.line = line;
 +        this.column = column;
++        this.endLine = UNKNOWN;
++        this.endColumn = UNKNOWN;
 +    }
 +    
 +    /**
 +     * Copy Constructor for a known source location.
 +     */
 +    public SourceLocation(ISourceLocation location)
 +    {
 +        this(location.getSourcePath(),
 +             location.getStart(),
 +             location.getEnd(),
 +             location.getLine(),
 +             location.getColumn());
 +    }
 +
 +    /**
 +     * Constructor for an unknown source location.
 +     */
 +    public SourceLocation()
 +    {
 +        this(null, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
 +    }
 +
 +    /**
 +     * Source path.
 +     */
 +    private String sourcePath;
 +
 +    /**
 +     * Zero-based starting offset.
 +     * <p>
 +     * This class does not distinguish between local and absolute offsets,
 +     * but subclasses may. If so, they should store the absolute starting
 +     * offset in this field and use it to compute the local starting offset.
 +     */
 +    private int start;
 +    
 +    /**
 +     * Zero-based ending offset.
 +     * <p>
 +     * This class does not distinguish between local and absolute offsets,
 +     * but subclasses may. If so, they should store the absolute ending
 +     * offset in this field and use it to compute the local ending offset.
 +     */
 +    private int end;
 +    
 +    /**
 +     * Zero-based line number.
 +     * Corresponds to start, not end.
 +     */
 +    private int line;
 +    
 +    /**
 +     * Zero-based column number.
 +     * Corresponds to start, not end.
 +     */
 +    private int column;
++
++    /**
++     * Zero-based line number that corresponds to end.
++     */
++    private int endLine;
++
++    /**
++     * Zero-based column number that corresponds to end.
++     */
++    private int endColumn;
 +    
 +    /**
 +     * Copies source location information from another instance
 +     * into this instance.
 +     */
 +    public final void setSourceLocation(ISourceLocation src)
 +    {
 +        assert src != null : "source location can't be null";
 +        
 +        this.start = src.getStart();
 +        this.end = src.getEnd();
 +        this.line = src.getLine();
 +        this.column = src.getColumn();
++        this.endLine = src.getEndLine();
++        this.endColumn = src.getEndColumn();
 +        this.sourcePath = src.getSourcePath();
 +    }
 +
 +    /**
 +     * @return The local start offset
 +     */
 +    @Override
 +    public int getStart()
 +    {
 +        assert start >= 0 || start == UNKNOWN : "Invalid value for start: " + start;
 +        return start;
 +    }
 +
 +    /**
 +     * @return The absolute start offset.
 +     */
 +    @Override
 +    public int getAbsoluteStart()
 +    {
 +        assert start >= 0 || start == UNKNOWN : "Invalid value for start: " + start;
 +        return start;
 +    }
 +    
 +    /**
 +     * @return The absolute end offset.
 +     */
 +    @Override
 +    public int getAbsoluteEnd()
 +    {
 +        assert end >= 0 || end == UNKNOWN : "Invalid value for end: " + end;
 +        return end;
 +    }
 +    
 +    /**
 +     * Set the absolute offset where this node starts.
 +     */
 +    public void setStart(int start)
 +    {
 +        if (start != UNKNOWN)
 +            this.start = start;
 +    }
 +
 +    /**
 +     * @return The local end offset.
 +     */
 +    @Override
 +    public int getEnd()
 +    {
 +        assert end >= 0 || end == UNKNOWN : "Invalid value for end: " + end;
 +        return end;
 +    }
 +
 +    /**
 +     * Set the absolute offset where this node ends.
 +     */
 +    public void setEnd(int end)
 +    {
 +        if (end != UNKNOWN)
 +            this.end = end;
 +    }
 +
 +    /**
 +     * Get the line number where this node starts.
 +     * Line numbers start at 0, not 1.
 +     * @return The line number
 +     */
 +    @Override
 +    public int getLine()
 +    {
 +        assert line >= 0 || line == UNKNOWN : "Invalid value for line: " + line;
 +        return line;
 +    }
 +
 +    /**
 +     * Set the line number where this node starts.
 +     * Column numbers start at 0, not 1.
 +     * @param line The line number
 +     */
 +    public void setLine(int line)
 +    {
 +        if (line != UNKNOWN)
 +            this.line = line;
 +    }
 +
 +    /**
 +     * Get the column number where this node starts.
 +     * @return The column number
 +     */
 +    @Override
 +    public int getColumn()
 +    {
 +        assert column >= 0 || column == UNKNOWN : "Invalid value for column: " + column;
 +        return column;
 +    }
 +
 +    /**
 +     * Set the column number where this node starts.
 +     * @param column The column number
 +     */
 +    public void setColumn(int column)
 +    {
 +        if (column != UNKNOWN)
 +            this.column = column;
 +    }
 +
 +    /**
++     * Get the line number where this node ends.
++     * Line numbers start at 0, not 1.
++     * @return The line number
++     */
++    public int getEndLine()
++    {
++        return endLine;
++    }
++
++    /**
++     * Set the line number where this node ends.
++     * Column numbers start at 0, not 1.
++     * @param line The line number
++     */
++    public void setEndLine(int line)
++    {
++        this.endLine = line;
++    }
++
++    /**
++     * Get the column number where this node ends.
++     * @return The column number
++     */
++    public int getEndColumn()
++    {
++        return endColumn;
++    }
++
++    /**
++     * Set the column number where this node ends.
++     * @param column The column number
++     */
++    public void setEndColumn(int column)
++    {
++        this.endColumn = column;
++    }
++
++    /**
 +     * Get the source path for this node.
 +     * @return The source path for this node
 +     */
 +    @Override
 +    public final String getSourcePath()
 +    {
 +        // null means the source is unknown.
 +        // "" means the source is a buffer that hasn't yet been saved to a file.
 +        // Something like "framework.swc:defaults.css" means the source is a file inside a SWC.
 +        // TODO Shouldn't the part before the colon be normalized?
 +        // Anything else should be a normalized path to a source file.
 +        assert sourcePath == null ||
 +               sourcePath.isEmpty() ||
 +               sourcePath.contains(".swc:") ||
 +               FilenameNormalization.isNormalized(sourcePath)  :
 +               "Invalid value for sourcePath: " + sourcePath;
 +        return sourcePath;
 +    }
 +
 +    /**
 +     * Set the source path of the node.
 +     * @param sourcePath The source path
 +     */
 +    public final void setSourcePath(String sourcePath)
 +    {
 +        this.sourcePath = sourcePath;
 +    }
 +    
 +    /**
 +     * Displays line, column, start, end, and sourcepath in a format such as 
 +     * <pre>
 +     * "17:5 160-188 C:\test.as"
 +     * </pre>
 +     */
 +    @Override
 +    public String toString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +        sb.append(getLineColumnString());
 +        sb.append(getOffsetsString());
 +        sb.append(getSourcePathString());
 +        return sb.toString();
 +    }
 +
 +    /**
 +     * Displays Line and Column numbers
 +     */
 +    protected String getLineColumnString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +        int line = getLine();
 +        if (line != UNKNOWN)
 +            sb.append(line);
 +        else
 +            sb.append('?');
 +        sb.append(':');
 +        int column = getColumn();
 +        if (column != UNKNOWN)
 +            sb.append(column);
 +        else
 +            sb.append('?');
 +        
 +        sb.append(' ');
 +        return sb.toString();
 +    }
 +
 +    /**
 +     * Displays sourcepath
 +     * 
 +     */
 +    protected String getSourcePathString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +        sb.append(' ');
 +        
 +        String sourcePath = getSourcePath();
 +        if (sourcePath != null)
 +            sb.append(sourcePath);
 +        else
 +            sb.append('?');
 +        return sb.toString();
 +    }
 +
 +    /**
 +     * Displays line, column, start, end
 +     * 
 +     */
 +    protected String getOffsetsString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +        sb.append("loc: ");
 +        int start = getStart();
 +        if (start != UNKNOWN)
 +            sb.append(start);
 +        else
 +            sb.append('?');
 +        sb.append('-');
 +        int end = getEnd();
 +        if (end != UNKNOWN)
 +            sb.append(end);
 +        else
 +            sb.append('?');
 +        
 +        sb.append(' ');
 +
 +        sb.append("abs: ");
 +        int absoluteStart = getAbsoluteStart();
 +        if (absoluteStart != UNKNOWN)
 +            sb.append(absoluteStart);
 +        else
 +            sb.append('?');
 +        sb.append('-');
 +        int absoluteEnd = getAbsoluteEnd();
 +        if (absoluteEnd != UNKNOWN)
 +            sb.append(absoluteEnd);
 +        else
 +            sb.append('?');
 +        return sb.toString();
 +    }
 +   
 +    
 +    /**
 +     * Span the location range from {@code start} to {@code end}.
 +     * 
 +     * @param start Start location.
 +     * @param end End location.
 +     */
 +    public final void span(ISourceLocation start, ISourceLocation end)
 +    {
 +        setSourcePath(start.getSourcePath());
 +        setStart(start.getStart());
 +        setEnd(end.getEnd());
 +        setLine(start.getLine());
 +        setColumn(start.getColumn());
++        setEndLine(end.getEndLine());
++        setEndColumn(end.getEndColumn());
 +    }
 +    
 +    /**
 +     * Span the location range from {@code start} to {@code end}.
 +     * 
 +     * @param location The location
 +     */
 +    public final void span(ISourceLocation location)
 +    {
 +        if (location != null)
 +            setSourceLocation(location);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/java/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
----------------------------------------------------------------------
diff --cc compiler/src/main/java/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
index 92b9350,0000000..5b0b18e
mode 100644,000000..100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
@@@ -1,365 -1,0 +1,377 @@@
 +/*
 + *
 + *  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.definitions.metadata;
 +
 +import java.util.Arrays;
 +
 +import org.apache.flex.compiler.common.IMetaInfo;
 +import org.apache.flex.compiler.common.NodeReference;
 +import org.apache.flex.compiler.constants.IMetaAttributeConstants;
 +import org.apache.flex.compiler.definitions.IDefinition;
 +import org.apache.flex.compiler.definitions.metadata.IMetaTag;
 +import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute;
 +import org.apache.flex.compiler.filespecs.IFileSpecification;
 +import org.apache.flex.compiler.internal.definitions.DefinitionBase;
 +import org.apache.flex.compiler.internal.parsing.as.OffsetLookup;
 +import org.apache.flex.compiler.internal.scopes.ASFileScope;
 +import org.apache.flex.compiler.internal.scopes.ASScope;
 +import org.apache.flex.compiler.internal.tree.as.ClassNode;
 +import org.apache.flex.compiler.tree.as.IASNode;
 +import org.apache.flex.compiler.tree.metadata.IMetaTagNode;
 +import org.apache.flex.compiler.tree.metadata.IMetaTagsNode;
 +import org.apache.flex.compiler.workspaces.IWorkspace;
 +
 +public class MetaTag implements IMetaTag
 +{
 +    /**
 +     * Append a {@link IMetaTag} to an array of {@link IMetaTag}.
 +     * 
 +     * @param metaTags An existing array of meta tags. May be empty but
 +     * may not be null.
 +     * @param metaTag The new meta tag to append to the metaTags array.
 +     * If null, the metaTags parameter is returned unmodified.
 +     * @return The new array of meta tags.
 +     */
 +    public static IMetaInfo[] addMetaTag(IMetaInfo[] metaTags, IMetaInfo metaTag)
 +    {
 +        assert metaTags != null;
 +        
 +        if (metaTag != null)
 +        {
 +            IMetaInfo[] newMetaTags = Arrays.copyOf(metaTags, metaTags.length + 1, IMetaInfo[].class);
 +            newMetaTags[metaTags.length] = metaTag;
 +            metaTags = newMetaTags;
 +        }
 +
 +        return metaTags;
 +    }
 +    
 +    /**
 +     * Create a new meta tag for either "__go_to_ctor_definition_help" or
 +     * "__go_to_definition_help".
 +     * 
 +     * @param definition The definition to add the meta data for.
 +     * @param file The absolute path of the source file the definition is found
 +     *  in. May be null.
 +     * @param pos The position of the definition in the source file. If "-1"
 +     * no MetaTag is created.
 +     * @param ctor True if the definition is for a constructor, false otherwise.
 +     * @return A new MetaTag. If the pos paramater is "-1", null is returned.
 +     */
 +    public static MetaTag createGotoDefinitionHelp(IDefinition definition, 
 +            String file, String pos, boolean ctor)
 +    {
 +        assert pos != null;
 +        
 +        if (pos.equals("-1"))
 +            return null;
 +        
 +        IMetaTagAttribute[] attributes = new MetaTagAttribute[file != null ? 2 : 1];
 +        if (file != null)
 +        {
 +            attributes[0] = new MetaTagAttribute(IMetaAttributeConstants.NAME_GOTODEFINITIONHELP_FILE,
 +                    file); 
 +        }
 +
 +        attributes[file != null ? 1 : 0] = new MetaTagAttribute(IMetaAttributeConstants.NAME_GOTODEFINITIONHELP_POS,
 +                pos); 
 +
 +        return new MetaTag(definition, 
 +                ctor ? IMetaAttributeConstants.ATTRIBUTE_GOTODEFINITION_CTOR_HELP :
 +                       IMetaAttributeConstants.ATTRIBUTE_GOTODEFINITIONHELP, 
 +                        attributes);
 +    }
 +    
 +    public MetaTag(IDefinition decoratedDefinition, String tagName, IMetaTagAttribute[] attributes)
 +    {
 +        this.decoratedDefinition = decoratedDefinition;
 +        this.tagName = tagName;
 +        if (attributes == null)
 +        {
 +            // this is a low cost way to make sure that clients never get null attributes
 +            attributes = emptyAttributes;
 +        }
 +        this.attributes = attributes;
 +    }
 +
 +    private IDefinition decoratedDefinition;
 +
 +    private String tagName;
 +
 +    private IMetaTagAttribute[] attributes;
 +
 +    // Singleton empty array to be shared by all instances that don't have attributes
 +    private static final IMetaTagAttribute[] emptyAttributes = new IMetaTagAttribute[0];
 +
 +    private String sourcePath;
 +
 +    private int absoluteStart = UNKNOWN;
 +
 +    private int absoluteEnd = UNKNOWN;
 +
 +    private int line = UNKNOWN;
 +
 +    private int column = UNKNOWN;
 +
 +    // Hold a reference to the node this definition came from
 +    // (NodeReference only holds onto the node weakly, so we don't have to worry about leaks).
 +    private NodeReference nodeRef = NodeReference.noReference;
 +
 +    @Override
 +    public String getTagName()
 +    {
 +        return tagName;
 +    }
 +
 +    @Override
 +    public IMetaTagAttribute[] getAllAttributes()
 +    {
 +        return attributes;
 +    }
 +
 +    @Override
 +    public IMetaTagAttribute getAttribute(String key)
 +    {
 +        for (IMetaTagAttribute attribute : attributes)
 +        {
 +            String attrKey = attribute.getKey();
 +            if (attrKey != null && attrKey.equals(key))
 +                return attribute;
 +        }
 +        return null;
 +    }
 +
 +    @Override
 +    public String getAttributeValue(String key)
 +    {
 +        for (IMetaTagAttribute attribute : attributes)
 +        {
 +            // For metadata such as [Foo("abc", "def")],
 +            // the attribute keys are null, so a null
 +            // check on the key is necessary.
 +            // BTW, keyless values like "abc" and "def"
 +            // cannot be retrieved by this API;
 +            // you have to use getAttributes()[i].getValue().
 +            String attrKey = attribute.getKey();
 +            if (attrKey != null && attrKey.equals(key))
 +                return attribute.getValue();
 +        }
 +        return null;
 +    }
 +
 +    @Override
 +    public String getSourcePath()
 +    {
 +        return sourcePath;
 +    }
 +
 +    private OffsetLookup getOffsetLookup()
 +    {
 +        DefinitionBase definition = (DefinitionBase)getDecoratedDefinition();
 +        if (definition == null)
 +            return null;
 +
 +        final ASFileScope fileScope = definition.getFileScope();
 +        if (fileScope == null)
 +            return null;
 +
 +        return fileScope.getOffsetLookup();
 +    }
 +
 +    @Override
 +    public int getStart()
 +    {
 +        OffsetLookup offsetLookup = getOffsetLookup();
 +
 +        if (offsetLookup == null)
 +            return absoluteStart;
 +
 +        return offsetLookup.getLocalOffset(absoluteStart);
 +    }
 +
 +    @Override
 +    public int getEnd()
 +    {
 +        OffsetLookup offsetLookup = getOffsetLookup();
 +
 +        if (offsetLookup == null)
 +            return absoluteEnd;
 +
 +        return offsetLookup.getLocalOffset(absoluteEnd);
 +    }
 +
 +    @Override
 +    public int getLine()
 +    {
 +        return line;
 +    }
 +
 +    @Override
 +    public int getColumn()
 +    {
 +        return column;
 +    }
 +
 +    @Override
++    public int getEndLine()
++    {
++        return line;
++    }
++
++    @Override
++    public int getEndColumn()
++    {
++        return column;
++    }
++
++    @Override
 +    public int getAbsoluteStart()
 +    {
 +        return absoluteStart;
 +    }
 +
 +    @Override
 +    public int getAbsoluteEnd()
 +    {
 +        return absoluteEnd;
 +    }
 +
 +    @Override
 +    public IDefinition getDecoratedDefinition()
 +    {
 +        return decoratedDefinition;
 +    }
 +
 +    @Override
 +    public String getValue()
 +    {
 +        return attributes.length == 1 && !attributes[0].hasKey() ?
 +                attributes[0].getValue() :
 +                null;
 +    }
 +
 +    @Override
 +    public IMetaTagNode getTagNode()
 +    {
 +        // If this definition didn't come from source, return null.
 +        if (nodeRef == NodeReference.noReference)
 +            return null;
 +
 +        // Get the scope for the definition this metadata is attached to.
 +        ASScope containingScope = (ASScope)getDecoratedDefinition().getContainingScope();
 +        if (containingScope == null)
 +            return null;
 +
 +        // Get the file scope for that scope.
 +        ASFileScope fileScope = containingScope.getFileScope();
 +        if (fileScope == null)
 +            return null;
 +
 +        // Get the workspace.
 +        IWorkspace workspace = fileScope.getWorkspace();
 +        assert workspace != null;
 +
 +        // Use the stored NodeReference to get the original node.
 +        IASNode node = nodeRef.getNode(workspace, containingScope);
 +        if (!(node instanceof IMetaTagNode))
 +        {
 +            // CMP-2168: The NodeReference resolver assumes that all definitions
 +            // have a unique start offset.  This true in every case except when
 +            // there are metadata definitions decorating a class.  In this case, the
 +            // start of the metadata and the start of the class are the same, and the
 +            // resolver will return the ClassNode, not the MetaTagNode.  Catch this
 +            // case by when we get a ClassNode, walking any metatags on the class
 +            // looking for an offset that matches this MetaTag offset.
 +            if (node instanceof ClassNode)
 +            {
 +                IMetaTagsNode metaTags = ((ClassNode)node).getMetaTags();
 +                if (metaTags != null)
 +                {
 +                    for (IMetaTagNode metaTagNode : metaTags.getAllTags())
 +                    {
 +                        if (metaTagNode.getAbsoluteStart() == getAbsoluteStart())
 +                            return metaTagNode;
 +                    }
 +                }
 +            }
 +
 +            return null;
 +        }
 +
 +        return (IMetaTagNode)node;
 +    }
 +
 +    /**
 +     * Updates the location information of this tag.
 +     */
 +    public void setLocation(IFileSpecification containingFileSpec, int absoluteStart, int absoluteEnd, int line, int column)
 +    {
 +        this.nodeRef = new NodeReference(containingFileSpec, absoluteStart);
 +        this.sourcePath = containingFileSpec.getPath();
 +        this.absoluteStart = absoluteStart;
 +        this.absoluteEnd = absoluteEnd;
 +        this.line = line;
 +        this.column = column;
 +    }
 +
 +    /**
 +     * For debugging only.
 +     */
 +    @Override
 +    public String toString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +
 +        sb.append('[');
 +        sb.append(tagName);
 +
 +        IMetaTagAttribute[] attrs = getAllAttributes();
 +        if (attrs != null && attrs.length > 0)
 +        {
 +            sb.append('(');
 +
 +            int i = 0;
 +            for (IMetaTagAttribute attr : getAllAttributes())
 +            {
 +                if (i != 0)
 +                {
 +                    sb.append(',');
 +                    sb.append(' ');
 +                }
 +
 +                String key = attr.getKey();
 +                String value = attr.getValue();
 +
 +                sb.append(key);
 +                sb.append('=');
 +                sb.append('"');
 +                sb.append(value);
 +                sb.append('"');
 +
 +                i++;
 +            }
 +            sb.append(')');
 +        }
 +
 +        sb.append(']');
 +
 +        return sb.toString();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/java/org/apache/flex/compiler/internal/parsing/TokenBase.java
----------------------------------------------------------------------
diff --cc compiler/src/main/java/org/apache/flex/compiler/internal/parsing/TokenBase.java
index 68a76eb,0000000..ff726da
mode 100644,000000..100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/parsing/TokenBase.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/parsing/TokenBase.java
@@@ -1,515 -1,0 +1,559 @@@
 +/*
 + *
 + *  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.parsing;
 +
 +import antlr.Token;
 +
 +import org.apache.flex.compiler.common.ISourceLocation;
 +import org.apache.flex.compiler.internal.common.Counter;
 +import org.apache.flex.compiler.internal.parsing.as.ASTokenTypes;
 +import org.apache.flex.compiler.internal.parsing.as.IncludeHandler;
 +import org.apache.flex.compiler.parsing.ICMToken;
 +
 +/**
 + * Base class of ASToken, MXMLToken, CSSToken
 + */
 +public abstract class TokenBase extends Token implements ICMToken, ISourceLocation
 +{
 +    /**
 +     * Constructor
 +     * 
 +     * @param tokenType type of token
 +     * @param start location location information
 +     * @param end location location information
 +     * @param line location location information
 +     * @param column location location information
 +     * @param text actual text represented by token
 +     */
 +    public TokenBase(int tokenType, int start, int end, int line, int column, CharSequence text)
 +    {
 +        type = tokenType;
 +        localStart = this.start = start;
 +        localEnd = this.end = end;
 +        this.line = line;
 +        this.column = column;
 +        this.text = text;
++        this.endLine = line;
++        this.endColumn = column + end - start;
 +
 +        if (Counter.COUNT_TOKENS)
 +            countTokens();
 +    }
 +
 +    /**
 +     * Copy constructor
 +     * 
 +     * @param o token to copy
 +     */
 +    public TokenBase(TokenBase o)
 +    {
 +        type = o.type;
 +        start = o.start;
 +        end = o.end;
 +        line = o.line;
 +        column = o.column;
++        endLine = o.endLine;
++        endColumn = o.endColumn;
 +        text = o.text;
 +
 +        localStart = o.localStart;
 +        localEnd = o.localEnd;
 +        sourcePath = o.sourcePath;
 +
 +        if (Counter.COUNT_TOKENS)
 +            countTokens();
 +    }
 +
 +    /**
 +     * Text represented by this token
 +     */
 +    private CharSequence text;
 +
 +    /**
 +     * Start of this token
 +     */
 +    private int start;
 +
 +    /**
 +     * End offset of this token
 +     */
 +    private int end;
 +
 +    /**
 +     * Line of this token
 +     */
 +    private int line;
 +
 +    /**
 +     * Column of this token
 +     */
 +    private int column;
 +
 +    /**
++     * End line of this token
++     */
++    private int endLine;
++
++    /**
++     * End column of this token
++     */
++    private int endColumn;
++
++    /**
 +     * Flag to determine if this token is locked
 +     */
 +    private boolean locked;
 +
 +    /**
 +     * Local start offset.
 +     */
 +    private int localStart;
 +
 +    /**
 +     * Local end offset.
 +     */
 +    private int localEnd;
 +
 +    protected abstract String getTypeString();
 +
 +    /**
 +     * @return Local start offset.
 +     */
 +    public final int getLocalStart()
 +    {
 +        return localStart;
 +    }
 +
 +    /**
 +     * @return Local end offset.
 +     */
 +    public final int getLocalEnd()
 +    {
 +        return localEnd;
 +    }
 +
 +    public final void reuse(final int tokenType, final int start, final int end,
 +            final int line, final int column, final CharSequence text)
 +    {
 +        type = tokenType;
 +        this.start = start;
 +        this.end = end;
 +        this.line = line;
 +        this.column = column;
++        this.endLine = line;
++        this.endColumn = column + end - start;
 +        this.text = text;
 +    }
 +
 +    /**
 +     * Locks this token. When locked, if this token is in a token pool, it will
 +     * not be overwritten
 +     */
 +    public void lock()
 +    {
 +        locked = true;
 +    }
 +
 +    /**
 +     * Returns whether this token can be overwritten when it is a member of a
 +     * token pool
 +     * 
 +     * @return true if we are locked
 +     */
 +    public boolean isLocked()
 +    {
 +        return locked;
 +    }
 +
 +    /**
 +     * Get the text represented by this token
 +     * 
 +     * @return text represented by this token
 +     * @see antlr.Token#getText()
 +     */
 +    @Override
 +    public String getText()
 +    {
 +        //we're either going to be a String or a StringBuilder
 +        //String.toString returns itself
 +        //StringBuilder toString returns a new String
 +        if (text != null)
 +            return text.toString();
 +        return "";
 +    }
 +
 +    /**
 +     * Returns the underlying CharSequence that represents the contents of this
 +     * token
 +     * 
 +     * @return a {@link CharSequence} or null
 +     */
 +    public CharSequence getCharSequence()
 +    {
 +        return text;
 +    }
 +
 +    /**
 +     * Set the text represented by this token
 +     * 
 +     * @param text text represented by this token
 +     * @see antlr.Token#setText(java.lang.String)
 +     */
 +    @Override
 +    public void setText(String text)
 +    {
 +        this.text = text;
 +    }
 +
 +    /**
 +     * Set the CharSequence represented by this token
 +     * 
 +     * @param text text represented by this token
 +     */
 +    public void setText(CharSequence text)
 +    {
 +        this.text = text;
 +    }
 +
 +    public void setLocation(int start, int end, int line, int column)
 +    {
 +        this.start = start;
 +        this.end = end;
 +        this.line = line;
 +        this.column = column;
++        this.endLine = line;
++        this.endColumn = column + end - start;
 +    }
 +
 +    @Override
 +    public int getStart()
 +    {
 +        return start;
 +    }
 +
 +    public void setStart(int start)
 +    {
 +        this.start = start;
 +    }
 +
 +    @Override
 +    public int getEnd()
 +    {
 +        return end;
 +    }
 +
 +    public void setEnd(int end)
 +    {
 +        this.end = end;
 +    }
 +
 +    @Override
 +    public int getLine()
 +    {
 +        return line;
 +    }
 +
 +    @Override
 +    public void setLine(int line)
 +    {
 +        this.line = line;
 +    }
 +
 +    public final boolean matchesLine(final TokenBase other)
 +    {
 +        return other != null && other.line == line;
 +    }
 +
 +    @Override
 +    public int getColumn()
 +    {
 +        return column;
 +    }
 +
 +    @Override
 +    public void setColumn(int column)
 +    {
 +        this.column = column;
 +    }
 +
++    @Override
++    public int getEndLine()
++    {
++        return endLine;
++    }
++
++    public void setEndLine(int line)
++    {
++        endLine = line;
++    }
++
++    @Override
++    public int getEndColumn()
++    {
++        return endColumn;
++    }
++
++    public void setEndColumn(int column)
++    {
++        endColumn = column;
++    }
++
 +    /**
 +     * Determine whether or not this token is bogus (i.e. the start and end
 +     * offsets are the same, which implies that it was inserted from an included
 +     * file or during token fixup)
 +     * 
 +     * @return true iff the token is bogus
 +     */
 +    @Override
 +    public boolean isImplicit()
 +    {
 +        return start == end;
 +    }
 +
 +    /**
 +     * For debugging only.
 +     */
 +    private String getEscapedText()
 +    {
 +        String text = getText();
 +
 +        text = text.replaceAll("\n", "\\\\n");
 +        text = text.replaceAll("\r", "\\\\r");
 +        text = text.replaceAll("\t", "\\\\t");
 +
 +        return text;
 +    }
 +
 +    /**
 +     * For debugging only. This format is nice in the Eclipse debugger.
 +     */
 +    @Override
 +    public String toString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +
 +        sb.append('|');
 +        sb.append(getEscapedText());
 +        sb.append('|');
 +
 +        sb.append(' ');
 +
 +        sb.append(getTypeString());
 +
 +        sb.append(' ');
 +
 +        if (locked)
 +            sb.append("locked ");
 +
 +        int line = getLine();
 +        if (line != UNKNOWN)
 +            sb.append(line + 1);
 +        else
 +            sb.append('?');
 +        sb.append(':');
 +        int column = getColumn();
 +        if (column != UNKNOWN)
 +            sb.append(column + 1);
 +        else
 +            sb.append('?');
 +
 +        sb.append(' ');
 +
 +        int start = getStart();
 +        if (start != UNKNOWN)
 +            sb.append(start);
 +        else
 +            sb.append('?');
 +        sb.append('-');
 +        int end = getEnd();
 +        if (end != UNKNOWN)
 +            sb.append(end);
 +        else
 +            sb.append('?');
 +
 +        sb.append(' ');
 +        String sourcePath = getSourcePath();
 +        if (sourcePath != null)
 +        {
 +            sb.append('"');
 +            sb.append(sourcePath);
 +            sb.append('"');
 +        }
 +        else
 +        {
 +            sb.append('?');
 +        }
 +
 +        return sb.toString();
 +    }
 +
 +    /**
 +     * For debugging only. This format is nice in a text file.
 +     */
 +    public String toDumpString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +
 +        sb.append(getLine() + 1);
 +        sb.append('\t');
 +        sb.append(getColumn() + 1);
 +        sb.append('\t');
 +        sb.append(getStart());
 +        sb.append('\t');
 +        sb.append(getEnd());
 +        sb.append('\t');
 +
 +        String typeString = getTypeString();
 +        sb.append(typeString);
 +        int n = 28 - typeString.length();
 +        for (int i = 0; i < n; i++)
 +            sb.append(' ');
 +        sb.append('\t');
 +
 +        sb.append('|');
 +        sb.append(getEscapedText());
 +        sb.append('|');
 +
 +        return sb.toString();
 +    }
 +
 +    /**
 +     * Reduce the span of the token by removing characters from the beginning
 +     * and end. This is used to remove quote characters and such from tokens.
 +     * 
 +     * @param trimLeft number of characters to remove from the left of the token
 +     * @param trimRight number of characters to remove from the right of the
 +     * token
 +     */
 +    public void truncate(int trimLeft, int trimRight)
 +    {
 +        String text = getText();
 +        if (trimLeft + trimRight <= text.length())
 +        {
 +            text = text.substring(trimLeft, text.length() - trimRight);
 +            setText(text);
 +            start += trimLeft;
 +            end -= trimRight;
 +        }
 +    }
 +
 +    /**
 +     * Adjust all associated offsets by the adjustment amount
 +     * 
 +     * @param offsetAdjustment amount to add to offsets
 +     */
 +    public void adjustOffsets(int offsetAdjustment)
 +    {
 +        start += offsetAdjustment;
 +        end += offsetAdjustment;
 +    }
 +
 +    /**
 +     * Adjust all associated offsets by the adjustment amount
 +     * 
 +     * @param offsetAdjustment amount to add to offsets
 +     * @param lineAdjustment amount to add to the line number
 +     * @param columnAdjustment amount to add to the column number
 +     */
 +    public void adjustLocation(int offsetAdjustment, int lineAdjustment, int columnAdjustment)
 +    {
 +        start += offsetAdjustment;
 +        end += offsetAdjustment;
 +        line += lineAdjustment;
 +        column += columnAdjustment;
++        endLine += lineAdjustment;
++        endColumn += columnAdjustment;
 +    }
 +
 +    /**
 +     * Capture the current start/end offsets as this token's local offsets. This
 +     * method is called in {@code StreamingASTokenizer#nextTokenFromReader()}
 +     * after the token is initialized, and before being updated by
 +     * {@link IncludeHandler#onNextToken}.
 +     */
 +    public final void storeLocalOffset()
 +    {
 +        this.localStart = start;
 +        this.localEnd = end;
 +    }
 +
 +    private String sourcePath;
 +
 +    @Override
 +    public final String getSourcePath()
 +    {
 +        return sourcePath;
 +    }
 +
 +    public final void setSourcePath(String path)
 +    {
 +        this.sourcePath = path;
 +    }
 +
 +    /**
 +     * Verifies that this token has its type and location information set.
 +     * <p>
 +     * This is used only in asserts.
 +     */
 +    public boolean verify()
 +    {
 +        // Verify the token type.
 +        int type = getType();
 +        assert type != 0 : "Token has no type: " + toString();
 +
 +        // Verify the source location (except for EOF tokens,
 +        // which are special and don't have a source location).
 +        if (type != ASTokenTypes.EOF)
 +        {
 +            assert getStart() != UNKNOWN : "Token has unknown start: " + toString();
 +            assert getEnd() != UNKNOWN : "Token has unknown end: " + toString();
 +            assert getLine() != UNKNOWN : "Token has an unknown line: " + toString();
 +            assert getColumn() != UNKNOWN : "Token has an unknown column: " + toString();
++            assert getEndLine() != UNKNOWN : "Token has an unknown end line: " + toString();
++            assert getEndColumn() != UNKNOWN : "Token has an unknown end column: " + toString();
 +        }
 +
 +        return true;
 +    }
 +
 +    /**
 +     * Counts various types of tokens that are created, as well as the total
 +     * number of tokens.
 +     */
 +    private void countTokens()
 +    {
 +        Counter counter = Counter.getInstance();
 +        counter.incrementCount(getClass().getSimpleName());
 +        counter.incrementCount("tokens");
 +    }
 +
 +    @Override
 +    public int getAbsoluteEnd()
 +    {
 +        return getEnd();
 +    }
 +
 +    @Override
 +    public int getAbsoluteStart()
 +    {
 +        return getStart();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/NodeBase.java
----------------------------------------------------------------------
diff --cc compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/NodeBase.java
index be0510d,0000000..8dd4fb6
mode 100644,000000..100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/NodeBase.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/NodeBase.java
@@@ -1,1038 -1,0 +1,1049 @@@
 +/*
 + *
 + *  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.tree.as;
 +
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.EnumSet;
 +
 +import antlr.Token;
 +
 +import org.apache.flex.compiler.common.ASModifier;
 +import org.apache.flex.compiler.common.ISourceLocation;
 +import org.apache.flex.compiler.common.SourceLocation;
 +import org.apache.flex.compiler.definitions.IDefinition;
 +import org.apache.flex.compiler.filespecs.IFileSpecification;
 +import org.apache.flex.compiler.internal.common.Counter;
 +import org.apache.flex.compiler.internal.definitions.DefinitionBase;
 +import org.apache.flex.compiler.internal.parsing.as.OffsetLookup;
 +import org.apache.flex.compiler.internal.scopes.ASFileScope;
 +import org.apache.flex.compiler.internal.scopes.ASScope;
 +import org.apache.flex.compiler.internal.scopes.TypeScope;
 +import org.apache.flex.compiler.internal.semantics.PostProcessStep;
 +import org.apache.flex.compiler.problems.ICompilerProblem;
 +import org.apache.flex.compiler.scopes.IASScope;
 +import org.apache.flex.compiler.tree.ASTNodeID;
 +import org.apache.flex.compiler.tree.as.IASNode;
 +import org.apache.flex.compiler.tree.as.IFileNode;
 +import org.apache.flex.compiler.tree.as.IImportNode;
 +import org.apache.flex.compiler.tree.as.IPackageNode;
 +import org.apache.flex.compiler.tree.as.IScopedNode;
 +import org.apache.flex.compiler.tree.mxml.IMXMLClassDefinitionNode;
 +import org.apache.flex.compiler.workspaces.IWorkspace;
 +
 +/**
 + * Base class for ActionScript parse tree nodes
 + */
 +public abstract class NodeBase extends SourceLocation implements IASNode
 +{
 +    /**
 +     * Used in calls to CheapArray functions. It represents the type of objects
 +     * that appear in fSymbols.
 +     */
 +    protected static final IASNode[] emptyNodeArray = new IASNode[0];
 +    
 +
 +    /**
 +     * Combine the attributes from the base class with the attributes specific
 +     * to this class
 +     * 
 +     * @param superAttributes The attributes of the base class.
 +     * @param myAttributes The attributes of this class.
 +     * @return attribute value
 +     */
 +    public static String[] combineAttributes(String[] superAttributes, String[] myAttributes)
 +    {
 +        String[] combinedAttributes = new String[superAttributes.length + myAttributes.length];
 +        for (int i = 0; i < superAttributes.length; i++)
 +        {
 +            combinedAttributes[i] = superAttributes[i];
 +        }
 +        for (int i = 0; i < myAttributes.length; i++)
 +        {
 +            combinedAttributes[superAttributes.length + i] = myAttributes[i];
 +        }
 +        return combinedAttributes;
 +    }
 +
 +    /**
 +     * Constructor.
 +     */
 +    public NodeBase()
 +    {
 +        super();
 +        parent = null;
 +        
 +        if (Counter.COUNT_NODES)
 +            countNodes();
 +    }
 +
 +    /**
 +     * Parent node.
 +     * <p>
 +     * Methods (even in NodeBase itself) should use getParent() instead of
 +     * accessing this member directly. getParent() is overridden in FileNode to
 +     * do something special when the FileNode represents a shared file.
 +     */
 +    protected IASNode parent;
 +
 +    @Override
 +    public IASNode getParent()
 +    {
 +        return parent;
 +    }
 +
 +    @Override
 +    public int getChildCount()
 +    {
 +        return 0;
 +    }
 +
 +    @Override
 +    public IASNode getChild(int i)
 +    {
 +        return null;
 +    }
 +
 +    @Override
 +    public IFileSpecification getFileSpecification()
 +    {
 +        // TODO Make sure this works with include processing!!!
 +        ASFileScope fileScope = getFileScope();
 +        IWorkspace w = fileScope.getWorkspace();
 +        return w.getFileSpecification(fileScope.getContainingPath());
 +    }
 +
 +    @Override
 +    public int getSpanningStart()
 +    {
 +        return getStart();
 +    }
 +
 +    /**
 +     * Get the node type as a string. For example, this will return
 +     * "IdentifierNode" for an IdentifierNode.
 +     * 
 +     * @return the node type
 +     */
 +    public String getNodeKind()
 +    {
 +        return getClass().getSimpleName();
 +    }
 +
 +    @Override
 +    public boolean contains(int offset)
 +    {
 +        return getAbsoluteStart() < offset && getAbsoluteEnd() >= offset;
 +    }
 +
 +    /**
 +     * Determine whether the offset "loosely" fits within this node. With normal
 +     * nodes, this will return true if the offset matches fLocation.fStart or
 +     * fLocation.fEnd or anything in between. With bogus nodes (which have
 +     * fStart == fEnd), this will return true if the offset comes after fStart
 +     * and before any other nodes in the parse tree
 +     * 
 +     * @param offset the offset to test
 +     * @return true if the offset is "loosely" contained within this node
 +     */
 +    public boolean looselyContains(int offset)
 +    {
 +        if (getAbsoluteStart() == getAbsoluteEnd())
 +        {
 +            // This is a bogus placeholder node (generally an identifier that's been inserted to complete an expression).
 +            // We'll pretend that it extends all the way to the start offset of the next node.  Now to find that next node...
 +            if (getAbsoluteStart() <= offset)
 +            {
 +                NodeBase containingNode = (NodeBase)getParent();
 +                // Step 1: Find a node that extends beyond the target offset
 +                while (containingNode != null && containingNode.getAbsoluteEnd() <= getAbsoluteEnd())
 +                    containingNode = (NodeBase)containingNode.getParent();
 +                // If no such node exists, we know that there aren't any tokens in the parse
 +                // tree that end after this bogus token.  So we can go ahead and pretend this node
 +                // extends all the way out.
 +                if (containingNode == null)
 +                    return true;
 +                // Step 2: Find a node that starts after the target offset
 +                IASNode succeedingNode = containingNode.getSucceedingNode(getAbsoluteEnd());
 +                // If no such node exists, we know that there aren't any tokens in the parse
 +                // tree that start after this bogus token.  So we can go ahead and pretend this
 +                // node extends all the way out.
 +                if (succeedingNode == null)
 +                    return true;
 +                // Otherwise, pretend this node extends all the way to the next token.
 +                if (succeedingNode.getAbsoluteStart() >= offset)
 +                    return true;
 +            }
 +        }
 +        else
 +        {
 +            // This is a real token.  See if the test offset fits within (including the boundaries, since we're looking
 +            // at "loose" containment.
 +            return getAbsoluteStart() <= offset && getAbsoluteEnd() >= offset;
 +        }
 +        return false;
 +    }
 +
 +    @Override
 +    public IASNode getSucceedingNode(int offset)
 +    {
 +        // This node ends before the offset is even reached.  This is hopeless.
 +        if (getAbsoluteEnd() <= offset)
 +            return null;
 +
 +        // See if one of our children starts after the offset
 +        for (int i = 0; i < getChildCount(); i++)
 +        {
 +            IASNode child = getChild(i);
 +            
 +            if (child.getAbsoluteStart() > offset)
 +                return child;
 +            else if (child.getAbsoluteEnd() > offset)
 +                return child.getSucceedingNode(offset);
 +        }
 +        
 +        return null;
 +    }
 +
 +    /**
 +     * Determine whether this node is transparent. If a node is transparent, it
 +     * can never be returned from getContainingNode... the offset will be
 +     * considered part of the parent node instead.
 +     * 
 +     * @return true if the node is transparent
 +     */
 +    public boolean isTransparent()
 +    {
 +        return false;
 +    }
 +
 +    @Override
 +    public IASNode getContainingNode(int offset)
 +    {
 +        // This node doesn't even contain the offset.  This is hopeless.
 +        if (!contains(offset))
 +        {
 +            return null;
 +        }
 +        IASNode containingNode = this;
 +        int childCount = getChildCount();
 +        // See if the offset is contained within one of our children.
 +        for (int i = 0; i < childCount; i++)
 +        {
 +            IASNode child = getChild(i);
 +            if (child.getAbsoluteStart() <= offset)
 +            {
 +                if (child.contains(offset))
 +                {
 +                    containingNode = child.getContainingNode(offset);
 +                    if (child instanceof NodeBase && ((NodeBase)child).canContinueContainmentSearch(containingNode, this, i, true))
 +                        continue;
 +                    break;
 +                }
 +            }
 +            else
 +            {
 +                if (child instanceof NodeBase && ((NodeBase)child).canContinueContainmentSearch(containingNode, this, i, false))
 +                    continue;
 +                // We've passed this offset without finding a child that contains it.  This is
 +                // the nearest enclosing node.
 +                break;
 +            }
 +        }
 +        // Make sure we don't return a transparent node
 +        while (containingNode != null && containingNode instanceof NodeBase && ((NodeBase)containingNode).isTransparent())
 +        {
 +            containingNode = containingNode.getParent();
 +        }
 +        return containingNode;
 +    }
 +
 +    @Override
 +    public boolean isTerminal()
 +    {
 +        return false;
 +    }
 +
 +    @Override
 +    public IScopedNode getContainingScope()
 +    {
 +        return (IScopedNode)getAncestorOfType(IScopedNode.class);
 +    }
 +
 +    // TODO Can probably eliminate this.
 +    protected boolean canContinueContainmentSearch(IASNode containingNode, IASNode currentNode, int childOffset, boolean offsetsStillValid)
 +    {
 +        return false;
 +    }
 +
 +    @Override
 +    public IASNode getAncestorOfType(Class<? extends IASNode> nodeType)
 +    {
 +        IASNode current = getParent();
 +        while (current != null && !(nodeType.isInstance(current)))
 +            current = current.getParent();
 +        if (current != null)
 +            return current;
 +        return null;
 +    }
 +
 +    @Override
 +    public String getPackageName()
 +    {
 +        // Starting with this node's parent, walk up the parent chain
 +        // looking for a package node or an MXML class definition node.
 +        // These two types of nodes understand what their package is.
 +        IASNode current = getParent();
 +        while (current != null &&
 +               !(current instanceof IPackageNode ||
 +                 current instanceof IMXMLClassDefinitionNode))
 +        {
 +            current = current.getParent();
 +        }
 +
 +        if (current instanceof IPackageNode)
 +            return ((IPackageNode)current).getPackageName();
 +        else if (current instanceof IMXMLClassDefinitionNode)
 +            return ((IMXMLClassDefinitionNode)current).getPackageName();
 +
 +        return null;
 +    }
 +
 +    /**
 +     * Set the start offset of the node to fall just after the token. Used
 +     * during parsing.
 +     * 
 +     * @param token start this node after this token
 +     */
 +    public void startAfter(Token token)
 +    {
 +        if (token instanceof ISourceLocation)
 +        {
 +            startAfter((ISourceLocation) token);
-             setColumn(getColumn() + token.getText().length());
 +        }
 +    }
 +    
 +    /**
 +     * Set the start offset of the node to fall just after the token. Used
 +     * during parsing.
 +     * 
 +     * @param location start this node after this token
 +     */
 +    public final void startAfter(ISourceLocation location)
 +    {
 +        final int end = location.getEnd();
 +        if (end != UNKNOWN)
 +        {
 +            setSourcePath(location.getSourcePath());
 +            setStart(end);
-             setLine(location.getLine());
-             setColumn(location.getColumn());
++            setLine(location.getEndLine());
++            setColumn(location.getEndColumn());
 +        }
 +    }
 +
 +    /**
 +     * Set the start offset of the node to fall just before the token. Used
 +     * during parsing.
 +     * 
 +     * @param token start this node before this token
 +     */
 +    public final void startBefore(Token token)
 +    {
 +        if (token instanceof ISourceLocation)
 +            startBefore((ISourceLocation)token);
 +    }
 +
 +    /**
 +     * Set the start offset of the node to fall just before the token. Used
 +     * during parsing.
 +     * 
 +     * @param location start this node before this token
 +     */
 +    public final void startBefore(ISourceLocation location)
 +    {
 +        final int start = location.getStart();
 +        if (start != UNKNOWN)
 +        {
 +            setSourcePath(location.getSourcePath());
 +            setStart(start);
 +            setLine(location.getLine());
 +            setColumn(location.getColumn());
 +        }
 +    }
 +
 +    /**
 +     * Set the end offset of the node to fall just after the token. Used during
 +     * parsing.
 +     * 
 +     * @param token end this node after this token
 +     */
 +    public final void endAfter(Token token)
 +    {
 +        if (token instanceof ISourceLocation)
 +            endAfter((ISourceLocation)token);
 +    }
 +
 +    /**
 +     * Set the end offset of the node to fall just after the token. Used during
 +     * parsing.
 +     * 
 +     * @param location end this node after this token
 +     */
 +    public final void endAfter(ISourceLocation location)
 +    {
 +        final int end = location.getEnd();
 +        if (end != UNKNOWN)
++        {
 +            setEnd(end);
++            setEndLine(location.getEndLine());
++            setEndColumn(location.getEndColumn());
++        }
 +    }
 +
 +    /**
 +     * Set the end offset of the node to fall just before the token. Used during
 +     * parsing.
 +     * 
 +     * @param token start this node before this token
 +     */
 +    public final void endBefore(Token token)
 +    {
 +        if (token instanceof ISourceLocation)
 +            endBefore((ISourceLocation)token);
 +    }
 +
 +    /**
 +     * Set the end offset of the node to fall just before the token. Used during
 +     * parsing.
 +     * 
 +     * @param location start this node before this token
 +     */
 +    public final void endBefore(ISourceLocation location)
 +    {
 +        final int start = location.getStart();
 +        if (start != UNKNOWN)
++        {
 +            setEnd(start);
++            setEndLine(location.getLine());
++            setEndColumn(location.getColumn());
++        }
 +    }
 +
 +    /**
 +     * Set the start and end offsets of the node to coincide with the token's
 +     * offsets. Used during parsing.
 +     * 
 +     * @param token the token to take the offsets from
 +     */
 +    public final void span(Token token)
 +    {
 +        if (token instanceof ISourceLocation)
 +            span((ISourceLocation)token);
 +    }
 +
 +    /**
 +     * Set the start and end offsets of the node to coincide with the tokens'
 +     * offsets. Used during parsing.
 +     * 
 +     * @param firstToken the token to take the start offset and line number from
 +     * @param lastToken the token to take the end offset from
 +     */
 +    public final void span(Token firstToken, Token lastToken)
 +    {
 +        if (firstToken instanceof ISourceLocation && lastToken instanceof ISourceLocation)
 +            span((ISourceLocation)firstToken, (ISourceLocation)lastToken);
 +    }
 +
 +    /**
 +     * Set the start and end offsets of the node. Used during parsing.
 +     * 
 +     * @param start start offset for the node
 +     * @param end end offset for the node
 +     * @param line line number for the node
 +     */
 +    public final void span(int start, int end, int line, int column)
 +    {
 +        setStart(start);
 +        setEnd(end);
 +        setLine(line);
 +        setColumn(column);
 +    }
 +
 +    public Collection<ICompilerProblem> runPostProcess(EnumSet<PostProcessStep> set, ASScope containingScope)
 +    {
 +        ArrayList<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(10);
 +        normalize(set.contains(PostProcessStep.CALCULATE_OFFSETS));
 +        if (set.contains(PostProcessStep.POPULATE_SCOPE) || set.contains(PostProcessStep.RECONNECT_DEFINITIONS))
 +            analyze(set, containingScope, problems);
 +        return problems;
 +    }
 +
 +    protected void analyze(EnumSet<PostProcessStep> set, ASScope scope, Collection<ICompilerProblem> problems)
 +    {
 +        int childrenSize = getChildCount();
 +        // Populate this scope with definitions found among the children
 +        for (int i = 0; i < childrenSize; i++)
 +        {
 +            IASNode child = getChild(i);
 +            if (child instanceof NodeBase)
 +            {
 +                if (child.getParent() == null)
 +                    ((NodeBase)child).setParent(this);
 +                ((NodeBase)child).analyze(set, scope, problems);
 +            }
 +        }
 +    }
 +
 +    /**
 +     * Changes the position of two children in our tree. Neither child can be
 +     * null and both must have the same parent
 +     * 
 +     * @param child the child to replace target
 +     * @param target the child to replace child
 +     */
 +    protected void swapChildren(NodeBase child, NodeBase target)
 +    {
 +        //no op in this impl
 +    }
 +
 +    /**
 +     * Replaces the child with the given target. The child will be removed from
 +     * the tree, and its parentage will be updated
 +     * 
 +     * @param child the {@link NodeBase} to replace
 +     * @param target the {@link NodeBase} to replace the replaced
 +     */
 +    protected void replaceChild(NodeBase child, NodeBase target)
 +    {
 +        //no op
 +    }
 +
 +    /**
 +     * Normalize the tree. Move custom children into the real child list and
 +     * fill in missing offsets so that offset lookup will work. Used during
 +     * parsing.
 +     */
 +    public void normalize(boolean fillInOffsets)
 +    {
 +        // The list of children doesn't change, so the child count should be constant throughout the loop
 +        int childrenSize = getChildCount();
 +        // Normalize the regular children
 +        for (int i = 0; i < childrenSize; i++)
 +        {
 +            IASNode child = getChild(i);
 +            if (child instanceof NodeBase)
 +            {
 +                ((NodeBase)child).setParent(this);
 +                ((NodeBase)child).normalize(fillInOffsets);
 +            }
 +        }
 +        // Add the special children (which get normalized as they're added)
 +        if (childrenSize == 0)
 +            setChildren(fillInOffsets);
 +        // Fill in offsets based on the child nodes
 +        if (fillInOffsets)
 +            fillInOffsets();
 +        // fill in any dangling ends
 +        //fillEndOffsets();
 +        // get rid of unused child space
 +    }
 +
 +    /**
 +     * Allow various subclasses to do special kludgy things like identify
 +     * mx.core.Application.application
 +     */
 +    protected void connectedToProjectScope()
 +    {
 +        // The list of children doesn't change, so the child count should be constant throughout the loop
 +        int childrenSize = getChildCount();
 +        for (int i = 0; i < childrenSize; i++)
 +        {
 +            IASNode child = getChild(i);
 +            if (child instanceof NodeBase)
 +                ((NodeBase)child).connectedToProjectScope();
 +        }
 +    }
 +
 +    /**
 +     * If this node has custom children (names, arguments, etc), shove them into
 +     * the list of children. Used during parsing.
 +     */
 +    protected void setChildren(boolean fillInOffsets)
 +    {
 +        //nothing in this class
 +    }
 +
 +    /**
 +     * If the start and end offsets haven't been set explicitly, fill them in
 +     * based on the offsets of the children. Used during parsing. If the end
 +     * offset is less than any of the kids' offsets, change fLocation.fEnd to
 +     * encompass kids.
 +     */
 +    protected void fillInOffsets()
 +    {
 +        int numChildren = getChildCount();
 +        if (numChildren > 0)
 +        {
 +            int start = getAbsoluteStart();
 +            int end = getAbsoluteEnd();
 +            if (start == -1)
 +            {
 +                for (int i = 0; i < numChildren; i++)
 +                {
 +                    IASNode child = getChild(i);
 +                    int childStart = child.getAbsoluteStart();
 +                    if (childStart != -1)
 +                    {
 +                        if (getSourcePath() == null)
 +                            setSourcePath(child.getSourcePath());
 +                        setStart(childStart);
 +                        setLine(child.getLine());
 +                        setColumn(child.getColumn());
 +                        break;
 +                    }
 +                }
 +            }
 +            for (int i = numChildren - 1; i >= 0; i--)
 +            {
 +                IASNode child = getChild(i);
 +                int childEnd = child.getAbsoluteEnd();
 +                if (childEnd != -1)
 +                {
 +                    if (end < childEnd)
++                    {
 +                        setEnd(childEnd);
++                        setEndLine(child.getEndLine());
++                        setEndColumn(child.getEndColumn());
++                    }
 +                    break;
 +                }
 +            }
 +        }
 +    }
 +
 +    /**
 +     * Set the parent node. Used during parsing.
 +     * 
 +     * @param parent parent node
 +     */
 +    public void setParent(NodeBase parent)
 +    {
 +        this.parent = parent;
 +    }
 +
 +    /**
 +     * Get the nearest containing scope for this node. Used during type
 +     * decoration.
 +     * 
 +     * @return nearest containing scope for this node
 +     */
 +    // TODO Make this more efficient using overrides on BlockNode and FileNode.
 +    public IScopedNode getScopeNode()
 +    {
 +        if (this instanceof IScopedNode && ((IScopedNode)this).getScope() != null)
 +            return (IScopedNode)this;
 +        IASNode parent = getParent();
 +        if (parent != null && parent instanceof NodeBase)
 +            return ((NodeBase)parent).getScopeNode();
 +        return null;
 +    }
 +
 +    /**
 +     * Get the path of the file in which this parse tree node resides.
 +     * <p>
 +     * The tree builder can set a node's origin source file using
 +     * {@link #setSourcePath(String)}. If the source path was set, return the
 +     * source path; Otherwise, use root {@link FileNode}'s path.
 +     * 
 +     * @return file path that contains this node
 +     */
 +    public String getContainingFilePath()
 +    {
 +        String path = getSourcePath();
 +        if (path != null)
 +            return path;
 +
 +        final FileNode fileNode = (FileNode)getAncestorOfType(FileNode.class);
 +        if (fileNode != null)
 +            return fileNode.getSourcePath();
 +        return null;
 +    }
 +
 +    /**
 +     * For debugging only. Displays this node and its children in a form like
 +     * this:
 +     * 
 +     * <pre>
 +     * FileNode "D:\tests\UIComponent.as" 0:0 0-467464  D:\tests\UIComponent.as
 +     *   PackageNode "mx.core" 12:1 436-465667 D:\tests\UIComponent.as
 +     *     FullNameNode "mx.core" 0:0 444-451 null
 +     *       IdentifierNode "mx" 12:9 444-446 D:\tests\UIComponent.as
 +     *       IdentifierNode "core" 12:12 447-451 D:\tests\UIComponent.as
 +     *     ScopedBlockNode 13:1 454-465667 D:\tests\UIComponent.as
 +     *       ImportNode "flash.accessibility.Accessibility" 14:1 457-497 D:\tests\UIComponent.as
 +     *       FullNameNode "flash.accessibility.Accessibility" 0:0 464-497 null
 +     *         FullNameNode "flash.accessibility" 0:0 464-483 null
 +     *           IdentifierNode "flash" 14:8 464-469 D:\tests\UIComponent.as
 +     *           IdentifierNode "accessibility" 14:14 470-483 D:\tests\UIComponent.as
 +     *         IdentifierNode "Accessibility" 14:28 484-497 D:\tests\UIComponent.as
 +     *       ...
 +     * </pre>
 +     * <p>
 +     * Subclasses may not override this, because we want to maintain regularity
 +     * for how all nodes display.
 +     */
 +    @Override
 +    public final String toString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +        buildStringRecursive(sb, 0, false);
 +        return sb.toString();
 +    }
 +
 +    /**
 +     * For debugging only. Called by {@code toString()}, and recursively by
 +     * itself, to display this node on one line and each descendant node on
 +     * subsequent indented lines.
 +     * 
 +     * * */
 +    public void buildStringRecursive(StringBuilder sb, int level, boolean skipSrcPath)
 +    {
 +        // Indent two spaces for each nesting level.
 +        for (int i = 0; i < level; i++)
 +        {
 +            sb.append("  ");
 +        }
 +
 +        // Build the string that represents this node.
 +        buildOuterString(sb, skipSrcPath);
 +      
 +        sb.append('\n');
 +        
 +        //To test scopes in ParserSuite
 +        if(skipSrcPath && (this instanceof IScopedNode)) {
 +            for (int i = 0; i < level+1; i++)
 +                sb.append("  ");
 +            sb.append("[Scope]");
 +            sb.append("\n");
 +            IScopedNode scopedNode = (IScopedNode)this;
 +            IASScope scope = scopedNode.getScope();
 +            Collection<IDefinition> definitions = scope.getAllLocalDefinitions();
 +            for(IDefinition def : definitions) {
 +                for (int i = 0; i < level+2; i++)
 +                    sb.append("  ");
 +                ((DefinitionBase)def).buildString(sb, false);
 +                sb.append('\n');
 +            }
 +        }
 +
 +        // Recurse over the child nodes.
 +        int n = getChildCount();
 +        for (int i = 0; i < n; i++)
 +        {
 +            NodeBase child = (NodeBase)getChild(i);
 +            // The child can be null if we're toString()'ing
 +            // in the debugger during tree building.
 +            if (child != null)
 +                child.buildStringRecursive(sb, level + 1, skipSrcPath);
 +        }
 +    }
 +
 +    /**
 +     * For debugging only. Called by {@code buildStringRecursive()} to display
 +     * information for this node only.
 +     * <p>
 +     * An example is
 +     * 
 +     * <pre>
 +     * PackageNode "mx.core" 12:1 436-465667 D:\tests\UIComponent.as
 +     * </pre>.
 +     * <p>
 +     * The type of node (PackageNode) is displayed first, followed by
 +     * node-specific information ("mx.core") followed by location information in
 +     * the form
 +     * 
 +     * <pre>
 +     * line:column start-end sourcepath
 +     * </pre>
 +     * 
 +     */
 +    private void buildOuterString(StringBuilder sb, boolean skipSrcPath)
 +    {
 +        // First display the type of node, as represented by 
 +        // the short name of the node class.
 +        sb.append(getNodeKind());
 +
 +        sb.append("(").append(getNodeID().name()).append(")");
 +        
 +        sb.append(' ');
 +
 +        // Display optional node-specific information in the middle.
 +        if (buildInnerString(sb))
 +            sb.append(' ');
 +
 +        // The SourceLocation superclass handles producing a string such as
 +        // "17:5 160-188" C:/test.as".
 +        if(skipSrcPath) 
 +            sb.append(getOffsetsString());
 +        else
 +            sb.append(super.toString());
 +    }
 +
 +    /**
 +     * For debugging only. This method is called by {@code buildOuterString()}.
 +     * It is overridden by subclasses to display optional node-specific
 +     * information in the middle of the string, between the node type and the
 +     * location information.
 +     */
 +    protected boolean buildInnerString(StringBuilder sb)
 +    {
 +        return false;
 +    }
 +    
 +    /**
 +     * For debugging only.
 +     */
 +    public String getInnerString()
 +    {
 +        StringBuilder sb = new StringBuilder();
 +        buildInnerString(sb);
 +        return sb.toString();
 +    }
 +
 +    public ASFileScope getFileScope()
 +    {
 +        ASScope scope = getASScope();
 +        assert scope != null;
 +        while (!(scope instanceof ASFileScope))
 +        {
 +            scope = scope.getContainingScope();
 +            assert scope != null;
 +        }
 +        return (ASFileScope)scope;
 +    }
 +
 +    /**
 +     * @return {@link OffsetLookup} object for the current tree or null.
 +     */
 +    protected final OffsetLookup tryGetOffsetLookup()
 +    {
 +        // Try FileNode.getOffsetLookup()
 +        final IASNode fileNode = getAncestorOfType(IFileNode.class);
 +        if (fileNode != null)
 +            return ((IFileNode)fileNode).getOffsetLookup();
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * Get's the {@link IWorkspace} in which this {@link NodeBase} lives.
 +     * 
 +     * @return The {@link IWorkspace} in which this {@link NodeBase} lives.
 +     */
 +    public IWorkspace getWorkspace()
 +    {
 +        return getFileScope().getWorkspace();
 +    }
 +
 +    /**
 +     * Get the scope this Node uses for name resolution as an ASScope.
 +     * 
 +     * @return the ASScope for this node, or null if there isn't one.
 +     */
 +    public ASScope getASScope()
 +    {
 +        IScopedNode scopeNode = getContainingScope();
 +        IASScope scope = scopeNode != null ? scopeNode.getScope() : null;
 +
 +        // If the ScopedNode had a null scope, keep looking up the tree until we
 +        // find one with a non-null scope.
 +        // TODO: Is it a bug that an IScopedNode returns null for it's scope?
 +        // TODO: this seems like a leftover from block scoping - for example, a
 +        // TODO: ForLoopNode is an IScopedNode, but it doesn't really have a scope
 +        while (scope == null && scopeNode != null)
 +        {
 +            scopeNode = scopeNode.getContainingScope();
 +            scope = scopeNode != null ? scopeNode.getScope() : null;
 +        }
 +
 +        if (scope instanceof TypeScope)
 +        {
 +            TypeScope typeScope = (TypeScope)scope;
 +            if (this instanceof BaseDefinitionNode)
 +            {
 +                if (((BaseDefinitionNode)this).hasModifier(ASModifier.STATIC))
 +                    scope = typeScope.getStaticScope();
 +                else
 +                    scope = typeScope.getInstanceScope();
 +            }
 +            else
 +            {
 +                // Do we need the class or instance scope?
 +                BaseDefinitionNode bdn = (BaseDefinitionNode)this.getAncestorOfType(BaseDefinitionNode.class);
 +                if (bdn instanceof ClassNode)
 +                {
 +                    // We must be loose code in a class
 +                    scope = typeScope.getStaticScope();
 +                }
 +                else
 +                {
 +                    if (bdn != null && bdn.hasModifier(ASModifier.STATIC)
 +                            // Namespaces are always static
 +                            || bdn instanceof NamespaceNode)
 +                        scope = typeScope.getStaticScope();
 +                    else
 +                        scope = typeScope.getInstanceScope();
 +                }
 +            }
 +        }
 +        ASScope asScope = scope instanceof ASScope ? (ASScope)scope : null;
 +        return asScope;
 +    }
 +
 +    /**
 +     * Get the node's local start offset.
 +     */
 +    @Override
 +    public int getStart()
 +    {
 +        final OffsetLookup offsetLookup = tryGetOffsetLookup();
 +        if (offsetLookup != null)
 +        {
 +            // to handle start offset in an included file
 +            int absoluteOffset = getAbsoluteStart();
 +            final String pathBeforeCaret = offsetLookup.getFilename(absoluteOffset - 1);
 +            // if the offset is the first offset in the included file return without adjustment
 +            if (pathBeforeCaret != null && pathBeforeCaret.equals(getSourcePath()))
 +                return offsetLookup.getLocalOffset(absoluteOffset-1)+1;
 +            
 +            return offsetLookup.getLocalOffset(absoluteOffset);
 +        }
 +        
 +        return super.getStart();
 +    }
 +
 +    /**
 +     * Get the node's local end offset.
 +     */
 +    @Override
 +    public int getEnd()
 +    {
 +        final OffsetLookup offsetLookup = tryGetOffsetLookup();
 +        return offsetLookup != null ?
 +                // to handle end offset in an included file
 +                offsetLookup.getLocalOffset(super.getEnd() - 1) + 1 :
 +                super.getEnd();
 +    }
 +
 +    /**
 +     * @return The node's absolute start offset.
 +     */
 +    @Override
 +    public int getAbsoluteStart()
 +    {
 +        return super.getStart();
 +    }
 +
 +    /**
 +     * @return The node's absolute end offset.
 +     */
 +    @Override
 +    public int getAbsoluteEnd()
 +    {
 +        return super.getEnd();
 +    }
 +    
 +    /**
 +     * Collects the import nodes that are descendants of this node
 +     * but which are not contained within a scoped node.
 +     * <p>
 +     * This is a helper method for {@link IScopedNode#getAllImportNodes}().
 +     * Since that method walks up the chain of scoped nodes, we don't want
 +     * to look inside scoped nodes that were already processed.
 +     * 
 +     * @param importNodes The collection of import nodes being built.
 +     */
 +    public void collectImportNodes(Collection<IImportNode> importNodes)
 +    {
 +        int childCount = getChildCount();
 +        for (int i = 0; i < childCount; ++i)
 +        {
 +            IASNode child = getChild(i);
 +            
 +            if (child instanceof IImportNode)
 +                importNodes.add((IImportNode)child);
 +
 +            else if (!(child instanceof IScopedNode))
 +                ((NodeBase)child).collectImportNodes(importNodes);
 +        }
 +    }
 +
 +    /**
 +     * Used only in asserts.
 +     */
 +    public boolean verify()
 +    {
 +        // Verify the id.
 +        ASTNodeID id = getNodeID();
 +        assert id != null &&
 +               id != ASTNodeID.InvalidNodeID &&
 +               id != ASTNodeID.UnknownID : "Definition has bad id";
 +
 +        // TODO: Verify the source location eventually.
 +        //      assert getSourcePath() != null : "Node has null source path:\n" + toString();
 +        //      assert getStart() != UNKNOWN : "Node has unknown start:\n" + toString();
 +        //      assert getEnd() != UNKNOWN : "Node has unknown end:\n" + toString();
 +        //      assert getLine() != UNKNOWN : "Node has unknown line:\n" + toString();
 +        //      assert getColumn() != UNKNOWN : "Node has unknown column:\n" + toString();
 +
 +        // Verify the children.
 +        int n = getChildCount();
 +        for (int i = 0; i < n; i++)
 +        {
 +            // Any null children?
 +            NodeBase child = (NodeBase)getChild(i);
 +            assert child != null : "Node has null child";
 +
 +            // Does each child have this node as its parent?
 +            // (Note: Two node classes override getParent() to not return the parent,
 +            // so exclude these for now.)
 +            if (!(child instanceof NamespaceIdentifierNode || child instanceof QualifiedNamespaceExpressionNode))
 +            {
 +                assert child.getParent() == this : "Child node has bad parent";
 +            }
 +
 +            // Recurse on each child.
 +            child.verify();
 +        }
 +
 +        return true;
 +    }
 +    
 +    /**
 +     * Counts various types of nodes that are created,
 +     * as well as the total number of nodes.
 +     */
 +    private void countNodes()
 +    {
 +        Counter counter = Counter.getInstance();
 +        counter.incrementCount(getClass().getSimpleName());
 +        counter.incrementCount("nodes");
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
----------------------------------------------------------------------
diff --cc compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
index 5de6521,0000000..51eb0fc
mode 100644,000000..100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
@@@ -1,130 -1,0 +1,132 @@@
 +/*
 + *
 + *  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.tree.as;
 +
 +import org.apache.flex.compiler.internal.parsing.as.OffsetLookup;
 +import org.apache.flex.compiler.parsing.IASToken;
 +import org.apache.flex.compiler.tree.as.IOperatorNode;
 +
 +/**
 + * ActionScript parse tree node representing a binary operator expression (e.g.
 + * x + 2 or var1 == var2)
 + */
 +public abstract class OperatorNodeBase extends ExpressionNodeBase implements IOperatorNode
 +{
 +    /**
 +     * Constructor.
 +     * 
 +     * @param operator ASToken holding the operator itself
 +     */
 +    public OperatorNodeBase(IASToken operator)
 +    {
 +        if (operator != null)
 +        {
 +            operatorStart = operator.getStart();
 +            setLine(operator.getLine());
 +            setColumn(operator.getColumn());
++            setEndLine(operator.getEndLine());
++            setEndColumn(operator.getEndColumn());
 +            setSourcePath(operator.getSourcePath());
 +        }
 +    }
 +    
 +    /**
 +     * Copy constructor.
 +     * 
 +     * @param other The node to copy.
 +     */
 +    protected OperatorNodeBase(OperatorNodeBase other)
 +    {
 +        super(other);
 +        
 +        this.operatorStart = other.operatorStart;
 +    }
 +
 +    /**
 +     * Offset where the operator starts
 +     */
 +    protected int operatorStart = UNKNOWN;
 +    
 +    //
 +    // NodeBase overrides
 +    //
 +    
 +    @Override
 +    public boolean isTerminal()
 +    {
 +        return false;
 +    }
 +    
 +    /*
 +     * For debugging only. Builds a string such as <code>"+"</code> from the
 +     * operator.
 +     */
 +    @Override
 +    protected boolean buildInnerString(StringBuilder sb)
 +    {
 +        sb.append('"');
 +        sb.append(getOperatorText());
 +        sb.append('"');
 +
 +        return true;
 +    }
 +
 +    //
 +    // IOperatorNode implementations
 +    //
 +    
 +    @Override
 +    public int getOperatorStart()
 +    {
 +        final OffsetLookup offsetLookup = tryGetOffsetLookup();
 +        return offsetLookup != null ?
 +               offsetLookup.getLocalOffset(operatorStart) :
 +               operatorStart;
 +    }
 +
 +    @Override
 +    public int getOperatorEnd()
 +    {
 +        int operatorStart = getOperatorStart();
 +        return operatorStart != -1 ? operatorStart + getOperatorText().length() : operatorStart;
 +    }
 +
 +    @Override
 +    public int getOperatorAbsoluteStart()
 +    {
 +        return operatorStart;
 +    }
 +
 +    @Override
 +    public int getOperatorAbsoluteEnd()
 +    {
 +        return operatorStart != -1 ? operatorStart + getOperatorText().length() : operatorStart;
 +    }
 +
 +    //
 +    // Other methods
 +    //
 +
 +    public String getOperatorText()
 +    {
 +        OperatorType operator = getOperator();
 +        return operator != null ? operator.getOperatorText() : "";
 +    }
 +}


[06/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - ASParser: array contents start after [ and before ], and ArrayLiteralNode includes them

Posted by cd...@apache.org.
ASParser: array contents start after [ and before ], and ArrayLiteralNode includes them


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

Branch: refs/heads/feature/maven-migration-test
Commit: b2bfa2c9a6a7da9ebe5363117f6e6438e5ddc6a4
Parents: c22e5a0
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 19:39:31 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 19:39:31 2016 -0700

----------------------------------------------------------------------
 .../src/org/apache/flex/compiler/internal/parsing/as/ASParser.g  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/b2bfa2c9/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g b/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
index 34cb240..4d4936b 100644
--- a/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
+++ b/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
@@ -2481,9 +2481,9 @@ arrayInitializer [ArrayLiteralNode node]
     {
         final ContainerNode contents = node.getContentsNode(); 
     }
-    :   open:TOKEN_SQUARE_OPEN            { contents.startBefore(open); }
+    :   open:TOKEN_SQUARE_OPEN            { node.startBefore(open); contents.startAfter(open); }
         arrayElements[contents]
-        close:TOKEN_SQUARE_CLOSE          { contents.endAfter(close); }
+        close:TOKEN_SQUARE_CLOSE          { node.endAfter(close); contents.endBefore(close); }
     ;	
     exception catch [RecognitionException ex] 
     { 


[09/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - compiler.jx.tests: expanded source map tests to include some missing mappings

Posted by cd...@apache.org.
compiler.jx.tests: expanded source map tests to include some missing mappings


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

Branch: refs/heads/feature/maven-migration-test
Commit: e9fd628e5305a651f4cf0be0b744b885aee68b39
Parents: 01629b2
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 23:27:10 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 23:27:10 2016 -0700

----------------------------------------------------------------------
 .../js/sourcemaps/TestSourceMapExpressions.java | 181 +++++++++++--------
 .../js/sourcemaps/TestSourceMapStatements.java  |  19 +-
 2 files changed, 124 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e9fd628e/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
index 57ab17b..90aab08 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
@@ -31,7 +31,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a + b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // +
     }
 
     @Test
@@ -39,7 +39,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a - b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // -
     }
 
     @Test
@@ -47,7 +47,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a / b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // /
     }
 
     @Test
@@ -55,7 +55,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a % b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // %
     }
 
     @Test
@@ -63,7 +63,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a * b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // *
     }
 
     @Test
@@ -71,7 +71,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("a++");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 3);
+        assertMapping(node, 0, 1, 0, 1, 0, 3); // ++
     }
 
     @Test
@@ -79,7 +79,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("++a");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 2);
+        assertMapping(node, 0, 0, 0, 0, 0, 2); // +
     }
 
     @Test
@@ -87,7 +87,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("a--");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 3);
+        assertMapping(node, 0, 1, 0, 1, 0, 3); // --
     }
 
     @Test
@@ -95,7 +95,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("--a");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 2);
+        assertMapping(node, 0, 0, 0, 0, 0, 2); // --
     }
 
     //----------------------------------
@@ -151,7 +151,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a = b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
     }
 
     //----------------------------------
@@ -163,7 +163,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a & b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // &
     }
 
     @Test
@@ -171,7 +171,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a << b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // <<
     }
 
     @Test
@@ -179,7 +179,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("~a");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 1);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // ~
     }
 
     @Test
@@ -187,7 +187,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a | b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // |
     }
 
     @Test
@@ -195,7 +195,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a >> b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // >>
     }
 
     @Test
@@ -203,7 +203,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a >>> b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 6);
+        assertMapping(node, 0, 1, 0, 1, 0, 6); // >>>
     }
 
     @Test
@@ -211,7 +211,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a ^ b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // ^
     }
 
     //----------------------------------
@@ -275,7 +275,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a == b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // ==
     }
 
     @Test
@@ -283,7 +283,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a > b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // >
     }
 
     @Test
@@ -291,7 +291,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a >= b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // >=
     }
 
     @Test
@@ -299,7 +299,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a != b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // !=
     }
 
     @Test
@@ -307,7 +307,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a < b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // <
     }
 
     @Test
@@ -315,7 +315,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a <= b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // <=
     }
 
     @Test
@@ -323,7 +323,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a === b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 6);
+        assertMapping(node, 0, 1, 0, 1, 0, 6); // ===
     }
 
     @Test
@@ -331,7 +331,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a !== b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 6);
+        assertMapping(node, 0, 1, 0, 1, 0, 6); // !==
     }
 
     //----------------------------------
@@ -343,7 +343,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a && b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // &&
     }
 
     @Test
@@ -352,8 +352,8 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IBinaryOperatorNode node = getBinaryNode("a &&= b");
         asBlockWalker.visitBinaryOperator(node);
         //a = a && b
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
-        assertMapping(node, 0, 1, 0, 5, 0, 9);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
+        assertMapping(node, 0, 1, 0, 5, 0, 9); // &&
     }
 
     @Test
@@ -361,7 +361,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("!a");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 1);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // !
     }
 
     @Test
@@ -369,7 +369,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a || b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // ||
     }
 
     @Test
@@ -378,8 +378,8 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IBinaryOperatorNode node = getBinaryNode("a ||= b");
         asBlockWalker.visitBinaryOperator(node);
         //a = a || b
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
-        assertMapping(node, 0, 1, 0, 5, 0, 9);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
+        assertMapping(node, 0, 1, 0, 5, 0, 9); // ||
     }
 
     //----------------------------------
@@ -391,8 +391,10 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IDynamicAccessNode node = getDynamicAccessNode("a[b]");
         asBlockWalker.visitDynamicAccess(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 2);
-        assertMapping(node, 0, 3, 0, 3, 0, 4);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
+        assertMapping(node, 0, 1, 0, 1, 0, 2); // [
+        assertMapping(node, 0, 2, 0, 2, 0, 3); // b
+        assertMapping(node, 0, 3, 0, 3, 0, 4); // ]
     }
 
     @Test
@@ -400,12 +402,16 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IDynamicAccessNode node = getDynamicAccessNode("a[b[c][d]]");
         asBlockWalker.visitDynamicAccess(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 2);
-        assertMapping(node, 0, 3, 0, 3, 0, 4);
-        assertMapping(node, 0, 5, 0, 5, 0, 6);
-        assertMapping(node, 0, 6, 0, 6, 0, 7);
-        assertMapping(node, 0, 8, 0, 8, 0, 9);
-        assertMapping(node, 0, 9, 0, 9, 0, 10);
+        assertMapping(node, 0, 0, 0, 0, 0, 1);   // a
+        assertMapping(node, 0, 1, 0, 1, 0, 2);   // [
+        assertMapping(node, 0, 2, 0, 2, 0, 3);   // b
+        assertMapping(node, 0, 3, 0, 3, 0, 4);   // [
+        assertMapping(node, 0, 4, 0, 4, 0, 5);   // c
+        assertMapping(node, 0, 5, 0, 5, 0, 6);   // ]
+        assertMapping(node, 0, 6, 0, 6, 0, 7);   // [
+        assertMapping(node, 0, 7, 0, 7, 0, 8);   // d
+        assertMapping(node, 0, 8, 0, 8, 0, 9);   // ]
+        assertMapping(node, 0, 9, 0, 9, 0, 10);  // ]
     }
 
     @Test
@@ -413,7 +419,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a, b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 3);
+        assertMapping(node, 0, 1, 0, 1, 0, 3); // ,
     }
 
     @Test
@@ -422,8 +428,8 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         ITernaryOperatorNode node = (ITernaryOperatorNode) getExpressionNode(
                 "a ? b : c", ITernaryOperatorNode.class);
         asBlockWalker.visitTernaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 4);
-        assertMapping(node, 0, 5, 0, 5, 0, 8);
+        assertMapping(node, 0, 1, 0, 1, 0, 4); // ?
+        assertMapping(node, 0, 5, 0, 5, 0, 8); // :
     }
 
     @Test
@@ -431,7 +437,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("delete a");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 7);
+        assertMapping(node, 0, 0, 0, 0, 0, 7); // delete
     }
 
     @Test
@@ -440,7 +446,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IMemberAccessExpressionNode node = (IMemberAccessExpressionNode) getExpressionNode(
                 "a.b", IMemberAccessExpressionNode.class);
         asBlockWalker.visitMemberAccessExpression(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 2);
+        assertMapping(node, 0, 1, 0, 1, 0, 2); // .
     }
 
     @Test
@@ -449,9 +455,9 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IMemberAccessExpressionNode node = (IMemberAccessExpressionNode) getExpressionNode(
                 "a.b.c.d", IMemberAccessExpressionNode.class);
         asBlockWalker.visitMemberAccessExpression(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 2);
-        assertMapping(node, 0, 3, 0, 3, 0, 4);
-        assertMapping(node, 0, 5, 0, 5, 0, 6);
+        assertMapping(node, 0, 1, 0, 1, 0, 2); // .
+        assertMapping(node, 0, 3, 0, 3, 0, 4); // .
+        assertMapping(node, 0, 5, 0, 5, 0, 6); // .
     }
 
     @Test
@@ -459,7 +465,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a in b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 5);
+        assertMapping(node, 0, 1, 0, 1, 0, 5); // in
     }
 
     @Test
@@ -467,7 +473,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IBinaryOperatorNode node = getBinaryNode("a instanceof b");
         asBlockWalker.visitBinaryOperator(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 13);
+        assertMapping(node, 0, 1, 0, 1, 0, 13); // instanceof
     }
 
     @Test
@@ -476,7 +482,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IFunctionCallNode node = (IFunctionCallNode) getExpressionNode(
                 "new Object()", IFunctionCallNode.class);
         asBlockWalker.visitFunctionCall(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 4);
+        assertMapping(node, 0, 0, 0, 0, 0, 4); // new
     }
 
     @Test
@@ -485,6 +491,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         ObjectLiteralNode node = (ObjectLiteralNode) getExpressionNode(
                 "a = {a:1}", ObjectLiteralNode.class);
         asBlockWalker.visitLiteral(node);
+        //{a: 1}
         assertMapping(node, 0, 0, 0, 0, 0, 1); // {
         assertMapping(node, 0, 1, 0, 1, 0, 2); // a
         assertMapping(node, 0, 2, 0, 2, 0, 3); // :
@@ -536,6 +543,24 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     }
 
     @Test
+    public void testVisitObjectLiteral_4()
+    {
+        ObjectLiteralNode node = (ObjectLiteralNode) getExpressionNode(
+                "a = {a:1,\nb:2}", ObjectLiteralNode.class);
+        asBlockWalker.visitLiteral(node);
+        //{a:1, b:2}
+        assertMapping(node, 0, 0, 0, 0, 0, 1);   // {
+        assertMapping(node, 0, 1, 0, 1, 0, 2);   // a
+        assertMapping(node, 0, 2, 0, 2, 0, 3);   // :
+        assertMapping(node, 0, 3, 0, 3, 0, 4);   // 1
+        assertMapping(node, 0, 4, 0, 4, 0, 6);   // ,
+        assertMapping(node, 1, 0, 0, 6, 0, 7);   // b
+        assertMapping(node, 1, 1, 0, 7, 0, 8);   // :
+        assertMapping(node, 1, 2, 0, 8, 0, 9);   // 2
+        assertMapping(node, 1, 3, 0, 9, 0, 10);  // }
+    }
+
+    @Test
     public void testVisitArrayLiteral_1()
     {
         ArrayLiteralNode node = (ArrayLiteralNode) getExpressionNode(
@@ -543,8 +568,11 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         asBlockWalker.visitLiteral(node);
         //[0, 1, 2]
         assertMapping(node, 0, 0, 0, 0, 0, 1); // [
+        assertMapping(node, 0, 1, 0, 1, 0, 2); // 0
         assertMapping(node, 0, 2, 0, 2, 0, 4); // ,
+        assertMapping(node, 0, 3, 0, 4, 0, 5); // 1
         assertMapping(node, 0, 4, 0, 5, 0, 7); // ,
+        assertMapping(node, 0, 5, 0, 7, 0, 8); // 2
         assertMapping(node, 0, 6, 0, 8, 0, 9); // ]
     }
 
@@ -598,8 +626,8 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         assertMapping(node, 0, 2, 0, 2, 0, 4);    // ,
         assertMapping(node, 1, 0, 0, 4, 0, 7);    // 123
         assertMapping(node, 1, 3, 0, 7, 0, 9);    // ,
-        assertMapping(node, 1, 5, 0, 9, 0, 11);    // 45
-        //TODO: figure out how to place the ] 
+        assertMapping(node, 1, 5, 0, 9, 0, 11);   // 45
+        assertMapping(node, 1, 7, 0, 11, 0, 12);  // 45
     }
 
     @Test
@@ -607,8 +635,9 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("typeof(a)");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 7);
-        assertMapping(node, 0, 0, 0, 8, 0, 9);
+        //typeof(a)
+        assertMapping(node, 0, 0, 0, 0, 0, 7); // typeof(
+        assertMapping(node, 0, 0, 0, 8, 0, 9); // )
     }
 
     @Test
@@ -617,8 +646,9 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         // TODO (mschmalle) the notation without parenthesis is also valid in AS/JS
         IUnaryOperatorNode node = getUnaryNode("typeof a");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 7);
-        assertMapping(node, 0, 0, 0, 8, 0, 9);
+        //typeof(a)
+        assertMapping(node, 0, 0, 0, 0, 0, 7); // typeof(
+        assertMapping(node, 0, 0, 0, 8, 0, 9); // )
     }
 
     @Test
@@ -626,7 +656,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IUnaryOperatorNode node = getUnaryNode("void a");
         asBlockWalker.visitUnaryOperator(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 5);
+        assertMapping(node, 0, 0, 0, 0, 0, 5); // void
     }
 
     @Test
@@ -635,7 +665,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IIterationFlowNode node = (IIterationFlowNode) getNode("break",
                 IIterationFlowNode.class);
         asBlockWalker.visitIterationFlow(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 5);
+        assertMapping(node, 0, 0, 0, 0, 0, 5); // break
     }
 
     @Test
@@ -644,7 +674,8 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IIterationFlowNode node = (IIterationFlowNode) getNode("break label",
                 IIterationFlowNode.class);
         asBlockWalker.visitIterationFlow(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 6);
+        assertMapping(node, 0, 0, 0, 0, 0, 6);  // break
+        assertMapping(node, 0, 6, 0, 6, 0, 11); // label
     }
 
     @Test
@@ -653,7 +684,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IIterationFlowNode node = (IIterationFlowNode) getNode("continue",
                 IIterationFlowNode.class);
         asBlockWalker.visitIterationFlow(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 8);
+        assertMapping(node, 0, 0, 0, 0, 0, 8); // continue
     }
 
     @Test
@@ -662,7 +693,8 @@ public class TestSourceMapExpressions extends SourceMapTestBase
         IIterationFlowNode node = (IIterationFlowNode) getNode("continue label",
                 IIterationFlowNode.class);
         asBlockWalker.visitIterationFlow(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 9);
+        assertMapping(node, 0, 0, 0, 0, 0, 9); // continue
+        assertMapping(node, 0, 9, 0, 9, 0, 14); // label
     }
 
     @Test
@@ -670,7 +702,7 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IReturnNode node = (IReturnNode) getNode("return", IReturnNode.class);
         asBlockWalker.visitReturn(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 6);
+        assertMapping(node, 0, 0, 0, 0, 0, 6); // return
     }
 
     @Test
@@ -678,7 +710,8 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IReturnNode node = (IReturnNode) getNode("return 0", IReturnNode.class);
         asBlockWalker.visitReturn(node);
-        assertMapping(node, 0, 0, 0, 0, 0, 7);
+        assertMapping(node, 0, 0, 0, 0, 0, 7); // return
+        assertMapping(node, 0, 7, 0, 7, 0, 8); // 0
     }
 
     @Test
@@ -686,8 +719,9 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IFunctionCallNode node = (IFunctionCallNode) getNode("a()", IFunctionCallNode.class);
         asBlockWalker.visitFunctionCall(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 2);
-        assertMapping(node, 0, 2, 0, 2, 0, 3);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
+        assertMapping(node, 0, 1, 0, 1, 0, 2); // (
+        assertMapping(node, 0, 2, 0, 2, 0, 3); // )
     }
 
     @Test
@@ -695,8 +729,10 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IFunctionCallNode node = (IFunctionCallNode) getNode("a(b)", IFunctionCallNode.class);
         asBlockWalker.visitFunctionCall(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 2);
-        assertMapping(node, 0, 3, 0, 3, 0, 4);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
+        assertMapping(node, 0, 1, 0, 1, 0, 2); // (
+        assertMapping(node, 0, 2, 0, 2, 0, 3); // b
+        assertMapping(node, 0, 3, 0, 3, 0, 4); // )
     }
 
     @Test
@@ -704,9 +740,12 @@ public class TestSourceMapExpressions extends SourceMapTestBase
     {
         IFunctionCallNode node = (IFunctionCallNode) getNode("a(b, c)", IFunctionCallNode.class);
         asBlockWalker.visitFunctionCall(node);
-        assertMapping(node, 0, 1, 0, 1, 0, 2);
-        assertMapping(node, 0, 3, 0, 3, 0, 5);
-        assertMapping(node, 0, 6, 0, 6, 0, 7);
+        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
+        assertMapping(node, 0, 1, 0, 1, 0, 2); // (
+        assertMapping(node, 0, 2, 0, 2, 0, 3); // b
+        assertMapping(node, 0, 3, 0, 3, 0, 5); // ,
+        assertMapping(node, 0, 5, 0, 5, 0, 6); // c
+        assertMapping(node, 0, 6, 0, 6, 0, 7); // )
     }
 
     protected IBackend createBackend()

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e9fd628e/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
index 436ee15..265b94c 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
@@ -128,6 +128,7 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 27, 0, 45, 0, 47); // ;
         assertMapping(node, 0, 32, 0, 50, 0, 52); // )
         assertMapping(node, 0, 34, 0, 52, 0, 53); // {
+        assertMapping(node, 0, 43, 2, 0, 2, 1);   // }
     }
 
     @Test
@@ -150,11 +151,12 @@ public class TestSourceMapStatements extends SourceMapTestBase
                 IForLoopNode.class);
         asBlockWalker.visitForLoop(node);
         //for (;;) {\n  break;\n}
-        assertMapping(node, 0, 0, 0, 0, 0, 5); // for (
-        assertMapping(node, 0, 5, 0, 5, 0, 6); // ;
-        assertMapping(node, 0, 6, 0, 6, 0, 7); // ;
-        assertMapping(node, 0, 7, 0, 7, 0, 9); // )
+        assertMapping(node, 0, 0, 0, 0, 0, 5);  // for (
+        assertMapping(node, 0, 5, 0, 5, 0, 6);  // ;
+        assertMapping(node, 0, 6, 0, 6, 0, 7);  // ;
+        assertMapping(node, 0, 7, 0, 7, 0, 9);  // )
         assertMapping(node, 0, 9, 0, 9, 0, 10); // {
+        assertMapping(node, 0, 18, 2, 0, 2, 1); // }
     }
 
     @Test
@@ -168,6 +170,7 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 14, 0, 32, 0, 36); // in
         assertMapping(node, 0, 21, 0, 39, 0, 41); // )
         assertMapping(node, 0, 23, 0, 41, 0, 42); // {
+        assertMapping(node, 0, 32, 2, 0, 2, 1);   // }
     }
 
     @Test
@@ -239,6 +242,7 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
         assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
         assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
+        assertMapping(node, 0, 14, 2, 0, 2, 1);   // }
     }
 
     @Test
@@ -252,8 +256,10 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
         assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
         assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
+        assertMapping(node, 0, 14, 2, 0, 2, 1);   // }
         assertMapping(node, 0, 16, 2, 2, 2, 7);   // else
         assertMapping(node, 0, 21, 2, 7, 2, 8);   // {
+        assertMapping(node, 0, 28, 4, 0, 4, 1);   // }
     }
 
     @Test
@@ -268,11 +274,14 @@ public class TestSourceMapStatements extends SourceMapTestBase
         assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
         assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
         assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
+        assertMapping(node, 0, 14, 2, 0, 2, 1);   // }
         assertMapping(node, 0, 16, 2, 2, 2, 11);  // else if(
         assertMapping(node, 0, 26, 2, 12, 2, 14); // )
         assertMapping(node, 0, 28, 2, 14, 2, 15); // {
+        assertMapping(node, 0, 35, 4, 0, 4, 1);   // }
         assertMapping(node, 0, 37, 4, 2, 4, 7);   // else
-        assertMapping(node, 0, 42, 4, 7, 4, 8);    // {
+        assertMapping(node, 0, 42, 4, 7, 4, 8);   // {
+        assertMapping(node, 0, 49, 6, 0, 6, 1);   // {
     }
 
     @Test


[10/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

Posted by cd...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler/src/main/java/org/apache/flex/compiler/problems/CompilerProblem.java
----------------------------------------------------------------------
diff --cc compiler/src/main/java/org/apache/flex/compiler/problems/CompilerProblem.java
index ee9c9a1,0000000..d2e9366
mode 100644,000000..100644
--- a/compiler/src/main/java/org/apache/flex/compiler/problems/CompilerProblem.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/problems/CompilerProblem.java
@@@ -1,222 -1,0 +1,234 @@@
 +/*
 + *
 + *  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.problems;
 +
 +import org.apache.flex.compiler.clients.problems.ProblemFormatter;
 +import org.apache.flex.compiler.common.ISourceLocation;
 +import org.apache.flex.compiler.definitions.IDefinition;
 +import org.apache.flex.compiler.internal.parsing.as.ASToken;
 +import org.apache.flex.compiler.problems.annotations.DefaultSeverity;
 +import org.apache.flex.compiler.problems.annotations.ProblemClassification;
 +import org.apache.flex.utils.FilenameNormalization;
 +
 +/**
 + * CompilerProblem is the base class for all error and warning classes in the compiler,
 + * which are collectively called "problems".
 + * 
 + * Each problem has
 + * 1) source location information (file/start/end/line/column);
 + * 2) a description with named placeholders which get filled in
 + *    from the public fields of the problem class;
 + * 3) the ability to compare itself to other problems,
 + *    to produce a nicely sorted list of problems;
 + * 4) the ability to toString() itself for command-line output such as
 + * 
 + *    C:\Faramir\compiler\trunk\tests\resources\milestones\m1\M1.as:4
 + *    Syntax error: '+' is not allowed here
 + *    import flash.display.+Sprite;
 + *                         ^
 + *    where a caret marks the offending spot in the offending line.
 + */
 +@ProblemClassification(CompilerProblemClassification.DEFAULT)
 +@DefaultSeverity(CompilerProblemSeverity.ERROR)
 +public abstract class CompilerProblem implements ICompilerProblem
 +{
 +    /**
 +     * Constructor.
 +     * 
 +     * @param sourcePath The path of the file in which the problem occurred.
 +     * @param start The offset within the source buffer at which the problem starts.
 +     * @param end The offset within the source buffer at which the problem ends.
 +     * @param line The line number within the source buffer at which the problem starts.
 +     * @param column The column number within the source buffer at which the problem starts.
 +     * @param normalizeFilePath true if the path can be normalized. This is needed 
 +     * by configuration problems that have the "command line" as there source.
 +     */
 +    public CompilerProblem(String sourcePath, int start, int end, int line, int column, 
 +                           boolean normalizeFilePath)
 +    {
 +        if (sourcePath != null && normalizeFilePath)
 +            sourcePath = FilenameNormalization.normalize(sourcePath);
 +
 +        this.sourcePath = sourcePath; 
 +        this.start = start;
 +        this.end = end;
 +        this.line = line;
 +        this.column = column;
 +    }
 +        
 +    /**
 +     * Constructor.
 +     * 
 +     * @param sourcePath The normalized path of the file in which the problem occurred.
 +     * @param start The offset within the source buffer at which the problem starts.
 +     * @param end The offset within the source buffer at which the problem ends.
 +     * @param line The line number within the source buffer at which the problem starts.
 +     * @param column The column number within the source buffer at which the problem starts.
 +     */
 +    public CompilerProblem(String sourcePath, int start, int end, int line, int column)
 +    {
 +        this(sourcePath, start, end, line, column, true);
 +    }
 +    
 +    /**
 +     * Constructor for a problem whose only source-location information
 +     * is a source path.
 +     * 
 +     * @param sourcePath The normalized path of the file
 +     * in which the problem occurred.
 +     */
 +    public CompilerProblem(String sourcePath)
 +    {
 +        this(sourcePath, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, true);
 +    }
 +    
 +    /**
 +     * Constructor for a problem with no source-location information.
 +     */
 +    public CompilerProblem()
 +    {
 +        this(null, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, true);
 +    }
 +    
 +    /**
 +     * Constructor for a problem associated with an object
 +     * implementing {@link ISourceLocation}.
 +     * 
 +     * @param site The {@link ISourceLocation} where the problem occurred.
 +     */
 +    public CompilerProblem(ISourceLocation site)
 +    {
 +        this(site.getSourcePath(),
 +             site.getStart(), site.getEnd(),
 +             site.getLine(), site.getColumn());
 +    }
 +    
 +    /**
 +     * Constructor for a problem associated with an {@link IDefinition}.
 +     * 
 +     * @param site The {@link IDefinition} where the problem occurred.
 +     */
 +    public CompilerProblem(IDefinition site)
 +    {
 +        this(site.getSourcePath(),
 +             site.getNameStart(), site.getNameEnd(),
 +             site.getNameLine(), site.getNameColumn());
 +    }
 +
 +    /**
 +     * Constructor for a problem associated with an {@link ASToken}.
 +     * 
 +     * @param site The {@link ASToken} where the problem occurred.
 +     */
 +    public CompilerProblem(ASToken site)
 +    {
 +        this(site.getSourcePath(),
 +             site.getLocalStart(), site.getLocalEnd(),
 +             site.getLine(), site.getColumn());
 +    }
 +
 +    private final String sourcePath;
 +    private final int start;
 +    private final int end;
 +    private final int line;
 +    private final int column;
 +    
 +    @Override
 +    public String getID()
 +    {
 +        // Return the fully-qualified classname of the CompilerProblem subclass
 +        // as a String to identify the type of problem that occurred.
 +        return getClass().getName();
 +    }
 +    
 +    @Override
 +    public String getSourcePath()
 +    {
 +        return sourcePath;
 +    }
 +    
 +    @Override
 +    public int getStart()
 +    {
 +        return start;
 +    }
 +    
 +    @Override
 +    public int getEnd()
 +    {
 +        return end;
 +    }
 +    
 +    @Override
 +    public int getLine()
 +    {
 +        return line;
 +    }
 +    
 +    @Override
 +    public int getColumn()
 +    {
 +        return column;
 +    }
 +
 +    @Override
++    public int getEndLine()
++    {
++        return line;
++    }
++
++    @Override
++    public int getEndColumn()
++    {
++        return column;
++    }
++
++    @Override
 +    public int getAbsoluteStart()
 +    {
 +        return start;
 +    }
 +
 +    @Override
 +    public int getAbsoluteEnd()
 +    {
 +        return end;
 +    }
 +    
 +    /**
 +     * Returns a String for displaying this compiler problem in a console window.
 +     * 
 +     * This is for debugging purposes, therefore no non-test code should call this.
 +     * 
 +     * There are typically four lines output for each problem:
 +     *  location (file and line number)
 +     *  description
 +     *  
 +     * For example:
 +     * 
 +     * C:\Faramir\compiler\trunk\tests\resources\milestones\m1\M1.as:4
 +     * Syntax error: '+' not allowed here.
 +     */
 +    @Override
 +    public String toString()
 +    {
 +        return ProblemFormatter.DEFAULT_FORMATTER.format(this);
 +    }
 +}


[08/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - compiler.jx: updated JSEmitter to support new getEndLine() and getEndColumn(), and tweaked some sub-emitters to use this change

Posted by cd...@apache.org.
compiler.jx: updated JSEmitter to support new getEndLine() and getEndColumn(), and tweaked some sub-emitters to use this change


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

Branch: refs/heads/feature/maven-migration-test
Commit: 01629b238544b16f934a91e863f0300956ba6d94
Parents: af3e883
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 22:46:54 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 22:46:54 2016 -0700

----------------------------------------------------------------------
 .../org/apache/flex/compiler/codegen/js/IJSEmitter.java   |  2 +-
 .../flex/compiler/internal/codegen/js/JSEmitter.java      | 10 +++++-----
 .../flex/compiler/internal/codegen/js/JSSubEmitter.java   |  4 ++--
 .../internal/codegen/js/jx/BlockCloseEmitter.java         |  2 +-
 .../internal/codegen/js/jx/LiteralContainerEmitter.java   |  2 +-
 .../codegen/js/jx/ObjectLiteralValuePairEmitter.java      |  6 +++---
 6 files changed, 13 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/01629b23/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
index 218b5be..287b8c8 100644
--- a/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/codegen/js/IJSEmitter.java
@@ -59,7 +59,7 @@ public interface IJSEmitter extends IASEmitter
      * 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.

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/01629b23/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
index 1a73cf6..d0a4aa8 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
@@ -366,11 +366,6 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
     {
         startMapping(node, node.getLine(), node.getColumn());
     }
-
-    public void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping)
-    {
-        startMapping(node, nodeBeforeMapping.getLine(), nodeBeforeMapping.getColumn() + nodeBeforeMapping.getAbsoluteEnd() - nodeBeforeMapping.getAbsoluteStart());
-    }
     
     public void startMapping(ISourceLocation node, int line, int column)
     {
@@ -414,6 +409,11 @@ public class JSEmitter extends ASEmitter implements IJSEmitter
         lastMapping = mapping;
     }
 
+    public void startMapping(ISourceLocation node, ISourceLocation afterNode)
+    {
+        startMapping(node, afterNode.getEndLine(), afterNode.getEndColumn());
+    }
+
     public void endMapping(ISourceLocation node)
     {
         if (lastMapping == null)

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/01629b23/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
index be0b9d1..f947af6 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
@@ -114,9 +114,9 @@ public class JSSubEmitter
         emitter.startMapping(node, line, column);
     }
 
-    protected void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping)
+    protected void startMapping(ISourceLocation node, ISourceLocation afterNode)
     {
-        emitter.startMapping(node, nodeBeforeMapping);
+        emitter.startMapping(node, afterNode);
     }
 
     protected void endMapping(ISourceLocation node)

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/01629b23/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java
index 3099eda..058d132 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/BlockCloseEmitter.java
@@ -36,7 +36,7 @@ public class BlockCloseEmitter extends JSSubEmitter implements
     @Override
     public void emit(IContainerNode node)
     {
-        startMapping(node);
+        startMapping(node, node);
         write(ASEmitterTokens.BLOCK_CLOSE);
         endMapping(node);
     }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/01629b23/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
index d1d24fd..5e0fdce 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
@@ -88,7 +88,7 @@ public class LiteralContainerEmitter extends JSSubEmitter implements
 
         if (postFix != null)
         {
-            startMapping(node, node.getLine(), node.getColumn() + node.getAbsoluteEnd() - node.getAbsoluteStart() - 1);
+            startMapping(node, node.getEndLine(), node.getEndColumn() - postFix.length());
             write(postFix);
             endMapping(node);
         }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/01629b23/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
index d93d701..ad12b77 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
@@ -38,14 +38,14 @@ public class ObjectLiteralValuePairEmitter extends JSSubEmitter implements
     @Override
     public void emit(IObjectLiteralValuePairNode node)
     {
-        ISourceLocation sourceLocationNode = (ISourceLocation) node;
+        ISourceLocation location = (ISourceLocation) node;
 
         IExpressionNode nameNode = node.getNameNode();
         getWalker().walk(nameNode);
 
-        startMapping(sourceLocationNode, nameNode);
+        startMapping(location, nameNode);
         write(ASEmitterTokens.COLON);
-        endMapping(sourceLocationNode);
+        endMapping(location);
 
         IExpressionNode valueNode = node.getValueNode();
         getWalker().walk(valueNode);


[13/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

Posted by cd...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
index a50e288,0000000..d0a4aa8
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
@@@ -1,453 -1,0 +1,471 @@@
 +/*
 + *
 + *  Licensed to the Apache Software Foundation (ASF) under one or more
 + *  contributor license agreements.  See the NOTICE file distributed with
 + *  this work for additional information regarding copyright ownership.
 + *  The ASF licenses this file to You under the Apache License, Version 2.0
 + *  (the "License"); you may not use this file except in compliance with
 + *  the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + *  Unless required by applicable law or agreed to in writing, software
 + *  distributed under the License is distributed on an "AS IS" BASIS,
 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + *  See the License for the specific language governing permissions and
 + *  limitations under the License.
 + *
 + */
 +
 +package org.apache.flex.compiler.internal.codegen.js;
 +
 +import java.io.FilterWriter;
 +import java.util.ArrayList;
 +import java.util.List;
 +import java.util.Stack;
 +
 +import org.apache.flex.compiler.codegen.js.IJSEmitter;
 +import org.apache.flex.compiler.common.ASModifier;
 +import org.apache.flex.compiler.common.ISourceLocation;
 +import org.apache.flex.compiler.definitions.ITypeDefinition;
 +import org.apache.flex.compiler.internal.codegen.as.ASEmitter;
 +import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
++import org.apache.flex.compiler.internal.codegen.js.jx.BlockCloseEmitter;
++import org.apache.flex.compiler.internal.codegen.js.jx.BlockOpenEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.DoWhileLoopEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.DynamicAccessEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ForLoopEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.FunctionCallArgumentsEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.IfEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.IterationFlowEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.LanguageIdentifierEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.LiteralContainerEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.MemberKeywordEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.NumericLiteralEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ObjectLiteralValuePairEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ParameterEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ParametersEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.ReturnEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.SourceMapDirectiveEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.StatementEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.TernaryOperatorEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.UnaryOperatorEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.jx.WhileLoopEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
 +import org.apache.flex.compiler.internal.tree.as.FunctionNode;
 +import org.apache.flex.compiler.tree.as.IASNode;
 +import org.apache.flex.compiler.tree.as.IContainerNode;
 +import org.apache.flex.compiler.tree.as.IDefinitionNode;
 +import org.apache.flex.compiler.tree.as.IDynamicAccessNode;
 +import org.apache.flex.compiler.tree.as.IForLoopNode;
 +import org.apache.flex.compiler.tree.as.IFunctionNode;
 +import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
 +import org.apache.flex.compiler.tree.as.IIfNode;
 +import org.apache.flex.compiler.tree.as.IIterationFlowNode;
 +import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
 +import org.apache.flex.compiler.tree.as.ILiteralContainerNode;
 +import org.apache.flex.compiler.tree.as.INumericLiteralNode;
 +import org.apache.flex.compiler.tree.as.IObjectLiteralValuePairNode;
 +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.ITernaryOperatorNode;
 +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.IWhileLoopNode;
 +
 +import com.google.debugging.sourcemap.FilePosition;
 +
 +/**
 + * @author Michael Schmalle
 + */
 +public class JSEmitter extends ASEmitter implements IJSEmitter
 +{
 +    private JSSessionModel model;
 +    
++    public BlockOpenEmitter blockOpenEmitter;
++    public BlockCloseEmitter blockCloseEmitter;
 +    public NumericLiteralEmitter numericLiteralEmitter;
 +    public ParametersEmitter parametersEmitter;
 +    public ParameterEmitter parameterEmitter;
 +    public FunctionCallArgumentsEmitter functionCallArgumentsEmitter;
 +    public LiteralContainerEmitter literalContainerEmitter;
 +    public ObjectLiteralValuePairEmitter objectLiteralValuePairEmitter;
 +    public ReturnEmitter returnEmitter;
 +    public DynamicAccessEmitter dynamicAccessEmitter;
 +    public UnaryOperatorEmitter unaryOperatorEmitter;
 +    public TernaryOperatorEmitter ternaryOperatorEmitter;
 +    public MemberKeywordEmitter memberKeywordEmitter;
 +    public IfEmitter ifEmitter;
 +    public WhileLoopEmitter whileLoopEmitter;
 +    public DoWhileLoopEmitter doWhileLoopEmitter;
 +    public ForLoopEmitter forLoopEmitter;
 +    public IterationFlowEmitter interationFlowEmitter;
 +    public StatementEmitter statementEmitter;
 +    public LanguageIdentifierEmitter languageIdentifierEmitter;
 +    public SourceMapDirectiveEmitter sourceMapDirectiveEmitter;
 +    
 +    @Override
 +    public JSSessionModel getModel()
 +    {
 +        return model;
 +    }
 +    
 +    private SourceMapMapping lastMapping;
 +    
 +    private Stack<String> nameStack = new Stack<String>();
 +    
 +    private List<SourceMapMapping> sourceMapMappings;
 +    
 +    public List<SourceMapMapping> getSourceMapMappings()
 +    {
 +        return sourceMapMappings;
 +    }
 +
 +    public JSEmitter(FilterWriter out)
 +    {
 +        super(out);
 +        
 +        model = new JSSessionModel();
 +        sourceMapMappings = new ArrayList<SourceMapMapping>();
 +
++        blockOpenEmitter = new BlockOpenEmitter(this);
++        blockCloseEmitter = new BlockCloseEmitter(this);
 +        numericLiteralEmitter = new NumericLiteralEmitter(this);
 +        parametersEmitter = new ParametersEmitter(this);
 +        parameterEmitter = new ParameterEmitter(this);
 +        functionCallArgumentsEmitter = new FunctionCallArgumentsEmitter(this);
 +        literalContainerEmitter = new LiteralContainerEmitter(this);
 +        objectLiteralValuePairEmitter = new ObjectLiteralValuePairEmitter(this);
 +        returnEmitter = new ReturnEmitter(this);
 +        dynamicAccessEmitter = new DynamicAccessEmitter(this);
 +        unaryOperatorEmitter = new UnaryOperatorEmitter(this);
 +        ternaryOperatorEmitter = new TernaryOperatorEmitter(this);
 +        memberKeywordEmitter = new MemberKeywordEmitter(this);
 +        ifEmitter = new IfEmitter(this);
 +        whileLoopEmitter = new WhileLoopEmitter(this);
 +        doWhileLoopEmitter = new DoWhileLoopEmitter(this);
 +        forLoopEmitter = new ForLoopEmitter(this);
 +        interationFlowEmitter = new IterationFlowEmitter(this);
 +        statementEmitter = new StatementEmitter(this);
 +        languageIdentifierEmitter = new LanguageIdentifierEmitter(this);
 +        sourceMapDirectiveEmitter = new SourceMapDirectiveEmitter(this);
 +    }
 +
 +    @Override
 +    public String formatQualifiedName(String name)
 +    {
 +        return name;
 +    }
 +    
 +    @Override
 +    public void emitLocalNamedFunction(IFunctionNode node)
 +    {
 +        startMapping(node);
 +        FunctionNode fnode = (FunctionNode)node;
 +        write(ASEmitterTokens.FUNCTION);
 +        write(ASEmitterTokens.SPACE);
 +        write(fnode.getName());
 +        endMapping(node);
 +        emitParameters(fnode.getParametersContainerNode());
 +        emitFunctionScope(fnode.getScopedNode());
 +    }
 +    
 +    @Override
 +    public void emitFunctionObject(IFunctionObjectNode node)
 +    {
 +        startMapping(node);
 +        FunctionNode fnode = node.getFunctionNode();
 +        write(ASEmitterTokens.FUNCTION);
 +        endMapping(node);
 +        emitParameters(fnode.getParametersContainerNode());
 +        emitFunctionScope(fnode.getScopedNode());
 +    }
 +
 +    public void emitClosureStart()
 +    {
 +    	
 +    }
 +
 +    public void emitClosureEnd(IASNode node)
 +    {
 +    	
 +    }
 +    
 +    public void emitSourceMapDirective(ITypeNode node)
 +    {
 +        sourceMapDirectiveEmitter.emit(node);
 +    }
 +
 +    public void emitParameters(IContainerNode node)
 +    {
 +        parametersEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitParameter(IParameterNode node)
 +    {
 +        parameterEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitArguments(IContainerNode node)
 +    {
 +        functionCallArgumentsEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitNumericLiteral(INumericLiteralNode node)
 +    {
 +        numericLiteralEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitLiteralContainer(ILiteralContainerNode node)
 +    {
 +        literalContainerEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitObjectLiteralValuePair(IObjectLiteralValuePairNode node)
 +    {
 +        objectLiteralValuePairEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitReturn(IReturnNode node)
 +    {
 +        returnEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitTypedExpression(ITypedExpressionNode node)
 +    {
 +        write(JSEmitterTokens.ARRAY);
 +    }
 +
 +    @Override
 +    public void emitDynamicAccess(IDynamicAccessNode node)
 +    {
 +        dynamicAccessEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitMemberKeyword(IDefinitionNode node)
 +    {
 +        memberKeywordEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitUnaryOperator(IUnaryOperatorNode node)
 +    {
 +        unaryOperatorEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitTernaryOperator(ITernaryOperatorNode node)
 +    {
 +        ternaryOperatorEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitLanguageIdentifier(ILanguageIdentifierNode node)
 +    {
 +        languageIdentifierEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitStatement(IASNode node)
 +    {
 +        statementEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitIf(IIfNode node)
 +    {
 +        ifEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitWhileLoop(IWhileLoopNode node)
 +    {
 +        whileLoopEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitDoLoop(IWhileLoopNode node)
 +    {
 +        doWhileLoopEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitForLoop(IForLoopNode node)
 +    {
 +        forLoopEmitter.emit(node);
 +    }
 +
 +    @Override
 +    public void emitIterationFlow(IIterationFlowNode node)
 +    {
 +        interationFlowEmitter.emit(node);
 +    }
 +
++    @Override
++    public void emitBlockOpen(IContainerNode node)
++    {
++        blockOpenEmitter.emit(node);
++    }
++
++    @Override
++    public void emitBlockClose(IContainerNode node)
++    {
++        blockCloseEmitter.emit(node);
++    }
++
 +    public void pushSourceMapName(ISourceLocation node)
 +    {
 +        boolean isValidMappingScope = node instanceof ITypeNode
 +                || node instanceof IPackageNode
 +                || node instanceof IFunctionNode;
 +        if(!isValidMappingScope)
 +        {
 +            throw new IllegalStateException("A source mapping scope must be a package, type, or function.");
 +        }
 +        
 +        IDefinitionNode definitionNode = (IDefinitionNode) node;
 +        String nodeName = definitionNode.getQualifiedName();
 +        ITypeDefinition typeDef = EmitterUtils.getTypeDefinition(definitionNode);
 +        if (typeDef != null)
 +        {
 +            boolean isConstructor = node instanceof IFunctionNode &&
 +                    ((IFunctionNode) node).isConstructor();
 +            boolean isStatic = definitionNode.hasModifier(ASModifier.STATIC);
 +            if (isConstructor)
 +            {
 +                nodeName = typeDef.getQualifiedName() + ".constructor";
 +            }
 +            else if (isStatic)
 +            {
 +                nodeName = typeDef.getQualifiedName() + "." + nodeName;
 +            }
 +            else
 +            {
 +                nodeName = typeDef.getQualifiedName() + ".prototype." + nodeName;
 +            }
 +        }
 +        nameStack.push(nodeName);
 +    }
 +    
 +    public void popSourceMapName()
 +    {
 +        nameStack.pop();
 +    }
 +
 +    public void startMapping(ISourceLocation node)
 +    {
 +        startMapping(node, node.getLine(), node.getColumn());
 +    }
- 
-     public void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping)
-     {
-         startMapping(node, nodeBeforeMapping.getLine(), nodeBeforeMapping.getColumn() + nodeBeforeMapping.getAbsoluteEnd() - nodeBeforeMapping.getAbsoluteStart());
-     }
 +    
 +    public void startMapping(ISourceLocation node, int line, int column)
 +    {
 +        if (lastMapping != null)
 +        {
 +            FilePosition sourceStartPosition = lastMapping.sourceStartPosition;
 +            throw new IllegalStateException("Cannot start new mapping when another mapping is already started. "
 +                    + "Previous mapping at Line " + sourceStartPosition.getLine()
 +                    + " and Column " + sourceStartPosition.getColumn()
 +                    + " in file " + lastMapping.sourcePath);
 +        }
 +        
 +        String sourcePath = node.getSourcePath();
 +        if (sourcePath == null)
 +        {
 +            //if the source path is null, this node may have been generated by
 +            //the compiler automatically. for example, an untyped variable will
 +            //have a node for the * type.
 +            if (node instanceof IASNode)
 +            {
 +                IASNode parentNode = ((IASNode) node).getParent();
 +                if (parentNode != null)
 +                {
 +                    //try the parent node
 +                    startMapping(parentNode, line, column);
 +                    return;
 +                }
 +            }
 +        }
 +        
 +        String nodeName = null;
 +        if (nameStack.size() > 0)
 +        {
 +            nodeName = nameStack.lastElement();
 +        }
 +        SourceMapMapping mapping = new SourceMapMapping();
 +        mapping.sourcePath = sourcePath;
 +        mapping.name = nodeName;
 +        mapping.sourceStartPosition = new FilePosition(line, column);
 +        mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
 +        lastMapping = mapping;
 +    }
 +
++    public void startMapping(ISourceLocation node, ISourceLocation afterNode)
++    {
++        startMapping(node, afterNode.getEndLine(), afterNode.getEndColumn());
++    }
++
 +    public void endMapping(ISourceLocation node)
 +    {
 +        if (lastMapping == null)
 +        {
 +            throw new IllegalStateException("Cannot end mapping when a mapping has not been started");
 +        }
 +
 +        lastMapping.destEndPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
 +        sourceMapMappings.add(lastMapping);
 +        lastMapping = null;
 +    }
 +
 +    /**
 +     * Adjusts the line numbers saved in the source map when a line should be
 +     * added during post processing.
 +     *
 +     * @param lineIndex
 +     */
 +    protected void addLineToMappings(int lineIndex)
 +    {
 +        for (SourceMapMapping mapping : sourceMapMappings)
 +        {
 +            FilePosition destStartPosition = mapping.destStartPosition;
 +            int startLine = destStartPosition.getLine();
 +            if(startLine > lineIndex)
 +            {
 +                mapping.destStartPosition = new FilePosition(startLine + 1, destStartPosition.getColumn());
 +                FilePosition destEndPosition = mapping.destEndPosition;
 +                mapping.destEndPosition = new FilePosition(destEndPosition.getLine() + 1, destEndPosition.getColumn());
 +            }
 +        }
 +    }
 +
 +    /**
 +     * Adjusts the line numbers saved in the source map when a line should be
 +     * removed during post processing.
 +     * 
 +     * @param lineIndex
 +     */
 +    protected void removeLineFromMappings(int lineIndex)
 +    {
 +        for (SourceMapMapping mapping : sourceMapMappings)
 +        {
 +            FilePosition destStartPosition = mapping.destStartPosition;
 +            int startLine = destStartPosition.getLine();
 +            if(startLine > lineIndex)
 +            {
 +                mapping.destStartPosition = new FilePosition(startLine - 1, destStartPosition.getColumn());
 +                FilePosition destEndPosition = mapping.destEndPosition;
 +                mapping.destEndPosition = new FilePosition(destEndPosition.getLine() - 1, destEndPosition.getColumn());
 +            }
 +        }
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
index be0b9d1,0000000..f947af6
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
@@@ -1,126 -1,0 +1,126 @@@
 +/*
 + *
 + *  Licensed to the Apache Software Foundation (ASF) under one or more
 + *  contributor license agreements.  See the NOTICE file distributed with
 + *  this work for additional information regarding copyright ownership.
 + *  The ASF licenses this file to You under the Apache License, Version 2.0
 + *  (the "License"); you may not use this file except in compliance with
 + *  the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + *  Unless required by applicable law or agreed to in writing, software
 + *  distributed under the License is distributed on an "AS IS" BASIS,
 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + *  See the License for the specific language governing permissions and
 + *  limitations under the License.
 + *
 + */
 +
 +package org.apache.flex.compiler.internal.codegen.js;
 +
 +import org.apache.flex.compiler.codegen.IEmitterTokens;
 +import org.apache.flex.compiler.codegen.js.IJSEmitter;
 +import org.apache.flex.compiler.common.ISourceLocation;
 +import org.apache.flex.compiler.projects.ICompilerProject;
 +import org.apache.flex.compiler.visitor.IBlockWalker;
 +
 +public class JSSubEmitter
 +{
 +    private IJSEmitter emitter;
 +
 +    protected IJSEmitter getEmitter()
 +    {
 +        return emitter; 
 +    }
 +
 +    protected IBlockWalker getWalker()
 +    {
 +        return emitter.getWalker();
 +    }
 +    
 +    protected ICompilerProject getProject()
 +    {
 +        return emitter.getWalker().getProject();
 +    }
 +
 +    protected JSSessionModel getModel()
 +    {
 +        return emitter.getModel();
 +    }
 +
 +    public JSSubEmitter(IJSEmitter emitter)
 +    {
 +        this.emitter = emitter;
 +    }
 +
 +    protected void write(IEmitterTokens value)
 +    {
 +        emitter.write(value);
 +    }
 +
 +    protected void write(String value)
 +    {
 +        emitter.write(value);
 +    }
 +
 +    protected void writeToken(IEmitterTokens value)
 +    {
 +        emitter.writeToken(value);
 +    }
 +
 +    protected void writeToken(String value)
 +    {
 +        emitter.writeToken(value);
 +    }
 +
 +    protected void writeNewline()
 +    {
 +        emitter.writeNewline();
 +    }
 +
 +    protected void writeNewline(IEmitterTokens value)
 +    {
 +        emitter.writeNewline(value);
 +    }
 +
 +    protected void writeNewline(String value)
 +    {
 +        emitter.writeNewline(value);
 +    }
 +
 +    protected void writeNewline(String value, boolean pushIndent)
 +    {
 +        emitter.writeNewline(value, pushIndent);
 +    }
 +
 +    protected void indentPush()
 +    {
 +        emitter.indentPush();
 +    }
 +
 +    protected void indentPop()
 +    {
 +        emitter.indentPop();
 +    }
 +
 +    protected void startMapping(ISourceLocation node)
 +    {
 +        emitter.startMapping(node);
 +    }
 +
 +    protected void startMapping(ISourceLocation node, int line, int column)
 +    {
 +        emitter.startMapping(node, line, column);
 +    }
 +
-     protected void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping)
++    protected void startMapping(ISourceLocation node, ISourceLocation afterNode)
 +    {
-         emitter.startMapping(node, nodeBeforeMapping);
++        emitter.startMapping(node, afterNode);
 +    }
 +
 +    protected void endMapping(ISourceLocation node)
 +    {
 +        emitter.endMapping(node);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
index d1d24fd,0000000..5e0fdce
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralContainerEmitter.java
@@@ -1,96 -1,0 +1,96 @@@
 +/*
 + *
 + *  Licensed to the Apache Software Foundation (ASF) under one or more
 + *  contributor license agreements.  See the NOTICE file distributed with
 + *  this work for additional information regarding copyright ownership.
 + *  The ASF licenses this file to You under the Apache License, Version 2.0
 + *  (the "License"); you may not use this file except in compliance with
 + *  the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + *  Unless required by applicable law or agreed to in writing, software
 + *  distributed under the License is distributed on an "AS IS" BASIS,
 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + *  See the License for the specific language governing permissions and
 + *  limitations under the License.
 + *
 + */
 +
 +package org.apache.flex.compiler.internal.codegen.js.jx;
 +
 +import org.apache.flex.compiler.codegen.ISubEmitter;
 +import org.apache.flex.compiler.codegen.js.IJSEmitter;
 +import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 +import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
 +import org.apache.flex.compiler.tree.as.IASNode;
 +import org.apache.flex.compiler.tree.as.IContainerNode;
 +import org.apache.flex.compiler.tree.as.ILiteralContainerNode;
 +
 +public class LiteralContainerEmitter extends JSSubEmitter implements
 +        ISubEmitter<ILiteralContainerNode>
 +{
 +    public LiteralContainerEmitter(IJSEmitter emitter)
 +    {
 +        super(emitter);
 +    }
 +
 +    @Override
 +    public void emit(ILiteralContainerNode node)
 +    {
 +        final IContainerNode cnode = node.getContentsNode();
 +        final IContainerNode.ContainerType type = cnode.getContainerType();
 +        String preFix = null;
 +        String postFix = null;
 +
 +        if (type == IContainerNode.ContainerType.BRACES)
 +        {
 +            preFix = ASEmitterTokens.BLOCK_OPEN.getToken();
 +            postFix = ASEmitterTokens.BLOCK_CLOSE.getToken();
 +        }
 +        else if (type == IContainerNode.ContainerType.BRACKETS)
 +        {
 +            preFix = ASEmitterTokens.SQUARE_OPEN.getToken();
 +            postFix = ASEmitterTokens.SQUARE_CLOSE.getToken();
 +        }
 +        else if (type == IContainerNode.ContainerType.IMPLICIT)
 +        {
 +            // nothing to write, move along
 +        }
 +        else if (type == IContainerNode.ContainerType.PARENTHESIS)
 +        {
 +            preFix = ASEmitterTokens.PAREN_OPEN.getToken();
 +            postFix = ASEmitterTokens.PAREN_CLOSE.getToken();
 +        }
 +
 +        if (preFix != null)
 +        {
 +            startMapping(node);
 +            write(preFix);
 +            endMapping(node);
 +        }
 +
 +        final int len = cnode.getChildCount();
 +        for (int i = 0; i < len; i++)
 +        {
 +            IASNode child = cnode.getChild(i);
 +            getWalker().walk(child);
 +            if (i < len - 1)
 +            {
 +                //we're mapping the comma to the literal container, but we fill
 +                //the space between the current child and the next because we
 +                //don't know exactly where the comma appears in ActionScript
 +                startMapping(node, child);
 +                writeToken(ASEmitterTokens.COMMA);
 +                endMapping(node);
 +            }
 +        }
 +
 +        if (postFix != null)
 +        {
-             startMapping(node, node.getLine(), node.getColumn() + node.getAbsoluteEnd() - node.getAbsoluteStart() - 1);
++            startMapping(node, node.getEndLine(), node.getEndColumn() - postFix.length());
 +            write(postFix);
 +            endMapping(node);
 +        }
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
index d93d701,0000000..ad12b77
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ObjectLiteralValuePairEmitter.java
@@@ -1,53 -1,0 +1,53 @@@
 +/*
 + *
 + *  Licensed to the Apache Software Foundation (ASF) under one or more
 + *  contributor license agreements.  See the NOTICE file distributed with
 + *  this work for additional information regarding copyright ownership.
 + *  The ASF licenses this file to You under the Apache License, Version 2.0
 + *  (the "License"); you may not use this file except in compliance with
 + *  the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + *  Unless required by applicable law or agreed to in writing, software
 + *  distributed under the License is distributed on an "AS IS" BASIS,
 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + *  See the License for the specific language governing permissions and
 + *  limitations under the License.
 + *
 + */
 +
 +package org.apache.flex.compiler.internal.codegen.js.jx;
 +
 +import org.apache.flex.compiler.codegen.ISubEmitter;
 +import org.apache.flex.compiler.codegen.js.IJSEmitter;
 +import org.apache.flex.compiler.common.ISourceLocation;
 +import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 +import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
 +import org.apache.flex.compiler.tree.as.IExpressionNode;
 +import org.apache.flex.compiler.tree.as.IObjectLiteralValuePairNode;
 +
 +public class ObjectLiteralValuePairEmitter extends JSSubEmitter implements
 +        ISubEmitter<IObjectLiteralValuePairNode>
 +{
 +    public ObjectLiteralValuePairEmitter(IJSEmitter emitter)
 +    {
 +        super(emitter);
 +    }
 +
 +    @Override
 +    public void emit(IObjectLiteralValuePairNode node)
 +    {
-         ISourceLocation sourceLocationNode = (ISourceLocation) node;
++        ISourceLocation location = (ISourceLocation) node;
 +
 +        IExpressionNode nameNode = node.getNameNode();
 +        getWalker().walk(nameNode);
 +
-         startMapping(sourceLocationNode, nameNode);
++        startMapping(location, nameNode);
 +        write(ASEmitterTokens.COLON);
-         endMapping(sourceLocationNode);
++        endMapping(location);
 +
 +        IExpressionNode valueNode = node.getValueNode();
 +        getWalker().walk(valueNode);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
index f43b288,0000000..911a280
mode 100644,000000..100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
@@@ -1,123 -1,0 +1,131 @@@
 +/*
 + *
 + *  Licensed to the Apache Software Foundation (ASF) under one or more
 + *  contributor license agreements.  See the NOTICE file distributed with
 + *  this work for additional information regarding copyright ownership.
 + *  The ASF licenses this file to You under the Apache License, Version 2.0
 + *  (the "License"); you may not use this file except in compliance with
 + *  the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + *  Unless required by applicable law or agreed to in writing, software
 + *  distributed under the License is distributed on an "AS IS" BASIS,
 + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + *  See the License for the specific language governing permissions and
 + *  limitations under the License.
 + *
 + */
 +
 +package org.apache.flex.compiler.internal.codegen.js.jx;
 +
 +import org.apache.flex.compiler.codegen.ISubEmitter;
 +import org.apache.flex.compiler.codegen.js.IJSEmitter;
 +import org.apache.flex.compiler.definitions.IDefinition;
 +import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 +import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
 +import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
 +import org.apache.flex.compiler.internal.tree.as.ChainedVariableNode;
 +import org.apache.flex.compiler.tree.as.IASNode;
 +import org.apache.flex.compiler.tree.as.IEmbedNode;
 +import org.apache.flex.compiler.tree.as.IExpressionNode;
 +import org.apache.flex.compiler.tree.as.IVariableNode;
 +
 +public class VarDeclarationEmitter extends JSSubEmitter implements
 +        ISubEmitter<IVariableNode>
 +{
 +
 +    public VarDeclarationEmitter(IJSEmitter emitter)
 +    {
 +        super(emitter);
 +    }
 +
 +    @Override
 +    public void emit(IVariableNode node)
 +    {
 +        // TODO (mschmalle) will remove this cast as more things get abstracted
 +        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
 +
 +        getModel().getVars().add(node);
 +        
 +        if (!(node instanceof ChainedVariableNode) && !node.isConst())
 +        {
 +            fjs.emitMemberKeyword(node);
 +        }
 +
 +        IExpressionNode variableTypeNode = node.getVariableTypeNode();
-         if(variableTypeNode.getLine() >= 0)
++        boolean hasVariableType = variableTypeNode.getLine() >= 0;
++        if(hasVariableType)
 +        {
 +            startMapping(variableTypeNode,
 +                    variableTypeNode.getLine(),
 +                    variableTypeNode.getColumn() - 1); //include the :
 +        }
 +        else
 +        {
 +            //the result of getVariableTypeNode() may not have a line and
 +            //column. this can happen when the type is omitted in the code, and
 +            //the compiler generates a node for type *.
 +            //in this case, put it at the end of the name expression.
 +            IExpressionNode nameExpressionNode = node.getNameExpressionNode();
 +            startMapping(variableTypeNode, nameExpressionNode.getLine(),
 +                    nameExpressionNode.getColumn() + nameExpressionNode.getAbsoluteEnd() - nameExpressionNode.getAbsoluteStart());
 +        }
 +        IExpressionNode avnode = node.getAssignedValueNode();
 +        if (avnode != null)
 +        {
 +            IDefinition def = avnode.resolveType(getWalker().getProject());
 +
 +            String opcode = avnode.getNodeID().getParaphrase();
 +            if (opcode != "AnonymousFunction")
 +            {
 +                fjs.getDocEmitter().emitVarDoc(node, def, getWalker().getProject());
 +            }
 +        }
 +        else
 +        {
 +            fjs.getDocEmitter().emitVarDoc(node, null, getWalker().getProject());
 +        }
 +        endMapping(variableTypeNode);
 +
 +        if (!(node instanceof ChainedVariableNode) && node.isConst())
 +        {
 +            fjs.emitMemberKeyword(node);
 +        }
 +
 +        fjs.emitDeclarationName(node);
 +        if (avnode != null && !(avnode instanceof IEmbedNode))
 +        {
-             startMapping(node, node.getVariableTypeNode());
++            if (hasVariableType)
++            {
++                startMapping(node, node.getVariableTypeNode());
++            }
++            else
++            {
++                startMapping(node, node.getNameExpressionNode());
++            }
 +            write(ASEmitterTokens.SPACE);
 +            writeToken(ASEmitterTokens.EQUAL);
 +            endMapping(node);
 +            fjs.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)
 +                {
 +                    startMapping(node, node.getChild(i - 1));
 +                    writeToken(ASEmitterTokens.COMMA);
 +                    endMapping(node);
 +                    fjs.emitVarDeclaration((IVariableNode) child);
 +                }
 +            }
 +        }
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
index 57ab17b,0000000..90aab08
mode 100644,000000..100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapExpressions.java
@@@ -1,716 -1,0 +1,755 @@@
 +package org.apache.flex.compiler.internal.codegen.js.sourcemaps;
 +
 +import org.apache.flex.compiler.driver.IBackend;
 +import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
 +import org.apache.flex.compiler.internal.test.SourceMapTestBase;
 +import org.apache.flex.compiler.internal.tree.as.ArrayLiteralNode;
 +import org.apache.flex.compiler.internal.tree.as.ObjectLiteralNode;
 +import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
 +import org.apache.flex.compiler.tree.as.IDynamicAccessNode;
 +import org.apache.flex.compiler.tree.as.IFunctionCallNode;
 +import org.apache.flex.compiler.tree.as.IIterationFlowNode;
 +import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
 +import org.apache.flex.compiler.tree.as.IReturnNode;
 +import org.apache.flex.compiler.tree.as.ITernaryOperatorNode;
 +import org.apache.flex.compiler.tree.as.IUnaryOperatorNode;
 +
 +import org.junit.Test;
 +
 +public class TestSourceMapExpressions extends SourceMapTestBase
 +{
 +    //----------------------------------
 +    // Primary expression keywords
 +    //----------------------------------
 +
 +    //----------------------------------
 +    // Arithmetic
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Plus()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a + b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // +
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Minus()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a - b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // -
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Divide()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a / b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // /
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Modulo()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a % b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // %
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Multiply()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a * b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // *
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_PostIncrement()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("a++");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 3);
++        assertMapping(node, 0, 1, 0, 1, 0, 3); // ++
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_PreIncrement()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("++a");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 2);
++        assertMapping(node, 0, 0, 0, 0, 0, 2); // +
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_PostDecrement()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("a--");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 3);
++        assertMapping(node, 0, 1, 0, 1, 0, 3); // --
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_PreDecrement()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("--a");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 2);
++        assertMapping(node, 0, 0, 0, 0, 0, 2); // --
 +    }
 +
 +    //----------------------------------
 +    // Arithmetic compound assignment
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_PlusAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a += b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_MinusAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a -= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_DivideAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a /= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_ModuloAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a %= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_MultiplyAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a *= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    //----------------------------------
 +    // Assignment
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Assignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a = b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
 +    }
 +
 +    //----------------------------------
 +    // Bitwise
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseAnd()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a & b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // &
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseLeftShift()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a << b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // <<
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_BitwiseNot()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("~a");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 1);
++        assertMapping(node, 0, 0, 0, 0, 0, 1); // ~
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseOr()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a | b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // |
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseRightShift()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a >> b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // >>
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseUnsignedRightShift()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a >>> b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 6);
++        assertMapping(node, 0, 1, 0, 1, 0, 6); // >>>
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseXOR()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a ^ b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // ^
 +    }
 +
 +    //----------------------------------
 +    // Bitwise compound assignment
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseAndAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a &= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseLeftShiftAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a <<= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 6);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseOrAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a |= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseRightShiftAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a >>= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 6);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseUnsignedRightShiftAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a >>>= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 7);
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_BitwiseXORAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a ^= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        assertMapping(node, 0, 1, 0, 1, 0, 5);
 +    }
 +
 +    //----------------------------------
 +    // Comparison
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Equal()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a == b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // ==
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_GreaterThan()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a > b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // >
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_GreaterThanEqual()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a >= b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // >=
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_NotEqual()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a != b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // !=
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_LessThan()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a < b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // <
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_LessThanEqual()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a <= b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // <=
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_StrictEqual()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a === b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 6);
++        assertMapping(node, 0, 1, 0, 1, 0, 6); // ===
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_StrictNotEqual()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a !== b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 6);
++        assertMapping(node, 0, 1, 0, 1, 0, 6); // !==
 +    }
 +
 +    //----------------------------------
 +    // Logical
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_LogicalAnd()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a && b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // &&
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_LogicalAndAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a &&= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        //a = a && b
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
-         assertMapping(node, 0, 1, 0, 5, 0, 9);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
++        assertMapping(node, 0, 1, 0, 5, 0, 9); // &&
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_LogicalNot()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("!a");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 1);
++        assertMapping(node, 0, 0, 0, 0, 0, 1); // !
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_LogicalOr()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a || b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // ||
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_LogicalOrAssignment()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a ||= b");
 +        asBlockWalker.visitBinaryOperator(node);
 +        //a = a || b
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
-         assertMapping(node, 0, 1, 0, 5, 0, 9);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // =
++        assertMapping(node, 0, 1, 0, 5, 0, 9); // ||
 +    }
 +
 +    //----------------------------------
 +    // Other
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitDynamicAccessNode_1()
 +    {
 +        IDynamicAccessNode node = getDynamicAccessNode("a[b]");
 +        asBlockWalker.visitDynamicAccess(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 2);
-         assertMapping(node, 0, 3, 0, 3, 0, 4);
++        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
++        assertMapping(node, 0, 1, 0, 1, 0, 2); // [
++        assertMapping(node, 0, 2, 0, 2, 0, 3); // b
++        assertMapping(node, 0, 3, 0, 3, 0, 4); // ]
 +    }
 +
 +    @Test
 +    public void testVisitDynamicAccessNode_2()
 +    {
 +        IDynamicAccessNode node = getDynamicAccessNode("a[b[c][d]]");
 +        asBlockWalker.visitDynamicAccess(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 2);
-         assertMapping(node, 0, 3, 0, 3, 0, 4);
-         assertMapping(node, 0, 5, 0, 5, 0, 6);
-         assertMapping(node, 0, 6, 0, 6, 0, 7);
-         assertMapping(node, 0, 8, 0, 8, 0, 9);
-         assertMapping(node, 0, 9, 0, 9, 0, 10);
++        assertMapping(node, 0, 0, 0, 0, 0, 1);   // a
++        assertMapping(node, 0, 1, 0, 1, 0, 2);   // [
++        assertMapping(node, 0, 2, 0, 2, 0, 3);   // b
++        assertMapping(node, 0, 3, 0, 3, 0, 4);   // [
++        assertMapping(node, 0, 4, 0, 4, 0, 5);   // c
++        assertMapping(node, 0, 5, 0, 5, 0, 6);   // ]
++        assertMapping(node, 0, 6, 0, 6, 0, 7);   // [
++        assertMapping(node, 0, 7, 0, 7, 0, 8);   // d
++        assertMapping(node, 0, 8, 0, 8, 0, 9);   // ]
++        assertMapping(node, 0, 9, 0, 9, 0, 10);  // ]
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperatorNode_Comma()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a, b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 3);
++        assertMapping(node, 0, 1, 0, 1, 0, 3); // ,
 +    }
 +
 +    @Test
 +    public void testVisitTernaryOperatorNode()
 +    {
 +        ITernaryOperatorNode node = (ITernaryOperatorNode) getExpressionNode(
 +                "a ? b : c", ITernaryOperatorNode.class);
 +        asBlockWalker.visitTernaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 4);
-         assertMapping(node, 0, 5, 0, 5, 0, 8);
++        assertMapping(node, 0, 1, 0, 1, 0, 4); // ?
++        assertMapping(node, 0, 5, 0, 5, 0, 8); // :
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperator_Delete()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("delete a");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 7);
++        assertMapping(node, 0, 0, 0, 0, 0, 7); // delete
 +    }
 +
 +    @Test
 +    public void testVisitMemberAccess_1()
 +    {
 +        IMemberAccessExpressionNode node = (IMemberAccessExpressionNode) getExpressionNode(
 +                "a.b", IMemberAccessExpressionNode.class);
 +        asBlockWalker.visitMemberAccessExpression(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 2);
++        assertMapping(node, 0, 1, 0, 1, 0, 2); // .
 +    }
 +
 +    @Test
 +    public void testVisitMemberAccess_2()
 +    {
 +        IMemberAccessExpressionNode node = (IMemberAccessExpressionNode) getExpressionNode(
 +                "a.b.c.d", IMemberAccessExpressionNode.class);
 +        asBlockWalker.visitMemberAccessExpression(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 2);
-         assertMapping(node, 0, 3, 0, 3, 0, 4);
-         assertMapping(node, 0, 5, 0, 5, 0, 6);
++        assertMapping(node, 0, 1, 0, 1, 0, 2); // .
++        assertMapping(node, 0, 3, 0, 3, 0, 4); // .
++        assertMapping(node, 0, 5, 0, 5, 0, 6); // .
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperator_In()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a in b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 5);
++        assertMapping(node, 0, 1, 0, 1, 0, 5); // in
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperator_Instancof()
 +    {
 +        IBinaryOperatorNode node = getBinaryNode("a instanceof b");
 +        asBlockWalker.visitBinaryOperator(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 13);
++        assertMapping(node, 0, 1, 0, 1, 0, 13); // instanceof
 +    }
 +
 +    @Test
 +    public void testVisitBinaryOperator_New()
 +    {
 +        IFunctionCallNode node = (IFunctionCallNode) getExpressionNode(
 +                "new Object()", IFunctionCallNode.class);
 +        asBlockWalker.visitFunctionCall(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 4);
++        assertMapping(node, 0, 0, 0, 0, 0, 4); // new
 +    }
 +
 +    @Test
 +    public void testVisitObjectLiteral_1()
 +    {
 +        ObjectLiteralNode node = (ObjectLiteralNode) getExpressionNode(
 +                "a = {a:1}", ObjectLiteralNode.class);
 +        asBlockWalker.visitLiteral(node);
++        //{a: 1}
 +        assertMapping(node, 0, 0, 0, 0, 0, 1); // {
 +        assertMapping(node, 0, 1, 0, 1, 0, 2); // a
 +        assertMapping(node, 0, 2, 0, 2, 0, 3); // :
 +        assertMapping(node, 0, 4, 0, 4, 0, 5); // }
 +    }
 +
 +    @Test
 +    public void testVisitObjectLiteral_2()
 +    {
 +        ObjectLiteralNode node = (ObjectLiteralNode) getExpressionNode(
 +                "a = {a:1,b:{c:2,d:{e:4}}}", ObjectLiteralNode.class);
 +        asBlockWalker.visitLiteral(node);
 +        //{a:1, b:{c:2, d:{e:4}}}
 +        assertMapping(node, 0, 0, 0, 0, 0, 1);    // {
 +        assertMapping(node, 0, 1, 0, 1, 0, 2);    // a
 +        assertMapping(node, 0, 2, 0, 2, 0, 3);    // :
 +        assertMapping(node, 0, 4, 0, 4, 0, 6);    // ,
 +        assertMapping(node, 0, 5, 0, 6, 0, 7);    // b
 +        assertMapping(node, 0, 6, 0, 7, 0, 8);    // :
 +        assertMapping(node, 0, 7, 0, 8, 0, 9);    // {
 +        assertMapping(node, 0, 8, 0, 9, 0, 10);   // c
 +        assertMapping(node, 0, 9, 0, 10, 0, 11);  // :
 +        assertMapping(node, 0, 11, 0, 12, 0, 14); // ,
 +        assertMapping(node, 0, 12, 0, 14, 0, 15); // d
 +        assertMapping(node, 0, 13, 0, 15, 0, 16); // :
 +        assertMapping(node, 0, 14, 0, 16, 0, 17); // {
 +        assertMapping(node, 0, 15, 0, 17, 0, 18); // e
 +        assertMapping(node, 0, 16, 0, 18, 0, 19); // :
 +        assertMapping(node, 0, 18, 0, 20, 0, 21); // }
 +        assertMapping(node, 0, 19, 0, 21, 0, 22); // }
 +        assertMapping(node, 0, 20, 0, 22, 0, 23); // }
 +        
 +    }
 +
 +    @Test
 +    public void testVisitObjectLiteral_3()
 +    {
 +        ObjectLiteralNode node = (ObjectLiteralNode) getExpressionNode(
 +                "a = { a: 12,  bb: 2   \t}", ObjectLiteralNode.class);
 +        asBlockWalker.visitLiteral(node);
 +        //{a:12, bb:2}
 +        assertMapping(node, 0, 0, 0, 0, 0, 1);    // {
 +        assertMapping(node, 0, 2, 0, 1, 0, 2);    // a
 +        assertMapping(node, 0, 3, 0, 2, 0, 3);    // :
 +        assertMapping(node, 0, 7, 0, 5, 0, 7);    // ,
 +        assertMapping(node, 0, 10, 0, 7, 0, 9);   // bb
 +        assertMapping(node, 0, 12, 0, 9, 0, 10);  // :
 +        assertMapping(node, 0, 19, 0, 11, 0, 12); // }
 +    }
 +
 +    @Test
++    public void testVisitObjectLiteral_4()
++    {
++        ObjectLiteralNode node = (ObjectLiteralNode) getExpressionNode(
++                "a = {a:1,\nb:2}", ObjectLiteralNode.class);
++        asBlockWalker.visitLiteral(node);
++        //{a:1, b:2}
++        assertMapping(node, 0, 0, 0, 0, 0, 1);   // {
++        assertMapping(node, 0, 1, 0, 1, 0, 2);   // a
++        assertMapping(node, 0, 2, 0, 2, 0, 3);   // :
++        assertMapping(node, 0, 3, 0, 3, 0, 4);   // 1
++        assertMapping(node, 0, 4, 0, 4, 0, 6);   // ,
++        assertMapping(node, 1, 0, 0, 6, 0, 7);   // b
++        assertMapping(node, 1, 1, 0, 7, 0, 8);   // :
++        assertMapping(node, 1, 2, 0, 8, 0, 9);   // 2
++        assertMapping(node, 1, 3, 0, 9, 0, 10);  // }
++    }
++
++    @Test
 +    public void testVisitArrayLiteral_1()
 +    {
 +        ArrayLiteralNode node = (ArrayLiteralNode) getExpressionNode(
 +                "a = [0,1,2]", ArrayLiteralNode.class);
 +        asBlockWalker.visitLiteral(node);
 +        //[0, 1, 2]
 +        assertMapping(node, 0, 0, 0, 0, 0, 1); // [
++        assertMapping(node, 0, 1, 0, 1, 0, 2); // 0
 +        assertMapping(node, 0, 2, 0, 2, 0, 4); // ,
++        assertMapping(node, 0, 3, 0, 4, 0, 5); // 1
 +        assertMapping(node, 0, 4, 0, 5, 0, 7); // ,
++        assertMapping(node, 0, 5, 0, 7, 0, 8); // 2
 +        assertMapping(node, 0, 6, 0, 8, 0, 9); // ]
 +    }
 +
 +    @Test
 +    public void testVisitArrayLiteral_2()
 +    {
 +        ArrayLiteralNode node = (ArrayLiteralNode) getExpressionNode(
 +                "a = [0,[0,1,[0,1]],2,[1,2]]", ArrayLiteralNode.class);
 +        asBlockWalker.visitLiteral(node);
 +        //[0, [0, 1, [0, 1]], 2, [1, 2]]
 +        assertMapping(node, 0, 0, 0, 0, 0, 1);    // [
 +        assertMapping(node, 0, 2, 0, 2, 0, 4);    // ,
 +        assertMapping(node, 0, 3, 0, 4, 0, 5);    // [
 +        assertMapping(node, 0, 5, 0, 6, 0, 8);    // ,
 +        assertMapping(node, 0, 7, 0, 9, 0, 11);   // ,
 +        assertMapping(node, 0, 8, 0, 11, 0, 12);  // [
 +        assertMapping(node, 0, 10, 0, 13, 0, 15); // ,
 +        assertMapping(node, 0, 12, 0, 16, 0, 17); // ]
 +        assertMapping(node, 0, 13, 0, 17, 0, 18); // ]
 +        
 +        assertMapping(node, 0, 14, 0, 18, 0, 20); // ,
 +        assertMapping(node, 0, 16, 0, 21, 0, 23); // ,
 +        assertMapping(node, 0, 17, 0, 23, 0, 24); // [
 +        assertMapping(node, 0, 19, 0, 25, 0, 27); // ,
 +        assertMapping(node, 0, 21, 0, 28, 0, 29); // ]
 +        assertMapping(node, 0, 22, 0, 29, 0, 30); // ]
 +    }
 +
 +    @Test
 +    public void testVisitArrayLiteral_3()
 +    {
 +        ArrayLiteralNode node = (ArrayLiteralNode) getExpressionNode(
 +                "a = [ 0,  123, 45   \t]", ArrayLiteralNode.class);
 +        asBlockWalker.visitLiteral(node);
 +        //[0, 123, 45]
 +        assertMapping(node, 0, 0, 0, 0, 0, 1);    // [
 +        assertMapping(node, 0, 3, 0, 2, 0, 4);    // ,
 +        assertMapping(node, 0, 9, 0, 7, 0, 9);    // ,
 +        assertMapping(node, 0, 17, 0, 11, 0, 12); // ]
 +    }
 +
 +    @Test
 +    public void testVisitArrayLiteral_4()
 +    {
 +        ArrayLiteralNode node = (ArrayLiteralNode) getExpressionNode(
 +                "a = [0,\n123, 45]", ArrayLiteralNode.class);
 +        asBlockWalker.visitLiteral(node);
 +        //[0, 123, 45]
 +        assertMapping(node, 0, 0, 0, 0, 0, 1);    // [
 +        assertMapping(node, 0, 1, 0, 1, 0, 2);    // 0
 +        assertMapping(node, 0, 2, 0, 2, 0, 4);    // ,
 +        assertMapping(node, 1, 0, 0, 4, 0, 7);    // 123
 +        assertMapping(node, 1, 3, 0, 7, 0, 9);    // ,
-         assertMapping(node, 1, 5, 0, 9, 0, 11);    // 45
-         //TODO: figure out how to place the ] 
++        assertMapping(node, 1, 5, 0, 9, 0, 11);   // 45
++        assertMapping(node, 1, 7, 0, 11, 0, 12);  // 45
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_Typeof()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("typeof(a)");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 7);
-         assertMapping(node, 0, 0, 0, 8, 0, 9);
++        //typeof(a)
++        assertMapping(node, 0, 0, 0, 0, 0, 7); // typeof(
++        assertMapping(node, 0, 0, 0, 8, 0, 9); // )
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_Typeof_NoParens()
 +    {
 +        // TODO (mschmalle) the notation without parenthesis is also valid in AS/JS
 +        IUnaryOperatorNode node = getUnaryNode("typeof a");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 7);
-         assertMapping(node, 0, 0, 0, 8, 0, 9);
++        //typeof(a)
++        assertMapping(node, 0, 0, 0, 0, 0, 7); // typeof(
++        assertMapping(node, 0, 0, 0, 8, 0, 9); // )
 +    }
 +
 +    @Test
 +    public void testVisitUnaryOperatorNode_Void()
 +    {
 +        IUnaryOperatorNode node = getUnaryNode("void a");
 +        asBlockWalker.visitUnaryOperator(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 5);
++        assertMapping(node, 0, 0, 0, 0, 0, 5); // void
 +    }
 +
 +    @Test
 +    public void testVisitIterationFlowNode_BreakWithoutLabel()
 +    {
 +        IIterationFlowNode node = (IIterationFlowNode) getNode("break",
 +                IIterationFlowNode.class);
 +        asBlockWalker.visitIterationFlow(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 5);
++        assertMapping(node, 0, 0, 0, 0, 0, 5); // break
 +    }
 +
 +    @Test
 +    public void testVisitIterationFlowNode_BreakWithLabel()
 +    {
 +        IIterationFlowNode node = (IIterationFlowNode) getNode("break label",
 +                IIterationFlowNode.class);
 +        asBlockWalker.visitIterationFlow(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 6);
++        assertMapping(node, 0, 0, 0, 0, 0, 6);  // break
++        assertMapping(node, 0, 6, 0, 6, 0, 11); // label
 +    }
 +
 +    @Test
 +    public void testVisitIterationFlowNode_ContinueWithoutLabel()
 +    {
 +        IIterationFlowNode node = (IIterationFlowNode) getNode("continue",
 +                IIterationFlowNode.class);
 +        asBlockWalker.visitIterationFlow(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 8);
++        assertMapping(node, 0, 0, 0, 0, 0, 8); // continue
 +    }
 +
 +    @Test
 +    public void testVisitIterationFlowNode_ContinueWithLabel()
 +    {
 +        IIterationFlowNode node = (IIterationFlowNode) getNode("continue label",
 +                IIterationFlowNode.class);
 +        asBlockWalker.visitIterationFlow(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 9);
++        assertMapping(node, 0, 0, 0, 0, 0, 9); // continue
++        assertMapping(node, 0, 9, 0, 9, 0, 14); // label
 +    }
 +
 +    @Test
 +    public void testVisitReturnWithoutValue()
 +    {
 +        IReturnNode node = (IReturnNode) getNode("return", IReturnNode.class);
 +        asBlockWalker.visitReturn(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 6);
++        assertMapping(node, 0, 0, 0, 0, 0, 6); // return
 +    }
 +
 +    @Test
 +    public void testVisitReturnWithValue()
 +    {
 +        IReturnNode node = (IReturnNode) getNode("return 0", IReturnNode.class);
 +        asBlockWalker.visitReturn(node);
-         assertMapping(node, 0, 0, 0, 0, 0, 7);
++        assertMapping(node, 0, 0, 0, 0, 0, 7); // return
++        assertMapping(node, 0, 7, 0, 7, 0, 8); // 0
 +    }
 +
 +    @Test
 +    public void testVisitFunctionCall_1()
 +    {
 +        IFunctionCallNode node = (IFunctionCallNode) getNode("a()", IFunctionCallNode.class);
 +        asBlockWalker.visitFunctionCall(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 2);
-         assertMapping(node, 0, 2, 0, 2, 0, 3);
++        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
++        assertMapping(node, 0, 1, 0, 1, 0, 2); // (
++        assertMapping(node, 0, 2, 0, 2, 0, 3); // )
 +    }
 +
 +    @Test
 +    public void testVisitFunctionCall_2()
 +    {
 +        IFunctionCallNode node = (IFunctionCallNode) getNode("a(b)", IFunctionCallNode.class);
 +        asBlockWalker.visitFunctionCall(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 2);
-         assertMapping(node, 0, 3, 0, 3, 0, 4);
++        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
++        assertMapping(node, 0, 1, 0, 1, 0, 2); // (
++        assertMapping(node, 0, 2, 0, 2, 0, 3); // b
++        assertMapping(node, 0, 3, 0, 3, 0, 4); // )
 +    }
 +
 +    @Test
 +    public void testVisitFunctionCall_3()
 +    {
 +        IFunctionCallNode node = (IFunctionCallNode) getNode("a(b, c)", IFunctionCallNode.class);
 +        asBlockWalker.visitFunctionCall(node);
-         assertMapping(node, 0, 1, 0, 1, 0, 2);
-         assertMapping(node, 0, 3, 0, 3, 0, 5);
-         assertMapping(node, 0, 6, 0, 6, 0, 7);
++        assertMapping(node, 0, 0, 0, 0, 0, 1); // a
++        assertMapping(node, 0, 1, 0, 1, 0, 2); // (
++        assertMapping(node, 0, 2, 0, 2, 0, 3); // b
++        assertMapping(node, 0, 3, 0, 3, 0, 5); // ,
++        assertMapping(node, 0, 5, 0, 5, 0, 6); // c
++        assertMapping(node, 0, 6, 0, 6, 0, 7); // )
 +    }
 +
 +    protected IBackend createBackend()
 +    {
 +        return new FlexJSBackend();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/beaf5b63/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
----------------------------------------------------------------------
diff --cc compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
index 3c25d07,0000000..265b94c
mode 100644,000000..100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/sourcemaps/TestSourceMapStatements.java
@@@ -1,171 -1,0 +1,307 @@@
 +package org.apache.flex.compiler.internal.codegen.js.sourcemaps;
 +
 +import org.apache.flex.compiler.driver.IBackend;
 +import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
 +import org.apache.flex.compiler.internal.test.SourceMapTestBase;
 +import org.apache.flex.compiler.tree.as.IForLoopNode;
++import org.apache.flex.compiler.tree.as.IIfNode;
 +import org.apache.flex.compiler.tree.as.IVariableNode;
 +
 +import org.junit.Test;
 +
 +public class TestSourceMapStatements extends SourceMapTestBase
 +{
 +    //----------------------------------
 +    // var declaration
 +    //----------------------------------
 +
 +    @Test
 +    public void testVarDeclaration()
 +    {
 +        IVariableNode node = (IVariableNode) getNode("var a;",
 +                IVariableNode.class);
 +        asBlockWalker.visitVariable(node);
 +        //var /** @type {*} */ a
 +        assertMapping(node, 0, 0, 0, 0, 0, 4);   // var
 +        assertMapping(node, 0, 4, 0, 21, 0, 22); // a
 +        assertMapping(node, 0, 5, 0, 4, 0, 21);  // (type)
 +    }
 +
 +    @Test
++    public void testVarDeclaration_withAssignedValue()
++    {
++        IVariableNode node = (IVariableNode) getNode("var a = 42;",
++                IVariableNode.class);
++        asBlockWalker.visitVariable(node);
++        //var /** @type {*} */ a = 42
++        assertMapping(node, 0, 0, 0, 0, 0, 4);   // var
++        assertMapping(node, 0, 4, 0, 21, 0, 22); // a
++        assertMapping(node, 0, 5, 0, 4, 0, 21);  // (type)
++        assertMapping(node, 0, 5, 0, 22, 0, 25); // =
++        assertMapping(node, 0, 8, 0, 25, 0, 27); // 42
++    }
++
++    @Test
 +    public void testVarDeclaration_withType()
 +    {
 +        IVariableNode node = (IVariableNode) getNode("var a:int;",
 +                IVariableNode.class);
 +        asBlockWalker.visitVariable(node);
 +        //var /** @type {number} */ a
 +        assertMapping(node, 0, 0, 0, 0, 0, 4);   // var
 +        assertMapping(node, 0, 4, 0, 26, 0, 27); // a
 +        assertMapping(node, 0, 5, 0, 4, 0, 26);  // :int
 +    }
 +
 +    @Test
 +    public void testVarDeclaration_withTypeAssignedValue()
 +    {
 +        IVariableNode node = (IVariableNode) getNode("var a:int = 42;",
 +                IVariableNode.class);
 +        asBlockWalker.visitVariable(node);
 +        //var /** @type {number} */ a = 42
 +        assertMapping(node, 0, 0, 0, 0, 0, 4);    // var
 +        assertMapping(node, 0, 4, 0, 26, 0, 27);  // a
 +        assertMapping(node, 0, 5, 0, 4, 0, 26);   // :int
 +        assertMapping(node, 0, 9, 0, 27, 0, 30);  // =
 +        assertMapping(node, 0, 12, 0, 30, 0, 32); // 42
 +    }
 +
 +    @Test
 +    public void testVarDeclaration_withTypeAssignedValueComplex()
 +    {
 +        IVariableNode node = (IVariableNode) getNode(
 +                "class A { public function b():void { var a:Foo = new Foo(42, 'goo');}} class Foo {}", IVariableNode.class, WRAP_LEVEL_PACKAGE);
 +        asBlockWalker.visitVariable(node);
 +        //var /** @type {Foo} */ a = new Foo(42, 'goo')
 +        assertMapping(node, 0, 0, 0, 0, 0, 4);    // var
 +        assertMapping(node, 0, 4, 0, 23, 0, 24);  // a
 +        assertMapping(node, 0, 5, 0, 4, 0, 23);   // :Foo
 +        assertMapping(node, 0, 9, 0, 24, 0, 27);  // =
 +        assertMapping(node, 0, 12, 0, 27, 0, 31);  // new
 +        assertMapping(node, 0, 16, 0, 31, 0, 34);  // Foo
 +        assertMapping(node, 0, 19, 0, 34, 0, 35);  // (
 +        assertMapping(node, 0, 20, 0, 35, 0, 37);  // 42
 +        assertMapping(node, 0, 22, 0, 37, 0, 39);  // ,
 +        assertMapping(node, 0, 24, 0, 39, 0, 44);  // 'goo'
 +        assertMapping(node, 0, 29, 0, 44, 0, 45);  // )
 +    }
 +
 +    @Test
 +    public void testVarDeclaration_withList()
 +    {
 +        IVariableNode node = (IVariableNode) getNode(
 +                "var a:int = 4, b:int = 11, c:int = 42;", IVariableNode.class);
 +        asBlockWalker.visitVariable(node);
 +        //var /** @type {number} */ a = 4, /** @type {number} */ b = 11, /** @type {number} */ c = 42
 +        assertMapping(node, 0, 0, 0, 0, 0, 4);    // var
 +        assertMapping(node, 0, 4, 0, 26, 0, 27);  // a
 +        assertMapping(node, 0, 5, 0, 4, 0, 26);   // :int
 +        assertMapping(node, 0, 9, 0, 27, 0, 30);  // =
 +        assertMapping(node, 0, 12, 0, 30, 0, 31); // 4
 +        assertMapping(node, 0, 13, 0, 31, 0, 33); // ,
 +        assertMapping(node, 0, 15, 0, 55, 0, 56); // b
 +        assertMapping(node, 0, 16, 0, 33, 0, 55); // :int
 +        assertMapping(node, 0, 20, 0, 56, 0, 59); // =
 +        assertMapping(node, 0, 23, 0, 59, 0, 61); // 11
 +        assertMapping(node, 0, 25, 0, 61, 0, 63); // ,
 +        assertMapping(node, 0, 27, 0, 85, 0, 86); // c
 +        assertMapping(node, 0, 28, 0, 63, 0, 85); // :int
 +        assertMapping(node, 0, 32, 0, 86, 0, 89); // =
 +        assertMapping(node, 0, 35, 0, 89, 0, 91); // 42
 +    }
 +
 +    //----------------------------------
 +    // for () { }
 +    //----------------------------------
 +
 +    @Test
 +    public void testVisitFor_1a()
 +    {
 +        IForLoopNode node = (IForLoopNode) getNode(
 +                "for (var i:int = 0; i < len; i++) { break; }",
 +                IForLoopNode.class);
 +        asBlockWalker.visitForLoop(node);
 +        //for (var /** @type {number} */ i = 0; i < len; i++) {\n  break;\n}
 +        assertMapping(node, 0, 0, 0, 0, 0, 5);    // for (
 +        assertMapping(node, 0, 18, 0, 36, 0, 38); // ;
 +        assertMapping(node, 0, 27, 0, 45, 0, 47); // ;
 +        assertMapping(node, 0, 32, 0, 50, 0, 52); // )
++        assertMapping(node, 0, 34, 0, 52, 0, 53); // {
++        assertMapping(node, 0, 43, 2, 0, 2, 1);   // }
 +    }
 +
 +    @Test
 +    public void testVisitFor_1b()
 +    {
 +        IForLoopNode node = (IForLoopNode) getNode(
 +                "for (var i:int = 0; i < len; i++) break;", IForLoopNode.class);
 +        asBlockWalker.visitForLoop(node);
 +        //for (var /** @type {number} */ i = 0; i < len; i++)\n  break;
 +        assertMapping(node, 0, 0, 0, 0, 0, 5);    // for (
 +        assertMapping(node, 0, 18, 0, 36, 0, 38); // ;
 +        assertMapping(node, 0, 27, 0, 45, 0, 47); // ;
 +        assertMapping(node, 0, 32, 0, 50, 0, 51); // )
 +    }
 +
 +    @Test
 +    public void testVisitFor_2()
 +    {
 +        IForLoopNode node = (IForLoopNode) getNode("for (;;) { break; }",
 +                IForLoopNode.class);
 +        asBlockWalker.visitForLoop(node);
 +        //for (;;) {\n  break;\n}
-         assertMapping(node, 0, 0, 0, 0, 0, 5); // for (
-         assertMapping(node, 0, 5, 0, 5, 0, 6); // ;
-         assertMapping(node, 0, 6, 0, 6, 0, 7); // ;
-         assertMapping(node, 0, 7, 0, 7, 0, 9); // )
++        assertMapping(node, 0, 0, 0, 0, 0, 5);  // for (
++        assertMapping(node, 0, 5, 0, 5, 0, 6);  // ;
++        assertMapping(node, 0, 6, 0, 6, 0, 7);  // ;
++        assertMapping(node, 0, 7, 0, 7, 0, 9);  // )
++        assertMapping(node, 0, 9, 0, 9, 0, 10); // {
++        assertMapping(node, 0, 18, 2, 0, 2, 1); // }
 +    }
 +
 +    @Test
 +    public void testVisitForIn_1()
 +    {
 +        IForLoopNode node = (IForLoopNode) getNode(
 +                "for (var i:int in obj) { break; }", IForLoopNode.class);
 +        asBlockWalker.visitForLoop(node);
 +        //for (var /** @type {number} */ i in obj) {\n  break;\n}
 +        assertMapping(node, 0, 0, 0, 0, 0, 5);    // for (
 +        assertMapping(node, 0, 14, 0, 32, 0, 36); // in
 +        assertMapping(node, 0, 21, 0, 39, 0, 41); // )
++        assertMapping(node, 0, 23, 0, 41, 0, 42); // {
++        assertMapping(node, 0, 32, 2, 0, 2, 1);   // }
 +    }
 +
 +    @Test
 +    public void testVisitForIn_1a()
 +    {
 +        IForLoopNode node = (IForLoopNode) getNode(
 +                "for (var i:int in obj)  break; ", IForLoopNode.class);
 +        asBlockWalker.visitForLoop(node);
 +        //for (var /** @type {number} */ i in obj)\n  break;
 +        assertMapping(node, 0, 0, 0, 0, 0, 5);    // for (
 +        assertMapping(node, 0, 14, 0, 32, 0, 36); // in
 +        assertMapping(node, 0, 21, 0, 39, 0, 40); // )
 +    }
 +
++    //----------------------------------
++    // if ()
++    //----------------------------------
++
++    @Test
++    public void testVisitIf_1()
++    {
++        IIfNode node = (IIfNode) getNode("if (a) b++;", IIfNode.class);
++        asBlockWalker.visitIf(node);
++        //if (a)\n  b++;
++        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
++        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
++        assertMapping(node, 0, 5, 0, 5, 0, 6);    // )
++    }
++
++    @Test
++    public void testVisitIf_2()
++    {
++        IIfNode node = (IIfNode) getNode("if (a) b++; else c++;", IIfNode.class);
++        asBlockWalker.visitIf(node);
++        //if (a)\n  b++;\nelse\n  c++;
++        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
++        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
++        assertMapping(node, 0, 5, 0, 5, 0, 6);    // )
++        assertMapping(node, 0, 12, 2, 0, 2, 4);   // else
++    }
++
++    @Test
++    public void testVisitIf_4()
++    {
++        IIfNode node = (IIfNode) getNode(
++                "if (a) b++; else if (c) d++; else if(e) --f;", IIfNode.class);
++        asBlockWalker.visitIf(node);
++        //if (a)\n  b++;\nelse if (c)\n  d++;\nelse if (e)\n  --f;
++        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
++        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
++        assertMapping(node, 0, 5, 0, 5, 0, 6);    // )
++        assertMapping(node, 0, 12, 2, 0, 2, 9);   // else if (
++        assertMapping(node, 0, 22, 2, 10, 2, 11); // )
++        assertMapping(node, 0, 29, 4, 0, 4, 9);   // else if (
++        assertMapping(node, 0, 38, 4, 10, 4, 11); // )
++    }
++
++    //----------------------------------
++    // if () { }
++    //----------------------------------
++
++    @Test
++    public void testVisitIf_1a()
++    {
++        IIfNode node = (IIfNode) getNode("if (a) { b++; }", IIfNode.class);
++        asBlockWalker.visitIf(node);
++        //if (a) {\n  b++;\n}
++        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
++        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
++        assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
++        assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
++        assertMapping(node, 0, 14, 2, 0, 2, 1);   // }
++    }
++
++    @Test
++    public void testVisitIf_1b()
++    {
++        IIfNode node = (IIfNode) getNode("if (a) { b++; } else { c++; }",
++                IIfNode.class);
++        asBlockWalker.visitIf(node);
++        //if (a) {\n  b++;\n} else {\n  c++;\n}
++        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
++        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
++        assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
++        assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
++        assertMapping(node, 0, 14, 2, 0, 2, 1);   // }
++        assertMapping(node, 0, 16, 2, 2, 2, 7);   // else
++        assertMapping(node, 0, 21, 2, 7, 2, 8);   // {
++        assertMapping(node, 0, 28, 4, 0, 4, 1);   // }
++    }
++
++    @Test
++    public void testVisitIf_1c()
++    {
++        IIfNode node = (IIfNode) getNode(
++                "if (a) { b++; } else if (b) { c++; } else { d++; }",
++                IIfNode.class);
++        asBlockWalker.visitIf(node);
++        //if (a) {\n  b++;\n} else if (b) {\n  c++;\n} else {\n  d++;\n}
++        assertMapping(node, 0, 0, 0, 0, 0, 4);    // if (
++        assertMapping(node, 0, 4, 0, 4, 0, 5);    // a
++        assertMapping(node, 0, 5, 0, 5, 0, 7);    // )
++        assertMapping(node, 0, 7, 0, 7, 0, 8);    // {
++        assertMapping(node, 0, 14, 2, 0, 2, 1);   // }
++        assertMapping(node, 0, 16, 2, 2, 2, 11);  // else if(
++        assertMapping(node, 0, 26, 2, 12, 2, 14); // )
++        assertMapping(node, 0, 28, 2, 14, 2, 15); // {
++        assertMapping(node, 0, 35, 4, 0, 4, 1);   // }
++        assertMapping(node, 0, 37, 4, 2, 4, 7);   // else
++        assertMapping(node, 0, 42, 4, 7, 4, 8);   // {
++        assertMapping(node, 0, 49, 6, 0, 6, 1);   // {
++    }
++
++    @Test
++    public void testVisitIf_3()
++    {
++        IIfNode node = (IIfNode) getNode(
++                "if (a) b++; else if (c) d++; else --e;", IIfNode.class);
++        asBlockWalker.visitIf(node);
++        //if (a)\n  b++;\nelse if (c)\n  d++;\nelse\n  --e;
++        assertMapping(node, 0, 0, 0, 0, 0, 4);     // if (
++        assertMapping(node, 0, 4, 0, 4, 0, 5);     // a
++        assertMapping(node, 0, 5, 0, 5, 0, 6);     // )
++        assertMapping(node, 0, 12, 2, 0, 2, 9);    // else if (
++        assertMapping(node, 0, 21, 2, 9, 2, 10);   // c
++        assertMapping(node, 0, 22, 2, 10, 2, 11);  // )
++        assertMapping(node, 0, 29, 4, 0, 4, 4);    // else
++    }
++
 +    protected IBackend createBackend()
 +    {
 +        return new FlexJSBackend();
 +    }
 +}


[07/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - compiler: added getEndLine() and getEndColumn() to ISourceLocation

Posted by cd...@apache.org.
compiler: added getEndLine() and getEndColumn() to ISourceLocation


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

Branch: refs/heads/feature/maven-migration-test
Commit: af3e883d75a1e270d2174e35007f48698822085c
Parents: b2bfa2c
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 22:44:59 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 22:44:59 2016 -0700

----------------------------------------------------------------------
 .../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 +++++
 7 files changed, 148 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/af3e883d/compiler/src/org/apache/flex/compiler/common/ISourceLocation.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/common/ISourceLocation.java b/compiler/src/org/apache/flex/compiler/common/ISourceLocation.java
index 738bdf3..25f6b6d 100644
--- a/compiler/src/org/apache/flex/compiler/common/ISourceLocation.java
+++ b/compiler/src/org/apache/flex/compiler/common/ISourceLocation.java
@@ -64,6 +64,16 @@ public interface ISourceLocation
     int getColumn();
     
     /**
+     * Gets the local line number at the end. It is zero-based.
+     */
+    int getEndLine();
+
+    /**
+     * Gets the local column number at the end. It is zero-based.
+     */
+    int getEndColumn();
+    
+    /**
      * Gets the absolute starting offset. It is zero-based.
      */
     int getAbsoluteStart();

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/af3e883d/compiler/src/org/apache/flex/compiler/common/SourceLocation.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/common/SourceLocation.java b/compiler/src/org/apache/flex/compiler/common/SourceLocation.java
index 88998b7..0d0e1b0 100644
--- a/compiler/src/org/apache/flex/compiler/common/SourceLocation.java
+++ b/compiler/src/org/apache/flex/compiler/common/SourceLocation.java
@@ -37,6 +37,8 @@ public class SourceLocation implements ISourceLocation
         this.end = end;
         this.line = line;
         this.column = column;
+        this.endLine = UNKNOWN;
+        this.endColumn = UNKNOWN;
     }
     
     /**
@@ -93,6 +95,16 @@ public class SourceLocation implements ISourceLocation
      * Corresponds to start, not end.
      */
     private int column;
+
+    /**
+     * Zero-based line number that corresponds to end.
+     */
+    private int endLine;
+
+    /**
+     * Zero-based column number that corresponds to end.
+     */
+    private int endColumn;
     
     /**
      * Copies source location information from another instance
@@ -106,6 +118,8 @@ public class SourceLocation implements ISourceLocation
         this.end = src.getEnd();
         this.line = src.getLine();
         this.column = src.getColumn();
+        this.endLine = src.getEndLine();
+        this.endColumn = src.getEndColumn();
         this.sourcePath = src.getSourcePath();
     }
 
@@ -212,6 +226,44 @@ public class SourceLocation implements ISourceLocation
     }
 
     /**
+     * Get the line number where this node ends.
+     * Line numbers start at 0, not 1.
+     * @return The line number
+     */
+    public int getEndLine()
+    {
+        return endLine;
+    }
+
+    /**
+     * Set the line number where this node ends.
+     * Column numbers start at 0, not 1.
+     * @param line The line number
+     */
+    public void setEndLine(int line)
+    {
+        this.endLine = line;
+    }
+
+    /**
+     * Get the column number where this node ends.
+     * @return The column number
+     */
+    public int getEndColumn()
+    {
+        return endColumn;
+    }
+
+    /**
+     * Set the column number where this node ends.
+     * @param column The column number
+     */
+    public void setEndColumn(int column)
+    {
+        this.endColumn = column;
+    }
+
+    /**
      * Get the source path for this node.
      * @return The source path for this node
      */
@@ -346,6 +398,8 @@ public class SourceLocation implements ISourceLocation
         setEnd(end.getEnd());
         setLine(start.getLine());
         setColumn(start.getColumn());
+        setEndLine(end.getEndLine());
+        setEndColumn(end.getEndColumn());
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/af3e883d/compiler/src/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java b/compiler/src/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
index 92b9350..5b0b18e 100644
--- a/compiler/src/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
+++ b/compiler/src/org/apache/flex/compiler/internal/definitions/metadata/MetaTag.java
@@ -230,6 +230,18 @@ public class MetaTag implements IMetaTag
     }
 
     @Override
+    public int getEndLine()
+    {
+        return line;
+    }
+
+    @Override
+    public int getEndColumn()
+    {
+        return column;
+    }
+
+    @Override
     public int getAbsoluteStart()
     {
         return absoluteStart;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/af3e883d/compiler/src/org/apache/flex/compiler/internal/parsing/TokenBase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/parsing/TokenBase.java b/compiler/src/org/apache/flex/compiler/internal/parsing/TokenBase.java
index 68a76eb..ff726da 100644
--- a/compiler/src/org/apache/flex/compiler/internal/parsing/TokenBase.java
+++ b/compiler/src/org/apache/flex/compiler/internal/parsing/TokenBase.java
@@ -50,6 +50,8 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
         this.line = line;
         this.column = column;
         this.text = text;
+        this.endLine = line;
+        this.endColumn = column + end - start;
 
         if (Counter.COUNT_TOKENS)
             countTokens();
@@ -67,6 +69,8 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
         end = o.end;
         line = o.line;
         column = o.column;
+        endLine = o.endLine;
+        endColumn = o.endColumn;
         text = o.text;
 
         localStart = o.localStart;
@@ -103,6 +107,16 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
     private int column;
 
     /**
+     * End line of this token
+     */
+    private int endLine;
+
+    /**
+     * End column of this token
+     */
+    private int endColumn;
+
+    /**
      * Flag to determine if this token is locked
      */
     private boolean locked;
@@ -143,6 +157,8 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
         this.end = end;
         this.line = line;
         this.column = column;
+        this.endLine = line;
+        this.endColumn = column + end - start;
         this.text = text;
     }
 
@@ -222,6 +238,8 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
         this.end = end;
         this.line = line;
         this.column = column;
+        this.endLine = line;
+        this.endColumn = column + end - start;
     }
 
     @Override
@@ -275,6 +293,28 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
         this.column = column;
     }
 
+    @Override
+    public int getEndLine()
+    {
+        return endLine;
+    }
+
+    public void setEndLine(int line)
+    {
+        endLine = line;
+    }
+
+    @Override
+    public int getEndColumn()
+    {
+        return endColumn;
+    }
+
+    public void setEndColumn(int column)
+    {
+        endColumn = column;
+    }
+
     /**
      * Determine whether or not this token is bogus (i.e. the start and end
      * offsets are the same, which implies that it was inserted from an included
@@ -439,6 +479,8 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
         end += offsetAdjustment;
         line += lineAdjustment;
         column += columnAdjustment;
+        endLine += lineAdjustment;
+        endColumn += columnAdjustment;
     }
 
     /**
@@ -485,6 +527,8 @@ public abstract class TokenBase extends Token implements ICMToken, ISourceLocati
             assert getEnd() != UNKNOWN : "Token has unknown end: " + toString();
             assert getLine() != UNKNOWN : "Token has an unknown line: " + toString();
             assert getColumn() != UNKNOWN : "Token has an unknown column: " + toString();
+            assert getEndLine() != UNKNOWN : "Token has an unknown end line: " + toString();
+            assert getEndColumn() != UNKNOWN : "Token has an unknown end column: " + toString();
         }
 
         return true;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/af3e883d/compiler/src/org/apache/flex/compiler/internal/tree/as/NodeBase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/NodeBase.java b/compiler/src/org/apache/flex/compiler/internal/tree/as/NodeBase.java
index be0510d..8dd4fb6 100644
--- a/compiler/src/org/apache/flex/compiler/internal/tree/as/NodeBase.java
+++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/NodeBase.java
@@ -337,7 +337,6 @@ public abstract class NodeBase extends SourceLocation implements IASNode
         if (token instanceof ISourceLocation)
         {
             startAfter((ISourceLocation) token);
-            setColumn(getColumn() + token.getText().length());
         }
     }
     
@@ -354,8 +353,8 @@ public abstract class NodeBase extends SourceLocation implements IASNode
         {
             setSourcePath(location.getSourcePath());
             setStart(end);
-            setLine(location.getLine());
-            setColumn(location.getColumn());
+            setLine(location.getEndLine());
+            setColumn(location.getEndColumn());
         }
     }
 
@@ -411,7 +410,11 @@ public abstract class NodeBase extends SourceLocation implements IASNode
     {
         final int end = location.getEnd();
         if (end != UNKNOWN)
+        {
             setEnd(end);
+            setEndLine(location.getEndLine());
+            setEndColumn(location.getEndColumn());
+        }
     }
 
     /**
@@ -436,7 +439,11 @@ public abstract class NodeBase extends SourceLocation implements IASNode
     {
         final int start = location.getStart();
         if (start != UNKNOWN)
+        {
             setEnd(start);
+            setEndLine(location.getLine());
+            setEndColumn(location.getColumn());
+        }
     }
 
     /**
@@ -620,7 +627,11 @@ public abstract class NodeBase extends SourceLocation implements IASNode
                 if (childEnd != -1)
                 {
                     if (end < childEnd)
+                    {
                         setEnd(childEnd);
+                        setEndLine(child.getEndLine());
+                        setEndColumn(child.getEndColumn());
+                    }
                     break;
                 }
             }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/af3e883d/compiler/src/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java b/compiler/src/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
index 5de6521..51eb0fc 100644
--- a/compiler/src/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
+++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/OperatorNodeBase.java
@@ -41,6 +41,8 @@ public abstract class OperatorNodeBase extends ExpressionNodeBase implements IOp
             operatorStart = operator.getStart();
             setLine(operator.getLine());
             setColumn(operator.getColumn());
+            setEndLine(operator.getEndLine());
+            setEndColumn(operator.getEndColumn());
             setSourcePath(operator.getSourcePath());
         }
     }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/af3e883d/compiler/src/org/apache/flex/compiler/problems/CompilerProblem.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/problems/CompilerProblem.java b/compiler/src/org/apache/flex/compiler/problems/CompilerProblem.java
index ee9c9a1..d2e9366 100644
--- a/compiler/src/org/apache/flex/compiler/problems/CompilerProblem.java
+++ b/compiler/src/org/apache/flex/compiler/problems/CompilerProblem.java
@@ -189,6 +189,18 @@ public abstract class CompilerProblem implements ICompilerProblem
     }
 
     @Override
+    public int getEndLine()
+    {
+        return line;
+    }
+
+    @Override
+    public int getEndColumn()
+    {
+        return column;
+    }
+
+    @Override
     public int getAbsoluteStart()
     {
         return start;


[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

Posted by cd...@apache.org.
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;
 +    }
 +}


[03/14] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - compiler.jx: curly braces to open and close blocks have been moved to the emitter

Posted by cd...@apache.org.
compiler.jx: curly braces to open and close blocks have been moved to the emitter


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

Branch: refs/heads/feature/maven-migration-test
Commit: 8c393616b508426fa621e20c8d2b10d7a473b721
Parents: a9a399b
Author: Josh Tynjala <jo...@apache.org>
Authored: Sun Apr 17 15:17:13 2016 -0700
Committer: Josh Tynjala <jo...@apache.org>
Committed: Sun Apr 17 15:17:13 2016 -0700

----------------------------------------------------------------------
 .../org/apache/flex/compiler/codegen/as/IASEmitter.java |  6 +++++-
 .../internal/codegen/as/ASAfterNodeStrategy.java        |  4 ++--
 .../internal/codegen/as/ASBeforeNodeStrategy.java       |  4 ++--
 .../flex/compiler/internal/codegen/as/ASEmitter.java    | 12 ++++++++++++
 4 files changed, 21 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/8c393616/compiler.jx/src/org/apache/flex/compiler/codegen/as/IASEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/codegen/as/IASEmitter.java b/compiler.jx/src/org/apache/flex/compiler/codegen/as/IASEmitter.java
index bd0d1eb..2fe9eea 100644
--- a/compiler.jx/src/org/apache/flex/compiler/codegen/as/IASEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/codegen/as/IASEmitter.java
@@ -86,7 +86,7 @@ public interface IASEmitter extends IEmitter
     void setDocEmitter(IDocEmitter value);
 
     String postProcess(String output);
-    
+
     void emitImport(IImportNode node);
 
     void emitPackageHeader(IPackageDefinition definition);
@@ -366,4 +366,8 @@ public interface IASEmitter extends IEmitter
 
     void emitUseNamespace(IUseNamespaceNode node);
 
+    void emitBlockOpen(IContainerNode node);
+
+    void emitBlockClose(IContainerNode node);
+
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/8c393616/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
index 1ac85f7..b274b57 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASAfterNodeStrategy.java
@@ -59,10 +59,10 @@ public class ASAfterNodeStrategy implements IASNodeStrategy
                 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)

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/8c393616/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
index d481573..d960057 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASBeforeNodeStrategy.java
@@ -61,12 +61,12 @@ public class ASBeforeNodeStrategy implements IASNodeStrategy
             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/8c393616/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
index 875d1d2..6f48f8e 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
@@ -1524,6 +1524,18 @@ public class ASEmitter implements IASEmitter, IEmitter
     }
 
     @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();