Repository: flex-falcon
Updated Branches:
  refs/heads/develop 3ee42de4b -> 3971196a4


FLEX-34990 Calling new on the result of a function call was not parsed correctly


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

Branch: refs/heads/develop
Commit: 3971196a4478853e1fd443e21e011ee1b8ea14c8
Parents: 3ee42de
Author: Alex Harui <[email protected]>
Authored: Tue Dec 22 22:02:18 2015 -0800
Committer: Alex Harui <[email protected]>
Committed: Tue Dec 22 22:02:18 2015 -0800

----------------------------------------------------------------------
 .../js/flexjs/TestFlexJSExpressions.java        | 27 +++++++++++++++++
 .../feature-tests/as/ASKeywordTests.java        | 32 ++++++++++++++++++++
 .../compiler/internal/parsing/as/ASParser.g     | 24 ++++++++++++---
 .../internal/tree/as/FunctionCallNode.java      |  7 +++++
 4 files changed, 85 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3971196a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSExpressions.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSExpressions.java
 
b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSExpressions.java
index 21d65a1..3ae3c4b 100644
--- 
a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSExpressions.java
+++ 
b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSExpressions.java
@@ -901,6 +901,33 @@ public class TestFlexJSExpressions extends 
TestGoogExpressions
         assertOut("\"\\u2028\"");
     }
     
+    @Test
+    public void testVisitCallFunctionReturnedFromFunction()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
foo(a:String, b:String):Function { return null }; return foo(3, 4)(1, 2);", 
+                                                               
IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("foo(3, 4)(1, 2)");
+    }
+    
+    @Test
+    public void testVisitNewSimple()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("return new Fn(1, 
2);", 
+                                                               
IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("new Fn(1, 2)");
+    }
+    
+    @Test
+    public void testVisitNewComplex()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("return new 
Fn(\"a\", \"b\", \"return a + b;\")(1, 2);", 
+                                                               
IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("new (Fn(\"a\", \"b\", \"return a + b;\"))(1, 2)");
+    }
+
     protected IBackend createBackend()
     {
         return new FlexJSBackend();

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3971196a/compiler.tests/feature-tests/as/ASKeywordTests.java
----------------------------------------------------------------------
diff --git a/compiler.tests/feature-tests/as/ASKeywordTests.java 
b/compiler.tests/feature-tests/as/ASKeywordTests.java
index e81e360..c1a5fb4 100644
--- a/compiler.tests/feature-tests/as/ASKeywordTests.java
+++ b/compiler.tests/feature-tests/as/ASKeywordTests.java
@@ -286,4 +286,36 @@ public class ASKeywordTests extends ASFeatureTestsBase
         compileAndRun(source);
     }
 
+    @Test
+    public void AS_new_function_returned_from_function()
+    {
+       // all tests can assume that flash.display.Sprite
+       // flash.system.System and flash.events.Event have been imported
+        String[] imports = new String[]
+        {
+        };
+        String[] declarations = new String[]
+        {
+        };
+        String[] testCode = new String[]
+        {
+            "function getClass(index:Number):Class {",
+            "  if (index == 0) return Inner;",
+            "  return Number;",
+            "}",
+               "var foo:Inner = new getClass(0)('foo');",
+            "assertEqual('foo.value', foo.value, 'foo');",
+        };
+        String[] extra = new String[]
+        {
+               "class Inner {",
+               "    public function Inner(value:String) {",
+               "        this.value = value;",
+               "    }",
+               "    public var value:String;",
+               "}",
+        };
+        String source = getAS(imports, declarations, testCode, extra);
+        compileAndRun(source);
+    }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3971196a/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 32e0135..9b21966 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
@@ -3074,10 +3074,21 @@ arguments[ExpressionNodeBase root] 
returns[ExpressionNodeBase n]
            final boolean isNewExpression = 
                    (n instanceof FunctionCallNode) && 
                    ((FunctionCallNode)n).isNewExpression();
-                   
-               if (n == null || !isNewExpression) 
+            final boolean newFunctionCallAlreadyHasArgs = isNewExpression &&
+                   ((FunctionCallNode)n).getArgumentsNode().getStart() != -1;
+                   // the above line is a hack to try to catch "new" 
expressions
+                   // where the class to instantiate is the result of a 
function
+                   // call:  new someFunction(someArgs)(constructorParams)
+                   // we check to see if the arg node as a start() value which
+                   // means that the first argument list (someargs) was already
+                   // processed.
+           final FunctionCallNode oldNode = newFunctionCallAlreadyHasArgs ? 
(FunctionCallNode)n : null;
+               if (n == null || !isNewExpression || 
newFunctionCallAlreadyHasArgs ) 
                        n = new FunctionCallNode(n);
-               
+               if (newFunctionCallAlreadyHasArgs) {
+                    
((FunctionCallNode)n).setNewKeywordNode(oldNode.getNewKeywordNode());
+                    oldNode.setNewKeywordNode(null);
+                }
                args = ((FunctionCallNode)n).getArgumentsNode();
                args.startAfter(lpT);
                args.endAfter(lpT);
@@ -3086,8 +3097,6 @@ arguments[ExpressionNodeBase root] 
returns[ExpressionNodeBase n]
                
         ( argumentList[args] )
     
-        rpT:TOKEN_PAREN_CLOSE
-       { args.endAfter(rpT); enableSemicolonInsertion(); }
     ;  
     exception catch [RecognitionException ex]
     {  
@@ -3158,7 +3167,12 @@ argumentList[ContainerNode args]
                                        args.addItem(n);
                                }
                        }
+       |  rpT:TOKEN_PAREN_CLOSE
+               { args.endAfter(rpT); enableSemicolonInsertion(); break;}
+
        )*
+
+
     ;
                
 /**

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/3971196a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionCallNode.java
----------------------------------------------------------------------
diff --git 
a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionCallNode.java 
b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionCallNode.java
index b3f887f..45b2a07 100644
--- 
a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionCallNode.java
+++ 
b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionCallNode.java
@@ -301,6 +301,13 @@ public class FunctionCallNode extends ExpressionNodeBase 
implements IFunctionCal
     {
         return newKeywordNode;
     }
+    
+    public void setNewKeywordNode(KeywordNode newNode)
+    {
+        newKeywordNode = newNode;
+        if (newKeywordNode != null)
+            newKeywordNode.setParent(this);
+    }
 
     @Override
     public boolean isCallToSuper()

Reply via email to