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
commit 3f76ef1ce305427f6e26f22d5d011b9706f22348 Author: Josh Tynjala <[email protected]> AuthorDate: Tue Mar 5 14:50:46 2024 -0800 RPC: arguments made with duplicate child tags are now treated as arrays Previously, the Royale compiler was setting the property multiple times instead. Using arrays more closely matches the Flex SDK compiler's behavior. --- .../mxml/MXMLHTTPServiceRequestPropertyNode.java | 63 ++++++++++++++++----- ...XMLRemoteObjectMethodArgumentsPropertyNode.java | 64 +++++++++++++++------- ...MLWebServiceOperationArgumentsPropertyNode.java | 61 ++++++++++++++++----- .../java/mxml/tags/MXMLHTTPServiceTagTests.java | 9 ++- .../java/mxml/tags/MXMLRemoteObjectTagTests.java | 9 ++- .../java/mxml/tags/MXMLWebServiceTagTests.java | 22 ++++++++ 6 files changed, 176 insertions(+), 52 deletions(-) diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java index 683b082b7..d519cc790 100644 --- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java +++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLHTTPServiceRequestPropertyNode.java @@ -19,6 +19,11 @@ package org.apache.royale.compiler.internal.tree.mxml; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.apache.royale.compiler.constants.IASLanguageConstants; import org.apache.royale.compiler.internal.projects.RoyaleProject; import org.apache.royale.compiler.mxml.IMXMLTagData; @@ -81,32 +86,60 @@ class MXMLHTTPServiceRequestPropertyNode extends MXMLPropertySpecifierNode imple MXMLNodeInfo info = createNodeInfo(builder); - // Process each child tag. + + + // look for duplicate property tags + // if there's more than one of the same tag, the value will be an array + Map<String, List<IMXMLTagData>> propertyNameToTags = new HashMap<>(); for (IMXMLUnitData unit = tag.getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit()) { if (unit instanceof IMXMLTagData) { - processChildTag(builder, tag, (IMXMLTagData) unit, info); + IMXMLTagData childTag = (IMXMLTagData) unit; + String propertyName = childTag.getShortName(); + List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName); + if (tagsForProperty == null) + { + tagsForProperty = new ArrayList<IMXMLTagData>(); + propertyNameToTags.put(propertyName, tagsForProperty); + } + tagsForProperty.add(childTag); + } + } + + // for each property found, initialize its tags + for (String propertyName : propertyNameToTags.keySet()) + { + final List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName); + final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this); + specifierNode.setDynamicName(propertyName); + if (tagsForProperty.size() > 1) + { + List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>(); + for (IMXMLTagData childTag : tagsForProperty) + { + final MXMLPropertySpecifierNode childSpecifierNode = new MXMLPropertySpecifierNode(this); + childSpecifierNode.setDynamicName(propertyName); + childSpecifierNode.initializeFromTag(builder, childTag); + argsChildNodes.add(childSpecifierNode.getInstanceNode()); + } + + MXMLArrayNode argsArrayNode = new MXMLArrayNode(objectNode); + argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0])); + specifierNode.setInstanceNode(argsArrayNode); + } + else + { + specifierNode.initializeFromTag(builder, tagsForProperty.get(0)); } + specifierNode.setParent(objectNode); + info.addChildNode(specifierNode); } // Do any final processing. initializationComplete(builder, tag, info); } - /** - * Add child tags as dynamic properties to the "object" node. - */ - @Override - protected void processChildTag(MXMLTreeBuilder builder, IMXMLTagData tag, IMXMLTagData childTag, MXMLNodeInfo info) - { - final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this); - specifierNode.setDynamicName(childTag.getShortName()); - specifierNode.initializeFromTag(builder, childTag); - specifierNode.setParent(objectNode); - info.addChildNode(specifierNode); - } - /** * Synthesize an "instance" node of type "Object" to own all the request * fields. diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java index 5a2b95d7b..52da032c7 100644 --- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java +++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLRemoteObjectMethodArgumentsPropertyNode.java @@ -19,6 +19,11 @@ package org.apache.royale.compiler.internal.tree.mxml; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.apache.royale.compiler.constants.IASLanguageConstants; import org.apache.royale.compiler.internal.projects.RoyaleProject; import org.apache.royale.compiler.mxml.IMXMLTagData; @@ -81,35 +86,56 @@ class MXMLRemoteObjectMethodArgumentsPropertyNode extends MXMLPropertySpecifierN MXMLNodeInfo info = createNodeInfo(builder); - // Process each child tag. + // look for duplicate property tags + // if there's more than one of the same tag, the value will be an array + Map<String, List<IMXMLTagData>> propertyNameToTags = new HashMap<>(); for (IMXMLUnitData unit = tag.getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit()) { if (unit instanceof IMXMLTagData) { - processChildTag(builder, tag, (IMXMLTagData) unit, info); + IMXMLTagData childTag = (IMXMLTagData) unit; + String propertyName = childTag.getShortName(); + List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName); + if (tagsForProperty == null) + { + tagsForProperty = new ArrayList<IMXMLTagData>(); + propertyNameToTags.put(propertyName, tagsForProperty); + } + tagsForProperty.add(childTag); } } - // Do any final processing. - initializationComplete(builder, tag, info); - } - - /** - * Add child tags as dynamic properties to the "object" node. - */ - @Override - protected void processChildTag(MXMLTreeBuilder builder, IMXMLTagData tag, IMXMLTagData childTag, MXMLNodeInfo info) - { - if (childTag.getPrefix() != null) + // for each property found, initialize its tags + for (String propertyName : propertyNameToTags.keySet()) { - // TODO Report a problem because a prefix means nothing. + final List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName); + final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this); + specifierNode.setDynamicName(propertyName); + if (tagsForProperty.size() > 1) + { + List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>(); + for (IMXMLTagData childTag : tagsForProperty) + { + final MXMLPropertySpecifierNode childSpecifierNode = new MXMLPropertySpecifierNode(this); + childSpecifierNode.setDynamicName(propertyName); + childSpecifierNode.initializeFromTag(builder, childTag); + argsChildNodes.add(childSpecifierNode.getInstanceNode()); + } + + MXMLArrayNode argsArrayNode = new MXMLArrayNode(objectNode); + argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0])); + specifierNode.setInstanceNode(argsArrayNode); + } + else + { + specifierNode.initializeFromTag(builder, tagsForProperty.get(0)); + } + specifierNode.setParent(objectNode); + info.addChildNode(specifierNode); } - final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this); - specifierNode.setDynamicName(childTag.getShortName()); - specifierNode.initializeFromTag(builder, childTag); - specifierNode.setParent(objectNode); - info.addChildNode(specifierNode); + // Do any final processing. + initializationComplete(builder, tag, info); } /** diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java index 81ac1c42e..e75a9d4cc 100644 --- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java +++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLWebServiceOperationArgumentsPropertyNode.java @@ -19,6 +19,11 @@ package org.apache.royale.compiler.internal.tree.mxml; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.apache.royale.compiler.constants.IASLanguageConstants; import org.apache.royale.compiler.internal.projects.RoyaleProject; import org.apache.royale.compiler.mxml.IMXMLTagData; @@ -81,32 +86,58 @@ class MXMLWebServiceOperationArgumentsPropertyNode extends MXMLPropertySpecifier MXMLNodeInfo info = createNodeInfo(builder); - // Process each child tag. + // look for duplicate property tags + // if there's more than one of the same tag, the value will be an array + Map<String, List<IMXMLTagData>> propertyNameToTags = new HashMap<>(); for (IMXMLUnitData unit = tag.getFirstChildUnit(); unit != null; unit = unit.getNextSiblingUnit()) { if (unit instanceof IMXMLTagData) { - processChildTag(builder, tag, (IMXMLTagData) unit, info); + IMXMLTagData childTag = (IMXMLTagData) unit; + String propertyName = childTag.getShortName(); + List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName); + if (tagsForProperty == null) + { + tagsForProperty = new ArrayList<IMXMLTagData>(); + propertyNameToTags.put(propertyName, tagsForProperty); + } + tagsForProperty.add(childTag); } } + // for each property found, initialize its tags + for (String propertyName : propertyNameToTags.keySet()) + { + final List<IMXMLTagData> tagsForProperty = propertyNameToTags.get(propertyName); + final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this); + specifierNode.setDynamicName(propertyName); + if (tagsForProperty.size() > 1) + { + List<IMXMLNode> argsChildNodes = new ArrayList<IMXMLNode>(); + for (IMXMLTagData childTag : tagsForProperty) + { + final MXMLPropertySpecifierNode childSpecifierNode = new MXMLPropertySpecifierNode(this); + childSpecifierNode.setDynamicName(propertyName); + childSpecifierNode.initializeFromTag(builder, childTag); + argsChildNodes.add(childSpecifierNode.getInstanceNode()); + } + + MXMLArrayNode argsArrayNode = new MXMLArrayNode(objectNode); + argsArrayNode.setChildren(argsChildNodes.toArray(new IMXMLNode[0])); + specifierNode.setInstanceNode(argsArrayNode); + } + else + { + specifierNode.initializeFromTag(builder, tagsForProperty.get(0)); + } + specifierNode.setParent(objectNode); + info.addChildNode(specifierNode); + } + // Do any final processing. initializationComplete(builder, tag, info); } - /** - * Add child tags as dynamic properties to the "object" node. - */ - @Override - protected void processChildTag(MXMLTreeBuilder builder, IMXMLTagData tag, IMXMLTagData childTag, MXMLNodeInfo info) - { - final MXMLPropertySpecifierNode specifierNode = new MXMLPropertySpecifierNode(this); - specifierNode.setDynamicName(childTag.getShortName()); - specifierNode.initializeFromTag(builder, childTag); - specifierNode.setParent(objectNode); - info.addChildNode(specifierNode); - } - /** * Synthesize an "instance" node of type "Object" to own all the arguments * fields. diff --git a/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java b/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java index 98c7ac20b..4984a15b2 100644 --- a/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java +++ b/compiler/src/test/java/mxml/tags/MXMLHTTPServiceTagTests.java @@ -95,7 +95,9 @@ public class MXMLHTTPServiceTagTests extends MXMLInstanceTagTestsBase " <a>abc</a>", " <b>123</b>", " <c>false</c>", - // " <d><d1>456.7</d1></d>", + " <d>456.7</d>", + " <d>hello</d>", + " <d>true</d>", " </mx:request>", " <mx:method>POST</mx:method>", "</mx:HTTPService>" @@ -107,7 +109,10 @@ public class MXMLHTTPServiceTagTests extends MXMLInstanceTagTestsBase "assertEqual('hs1.request.a', hs1.request['a'], 'abc');", "assertEqual('hs1.request.b', hs1.request['b'], 123);", "assertEqual('hs1.request.c', hs1.request['c'], false);", - // "assertEqual('hs1.request.d.d1', hs1.request['d']['d1'], 456.7);", + "assertEqual('hs1.request.d.length', hs1.request['d'].length, 3);", + "assertEqual('hs1.request.d[0]', hs1.request['d'][0], 456.7);", + "assertEqual('hs1.request.d[1]', hs1.request['d'][1], 'hello');", + "assertEqual('hs1.request.d[2]', hs1.request['d'][2], true);", "assertEqual('hs1.method', hs1.method, 'POST');" }; String mxml = getMXML(declarations, asserts); diff --git a/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java b/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java index 400b26d50..4cb616e2f 100644 --- a/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java +++ b/compiler/src/test/java/mxml/tags/MXMLRemoteObjectTagTests.java @@ -124,6 +124,9 @@ public class MXMLRemoteObjectTagTests extends MXMLInstanceTagTestsBase " <a>abc</a>", " <b>123</b>", " <c>false</c>", + " <d>456.7</d>", + " <d>hello</d>", + " <d>true</d>", " </mx:arguments>", " </mx:method>", "</mx:RemoteObject>" @@ -137,13 +140,17 @@ public class MXMLRemoteObjectTagTests extends MXMLInstanceTagTestsBase "assertEqual('ro1 is RemoteObject', ro1 is RemoteObject, true);", "assertEqual('ro1.operations.m1', ro1.operations['m1'] is Operation, true);", "assertEqual('ro1.operations.m1.name', ro1.operations['m1'].name, 'm1');", - "assertEqual('ro1.operations.m1.argumentNames.length', ro1.operations['m1'].argumentNames.length, 3);", + "assertEqual('ro1.operations.m1.argumentNames.length', ro1.operations['m1'].argumentNames.length, 4);", "assertEqual('ro1.operations.m1.argumentNames[0]', ro1.operations['m1'].argumentNames[0], 'a');", "assertEqual('ro1.operations.m1.argumentNames[1]', ro1.operations['m1'].argumentNames[1], 'b');", "assertEqual('ro1.operations.m1.argumentNames[1]', ro1.operations['m1'].argumentNames[2], 'c');", "assertEqual('ro1.operations.m1.arguments.a', ro1.operations['m1'].arguments['a'], 'abc');", "assertEqual('ro1.operations.m1.arguments.b', ro1.operations['m1'].arguments['b'], 123);", "assertEqual('ro1.operations.m1.arguments.c', ro1.operations['m1'].arguments['c'], false);", + "assertEqual('ro1.operations.m1.arguments.d.length', ro1.operations['m1'].arguments['d'].length, 3);", + "assertEqual('ro1.operations.m1.arguments.d[0]', ro1.operations['m1'].arguments['d'][0], 456.7);", + "assertEqual('ro1.operations.m1.arguments.d[1]', ro1.operations['m1'].arguments['d'][1], 'hello');", + "assertEqual('ro1.operations.m1.arguments.d[2]', ro1.operations['m1'].arguments['d'][2], true);", }; String mxml = getMXML(declarations, scriptDeclarations, asserts); compileAndRun(mxml, true, true, false, null); diff --git a/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java b/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java index 69b680b31..16ce452ee 100644 --- a/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java +++ b/compiler/src/test/java/mxml/tags/MXMLWebServiceTagTests.java @@ -146,6 +146,9 @@ public class MXMLWebServiceTagTests extends MXMLInstanceTagTestsBase " <a>abc</a>", " <b>123</b>", " <c>false</c>", + " <d>456.7</d>", + " <d>hello</d>", + " <d>true</d>", " </mx:arguments>", " </mx:operation>", "</mx:WebService>" @@ -162,9 +165,17 @@ public class MXMLWebServiceTagTests extends MXMLInstanceTagTestsBase "assertEqual('ws1.operations.op1.arguments.a', ws1.operations['op1'].arguments['a'], 'abc');", "assertEqual('ws1.operations.op1.arguments.b', ws1.operations['op1'].arguments['b'], 123);", "assertEqual('ws1.operations.op1.arguments.c', ws1.operations['op1'].arguments['c'], false);", + "assertEqual('ws1.operations.op1.arguments.d.length', ws1.operations['op1'].arguments['d'].length, 3);", + "assertEqual('ws1.operations.op1.arguments.d[0]', ws1.operations['op1'].arguments['d'][0], 456.7);", + "assertEqual('ws1.operations.op1.arguments.d[1]', ws1.operations['op1'].arguments['d'][1], 'hello');", + "assertEqual('ws1.operations.op1.arguments.d[2]', ws1.operations['op1'].arguments['d'][2], true);", "assertEqual('ws1.operations.op1.request.a', ws1.operations['op1'].request['a'], 'abc');", "assertEqual('ws1.operations.op1.request.b', ws1.operations['op1'].request['b'], 123);", "assertEqual('ws1.operations.op1.request.c', ws1.operations['op1'].request['c'], false);", + "assertEqual('ws1.operations.op1.request.d.length', ws1.operations['op1'].request['d'].length, 3);", + "assertEqual('ws1.operations.op1.request.d[0]', ws1.operations['op1'].request['d'][0], 456.7);", + "assertEqual('ws1.operations.op1.request.d[1]', ws1.operations['op1'].request['d'][1], 'hello');", + "assertEqual('ws1.operations.op1.request.d[2]', ws1.operations['op1'].request['d'][2], true);", }; String mxml = getMXML(declarations, scriptDeclarations, asserts); compileAndRun(mxml, true, true, false, null); @@ -181,6 +192,9 @@ public class MXMLWebServiceTagTests extends MXMLInstanceTagTestsBase " <a>abc</a>", " <b>123</b>", " <c>false</c>", + " <d>456.7</d>", + " <d>hello</d>", + " <d>true</d>", " </mx:request>", " </mx:operation>", "</mx:WebService>" @@ -197,9 +211,17 @@ public class MXMLWebServiceTagTests extends MXMLInstanceTagTestsBase "assertEqual('ws1.operations.op1.arguments.a', ws1.operations['op1'].arguments['a'], 'abc');", "assertEqual('ws1.operations.op1.arguments.b', ws1.operations['op1'].arguments['b'], 123);", "assertEqual('ws1.operations.op1.arguments.c', ws1.operations['op1'].arguments['c'], false);", + "assertEqual('ws1.operations.op1.arguments.d.length', ws1.operations['op1'].arguments['d'].length, 3);", + "assertEqual('ws1.operations.op1.arguments.d[0]', ws1.operations['op1'].arguments['d'][0], 456.7);", + "assertEqual('ws1.operations.op1.arguments.d[1]', ws1.operations['op1'].arguments['d'][1], 'hello');", + "assertEqual('ws1.operations.op1.arguments.d[2]', ws1.operations['op1'].arguments['d'][2], true);", "assertEqual('ws1.operations.op1.request.a', ws1.operations['op1'].request['a'], 'abc');", "assertEqual('ws1.operations.op1.request.b', ws1.operations['op1'].request['b'], 123);", "assertEqual('ws1.operations.op1.request.c', ws1.operations['op1'].request['c'], false);", + "assertEqual('ws1.operations.op1.request.d.length', ws1.operations['op1'].request['d'].length, 3);", + "assertEqual('ws1.operations.op1.request.d[0]', ws1.operations['op1'].request['d'][0], 456.7);", + "assertEqual('ws1.operations.op1.request.d[1]', ws1.operations['op1'].request['d'][1], 'hello');", + "assertEqual('ws1.operations.op1.request.d[2]', ws1.operations['op1'].request['d'][2], true);", }; String mxml = getMXML(declarations, scriptDeclarations, asserts); compileAndRun(mxml, true, true, false, null);
