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 2020/04/02 09:50:42 UTC
[royale-compiler] 07/08: Additions to XML and XML list to support
more e4X conformance. Aligned with framework classes (extra unit tests)
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
commit 4c1b2f4aa1b11b58cad648c912ac633ebecf0590
Author: greg-dove <gr...@gmail.com>
AuthorDate: Thu Apr 2 22:38:12 2020 +1300
Additions to XML and XML list to support more e4X conformance. Aligned with framework classes (extra unit tests)
---
.../codegen/js/jx/BinaryOperatorEmitter.java | 40 ++++++++++++++++------
.../codegen/js/jx/DynamicAccessEmitter.java | 2 +-
.../internal/codegen/js/jx/ForEachEmitter.java | 2 +-
.../codegen/js/jx/MemberAccessEmitter.java | 2 +-
.../codegen/js/royale/JSRoyaleEmitter.java | 23 +++++++++----
.../internal/codegen/js/utils/EmitterUtils.java | 12 ++++---
.../codegen/js/royale/TestRoyaleGlobalClasses.java | 2 +-
7 files changed, 57 insertions(+), 26 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 2aa2e77..2138d61 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
@@ -192,19 +192,35 @@ public class BinaryOperatorEmitter extends JSSubEmitter implements
MemberAccessExpressionNode xmlNode = (MemberAccessExpressionNode)leftSide;
if (node.getNodeID() == ASTNodeID.Op_AssignId)
{
+ boolean wrapQuotes = true;
getWalker().walk(xmlNode.getLeftOperandNode());
IExpressionNode rightSide = xmlNode.getRightOperandNode();
if (rightSide instanceof UnaryOperatorAtNode)
{
write(".setAttribute('");
- getWalker().walk(((UnaryOperatorAtNode)rightSide).getChild(0));
+ getWalker().walk(rightSide.getChild(0));
}
+ else if (rightSide instanceof IDynamicAccessNode && ((IDynamicAccessNode) rightSide).getLeftOperandNode().getNodeID() == ASTNodeID.Op_AtID) {
+ write(".setAttribute(");
+ wrapQuotes = false;
+ getWalker().walk(((IDynamicAccessNode)rightSide).getRightOperandNode());
+ }
+ else if (rightSide instanceof INamespaceAccessExpressionNode) {
+ write(".setChild(");
+ write("new QName(");
+ getWalker().walk(((INamespaceAccessExpressionNode) rightSide).getLeftOperandNode());
+ write(",'");
+ getWalker().walk(((INamespaceAccessExpressionNode) rightSide).getRightOperandNode());
+ write("')");
+ wrapQuotes = false;
+ }
else
{
write(".setChild('");
getWalker().walk(rightSide);
}
- write("', ");
+ if (wrapQuotes) write("'");
+ write(", ");
getWalker().walk(node.getRightOperandNode());
write(ASEmitterTokens.PAREN_CLOSE);
return;
@@ -240,7 +256,7 @@ public class BinaryOperatorEmitter extends JSSubEmitter implements
return;
}
}
- else if (isDynamicAccess && ((JSRoyaleEmitter)getEmitter()).isXML((IExpressionNode)lnode))
+ else if (isDynamicAccess && ((JSRoyaleEmitter)getEmitter()).isXMLish((IExpressionNode)lnode))
{
DynamicAccessNode dyn = (DynamicAccessNode)rnode;
ITypeDefinition type = dyn.getRightOperandNode().resolveType(getProject());
@@ -368,7 +384,7 @@ public class BinaryOperatorEmitter extends JSSubEmitter implements
DynamicAccessNode dyn = (DynamicAccessNode)leftSide;
IExpressionNode dynLeft = dyn.getLeftOperandNode();
ITypeDefinition type = dyn.getRightOperandNode().resolveType(getProject());
- if (((JSRoyaleEmitter)getEmitter()).isXML(dynLeft) && type.isInstanceOf("String", getProject()))
+ if (((JSRoyaleEmitter)getEmitter()).isXMLish(dynLeft)/* && !SemanticUtils.isNumericType(type, getProject())*/) //type.isInstanceOf("String", getProject())
{
String field;
if (node.getNodeID() == ASTNodeID.Op_AssignId)
@@ -377,17 +393,19 @@ public class BinaryOperatorEmitter extends JSSubEmitter implements
IExpressionNode rightSide = dyn.getRightOperandNode();
if (rightSide instanceof UnaryOperatorAtNode)
{
- write(".setAttribute('");
- field = fjs.stringifyNode(((UnaryOperatorAtNode)rightSide).getChild(0));
- field = field.replace("\"", ""); // remove wrapping double-quotes
+ write(".setAttribute(");
+ field = fjs.stringifyNode((rightSide).getChild(0));
}
else
{
- write(".setChild('");
+ write(".setChild(");
field = fjs.stringifyNode(rightSide);
- field = field.replace("\"", ""); // remove wrapping double-quotes
}
- write(field + "', ");
+ if (field.startsWith("\"") && field.endsWith("\"")) {
+ // remove wrapping double-quotes and swap to single quotes
+ field = "'" + field.substring(1, field.length() - 1) + "'";
+ }
+ write(field + ", ");
getWalker().walk(node.getRightOperandNode());
write(ASEmitterTokens.PAREN_CLOSE);
return;
@@ -576,7 +594,7 @@ public class BinaryOperatorEmitter extends JSSubEmitter implements
getWalker().walk(node.getRightOperandNode());
if (node.getNodeID() == ASTNodeID.Op_InID &&
- ((JSRoyaleEmitter)getEmitter()).isXML(node.getRightOperandNode()))
+ ((JSRoyaleEmitter)getEmitter()).isXMLish(node.getRightOperandNode()))
{
write(".elementNames()");
}
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 bdcb9c6..878b69a 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
@@ -72,7 +72,7 @@ public class DynamicAccessEmitter extends JSSubEmitter implements
if (leftOperandNode instanceof MemberAccessExpressionNode)
isXML = fjs.isLeftNodeXMLish((MemberAccessExpressionNode)leftOperandNode);
else if (leftOperandNode instanceof IExpressionNode)
- isXML = fjs.isXML((IExpressionNode)leftOperandNode);
+ isXML = fjs.isXMLish((IExpressionNode)leftOperandNode);
if (leftOperandNode instanceof MemberAccessExpressionNode)
isProxy = fjs.isProxy((MemberAccessExpressionNode)leftOperandNode);
else if (leftOperandNode instanceof IExpressionNode)
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 2994707..4920604 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
@@ -104,7 +104,7 @@ public class ForEachEmitter extends JSSubEmitter implements
boolean isProxy = false;
if (obj.getNodeID() == ASTNodeID.IdentifierID)
{
- if (((JSRoyaleEmitter)getEmitter()).isXML((IdentifierNode)obj))
+ if (((JSRoyaleEmitter)getEmitter()).isXMLish((IdentifierNode)obj))
{
write(".elementNames()");
isXML = true;
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 51d45b5..274cd4f 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
@@ -108,7 +108,7 @@ public class MemberAccessEmitter extends JSSubEmitter implements
if (leftNode instanceof MemberAccessExpressionNode)
isXML = fjs.isLeftNodeXMLish(leftNode);
else if (leftNode != null)
- isXML = fjs.isXML(leftNode);
+ isXML = fjs.isXMLish(leftNode);
if (!isXML) {
if (leftNode instanceof MemberAccessExpressionNode)
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
index 0a05318..0626e79 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java
@@ -709,7 +709,7 @@ public class JSRoyaleEmitter extends JSGoogEmitter implements IJSRoyaleEmitter
{
if (getModel().inStaticInitializer)
if (!staticUsedNames.contains(name) && !NativeUtils.isJSNative(name)
- && isGoogProvided(name) && !getModel().getCurrentClass().getQualifiedName().equals(name)
+ && isGoogProvided(name) && (getModel().getCurrentClass() == null || !getModel().getCurrentClass().getQualifiedName().equals(name))
&& (getModel().primaryDefinitionQName == null
|| !getModel().primaryDefinitionQName.equals(name)))
staticUsedNames.add(name);
@@ -1245,7 +1245,7 @@ public class JSRoyaleEmitter extends JSGoogEmitter implements IJSRoyaleEmitter
}
else if (node.getChild(0).getChild(0).getNodeID() == ASTNodeID.IdentifierID)
{
- if (isXML((IdentifierNode)(node.getChild(0).getChild(0))))
+ if (isXMLish((IdentifierNode)(node.getChild(0).getChild(0))))
{
if (ASNodeUtils.hasParenOpen(node))
write(ASEmitterTokens.PAREN_OPEN);
@@ -1288,13 +1288,15 @@ public class JSRoyaleEmitter extends JSGoogEmitter implements IJSRoyaleEmitter
IExpressionNode rightNode = obj.getRightOperandNode();
String s = stringifyNode(obj.getLeftOperandNode());
- boolean needsQuotes = rightNode.getNodeID() != ASTNodeID.Op_AtID;
+ boolean avoidMethodAccess = (rightNode instanceof IDynamicAccessNode && ((IDynamicAccessNode) rightNode).getLeftOperandNode().getNodeID() == ASTNodeID.Op_AtID);
+ boolean needsQuotes = rightNode.getNodeID() != ASTNodeID.Op_AtID
+ && !avoidMethodAccess;
write(s);
write(".removeChild(");
if (needsQuotes)
write("'");
else
- write(s + ".");
+ if (!avoidMethodAccess) write(s + ".");
s = stringifyNode(rightNode);
write(s);
if (needsQuotes)
@@ -1353,6 +1355,15 @@ public class JSRoyaleEmitter extends JSGoogEmitter implements IJSRoyaleEmitter
DynamicAccessNode parentNode = (DynamicAccessNode)node.getParent();
if (EmitterUtils.writeE4xFilterNode(getWalker().getProject(), getModel(), node))
write("node.");
+ if (node.getParent().getParent() != null
+ && node.getParent().getParent().getParent() != null
+ && node.getParent().getParent().getParent().getNodeID() == ASTNodeID.Op_DeleteID) {
+ write ("'@' + ");
+ //example : delete myXML.@[MyConst];
+ //output myXML.removeChild('@' + MyConst) <-- variant is handled in emulation class
+ getWalker().walk(parentNode.getRightOperandNode());
+ return;
+ }
write("attribute(");
getWalker().walk(parentNode.getRightOperandNode());
write(")");
@@ -1474,9 +1485,9 @@ public class JSRoyaleEmitter extends JSGoogEmitter implements IJSRoyaleEmitter
* @param obj
* @return
*/
- public boolean isXML(IExpressionNode obj)
+ public boolean isXMLish(IExpressionNode obj)
{
- return EmitterUtils.isXML(obj, getWalker().getProject());
+ return EmitterUtils.isXMLish(obj, getWalker().getProject());
}
public MemberAccessExpressionNode getLastMAEInChain(MemberAccessExpressionNode node)
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java
index 2e03bf2..0be6c74 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/utils/EmitterUtils.java
@@ -751,16 +751,16 @@ public class EmitterUtils
* @param obj
* @return
*/
- public static boolean isXML(IExpressionNode obj, ICompilerProject project )
+ public static boolean isXMLish(IExpressionNode obj, ICompilerProject project )
{
// See if the left side is XML or XMLList
IDefinition leftDef = obj.resolveType(project);
if (leftDef == null && obj.getNodeID() == ASTNodeID.MemberAccessExpressionID)
{
- return isXML(((MemberAccessExpressionNode)obj).getLeftOperandNode(), project);
+ return isXMLish(((MemberAccessExpressionNode)obj).getLeftOperandNode(), project);
}
else if (leftDef != null && leftDef.getBaseName().equals("*") && obj instanceof DynamicAccessNode) {
- return isXML(((DynamicAccessNode)obj).getLeftOperandNode(), project);
+ return isXMLish(((DynamicAccessNode)obj).getLeftOperandNode(), project);
}
return SemanticUtils.isXMLish(leftDef, project);
}
@@ -785,7 +785,7 @@ public class EmitterUtils
IExpressionNode leftNode = obj.getLeftOperandNode();
IExpressionNode rightNode = obj.getRightOperandNode();
ASTNodeID rightID = rightNode.getNodeID();
- if (rightID == ASTNodeID.IdentifierID)
+ if (rightID == ASTNodeID.IdentifierID || (rightID == ASTNodeID.NamespaceAccessExpressionID && rightNode.getChild(1).getNodeID() == ASTNodeID.IdentifierID))
{
IDefinition rightDef = rightNode.resolveType(project);
if (rightDef != null)
@@ -800,6 +800,8 @@ public class EmitterUtils
}
else if (rightID == ASTNodeID.Op_AtID)
return true;
+ else if (rightNode instanceof IDynamicAccessNode && ((IDynamicAccessNode) rightNode).getLeftOperandNode().getNodeID() == ASTNodeID.Op_AtID)
+ return true;
return false;
}
@@ -904,7 +906,7 @@ public class EmitterUtils
boolean isXML = leftNode instanceof MemberAccessExpressionNode
&& isLeftNodeXMLish((MemberAccessExpressionNode) leftNode, project);
if (!isXML) {
- isXML = leftNode instanceof IExpressionNode && isXML((IExpressionNode)leftNode, project);
+ isXML = leftNode instanceof IExpressionNode && isXMLish((IExpressionNode)leftNode, project);
}
if (isXML) {
//check argumentsNode
diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java
index d090658..bae6cd4 100644
--- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java
+++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleGlobalClasses.java
@@ -1098,7 +1098,7 @@ public class TestRoyaleGlobalClasses extends TestGoogGlobalClasses
{
IBinaryOperatorNode node = (IBinaryOperatorNode)getNode("var a:XMLList = new XMLList();a[a.length()] = <foo/>;a[a.length()] = <baz/>;", IBinaryOperatorNode.class);
asBlockWalker.visitBinaryOperator(node);
- assertOut("a[a.length()] = new XML( '<foo/>')");
+ assertOut("a.setChild(a.length(), new XML( '<foo/>'))");
}
@Test