Author: erikdebruin
Date: Thu Feb 14 14:06:19 2013
New Revision: 1446182

URL: http://svn.apache.org/r1446182
Log:
Added support for 'for-each' loops.
Added support for constructors with arguments and matching 'super' calls.

Modified:
    
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/as/codegen/TestClass.java
    
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java
    
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
    
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogStatements.java
    
flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java

Modified: 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/as/codegen/TestClass.java
URL: 
http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/as/codegen/TestClass.java?rev=1446182&r1=1446181&r2=1446182&view=diff
==============================================================================
--- 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/as/codegen/TestClass.java
 (original)
+++ 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/as/codegen/TestClass.java
 Thu Feb 14 14:06:19 2013
@@ -132,6 +132,22 @@ public class TestClass extends TestWalke
     }
 
     @Test
+    public void testConstructor_withArguments()
+    {
+        IClassNode node = getClassNode("public class A {public function 
A(arg1:String, arg2:int) {}}");
+        visitor.visitClass(node);
+        assertOut("public class A {\n\tpublic function A(arg1:String, 
arg2:int) {\n\t}\n}");
+    }
+
+    @Test
+    public void testExtendsConstructor_withArguments()
+    {
+        IClassNode node = getClassNode("public class A extends B {public 
function A(arg1:String, arg2:int) {}}");
+        visitor.visitClass(node);
+        assertOut("public class A extends B {\n\tpublic function 
A(arg1:String, arg2:int) {\n\t}\n}");
+    }
+
+    @Test
     public void testFields()
     {
         IClassNode node = getClassNode("public class A {public var 
a:Object;protected var b:String; "

Modified: 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java
URL: 
http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java?rev=1446182&r1=1446181&r2=1446182&view=diff
==============================================================================
--- 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java
 (original)
+++ 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java
 Thu Feb 14 14:06:19 2013
@@ -70,7 +70,7 @@ public class TestGoogAccessorMembers ext
     {
         // TODO (erikdebruin) need to figure out how to handle calls to 
         //                    'super' since the JS getter is actually an 
-        //                    anonymous function...
+        //                    anonymous function... goog.bind or goog.partial?
         IGetterNode node = (IGetterNode) getAccessor("public override function 
get foo():int{super.foo(); return -1;}");
         visitor.visitGetter(node);
         assertOut("Object.defineProperty(\n\tA.prototype, \n\t'foo', 
\n\t{get:function() {\n\t\tvar self = this;\n\t\tgoog.base(this, 
'foo');\n\t\treturn -1;\n\t}, configurable:true}\n)");

Modified: 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
URL: 
http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java?rev=1446182&r1=1446181&r2=1446182&view=diff
==============================================================================
--- 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
 (original)
+++ 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
 Thu Feb 14 14:06:19 2013
@@ -149,6 +149,24 @@ public class TestGoogClass extends TestC
 
     @Override
     @Test
+    public void testConstructor_withArguments()
+    {
+        IClassNode node = getClassNode("public class A {public function 
A(arg1:String, arg2:int) {}}");
+        visitor.visitClass(node);
+        assertOut("/**\n * @constructor\n * @param {string} arg1\n * @param 
{number} arg2\n */\norg.apache.flex.A = function(arg1, arg2) {\n};");
+    }
+
+    @Override
+    @Test
+    public void testExtendsConstructor_withArguments()
+    {
+        IClassNode node = getClassNode("public class A extends 
spark.components.Button {public function A(arg1:String, arg2:int) {}}");
+        visitor.visitClass(node);
+        assertOut("/**\n * @constructor\n * @extends 
{spark.components.Button}\n * @param {string} arg1\n * @param {number} arg2\n 
*/\norg.apache.flex.A = function(arg1, arg2) {\n\tgoog.base(this, arg1, 
arg2);\n}\ngoog.inherits(org.apache.flex.A, spark.components.Button);");
+    }
+
+    @Override
+    @Test
     public void testFields()
     {
         IClassNode node = getClassNode("public class A {public var 
a:Object;protected var b:String; "

Modified: 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogStatements.java
URL: 
http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogStatements.java?rev=1446182&r1=1446181&r2=1446182&view=diff
==============================================================================
--- 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogStatements.java
 (original)
+++ 
flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogStatements.java
 Thu Feb 14 14:06:19 2013
@@ -172,22 +172,20 @@ public class TestGoogStatements extends 
     @Test
     public void testVisitForEach_1()
     {
-        // TODO (erikdebruin) the assert is a placeholder for the eventual 
workaround
         IForLoopNode node = (IForLoopNode) getNode(
                 "for each(var i:int in obj) { break; }", IForLoopNode.class);
         visitor.visitForLoop(node);
-        assertOut("for-each (var /** @type {number} */ i in obj) 
{\n\tbreak;\n}");
+        assertOut("goog.array.forEach(obj, function (i) {\n\tbreak;\n})");
     }
 
     @Override
     @Test
     public void testVisitForEach_1a()
     {
-        // TODO (erikdebruin) the assert is a placeholder for the eventual 
workaround
         IForLoopNode node = (IForLoopNode) getNode(
                 "for each(var i:int in obj)  break; ", IForLoopNode.class);
         visitor.visitForLoop(node);
-        assertOut("for-each (var /** @type {number} */ i in obj)\n\tbreak;");
+        assertOut("goog.array.forEach(obj, function (i) {\n\tbreak;\n})");
     }
 
     //----------------------------------
@@ -219,6 +217,7 @@ public class TestGoogStatements extends 
     @Test
     public void testVisitTry_Catch_Catch_Finally()
     {
+        // TODO (erikdebruin) handle multiple 'catch' statements (FW in Wiki)
         ITryNode node = (ITryNode) getNode(
                 "try { a; } catch (e:Error) { b; } catch (f:Error) { c; } 
finally { d; }",
                 ITryNode.class);
@@ -248,7 +247,7 @@ public class TestGoogStatements extends 
                 "foo: for each(var i:int in obj) { break foo; }",
                 LabeledStatementNode.class);
         visitor.visitLabeledStatement(node);
-        assertOut("foo : for-each (var /** @type {number} */ i in obj) 
{\n\tbreak foo;\n}");
+        assertOut("foo : goog.array.forEach(obj, function (i) {\n\tbreak 
foo;\n})");
     }
 
     @Override
@@ -260,7 +259,7 @@ public class TestGoogStatements extends 
                 "foo: for each(var i:int in obj) break foo;",
                 LabeledStatementNode.class);
         visitor.visitLabeledStatement(node);
-        assertOut("foo : for-each (var /** @type {number} */ i in 
obj)\n\tbreak foo;");
+        assertOut("foo : goog.array.forEach(obj, function (i) {\n\tbreak 
foo;\n})");
     }
 
     //----------------------------------
@@ -271,7 +270,6 @@ public class TestGoogStatements extends 
     @Test
     public void testVisit()
     {
-        // TODO (erikdebruin) check if resulting 'goog' JS is valid
         IFileNode node = (IFileNode) getNode(
                 "try { a; } catch (e:Error) { if (a) { if (b) { if (c) b; else 
if (f) a; else e; }} } finally {  }"
                         + "if (d) for (var i:int = 0; i < len; i++) break;"
@@ -279,13 +277,13 @@ public class TestGoogStatements extends 
                         + "do {a++;do a++; while(a > b);} while(c > d); }"
                         + "if (b) { try { a; throw new Error('foo'); } catch 
(e:Error) { "
                         + " switch(i){case 1: break; default: return;}"
-                        + " } catch (f:Error) { c; eee.dd; } finally { "
+                        + " } finally { "
                         + "  d;  var a:Object = function(foo:int, bar:String = 
'goo'):int{return -1;};"
                         + "  eee.dd; eee.dd; eee.dd; eee.dd;} }"
                         + "foo: for each(var i:int in obj) break foo;",
                 IFileNode.class);
         visitor.visitFile(node);
-        assertOut("goog.provide('A');\n\n/**\n * @constructor\n */\nA = 
function() {\n};\n\nA.prototype.a = function() {\n\tvar self = this;\n\ttry 
{\n\t\ta;\n\t} catch (e) {\n\t\tif (a) {\n\t\t\tif (b) {\n\t\t\t\tif 
(c)\n\t\t\t\t\tb;\n\t\t\t\telse if 
(f)\n\t\t\t\t\ta;\n\t\t\t\telse\n\t\t\t\t\te;\n\t\t\t}\n\t\t}\n\t} finally 
{\n\t}\n\tif (d)\n\t\tfor (var /** @type {number} */ i = 0; i < len; 
i++)\n\t\t\tbreak;\n\tif (a) {\n\t\twith (ab) {\n\t\t\tc();\n\t\t}\n\t\tdo 
{\n\t\t\ta++;\n\t\t\tdo\n\t\t\t\ta++;\n\t\t\twhile (a > b);\n\t\t} while (c > 
d);\n\t}\n\tif (b) {\n\t\ttry {\n\t\t\ta;\n\t\t\tthrow new Error('foo');\n\t\t} 
catch (e) {\n\t\t\tswitch (i) {\n\t\t\t\tcase 
1:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} catch 
(f) {\n\t\t\tc;\n\t\t\teee.dd;\n\t\t} finally {\n\t\t\td;\n\t\t\tvar /** @type 
{Object} */ a = function(foo, bar) {\n\t\t\t\tvar self = this;\n\t\t\t\tbar = 
typeof bar !== 'undefined' ? bar : 'goo';\n\t\t\t\treturn -1;\n\t\t\t};\n\t\t
 \teee.dd;\n\t\t\teee.dd;\n\t\t\teee.dd;\n\t\t\teee.dd;\n\t\t}\n\t}\n\tfoo : 
for-each (var /** @type {number} */ i in obj)\n\t\tbreak foo;;\n};");
+        assertOut("goog.provide('A');\n\n/**\n * @constructor\n */\nA = 
function() {\n};\n\nA.prototype.a = function() {\n\tvar self = this;\n\ttry 
{\n\t\ta;\n\t} catch (e) {\n\t\tif (a) {\n\t\t\tif (b) {\n\t\t\t\tif 
(c)\n\t\t\t\t\tb;\n\t\t\t\telse if 
(f)\n\t\t\t\t\ta;\n\t\t\t\telse\n\t\t\t\t\te;\n\t\t\t}\n\t\t}\n\t} finally 
{\n\t}\n\tif (d)\n\t\tfor (var /** @type {number} */ i = 0; i < len; 
i++)\n\t\t\tbreak;\n\tif (a) {\n\t\twith (ab) {\n\t\t\tc();\n\t\t}\n\t\tdo 
{\n\t\t\ta++;\n\t\t\tdo\n\t\t\t\ta++;\n\t\t\twhile (a > b);\n\t\t} while (c > 
d);\n\t}\n\tif (b) {\n\t\ttry {\n\t\t\ta;\n\t\t\tthrow new Error('foo');\n\t\t} 
catch (e) {\n\t\t\tswitch (i) {\n\t\t\t\tcase 
1:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} 
finally {\n\t\t\td;\n\t\t\tvar /** @type {Object} */ a = function(foo, bar) 
{\n\t\t\t\tvar self = this;\n\t\t\t\tbar = typeof bar !== 'undefined' ? bar : 
'goo';\n\t\t\t\treturn 
-1;\n\t\t\t};\n\t\t\teee.dd;\n\t\t\teee.dd;\n\t\t\teee.dd;\n\t\
 t\teee.dd;\n\t\t}\n\t}\n\tfoo : goog.array.forEach(obj, function (i) 
{\n\t\tbreak foo;\n\t});\n};");
     }
 
     protected IBackend createBackend()

Modified: 
flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java
URL: 
http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java?rev=1446182&r1=1446181&r2=1446182&view=diff
==============================================================================
--- 
flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java
 (original)
+++ 
flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java
 Thu Feb 14 14:06:19 2013
@@ -78,6 +78,7 @@ public class JSGoogEmitter extends JSEmi
     private static final String CONSTRUCTOR_FULL = "fullConstructor";
     private static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";
 
+    public static final String GOOG_ARRAY_FOREACH = "goog.array.forEach";
     public static final String GOOG_BASE = "goog.base";
     public static final String GOOG_INHERITS = "goog.inherits";
     public static final String GOOG_PROVIDE = "goog.provide";
@@ -579,7 +580,8 @@ public class JSGoogEmitter extends JSEmi
         if (hasBody(node))
             emitSelfReference(node);
 
-        if (node.isConstructor() && hasSuperClass(node) && 
!hasSuperCall(node.getScopedNode()))
+        if (node.isConstructor()
+                && hasSuperClass(node) && !hasSuperCall(node.getScopedNode()))
             emitSuperCall(node, CONSTRUCTOR_FULL);
 
         emitRestParameterCodeBlock(node);
@@ -613,12 +615,6 @@ public class JSGoogEmitter extends JSEmi
             writeNewline();
             indentPop();
         }
-        else if (type == CONSTRUCTOR_FULL)
-        {
-            // TODO (erikdebruin) don't emit 'default' super call when there is
-            //                    a user implemented super call in the function
-            //                    body
-        }
         else if (type == SUPER_FUNCTION_CALL)
         {
             if (fnode == null)
@@ -639,18 +635,30 @@ public class JSGoogEmitter extends JSEmi
             write(SINGLE_QUOTE);
         }
 
-        // TODO (erikdebruin) handle 'goog.base' call in constructor when it 
has
-        //                    no super call, but does have arguments
+        IASNode[] anodes = null;
+        boolean writeArguments = false;
         if (fcnode != null)
         {
-            IExpressionNode[] enodes = fcnode.getArgumentNodes();
-            int len = enodes.length;
+            anodes = fcnode.getArgumentNodes();
+
+            writeArguments = anodes.length > 0;
+        }
+        else if (fnode.isConstructor())
+        {
+            anodes = fnode.getParameterNodes();
+
+            writeArguments = (anodes != null && anodes.length > 0);
+        }
+
+        if (writeArguments)
+        {
+            int len = anodes.length;
             for (int i = 0; i < len; i++)
             {
                 write(COMMA);
                 write(SPACE);
 
-                getWalker().walk(enodes[i]);
+                getWalker().walk(anodes[i]);
             }
         }
 
@@ -796,27 +804,36 @@ public class JSGoogEmitter extends JSEmi
     public void emitTypedExpression(ITypedExpressionNode node)
     {
         getWalker().walk(node.getCollectionNode());
-        // (erikdebruin) for 'goog', leave out the ".<WhateverType>" part
     }
 
     @Override
     public void emitForEachLoop(IForLoopNode node)
     {
         IContainerNode xnode = (IContainerNode) node.getChild(1);
-        write(IASKeywordConstants.FOR);
-        write(DASH);
-        write(IASKeywordConstants.EACH);
+        IBinaryOperatorNode bnode = (IBinaryOperatorNode) node
+                .getConditionalsContainerNode().getChild(0);
+        IVariableNode vnode = (IVariableNode) bnode.getChild(0).getChild(0);
+
+        write(GOOG_ARRAY_FOREACH);
+        write(PARENTHESES_OPEN);
+        getWalker().walk(bnode.getChild(1));
+        write(COMMA);
+        write(SPACE);
+        write(IASKeywordConstants.FUNCTION);
         write(SPACE);
         write(PARENTHESES_OPEN);
-
-        IContainerNode cnode = node.getConditionalsContainerNode();
-        getWalker().walk(cnode.getChild(0));
-
+        write(vnode.getName());
         write(PARENTHESES_CLOSE);
-        if (!isImplicit(xnode))
-            write(SPACE);
-
+        write(SPACE);
+        if (isImplicit(xnode))
+            write(CURLYBRACE_OPEN);
         getWalker().walk(node.getStatementContentsNode());
+        if (isImplicit(xnode))
+        {
+            writeNewline();
+            write(CURLYBRACE_CLOSE);
+        }
+        write(PARENTHESES_CLOSE);
     }
 
     public JSGoogEmitter(FilterWriter out)
@@ -904,10 +921,10 @@ public class JSGoogEmitter extends JSEmi
                     && cnode.getChild(0).getNodeID() == ASTNodeID.SuperID)
                 return true;
         }
-        
+
         return false;
     }
-    
+
     private static boolean hasBody(IFunctionNode node)
     {
         IScopedNode scope = node.getScopedNode();


Reply via email to