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 <[email protected]>
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()

Reply via email to