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);

Reply via email to