This is an automated email from the ASF dual-hosted git repository. aharui pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
commit 86bfe0a6ef8789e8ce065c856ce6f888f7562776 Author: Alex Harui <[email protected]> AuthorDate: Tue Sep 25 12:19:02 2018 -0700 fix bracket access of XML/XMLList --- .../codegen/js/jx/DynamicAccessEmitter.java | 34 +++++++++++++++++++++- .../codegen/js/royale/TestRoyaleGlobalClasses.java | 30 ++++++++++++++++++- 2 files changed, 62 insertions(+), 2 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 ae977f9..0d94fac 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 @@ -21,8 +21,12 @@ package org.apache.royale.compiler.internal.codegen.js.jx; import org.apache.royale.compiler.codegen.ISubEmitter; import org.apache.royale.compiler.codegen.js.IJSEmitter; +import org.apache.royale.compiler.definitions.ITypeDefinition; import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens; import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter; +import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter; +import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode; +import org.apache.royale.compiler.internal.tree.as.NumericLiteralNode; import org.apache.royale.compiler.tree.ASTNodeID; import org.apache.royale.compiler.tree.as.IDynamicAccessNode; import org.apache.royale.compiler.tree.as.IExpressionNode; @@ -43,11 +47,39 @@ public class DynamicAccessEmitter extends JSSubEmitter implements if (leftOperandNode.getNodeID() == ASTNodeID.Op_AtID) return; + IExpressionNode rightOperandNode = node.getRightOperandNode(); + IJSEmitter ijs = getEmitter(); + JSRoyaleEmitter fjs = (ijs instanceof JSRoyaleEmitter) ? + (JSRoyaleEmitter)ijs : null; + if (fjs != null) + { + boolean isXML = false; + if (leftOperandNode instanceof MemberAccessExpressionNode) + isXML = fjs.isLeftNodeXMLish((MemberAccessExpressionNode)leftOperandNode); + else if (leftOperandNode instanceof IExpressionNode) + isXML = fjs.isXML((IExpressionNode)leftOperandNode); + if (isXML) + { + ITypeDefinition type = rightOperandNode.resolveType(getProject()); + if (!type.isInstanceOf("int", getProject()) && !type.isInstanceOf("uint", getProject()) && !type.isInstanceOf("Number", getProject()) ) + { + String field = fjs.stringifyNode(rightOperandNode); + if (field.startsWith("\"@")) + { + field = field.replace("@", ""); + write(".attribute(" + field + ")"); + } + else + write(".child(" + field + ")"); + return; + } + } + } + startMapping(node, leftOperandNode); write(ASEmitterTokens.SQUARE_OPEN); endMapping(node); - IExpressionNode rightOperandNode = node.getRightOperandNode(); getWalker().walk(rightOperandNode); startMapping(node, rightOperandNode); 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 85b3a15..b2c8a17 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 @@ -482,7 +482,17 @@ public class TestRoyaleGlobalClasses extends TestGoogGlobalClasses asBlockWalker.visitVariable(node); assertOut("var /** @type {XMLList} */ b = a.child('child')"); } - + + @Test + public void testXMLSingleDotBracket() + { + IVariableNode node = getVariable("var a:XML = new XML(\"<top attr1='cat'><child attr2='dog'><grandchild attr3='fish'>text</grandchild></child></top>\");var b:XMLList = a[\"child\"];"); + IASNode parentNode = node.getParent(); + node = (IVariableNode) parentNode.getChild(1); + asBlockWalker.visitVariable(node); + assertOut("var /** @type {XMLList} */ b = a.child(\"child\")"); + } + @Test public void testXMLSingleDotChain() { @@ -636,6 +646,16 @@ public class TestRoyaleGlobalClasses extends TestGoogGlobalClasses } @Test + public void testXMLAttributeBracket2() + { + IVariableNode node = getVariable("var a:XML = new XML(\"<top attr1='cat'><child attr2='dog'><grandchild attr3='fish'>text</grandchild></child></top>\");var b:XMLList = a[\"@attr1\"];"); + IASNode parentNode = node.getParent(); + node = (IVariableNode) parentNode.getChild(1); + asBlockWalker.visitVariable(node); + assertOut("var /** @type {XMLList} */ b = a.attribute(\"attr1\")"); + } + + @Test public void testXMLAttributeToString() { IVariableNode node = getVariable("var a:XML = new XML(\"<top attr1='cat'><child attr2='dog'><grandchild attr3='fish'>text</grandchild></child></top>\");var b:String = a.@attr1;"); @@ -726,6 +746,14 @@ public class TestRoyaleGlobalClasses extends TestGoogGlobalClasses } @Test + public void testXMLListSetAttributeIndex() + { + IBinaryOperatorNode node = getBinaryNode("var n:int = 1;var a:XMLList;a[n].@bar = 'foo'"); + asBlockWalker.visitBinaryOperator(node); + assertOut("a[n].setAttribute('bar', 'foo')"); + } + + @Test public void testXMLListSetAttributeComplex() { IBinaryOperatorNode node = getBinaryNode("var a:XMLList;a.(@id==3).@height = '100px'");
