flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aha...@apache.org
Subject [5/5] git commit: [flex-falcon] [refs/heads/develop] - es5 strict required local functions declared before code
Date Tue, 24 Nov 2015 16:42:42 GMT
es5 strict required local functions declared before code


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

Branch: refs/heads/develop
Commit: f0ebbf0ca473a6938cb05f86b40d7053abab3014
Parents: 47ed21a
Author: Alex Harui <aharui@apache.org>
Authored: Tue Nov 24 08:42:09 2015 -0800
Committer: Alex Harui <aharui@apache.org>
Committed: Tue Nov 24 08:42:09 2015 -0800

----------------------------------------------------------------------
 .../codegen/js/flexjs/TestFlexJSClass.java      |  4 +-
 .../js/flexjs/TestFlexJSExpressions.java        | 99 +++++++++++++++-----
 .../flexjs/files/LocalFunction_result.js        |  3 +-
 .../codegen/js/flexjs/JSFlexJSEmitter.java      | 65 +++++++++++++
 .../codegen/js/jx/IdentifierEmitter.java        |  8 +-
 .../codegen/js/jx/SelfReferenceEmitter.java     |  2 +-
 .../compiler/internal/tree/as/FunctionNode.java | 40 ++++++--
 .../internal/tree/as/FunctionObjectNode.java    |  4 -
 .../flex/compiler/tree/as/IFunctionNode.java    | 28 +++++-
 9 files changed, 209 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
index 801b9f6..db12f5b 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
@@ -243,7 +243,7 @@ public class TestFlexJSClass extends TestGoogClass
                 + "public function foo2():Object{function bar2(param1:Object):Object {return
null;}; return bar2('foo');}"
                 + "}");
         asBlockWalker.visitClass(node);
-        assertOut("/**\n * @constructor\n */\norg.apache.flex.B = function() {\n};\n\n\n/**\n
* @export\n * @return {Object}\n */\norg.apache.flex.B.prototype.foo1 = function() {\n  function
bar1() {\n    return null;\n  };\n  return org.apache.flex.utils.Language.closure(bar1, this,
'bar1')();\n};\n\n\n/**\n * @export\n * @return {Object}\n */\norg.apache.flex.B.prototype.foo2
= function() {\n  function bar2(param1) {\n    return null;\n  };\n  return org.apache.flex.utils.Language.closure(bar2,
this, 'bar2')('foo');\n};");
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.B = function() {\n};\n\n\n/**\n
* @export\n * @return {Object}\n */\norg.apache.flex.B.prototype.foo1 = function() {\n  var
self = this;\n  function bar1() {\n    return null;\n  };\n  return bar1();\n};\n\n\n/**\n
* @export\n * @return {Object}\n */\norg.apache.flex.B.prototype.foo2 = function() {\n  var
self = this;\n  function bar2(param1) {\n    return null;\n  };\n  return bar2('foo');\n};");
     }
 
     @Test
@@ -255,7 +255,7 @@ public class TestFlexJSClass extends TestGoogClass
                 + "public function foo2():String{function bar2(param1:String):String {return
param1 + baz1;}; return bar2('foo');}"
                 + "}");
         asBlockWalker.visitClass(node);
-        assertOut("/**\n * @constructor\n */\norg.apache.flex.B = function() {\n};\n\n\n/**\n
* @export\n * @type {string}\n */\norg.apache.flex.B.prototype.baz1;\n\n\n/**\n * @export\n
* @return {string}\n */\norg.apache.flex.B.prototype.foo1 = function() {\n  function bar1()
{\n    return this.baz1;\n  };\n  return org.apache.flex.utils.Language.closure(bar1, this,
'bar1')();\n};\n\n\n/**\n * @export\n * @return {string}\n */\norg.apache.flex.B.prototype.foo2
= function() {\n  function bar2(param1) {\n    return param1 + this.baz1;\n  };\n  return
org.apache.flex.utils.Language.closure(bar2, this, 'bar2')('foo');\n};");
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.B = function() {\n};\n\n\n/**\n
* @export\n * @type {string}\n */\norg.apache.flex.B.prototype.baz1;\n\n\n/**\n * @export\n
* @return {string}\n */\norg.apache.flex.B.prototype.foo1 = function() {\n  var self = this;\n
 function bar1() {\n    return this.baz1;\n  };\n  return bar1();\n};\n\n\n/**\n * @export\n
* @return {string}\n */\norg.apache.flex.B.prototype.foo2 = function() {\n  var self = this;\n
 function bar2(param1) {\n    return param1 + this.baz1;\n  };\n  return bar2('foo');\n};");
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/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 fdb40ec..76d48dc 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
@@ -552,7 +552,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function c(f:Function):void {}; function
d():void {}; c(d); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function c(f) {\n
 };\n  function d() {\n  };\n  org.apache.flex.utils.Language.closure(c, this, 'c')(org.apache.flex.utils.Language.closure(d,
this, 'd'));\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(f) {\n  };\n  function d() {\n  };\n  c(org.apache.flex.utils.Language.closure(d,
this, 'd'));\n}");
     }
 
     @Test
@@ -562,7 +562,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function c(s:String, f:Function):void
{}; function d():void {}; c('foo', d); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function c(s, f)
{\n  };\n  function d() {\n  };\n  org.apache.flex.utils.Language.closure(c, this, 'c')('foo',
org.apache.flex.utils.Language.closure(d, this, 'd'));\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(s, f) {\n  };\n  function d() {\n  };\n  c('foo', org.apache.flex.utils.Language.closure(d,
this, 'd'));\n}");
     }
 
     @Test
@@ -572,7 +572,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() {  c('foo', d); function c(s:String,
f:Function):void {}; function d():void {};}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  org.apache.flex.utils.Language.closure(c,
this, 'c')('foo', org.apache.flex.utils.Language.closure(d, this, 'd'));\n  function c(s,
f) {\n  };\n  function d() {\n  };\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(s, f) {\n  };\n  function d() {\n  };\n  c('foo', org.apache.flex.utils.Language.closure(d,
this, 'd'));\n  \n}");
     }
 
     @Test
@@ -582,7 +582,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function d():void {}; c('foo', d);
} public function c(s:String, f:Function):void {};}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function d() {\n
 };\n  this.c('foo', org.apache.flex.utils.Language.closure(d, this, 'd'));\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function d() {\n  };\n  this.c('foo', org.apache.flex.utils.Language.closure(d, this, 'd'));\n}");
     }
 
     @Test
@@ -592,7 +592,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function c(f:Function):void {}; c(b);
}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function c(f) {\n
 };\n  org.apache.flex.utils.Language.closure(c, this, 'c')(org.apache.flex.utils.Language.closure(this.b,
this, 'b'));\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(f) {\n  };\n  c(org.apache.flex.utils.Language.closure(this.b, this, 'b'));\n}");
     }
 
     @Test
@@ -602,7 +602,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {static public function b() { function c(f:Function):void
{}; c(b); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  org.apache.flex.utils.Language.closure(c, this, 'c')(foo.bar.B.b);\n}");
+        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  c(foo.bar.B.b);\n}");
     }
 
     @Test
@@ -612,7 +612,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function c(f:Function):void {}; var
f:Function = b; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Function} */ f = org.apache.flex.utils.Language.closure(this.b, this,
'b');\n  org.apache.flex.utils.Language.closure(c, this, 'c')(f);\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(f) {\n  };\n  var /** @type {Function} */ f = org.apache.flex.utils.Language.closure(this.b,
this, 'b');\n  c(f);\n}");
     }
     
     @Test
@@ -622,7 +622,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {static public function b() { function c(f:Function):void
{}; var f:Function = b; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Function} */ f = foo.bar.B.b;\n  org.apache.flex.utils.Language.closure(c,
this, 'c')(f);\n}");
+        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Function} */ f = foo.bar.B.b;\n  c(f);\n}");
     }
     
     @Test
@@ -632,7 +632,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function c(f:Function):void {}; var
f:Function; f = b; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Function} */ f;\n  f = org.apache.flex.utils.Language.closure(this.b,
this, 'b');\n  org.apache.flex.utils.Language.closure(c, this, 'c')(f);\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(f) {\n  };\n  var /** @type {Function} */ f;\n  f = org.apache.flex.utils.Language.closure(this.b,
this, 'b');\n  c(f);\n}");
     }
     
     @Test
@@ -642,7 +642,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {static public function b() { function c(f:Function):void
{}; var f:Function; f = b; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Function} */ f;\n  f = foo.bar.B.b;\n  org.apache.flex.utils.Language.closure(c,
this, 'c')(f);\n}");
+        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Function} */ f;\n  f = foo.bar.B.b;\n  c(f);\n}");
     }
     
     @Test
@@ -652,7 +652,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function c(f:Function):void {}; var
f:Array = [b]; c(f[0]); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Array} */ f = [org.apache.flex.utils.Language.closure(this.b, this,
'b')];\n  org.apache.flex.utils.Language.closure(c, this, 'c')(f[0]);\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(f) {\n  };\n  var /** @type {Array} */ f = [org.apache.flex.utils.Language.closure(this.b,
this, 'b')];\n  c(f[0]);\n}");
     }
     
     @Test
@@ -662,7 +662,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {static public function b() { function c(f:Function):void
{}; var f:Array = [b]; c(f); }}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE, true);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Array} */ f = [foo.bar.B.b];\n  org.apache.flex.utils.Language.closure(c,
this, 'c')(f);\n}");
+        assertOut("/**\n * @export\n */\nfoo.bar.B.b = function() {\n  function c(f) {\n
 };\n  var /** @type {Array} */ f = [foo.bar.B.b];\n  c(f);\n}");
     }
     
     @Test
@@ -672,7 +672,7 @@ public class TestFlexJSExpressions extends TestGoogExpressions
                 "public class B {public function b() { function c(f:Function):void {}; c(this.b);
}}",
                 IFunctionNode.class, WRAP_LEVEL_PACKAGE);
         asBlockWalker.visitFunction(node);
-        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  function c(f) {\n
 };\n  org.apache.flex.utils.Language.closure(c, this, 'c')(org.apache.flex.utils.Language.closure(this.b,
this, 'b'));\n}");
+        assertOut("/**\n * @export\n */\nB.prototype.b = function() {\n  var self = this;\n
 function c(f) {\n  };\n  c(org.apache.flex.utils.Language.closure(this.b, this, 'b'));\n}");
     }
     
     @Test
@@ -735,26 +735,83 @@ public class TestFlexJSExpressions extends TestGoogExpressions
 
     @Override
     @Test
+    public void testAnonymousFunction()
+    {
+    	IFunctionNode node = (IFunctionNode) getNode("var a = function(){};",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("FalconTest_A.prototype.falconTest_a = function() {\n" +
+        		  "  var self = this;\n" +
+        		  "    var /** @type {Function} */ __localFn0__ = function() {\n" +
+        		  "  }\n" +
+        		  "  var /** @type {*} */ a = __localFn0__;\n" +
+        		  "}");
+    }
+
+    @Override
+    @Test
     public void testAnonymousFunctionWithParamsReturn()
     {
-        IVariableNode node = (IVariableNode) getNode(
+        IFunctionNode node = (IFunctionNode) getNode(
                 "var a:Object = function(foo:int, bar:String = 'goo'):int{return -1;};",
-                IVariableNode.class);
-        asBlockWalker.visitVariable(node);
-        assertOut("var /** @type {Object} */ a = function(foo, bar) {\n  bar = typeof bar
!== 'undefined' ? bar : 'goo';\n  return -1;\n}");
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("FalconTest_A.prototype.falconTest_a = function() {\n" +
+      		  "  var self = this;\n" +
+      		  "    var /** @type {Function} */ __localFn0__ = function(foo, bar) {\n" +
+      		  "    bar = typeof bar !== 'undefined' ? bar : 'goo';\n" +
+      		  "    return -1;\n" +
+      		  "  }\n" +
+      		  "  var /** @type {Object} */ a = __localFn0__;\n" +
+      		  "}");
     }
 
     @Override
     @Test
     public void testAnonymousFunctionAsArgument()
     {
-        IFunctionCallNode node = (IFunctionCallNode) getNode(
+        IFunctionNode node = (IFunctionNode) getNode(
                 "addListener('foo', function(event:Object):void{doit();})",
-                IFunctionCallNode.class);
-        asBlockWalker.visitFunctionCall(node);
-        assertOut("addListener('foo', function(event) {\n  doit();\n})");
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("FalconTest_A.prototype.falconTest_a = function() {\n" +
+      		  "  var self = this;\n" +
+      		  "    var /** @type {Function} */ __localFn0__ = function(event) {\n" +
+      		  "    doit();\n" +
+      		  "  }\n" +
+      		  "  addListener('foo', __localFn0__);\n" +
+      		  "}");
     }
 
+    @Test
+    public void testES5StrictAnonymousFunctions()
+    {
+        IFunctionNode node = (IFunctionNode) getNode(
+                "var a:Object = {}; var b:Function = function(foo:Object) { foo.bar = 10
}; var c:Object = b(a);",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("FalconTest_A.prototype.falconTest_a = function() {\n" +
+        		  "  var self = this;\n" +
+        		  "    var /** @type {Function} */ __localFn0__ = function(foo) {\n    foo.bar
= 10;\n  }\n" +
+        		  "  var /** @type {Object} */ a = {};\n" +
+        		  "  var /** @type {Function} */ b = __localFn0__;\n" +
+        		  "  var /** @type {Object} */ c = b(a);\n}");
+    }
+    
+    @Test
+    public void testES5StrictNamedLocalFunctions()
+    {
+        IFunctionNode node = (IFunctionNode) getNode(
+                "var a:Object = {}; function b(foo:Object) { foo.bar = 10 }; var c:Object
= b(a);",
+                IFunctionNode.class);
+        asBlockWalker.visitFunction(node);
+        assertOut("FalconTest_A.prototype.falconTest_a = function() {\n" +
+        		  "  var self = this;\n" +
+        		  "  function b(foo) {\n    foo.bar = 10;\n  };\n" +
+        		  "  var /** @type {Object} */ a = {};\n" +
+        		  "  var /** @type {Object} */ c = b(a);\n}");
+    }
+    
     @Override
     @Test
     public void testVisitAs()

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler.jx.tests/test-files/flexjs/files/LocalFunction_result.js
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/test-files/flexjs/files/LocalFunction_result.js b/compiler.jx.tests/test-files/flexjs/files/LocalFunction_result.js
index 9d51bc3..09f3245 100644
--- a/compiler.jx.tests/test-files/flexjs/files/LocalFunction_result.js
+++ b/compiler.jx.tests/test-files/flexjs/files/LocalFunction_result.js
@@ -42,10 +42,11 @@ LocalFunction.prototype.myMemberProperty = "got it: ";
  * @param {number} value
  */
 LocalFunction.prototype.myMemberMethod = function(value) {
+  var self = this;
   function myLocalFunction(value) {
     return this.myMemberProperty + value;
   };
-  org.apache.flex.utils.Language.trace("WOW! :: " + org.apache.flex.utils.Language.closure(myLocalFunction,
this, 'myLocalFunction')(value + 42));
+  org.apache.flex.utils.Language.trace("WOW! :: " + myLocalFunction(value + 42));
 };
 
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index 57eb309..8903c25 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@ -20,6 +20,7 @@
 package org.apache.flex.compiler.internal.codegen.js.flexjs;
 
 import java.io.FilterWriter;
+import java.util.List;
 
 import org.apache.flex.compiler.codegen.js.flexjs.IJSFlexJSEmitter;
 import org.apache.flex.compiler.codegen.js.goog.IJSGoogDocEmitter;
@@ -53,6 +54,7 @@ import org.apache.flex.compiler.internal.projects.FlexJSProject;
 import org.apache.flex.compiler.internal.tree.as.BinaryOperatorAsNode;
 import org.apache.flex.compiler.internal.tree.as.DynamicAccessNode;
 import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
 import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
 import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
 import org.apache.flex.compiler.internal.tree.as.TernaryOperatorNode;
@@ -68,6 +70,7 @@ import org.apache.flex.compiler.tree.as.IFileNode;
 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.IInterfaceNode;
@@ -202,8 +205,19 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     }
 
     @Override
+    public void emitLocalNamedFunction(IFunctionNode node)
+    {
+		IFunctionNode fnNode = (IFunctionNode)node.getAncestorOfType(IFunctionNode.class);
+    	if (fnNode.getEmittingLocalFunctions())
+    	{
+    		super.emitLocalNamedFunction(node);
+    	}
+    }
+    
+    @Override
     public void emitFunctionBlockHeader(IFunctionNode node)
     {
+    	node.setEmittingLocalFunctions(true);
     	super.emitFunctionBlockHeader(node);
     	if (node.isConstructor())
     	{
@@ -211,6 +225,46 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
             .getAncestorOfType(IClassNode.class);
             emitComplexInitializers(cnode);
     	}
+        if (node.containsLocalFunctions())
+        {
+            List<IFunctionNode> anonFns = node.getLocalFunctions();
+            int n = anonFns.size();
+            for (int i = 0; i < n; i++)
+            {
+                IFunctionNode anonFn = anonFns.get(i);
+                if (anonFn.getParent().getNodeID() == ASTNodeID.AnonymousFunctionID)
+                {
+                    write("  var /** @type {Function} */ __localFn" + Integer.toString(i)
+ "__ = ");
+                	getWalker().walk(anonFn.getParent());
+                }
+                else
+                {
+                	getWalker().walk(anonFn);
+                	write(ASEmitterTokens.SEMICOLON);
+                }
+                this.writeNewline();
+            }
+        }
+    	node.setEmittingLocalFunctions(false);
+    }
+    
+    @Override
+    public void emitFunctionObject(IFunctionObjectNode node)
+    {
+		IFunctionNode fnNode = (IFunctionNode)node.getAncestorOfType(IFunctionNode.class);
+    	if (fnNode.getEmittingLocalFunctions())
+    	{
+    		super.emitFunctionObject(node);
+    	}
+    	else
+    	{
+            List<IFunctionNode> anonFns = fnNode.getLocalFunctions();
+            int i = anonFns.indexOf(node.getFunctionNode());
+            if (i < 0)
+            	System.out.println("missing index for " + node.toString());
+            else
+            	write("__localFn" + Integer.toString(i) + "__");
+    	}
     }
     
     @Override
@@ -486,6 +540,17 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
         write(ASEmitterTokens.PAREN_CLOSE);
     }
     
+    @Override
+    public void emitStatement(IASNode node)
+    {
+    	// don't emit named local functions as statements
+    	// they are emitted as part of the function block header
+    	if (node.getNodeID() == ASTNodeID.FunctionID)
+    	{
+    		return;
+    	}
+    	super.emitStatement(node);
+    }
     private void writeChainName(IASNode node)
     {
     	while (node.getNodeID() == ASTNodeID.MemberAccessExpressionID)

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
index 704b77d..a21cd63 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/IdentifierEmitter.java
@@ -73,11 +73,9 @@ public class IdentifierEmitter extends JSSubEmitter implements
             {
             	FunctionClassification fc = ((FunctionDefinition)nodeDef).getFunctionClassification();
             	identifierIsLocalOrInstanceFunctionAsValue = 
-            		fc == FunctionClassification.LOCAL || 
-            		(fc == FunctionClassification.CLASS_MEMBER && 
-            				// not a value if parent is a function call or member access expression
-            				(!(parentNodeId == ASTNodeID.MemberAccessExpressionID ||
-            				   parentNodeId == ASTNodeID.FunctionCallID)));
+            		(fc == FunctionClassification.LOCAL || fc == FunctionClassification.CLASS_MEMBER)
&& 
+            		// not a value if parent is a function call or member access expression
+            		(!(parentNodeId == ASTNodeID.MemberAccessExpressionID || parentNodeId == ASTNodeID.FunctionCallID));
             	
             }
             // an instance method as a parameter or

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SelfReferenceEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SelfReferenceEmitter.java
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SelfReferenceEmitter.java
index 0d7849c..6e662ce 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SelfReferenceEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/SelfReferenceEmitter.java
@@ -40,7 +40,7 @@ public class SelfReferenceEmitter extends JSSubEmitter implements
     {
         // we don't want 'var self = this;' in FlexJS
         // unless there are anonymous functions
-        if (node.containsAnonymousFunctions())
+        if (node.containsLocalFunctions())
         {
             writeToken(ASEmitterTokens.VAR);
             writeToken(JSGoogEmitterTokens.SELF);

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java
index af63395..5eb3621 100644
--- a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java
+++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java
@@ -68,6 +68,7 @@ import org.apache.flex.compiler.tree.as.IContainerNode;
 import org.apache.flex.compiler.tree.as.IDefinitionNode;
 import org.apache.flex.compiler.tree.as.IExpressionNode;
 import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
 import org.apache.flex.compiler.tree.as.INamespaceDecorationNode;
 import org.apache.flex.compiler.tree.as.IParameterNode;
 import org.apache.flex.compiler.tree.as.IScopedNode;
@@ -209,6 +210,10 @@ public class FunctionNode extends BaseTypedDefinitionNode implements
IFunctionNo
     {
         if (set.contains(PostProcessStep.POPULATE_SCOPE))
         {
+            final IFunctionNode parentFunctionNode = (IFunctionNode)getAncestorOfType(IFunctionNode.class);
+            if (parentFunctionNode != null)
+                parentFunctionNode.rememberLocalFunction(this);
+        
             FunctionDefinition definition = buildDefinition();
             setDefinition(definition);
 
@@ -933,7 +938,7 @@ public class FunctionNode extends BaseTypedDefinitionNode implements IFunctionNo
      */
     public final void discardFunctionBody()
     {
-        if (!isBodyDeferred)
+        if (!isBodyDeferred || containsLocalFunctions())
             return;
 
         deferredBodyParsingLock.lock();
@@ -1015,17 +1020,40 @@ public class FunctionNode extends BaseTypedDefinitionNode implements
IFunctionNo
             this.functionBodyText = bodyCache.toString();
     }
     
+    private ArrayList<IFunctionNode> localFunctions;
+    
     @Override
-    public boolean containsAnonymousFunctions()
+    public List<IFunctionNode> getLocalFunctions()
     {
-        return hasAnonymousFunctions;
+        return localFunctions;
     }
 
-
     @Override
-    public void setAnonymousFunctionsFlag(boolean value)
+    public boolean containsLocalFunctions()
     {
-        hasAnonymousFunctions = value;
+        return localFunctions != null;
     }
 
+    @Override
+    public void rememberLocalFunction(IFunctionNode value)
+    {
+        if (localFunctions == null)
+            localFunctions = new ArrayList<IFunctionNode>();
+        
+        localFunctions.add(value);
+    }  
+
+    private boolean emitLocalFunctions;
+    
+    @Override
+    public boolean getEmittingLocalFunctions()
+    {
+        return emitLocalFunctions;
+    }
+    
+    @Override
+    public void setEmittingLocalFunctions(boolean emit)
+    {
+        emitLocalFunctions = emit;
+    }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionObjectNode.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionObjectNode.java
b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionObjectNode.java
index 4750272..4b6b268 100644
--- a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionObjectNode.java
+++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionObjectNode.java
@@ -93,10 +93,6 @@ public class FunctionObjectNode extends ExpressionNodeBase implements IFunctionO
     @Override
     protected void analyze(EnumSet<PostProcessStep> set, ASScope scope, Collection<ICompilerProblem>
problems)
     {
-        final IFunctionNode parentFunctionNode = (IFunctionNode)getAncestorOfType(IFunctionNode.class);
-        if (parentFunctionNode != null)
-            parentFunctionNode.setAnonymousFunctionsFlag(true);
-    
         EnumSet<PostProcessStep> stepsToRunOnChildren;
         if (set.contains(PostProcessStep.RECONNECT_DEFINITIONS))
         {

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f0ebbf0c/compiler/src/org/apache/flex/compiler/tree/as/IFunctionNode.java
----------------------------------------------------------------------
diff --git a/compiler/src/org/apache/flex/compiler/tree/as/IFunctionNode.java b/compiler/src/org/apache/flex/compiler/tree/as/IFunctionNode.java
index a7e5ee6..361ae5d 100644
--- a/compiler/src/org/apache/flex/compiler/tree/as/IFunctionNode.java
+++ b/compiler/src/org/apache/flex/compiler/tree/as/IFunctionNode.java
@@ -19,6 +19,8 @@
 
 package org.apache.flex.compiler.tree.as;
 
+import java.util.List;
+
 import org.apache.flex.compiler.definitions.IFunctionDefinition;
 import org.apache.flex.compiler.definitions.IFunctionDefinition.FunctionClassification;
 
@@ -156,12 +158,30 @@ public interface IFunctionNode extends IScopedDefinitionNode, IDocumentableDefin
     boolean hasBody();
     
     /**
-     * Does this function have a anonymous functions within
+     * Does this function have a local functions within
+     */
+    boolean containsLocalFunctions();
+    
+    /**
+     * Get local functions within
+     */
+    List<IFunctionNode> getLocalFunctions();
+    
+    /**
+     * Remember local Functions in this function node().
+     * JS codegen needs to know about them.
+     */
+    void rememberLocalFunction(IFunctionNode localFunction);
+    
+    /**
+     * flag to determine whether to emit the local function
+     * or a reference to it
      */
-    boolean containsAnonymousFunctions();
+    boolean getEmittingLocalFunctions();
     
     /**
-     * Set containsAnonymousFunction()
+     * flag to determine whether to emit the local function
+     * or a reference to it
      */
-    void setAnonymousFunctionsFlag(boolean value);
+    void setEmittingLocalFunctions(boolean emit);
 }


Mime
View raw message