You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2021/11/28 23:41:46 UTC

[royale-compiler] branch develop updated: (JX) Fix for various code output scenarios that can be missing closing parenthesis. Closes #198

This is an automated email from the ASF dual-hosted git repository.

gregdove 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 dd13c42  (JX) Fix for various code output scenarios that can be missing closing parenthesis. Closes #198
dd13c42 is described below

commit dd13c421a196497be327453a083e643df19c971a
Author: greg-dove <gr...@gmail.com>
AuthorDate: Mon Nov 29 12:41:33 2021 +1300

    (JX) Fix for various code output scenarios that can be missing closing parenthesis. Closes #198
---
 .../codegen/js/jx/DynamicAccessEmitter.java        | 21 ++++++++++++---
 .../codegen/js/jx/MemberAccessEmitter.java         |  4 +++
 .../codegen/js/royale/TestRoyaleExpressions.java   | 30 ++++++++++++++--------
 3 files changed, 42 insertions(+), 13 deletions(-)

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 878b69a..fb5b1cb 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
@@ -42,6 +42,7 @@ import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
 import org.apache.royale.compiler.tree.as.IExpressionNode;
 import org.apache.royale.compiler.tree.as.ILiteralNode;
 import org.apache.royale.compiler.tree.as.IOperatorNode.OperatorType;
+import org.apache.royale.compiler.utils.ASNodeUtils;
 import org.apache.royale.compiler.utils.NativeUtils;
 
 public class DynamicAccessEmitter extends JSSubEmitter implements
@@ -55,6 +56,9 @@ public class DynamicAccessEmitter extends JSSubEmitter implements
     @Override
     public void emit(IDynamicAccessNode node)
     {
+		if (ASNodeUtils.hasParenOpen(node))
+			write(ASEmitterTokens.PAREN_OPEN);
+
         IExpressionNode leftOperandNode = node.getLeftOperandNode();
         getWalker().walk(leftOperandNode);
         if (leftOperandNode.getNodeID() == ASTNodeID.Op_AtID)
@@ -86,6 +90,8 @@ public class DynamicAccessEmitter extends JSSubEmitter implements
 					write(".child('' +");
 						getWalker().walk(rightOperandNode);
 					write(")");
+					if (ASNodeUtils.hasParenClose(node))
+						write(ASEmitterTokens.PAREN_CLOSE);
 					return;
 				}
 				if (type.isInstanceOf("String", getProject()))
@@ -98,24 +104,30 @@ public class DynamicAccessEmitter extends JSSubEmitter implements
 					}
 					else
 						write(".child(" + field + ")");
+					if (ASNodeUtils.hasParenClose(node))
+						write(ASEmitterTokens.PAREN_CLOSE);
 					return;
 				}
 				else if (type.isInstanceOf("QName", getProject()))
 				{
 					String field = fjs.stringifyNode(rightOperandNode);					
 					write(".child(" + field + ")");
+					if (ASNodeUtils.hasParenClose(node))
+						write(ASEmitterTokens.PAREN_CLOSE);
 					return;
 				}
 	    	}
         	else if (isProxy)
         	{
-        		boolean isLiteral = rightOperandNode instanceof ILiteralNode;
+        		boolean isNonStringLiteral = rightOperandNode instanceof ILiteralNode && ((ILiteralNode) rightOperandNode).getLiteralType() != ILiteralNode.LiteralType.STRING;
         		write(".getProperty(");
-        		if (isLiteral) write("'");
+        		if (isNonStringLiteral) write("'");
         		String s = fjs.stringifyNode(rightOperandNode);
         		write(s);
-        		if (isLiteral) write("'");
+        		if (isNonStringLiteral) write("'");
         		write(")");
+				if (ASNodeUtils.hasParenClose(node))
+					write(ASEmitterTokens.PAREN_CLOSE);
         		return;
         	}
     	}
@@ -174,5 +186,8 @@ public class DynamicAccessEmitter extends JSSubEmitter implements
         startMapping(node, rightOperandNode);
         write(ASEmitterTokens.SQUARE_CLOSE);
         endMapping(node);
+
+		if (ASNodeUtils.hasParenClose(node))
+			write(ASEmitterTokens.PAREN_CLOSE);
     }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
index 19c57db..2137004 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
@@ -83,6 +83,8 @@ public class MemberAccessEmitter extends JSSubEmitter implements
             write(propGetter.getFunctionName());
             write(ASEmitterTokens.PAREN_OPEN);
             write(ASEmitterTokens.PAREN_CLOSE);
+			if (ASNodeUtils.hasParenClose(node))
+				write(ASEmitterTokens.PAREN_CLOSE);
     		return;
         }
         IDefinition def = node.resolve(getProject());
@@ -253,6 +255,8 @@ public class MemberAccessEmitter extends JSSubEmitter implements
 						write(s);
 						write(closeMethodCall);
 					}
+					if (ASNodeUtils.hasParenClose(node))
+						write(ASEmitterTokens.PAREN_CLOSE);
 					return;
 				}
         	}
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
index 8f7ba31..388c1ec 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
@@ -30,16 +30,7 @@ import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.tree.as.ClassNode;
 import org.apache.royale.compiler.internal.tree.as.LiteralNode;
 import org.apache.royale.compiler.internal.tree.as.NodeBase;
-import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
-import org.apache.royale.compiler.tree.as.IClassNode;
-import org.apache.royale.compiler.tree.as.IDynamicAccessNode;
-import org.apache.royale.compiler.tree.as.IFileNode;
-import org.apache.royale.compiler.tree.as.IFunctionCallNode;
-import org.apache.royale.compiler.tree.as.IFunctionNode;
-import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
-import org.apache.royale.compiler.tree.as.INamespaceAccessExpressionNode;
-import org.apache.royale.compiler.tree.as.IReturnNode;
-import org.apache.royale.compiler.tree.as.IVariableNode;
+import org.apache.royale.compiler.tree.as.*;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -53,6 +44,7 @@ public class TestRoyaleExpressions extends TestGoogExpressions
     {
         backend = createBackend();
         project = new RoyaleJSProject(workspace, backend);
+        project.setProxyBaseClass("custom.TestProxy");
         workspace.setASDocDelegate(new RoyaleASDocDelegate());
     	JSGoogConfiguration config = new JSGoogConfiguration();
     	try {
@@ -2191,6 +2183,24 @@ public class TestRoyaleExpressions extends TestGoogExpressions
         assertOut("foo.bar.RoyaleTest_A.prototype.foo = function() {\n  this.http_$$ns_apache_org$2017$custom$namespace__b;\n}");
     }
 
+     @Test
+     public void testSpecialMemberAccessWithEnclosingParentheses()
+     {
+         IUnaryOperatorNode node = (IUnaryOperatorNode) getNode(
+                 "public class TestDateNegate { public function TestDateNegate() { var d:Date = new Date();var n:Number = -(d.date); } }", IUnaryOperatorNode.class, WRAP_LEVEL_PACKAGE);
+         asBlockWalker.visitUnaryOperator(node);
+         assertOut("-(d.getDate())");
+     }
+
+     @Test
+     public void testProxyMemberAccessWithEnclosingParentheses()
+     { //also with dynamic string literal access and implicit int coercion
+         IVariableNode node = (IVariableNode) getNode(
+                 "import custom.TestProxy; public class TestProxyMemberNegate { public function TestProxyMemberNegate() { var p:TestProxy = new TestProxy();var n:int = -(p['something']); } }", IUnaryOperatorNode.class, WRAP_LEVEL_PACKAGE).getParent();
+         asBlockWalker.visitVariable(node);
+         assertOut("var /** @type {number} */ n = (-(p.getProperty('something'))) >> 0");
+     }
+
     protected IBackend createBackend()
     {
         return new RoyaleBackend();