This is an automated email from the ASF dual-hosted git repository.
joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
The following commit(s) were added to refs/heads/develop by this push:
new 5227fb433 JSDynamicAccessOverride, JSForInOverride, and
JSForEachOverride metadata: followup to detect this metadata on subclasses and
interfaces
5227fb433 is described below
commit 5227fb433493dd123fffc7fca065e7b088335c5f
Author: Josh Tynjala <[email protected]>
AuthorDate: Fri Aug 7 08:43:47 2026 -0700
JSDynamicAccessOverride, JSForInOverride, and JSForEachOverride metadata:
followup to detect this metadata on subclasses and interfaces
Also added tests for the metadata to ensure that the emitted JS uses the
methods specified
Followup to commit 308d8867b923c0edff4bf814fa89a175123dcf37
---
.../codegen/js/jx/BinaryOperatorEmitter.java | 20 +-
.../codegen/js/jx/DynamicAccessEmitter.java | 24 ++-
.../internal/codegen/js/jx/ForEachEmitter.java | 46 +++--
.../internal/codegen/js/jx/ForLoopEmitter.java | 12 +-
.../codegen/js/jx/UnaryOperatorEmitter.java | 34 ++--
.../js/royale/TestRoyaleJSDynamicOverrides.java | 155 +++++++++++++++
.../js/royale/TestRoyaleJSForEachOverrides.java | 128 +++++++++++++
.../js/royale/TestRoyaleJSForInOverrides.java | 209 +++++++++++++++++++++
8 files changed, 582 insertions(+), 46 deletions(-)
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
index 904909e4f..0096ae5bf 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
@@ -869,7 +869,15 @@ public class BinaryOperatorEmitter extends JSSubEmitter
implements
{
return null;
}
- IMetaTag dynamicOverrideMeta =
dynamicLeftType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
+ IMetaTag dynamicOverrideMeta = null;
+ for (ITypeDefinition currentType :
dynamicLeftType.typeIteratable(getProject(), false))
+ {
+ dynamicOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
+ if (dynamicOverrideMeta != null)
+ {
+ break;
+ }
+ }
if (dynamicOverrideMeta == null)
{
return null;
@@ -884,7 +892,15 @@ public class BinaryOperatorEmitter extends JSSubEmitter
implements
{
return null;
}
- IMetaTag dynamicOverrideMeta =
typeDef.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
+ IMetaTag dynamicOverrideMeta = null;
+ for (ITypeDefinition currentType :
typeDef.typeIteratable(getProject(), false))
+ {
+ dynamicOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
+ if (dynamicOverrideMeta != null)
+ {
+ break;
+ }
+ }
if (dynamicOverrideMeta == null)
{
return null;
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java
index b0392de31..7fbac28f1 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/DynamicAccessEmitter.java
@@ -95,18 +95,22 @@ public class DynamicAccessEmitter extends JSSubEmitter
implements
ITypeDefinition leftType =
leftOperandNode.resolveType(getProject());
if (leftType != null)
{
- IMetaTag dynamicOverrideMeta =
leftType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
- if (dynamicOverrideMeta != null)
+ IMetaTag dynamicOverrideMeta = null;
+ for (ITypeDefinition currentType :
leftType.typeIteratable(getProject(), false))
{
- String getMethod =
dynamicOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_DYNAMIC_OVERRIDE_GET_METHOD);
- if (getMethod != null)
+ dynamicOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
+ if (dynamicOverrideMeta != null)
{
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(getMethod);
- write(ASEmitterTokens.PAREN_OPEN);
- getWalker().walk(rightOperandNode);
- write(ASEmitterTokens.PAREN_CLOSE);
- return;
+ String getMethod =
dynamicOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_DYNAMIC_OVERRIDE_GET_METHOD);
+ if (getMethod != null)
+ {
+
write(ASEmitterTokens.MEMBER_ACCESS);
+ write(getMethod);
+
write(ASEmitterTokens.PAREN_OPEN);
+
getWalker().walk(rightOperandNode);
+
write(ASEmitterTokens.PAREN_CLOSE);
+ return;
+ }
}
}
}
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForEachEmitter.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForEachEmitter.java
index 4b603b287..05b707118 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForEachEmitter.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForEachEmitter.java
@@ -61,18 +61,26 @@ public class ForEachEmitter extends JSSubEmitter implements
ITypeDefinition rtype = rnode.resolveType(getProject());
if (rtype != null)
{
- IMetaTag forEachOverrideMeta =
rtype.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_FOR_EACH_OVERRIDE);
- if (forEachOverrideMeta != null)
+ IMetaTag forEachOverrideMeta = null;
+ for (ITypeDefinition currentType :
rtype.typeIteratable(getProject(), false))
{
- emitForEachOverride(node, rtype, forEachOverrideMeta);
- return;
+ forEachOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_FOR_EACH_OVERRIDE);
+ if (forEachOverrideMeta != null)
+ {
+ emitForEachOverride(node, rtype, forEachOverrideMeta);
+ return;
+ }
}
// it's possible to use ForInOverride for for-each loops too
- IMetaTag forInOverrideMeta =
rtype.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_FOR_IN_OVERRIDE);
- if (forInOverrideMeta != null)
+ IMetaTag forInOverrideMeta = null;
+ for (ITypeDefinition currentType :
rtype.typeIteratable(getProject(), false))
{
- emitForInOverride(node, rtype, forInOverrideMeta);
- return;
+ forInOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_FOR_IN_OVERRIDE);
+ if (forInOverrideMeta != null)
+ {
+ emitForInOverride(node, rtype, forInOverrideMeta);
+ return;
+ }
}
}
@@ -349,7 +357,7 @@ public class ForEachEmitter extends JSSubEmitter implements
getModel().incForeachLoopCount();
final String iterTargetName = iterBaseName + "_target";
final String iterResultName = iterBaseName + "_iterator";
- final String iterKeyName = iterBaseName + "_key";
+ final String iterValueName = iterBaseName + "_value";
final String iteratorMethodName =
forEachOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_FOR_EACH_OVERRIDE_ITERATOR_METHOD);
final String iteratorNextMethodName =
forEachOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_FOR_EACH_OVERRIDE_ITERATOR_NEXT_METHOD);
@@ -422,7 +430,7 @@ public class ForEachEmitter extends JSSubEmitter implements
if (iteratorHasNextMethodName == null && iteratorDoneMethodName ==
null)
{
writeToken(ASEmitterTokens.VAR);
- writeToken(iterKeyName);
+ writeToken(iterValueName);
writeToken(ASEmitterTokens.EQUAL);
write(iterResultName);
write(ASEmitterTokens.MEMBER_ACCESS);
@@ -434,7 +442,7 @@ public class ForEachEmitter extends JSSubEmitter implements
writeToken(ASEmitterTokens.IF);
write(ASEmitterTokens.PAREN_OPEN);
- writeToken(iterKeyName);
+ writeToken(iterValueName);
writeToken("==");
write(ASEmitterTokens.UNDEFINED);
writeToken(ASEmitterTokens.PAREN_CLOSE);
@@ -466,7 +474,7 @@ public class ForEachEmitter extends JSSubEmitter implements
if (iteratorHasNextMethodName == null && iteratorDoneMethodName ==
null)
{
- write(iterKeyName);
+ write(iterValueName);
write(ASEmitterTokens.SEMICOLON);
writeNewline();
}
@@ -499,11 +507,19 @@ public class ForEachEmitter extends JSSubEmitter
implements
IExpressionNode childNode = bnode.getLeftOperandNode();
IExpressionNode rnode = bnode.getRightOperandNode();
- IMetaTag dynamicOverrideMeta =
rtype.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
String getMethod = null;
- if (dynamicOverrideMeta != null)
+ IMetaTag dynamicOverrideMeta = null;
+ for (ITypeDefinition currentType : rtype.typeIteratable(getProject(),
false))
{
- getMethod =
dynamicOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_DYNAMIC_OVERRIDE_GET_METHOD);
+ dynamicOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
+ if (dynamicOverrideMeta != null)
+ {
+ getMethod =
dynamicOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_DYNAMIC_OVERRIDE_GET_METHOD);
+ if (getMethod != null)
+ {
+ break;
+ }
+ }
}
final String iterBaseName = getModel().getCurrentForeachName();
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForLoopEmitter.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForLoopEmitter.java
index 0a4ad168d..7a1bc899a 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForLoopEmitter.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/ForLoopEmitter.java
@@ -59,11 +59,15 @@ public class ForLoopEmitter extends JSSubEmitter implements
ITypeDefinition rtype = rnode.resolveType(getProject());
if (rtype != null)
{
- IMetaTag forInOverrideMeta =
rtype.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_FOR_IN_OVERRIDE);
- if (forInOverrideMeta != null)
+ IMetaTag forInOverrideMeta = null;
+ for (ITypeDefinition currentType :
rtype.typeIteratable(getProject(), false))
{
- emitForInOverride(node, rtype, forInOverrideMeta);
- return;
+ forInOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_FOR_IN_OVERRIDE);
+ if (forInOverrideMeta != null)
+ {
+ emitForInOverride(node, rtype, forInOverrideMeta);
+ return;
+ }
}
}
}
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java
index 72475713c..5b0171ded 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/UnaryOperatorEmitter.java
@@ -147,23 +147,27 @@ public class UnaryOperatorEmitter extends JSSubEmitter
implements
ITypeDefinition leftType =
leftOperandNode.resolveType(getProject());
if (leftType != null)
{
- IMetaTag dynamicOverrideMeta =
leftType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
- if (dynamicOverrideMeta != null)
+ IMetaTag dynamicOverrideMeta = null;
+ for (ITypeDefinition currentType :
leftType.typeIteratable(getProject(), false))
{
- String deleteMethod =
dynamicOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_DYNAMIC_OVERRIDE_DELETE_METHOD);
- if (deleteMethod != null)
+ dynamicOverrideMeta =
currentType.getMetaTagByName(IJSMetaAttributeConstants.ATTRIBUTE_DYNAMIC_OVERRIDE);
+ if (dynamicOverrideMeta != null)
{
-
getWalker().walk(dynamicAccessNode.getLeftOperandNode());
- startMapping(node);
- write(ASEmitterTokens.MEMBER_ACCESS);
- write(deleteMethod);
- write(ASEmitterTokens.PAREN_OPEN);
- endMapping(node);
-
getWalker().walk(dynamicAccessNode.getRightOperandNode());
- startMapping(node);
- write(ASEmitterTokens.PAREN_CLOSE);
- endMapping(node);
- return;
+ String deleteMethod =
dynamicOverrideMeta.getAttributeValue(IJSMetaAttributeConstants.NAME_DYNAMIC_OVERRIDE_DELETE_METHOD);
+ if (deleteMethod != null)
+ {
+
getWalker().walk(dynamicAccessNode.getLeftOperandNode());
+ startMapping(node);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(deleteMethod);
+ write(ASEmitterTokens.PAREN_OPEN);
+ endMapping(node);
+
getWalker().walk(dynamicAccessNode.getRightOperandNode());
+ startMapping(node);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ endMapping(node);
+ return;
+ }
}
}
}
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSDynamicOverrides.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSDynamicOverrides.java
new file mode 100644
index 000000000..217296030
--- /dev/null
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSDynamicOverrides.java
@@ -0,0 +1,155 @@
+/*
+ *
+ * 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.royale.compiler.internal.codegen.js.royale;
+
+import org.apache.royale.compiler.driver.IBackend;
+import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend;
+import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.test.ASTestBase;
+import org.apache.royale.compiler.tree.as.IClassNode;
+import org.junit.Test;
+
+public class TestRoyaleJSDynamicOverrides extends ASTestBase
+{
+ @Override
+ public void setUp()
+ {
+ backend = createBackend();
+ project = new RoyaleJSProject(workspace, backend);
+ project.config = new JSGoogConfiguration();
+ super.setUp();
+ }
+
+ @Test
+ public void testDynamicOverride_getMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSDynamicOverride(getMethod=\"get\")] class A { public function A() {
var a = this[0]; } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var /**
@type {*} */ a = this.get(0);\n};");
+ }
+
+ @Test
+ public void testDynamicOverride_getMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { var a = this[0]; } };
[JSDynamicOverride(getMethod=\"get\")] public class A { public function A() {}
}",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var /** @type {*} */ a =
this.get(0);\n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void testDynamicOverride_getMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { var a = this[0]; } };
[JSDynamicOverride(getMethod=\"get\")] public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var /** @type {*} */ a = this.get(0);\n};");
+ }
+
+ @Test
+ public void testDynamicOverride_setMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSDynamicOverride(setMethod=\"set\")] class A { public function A() {
this[0] = 123.4; } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n
this.set(0,123.4);\n};");
+ }
+
+ @Test
+ public void testDynamicOverride_setMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { this[0] = 123.4; } };
[JSDynamicOverride(setMethod=\"set\")] public class A { public function A() {}
}",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n this.set(0,123.4);\n};\ngoog.inherits(B,
A);");
+ }
+
+ @Test
+ public void testDynamicOverride_setMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { this[0] = 123.4; } };
[JSDynamicOverride(setMethod=\"set\")] public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n this.set(0,123.4);\n};");
+ }
+
+ @Test
+ public void testDynamicOverride_deleteMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSDynamicOverride(deleteMethod=\"del\")] class A { public function
A() { delete this[0]; } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n
this.del(0);\n};");
+ }
+
+ @Test
+ public void testDynamicOverride_deleteMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { delete this[0]; } };
[JSDynamicOverride(deleteMethod=\"del\")] public class A { public function A()
{} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n this.del(0);\n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void testDynamicOverride_deleteMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { delete this[0]; } };
[JSDynamicOverride(deleteMethod=\"del\")] public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n this.del(0);\n};");
+ }
+
+ @Test
+ public void testDynamicOverride_inMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSDynamicOverride(inMethod=\"exists\")] class A { public function A()
{ 0 in this; } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n
this.exists(0);\n};");
+ }
+
+ @Test
+ public void testDynamicOverride_inMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { 0 in this; } }; [JSDynamicOverride(inMethod=\"exists\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n this.exists(0);\n};\ngoog.inherits(B,
A);");
+ }
+
+ @Test
+ public void testDynamicOverride_inMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { 0 in this; } }; [JSDynamicOverride(inMethod=\"exists\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n this.exists(0);\n};");
+ }
+
+ @Override
+ protected IBackend createBackend()
+ {
+ return new RoyaleBackend();
+ }
+
+}
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSForEachOverrides.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSForEachOverrides.java
new file mode 100644
index 000000000..7fe56a5fd
--- /dev/null
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSForEachOverrides.java
@@ -0,0 +1,128 @@
+/*
+ *
+ * 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.royale.compiler.internal.codegen.js.royale;
+
+import org.apache.royale.compiler.driver.IBackend;
+import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend;
+import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.test.ASTestBase;
+import org.apache.royale.compiler.tree.as.IClassNode;
+import org.junit.Test;
+
+public class TestRoyaleJSForEachOverrides extends ASTestBase
+{
+ @Override
+ public void setUp()
+ {
+ backend = createBackend();
+ project = new RoyaleJSProject(workspace, backend);
+ project.config = new JSGoogConfiguration();
+ super.setUp();
+ }
+
+ @Test
+ public void testForEachOverride_iteratorMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForEachOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
class A { public function A() { for each (var value in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while (true)\n
{\n var foreachiter0_value = foreachiter0_iterator.next();\n if
(foreachiter0_value == undefined) break;\n var value =
foreachiter0_value;\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for each (var value in this) {} } };
[JSForEachOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (true)\n {\n var
foreachiter0_value = foreachiter0_iterator.next();\n if
(foreachiter0_value == undefined) break;\n var value =
foreachiter0_value;\n {\n }}\n }\n \n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for each (var value in this) {} } };
[JSForEachOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(true)\n {\n var foreachiter0_value = foreachiter0_iterator.next();\n
if (foreachiter0_value == undefined) break;\n var value =
foreachiter0_value;\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForEachOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
class A { public function A() { for each (var value in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while
(foreachiter0_iterator.hasNext())\n {\n var value =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for each (var value in this) {} } };
[JSForEachOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (foreachiter0_iterator.hasNext())\n
{\n var value = foreachiter0_iterator.next();\n {\n }}\n
}\n \n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for each (var value in this) {} } };
[JSForEachOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(foreachiter0_iterator.hasNext())\n {\n var value =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorDoneMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForEachOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
class A { public function A() { for each (var value in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while
(!foreachiter0_iterator.done())\n {\n var value =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorDoneMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for each (var value in this) {} } };
[JSForEachOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (!foreachiter0_iterator.done())\n
{\n var value = foreachiter0_iterator.next();\n {\n }}\n }\n
\n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForEachOverride_iteratorMethod_iteratorDoneMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for each (var value in this) {} } };
[JSForEachOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(!foreachiter0_iterator.done())\n {\n var value =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Override
+ protected IBackend createBackend()
+ {
+ return new RoyaleBackend();
+ }
+
+}
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSForInOverrides.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSForInOverrides.java
new file mode 100644
index 000000000..5c4e87747
--- /dev/null
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleJSForInOverrides.java
@@ -0,0 +1,209 @@
+/*
+ *
+ * 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.royale.compiler.internal.codegen.js.royale;
+
+import org.apache.royale.compiler.driver.IBackend;
+import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend;
+import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
+import org.apache.royale.compiler.internal.test.ASTestBase;
+import org.apache.royale.compiler.tree.as.IClassNode;
+import org.junit.Test;
+
+public class TestRoyaleJSForInOverrides extends ASTestBase
+{
+ @Override
+ public void setUp()
+ {
+ backend = createBackend();
+ project = new RoyaleJSProject(workspace, backend);
+ project.config = new JSGoogConfiguration();
+ super.setUp();
+ }
+
+ @Test
+ public void testForInOverride_iteratorMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForInOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
class A { public function A() { for (var key in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while (true)\n
{\n var foreachiter0_key = foreachiter0_iterator.next();\n if
(foreachiter0_key == undefined) break;\n var key = foreachiter0_key;\n
{\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void testForInOverride_iteratorMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for (var key in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (true)\n {\n var
foreachiter0_key = foreachiter0_iterator.next();\n if (foreachiter0_key ==
undefined) break;\n var key = foreachiter0_key;\n {\n }}\n
}\n \n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForInOverride_iteratorMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for (var key in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(true)\n {\n var foreachiter0_key = foreachiter0_iterator.next();\n
if (foreachiter0_key == undefined) break;\n var key = foreachiter0_key;\n
{\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForInOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
class A { public function A() { for (var key in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while
(foreachiter0_iterator.hasNext())\n {\n var key =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for (var key in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (foreachiter0_iterator.hasNext())\n
{\n var key = foreachiter0_iterator.next();\n {\n }}\n }\n
\n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForInOverride_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for (var key in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(foreachiter0_iterator.hasNext())\n {\n var key =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_iteratorMethod_iteratorDoneMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForInOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
class A { public function A() { for (var key in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while
(!foreachiter0_iterator.done())\n {\n var key =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_iteratorMethod_iteratorDoneMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for (var key in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (!foreachiter0_iterator.done())\n
{\n var key = foreachiter0_iterator.next();\n {\n }}\n }\n
\n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForInOverride_iteratorMethod_iteratorDoneMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for (var key in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(!foreachiter0_iterator.done())\n {\n var key =
foreachiter0_iterator.next();\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void testForInOverride_forEach_iteratorMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForInOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
class A { public function A() { for each (var value in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while (true)\n
{\n var foreachiter0_key = foreachiter0_iterator.next();\n if
(foreachiter0_key == undefined) break;\n var value =
foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for each (var value in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (true)\n {\n var
foreachiter0_key = foreachiter0_iterator.next();\n if (foreachiter0_key ==
undefined) break;\n var value = foreachiter0_target[foreachiter0_key];\n
{\n }}\n }\n \n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for each (var value in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(true)\n {\n var foreachiter0_key = foreachiter0_iterator.next();\n
if (foreachiter0_key == undefined) break;\n var value =
foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForInOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
class A { public function A() { for each (var value in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while
(foreachiter0_iterator.hasNext())\n {\n var foreachiter0_key =
foreachiter0_iterator.next();\n var value =
foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for each (var value in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (foreachiter0_iterator.hasNext())\n
{\n var foreachiter0_key = foreachiter0_iterator.next();\n var
value = foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n
\n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorHasNextMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for each (var value in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorHasNextMethod=\"hasNext\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(foreachiter0_iterator.hasNext())\n {\n var foreachiter0_key =
foreachiter0_iterator.next();\n var value =
foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorDoneMethod_iteratorNextMethod()
+ {
+ IClassNode node = (IClassNode)
getNode("[JSForInOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
class A { public function A() { for each (var value in this) {} } }",
+ IClassNode.class, WRAP_LEVEL_NONE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n */\nA = function() {\n var
foreachiter0_target = this;\n if (foreachiter0_target)\n {\n var
foreachiter0_iterator = foreachiter0_target.iterator();\n while
(!foreachiter0_iterator.done())\n {\n var foreachiter0_key =
foreachiter0_iterator.next();\n var value =
foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n \n};");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorDoneMethod_iteratorNextMethod_subclass()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A {
public function B() { for each (var value in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
public class A { public function A() {} }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function()
{\n B.base(this, 'constructor');\n var foreachiter0_target = this;\n if
(foreachiter0_target)\n {\n var foreachiter0_iterator =
foreachiter0_target.iterator();\n while (!foreachiter0_iterator.done())\n
{\n var foreachiter0_key = foreachiter0_iterator.next();\n var value
= foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n
\n};\ngoog.inherits(B, A);");
+ }
+
+ @Test
+ public void
testForInOverride_forEach_iteratorMethod_iteratorDoneMethod_iteratorNextMethod_implementsInterface()
+ {
+ IClassNode node = (IClassNode) getNode("public class B implements A {
public function B() { for each (var value in this) {} } };
[JSForInOverride(iteratorMethod=\"iterator\",iteratorDoneMethod=\"done\",iteratorNextMethod=\"next\")]
public interface A { }",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @implements {A}\n */\nB =
function() {\n var foreachiter0_target = this;\n if (foreachiter0_target)\n
{\n var foreachiter0_iterator = foreachiter0_target.iterator();\n while
(!foreachiter0_iterator.done())\n {\n var foreachiter0_key =
foreachiter0_iterator.next();\n var value =
foreachiter0_target[foreachiter0_key];\n {\n }}\n }\n \n};");
+ }
+
+ @Override
+ protected IBackend createBackend()
+ {
+ return new RoyaleBackend();
+ }
+
+}