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();