You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by jo...@apache.org on 2022/03/30 16:21:36 UTC
[royale-compiler] branch develop updated: BinaryOperatorEmitter: Fixed value not propgating beyond super setter when it is part of a chained assignment (closes #210)
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 0f350d6 BinaryOperatorEmitter: Fixed value not propgating beyond super setter when it is part of a chained assignment (closes #210)
0f350d6 is described below
commit 0f350d600e866da3476a84785fa70a7d94fcce79
Author: Josh Tynjala <jo...@apache.org>
AuthorDate: Wed Mar 30 09:21:20 2022 -0700
BinaryOperatorEmitter: Fixed value not propgating beyond super setter when it is part of a chained assignment (closes #210)
Per discussion, the original value is propagated, and the getter is not called, to match SWF behavior
---
.../codegen/js/jx/BinaryOperatorEmitter.java | 35 +++++++++++++++++++++-
.../js/royale/TestRoyaleAccessorMembers.java | 22 ++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
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 674b198..33a2dd8 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
@@ -152,7 +152,18 @@ public class BinaryOperatorEmitter extends JSSubEmitter implements
{
if (isAssignment)
{
- IClassNode cnode = (IClassNode) node
+ boolean propagateAssignedValue = !(node.getParent() instanceof IBlockNode);
+ if (propagateAssignedValue)
+ {
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.FUNCTION);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write("$value");
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.BLOCK_OPEN);
+ }
+
+ IClassNode cnode = (IClassNode) node
.getAncestorOfType(IClassNode.class);
if (cnode != null)
write(getEmitter().formatQualifiedName(
@@ -187,6 +198,28 @@ public class BinaryOperatorEmitter extends JSSubEmitter implements
write(op.substring(0, 1));
}
+ if (propagateAssignedValue)
+ {
+ write("$value");
+ write(ASEmitterTokens.SQUARE_CLOSE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.SEMICOLON);
+ // returning the original $value ensures that
+ // chained assignments work properly
+ // the getter should NOT be called!
+ // x = super.y = z;
+ writeToken(ASEmitterTokens.RETURN);
+ write("$value");
+ write(ASEmitterTokens.SEMICOLON);
+ write(ASEmitterTokens.BLOCK_CLOSE);
+ write(ASEmitterTokens.PAREN_CLOSE);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.APPLY);
+ write(ASEmitterTokens.PAREN_OPEN);
+ write(ASEmitterTokens.THIS);
+ writeToken(ASEmitterTokens.COMMA);
+ write(ASEmitterTokens.SQUARE_OPEN);
+ }
getWalker().walk(node.getRightOperandNode());
write(ASEmitterTokens.SQUARE_CLOSE);
write(ASEmitterTokens.PAREN_CLOSE);
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java
index 56185c3..6aaac73 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleAccessorMembers.java
@@ -179,6 +179,28 @@ public class TestRoyaleAccessorMembers extends TestGoogAccessorMembers
"B.prototype.set__foo = function(value) {\n B.superClass_.set__foo.apply(this, [value]);\n};\n\n\n" +
"Object.defineProperties(B.prototype, /** @lends {B.prototype} */ {\n/**\n * @type {number}\n */\nfoo: {\nget: A.prototype.get__foo,\nset: B.prototype.set__foo}}\n);");
}
+
+ @Test
+ public void testSetAccessorWithSuperSet()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A { public override function set foo(value:int):void {super.foo = value;} }; public class A { public function set foo(value:int):void{} public function get foo():int { return 0;}}",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function() {\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
+ "B.prototype.set__foo = function(value) {\n B.superClass_.set__foo.apply(this, [value]);\n};\n\n\n" +
+ "Object.defineProperties(B.prototype, /** @lends {B.prototype} */ {\n/**\n * @type {number}\n */\nfoo: {\nget: A.prototype.get__foo,\nset: B.prototype.set__foo}}\n);");
+ }
+
+ @Test
+ public void testSetAccessorWithSuperSetAndPropagatedValue()
+ {
+ IClassNode node = (IClassNode) getNode("public class B extends A { public override function set foo(value:int):void {var z:int = super.foo = value;} }; public class A { public function set foo(value:int):void{} public function get foo():int { return 0;}}",
+ IClassNode.class, WRAP_LEVEL_PACKAGE);
+ asBlockWalker.visitClass(node);
+ assertOut("/**\n * @constructor\n * @extends {A}\n */\nB = function() {\n B.base(this, 'constructor');\n};\ngoog.inherits(B, A);\n\n\n" +
+ "B.prototype.set__foo = function(value) {\n var /** @type {number} */ z = (function($value){B.superClass_.set__foo.apply(this, [$value]);return $value;}).apply(this, [value]);\n};\n\n\n" +
+ "Object.defineProperties(B.prototype, /** @lends {B.prototype} */ {\n/**\n * @type {number}\n */\nfoo: {\nget: A.prototype.get__foo,\nset: B.prototype.set__foo}}\n);");
+ }
@Override
protected IBackend createBackend()