You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ah...@apache.org on 2019/11/07 21:56:49 UTC
[royale-compiler] 01/02: fix binding in fx:XMLList. Fixes
apache/royale-asjs#545
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 2b518588cd79db84a5c96e2bbd177227e52cec4e
Author: Alex Harui <ah...@apache.org>
AuthorDate: Wed Nov 6 17:11:56 2019 -0800
fix binding in fx:XMLList. Fixes apache/royale-asjs#545
---
.../codegen/mxml/royale/MXMLRoyaleEmitter.java | 98 ++++++++++++++++++----
.../as/codegen/MXMLClassDirectiveProcessor.java | 4 +
.../internal/tree/mxml/MXMLXMLListNode.java | 22 ++++-
.../compiler/internal/tree/mxml/XMLBuilder.java | 4 +-
4 files changed, 110 insertions(+), 18 deletions(-)
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
index 67ca0cd..7e9747f 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
@@ -35,9 +35,13 @@ import java.util.Set;
import java.util.Stack;
import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.royale.abc.ABCConstants;
+import org.apache.royale.abc.instructionlist.InstructionList;
+import org.apache.royale.abc.semantics.Instruction;
import org.apache.royale.abc.semantics.MethodInfo;
import org.apache.royale.abc.semantics.Name;
import org.apache.royale.abc.semantics.Namespace;
+import org.apache.royale.abc.semantics.OneOperandInstruction;
import org.apache.royale.compiler.codegen.as.IASEmitter;
import org.apache.royale.compiler.codegen.js.IJSEmitter;
import org.apache.royale.compiler.codegen.js.IMappingEmitter;
@@ -1673,28 +1677,90 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements
parentNode = parentNode.getParent();
}
boolean isXML = parentNode instanceof IMXMLXMLNode;
+ boolean isXMLList = parentNode instanceof IMXMLXMLListNode;
+ String effectiveID = ((IMXMLInstanceNode)parentNode).getEffectiveID();
sb.append("this.");
- sb.append(((IMXMLInstanceNode)parentNode).getEffectiveID());
- while (nodeStack.size() > 0)
+ sb.append(effectiveID);
+ // at least for one XMLList case, we could not trust
+ // the nodestack as children were only binding nodes
+ // and not preceding XML nodes
+ if (isXMLList)
{
- IASNode childNode = nodeStack.pop();
- int n = parentNode.getChildCount();
- int i = 0;
- for (; i < n; i++)
+ // re-interpret the instruction list.
+ // it would not be a surprise of the non-XMLList cases will
+ // eventually require this code path
+ InstructionListNode ilNode = (InstructionListNode)destNode.getExpressionNode();
+ InstructionList il = ilNode.getInstructions();
+ ArrayList<Instruction> abcs = il.getInstructions();
+ int n = abcs.size();
+ for (int i = 0; i < n; i++)
{
- if (childNode == parentNode.getChild(i))
- break;
- }
- assert i < n;
- sb.append("[" + new Integer(i).toString() + "]" );
- parentNode = childNode;
+ Instruction inst = abcs.get(i);
+ int opCode = inst.getOpcode();
+ if (opCode == ABCConstants.OP_getlocal0)
+ {
+ if (i > 0)
+ System.out.println("unexpected getLocal0 in binding expression");
+ }
+ else if (opCode == ABCConstants.OP_getproperty)
+ {
+ OneOperandInstruction getProp = (OneOperandInstruction)inst;
+ Name propName = (Name)getProp.getOperand(0);
+ if (i == 0)
+ System.out.println("unexpected opcode in binding expression");
+ else if (i == 1 && !propName.getBaseName().contentEquals(effectiveID))
+ System.out.println("unexpected effectiveID in binding expression");
+ else if (i > 1)
+ {
+ try
+ {
+ Integer.parseInt(propName.getBaseName());
+ sb.append("[" + propName.getBaseName() + "]" );
+ } catch (NumberFormatException ex)
+ {
+ sb.append(".elements(" + propName.getBaseName() + ")" );
+ }
+ }
+ }
+ else if (opCode == ABCConstants.OP_getlocal1)
+ {
+ if (i != n - 3)
+ System.out.println("unexpected getLocal1 in binding expression");
+ }
+ else if (opCode == ABCConstants.OP_setproperty)
+ {
+ if (i != n - 2)
+ System.out.println("unexpected setProperty in binding expression");
+ OneOperandInstruction setProp = (OneOperandInstruction)inst;
+ Name propName = (Name)setProp.getOperand(0);
+ if (!propName.getBaseName().contentEquals(destNode.getName()))
+ System.out.println("unexpected setProperty name in binding expression");
+ break; // exit loop
+ }
+ }
+ sb.append(".setAttribute('" + destNode.getName() + "', value);" );
}
- if (isXML)
+ else
{
- sb.append(".setAttribute('" + destNode.getName() + "', value);" );
+ while (nodeStack.size() > 0)
+ {
+ IASNode childNode = nodeStack.pop();
+ int n = parentNode.getChildCount();
+ int i = 0;
+ for (; i < n; i++)
+ {
+ if (childNode == parentNode.getChild(i))
+ break;
+ }
+ assert i < n;
+ sb.append("[" + new Integer(i).toString() + "]" );
+ parentNode = childNode;
+ }
+ if (isXML)
+ sb.append(".setAttribute('" + destNode.getName() + "', value);" );
+ else
+ sb.append("." + destNode.getName() + " = value;");
}
- else
- sb.append("." + destNode.getName() + " = value;");
return sb.toString();
}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
index 01adf85..a0a97ac 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/as/codegen/MXMLClassDirectiveProcessor.java
@@ -5019,6 +5019,10 @@ public class MXMLClassDirectiveProcessor extends ClassDirectiveProcessor
context.addInstruction(OP_findpropstrict, ABCGeneratingReducer.xmlListType);
context.addInstruction(OP_pushstring, node.getXMLString());
context.addInstruction(OP_constructprop, CONSTRUCT_XML_LIST_OPERANDS);
+
+ // Traverse the children - these will be any MXMLBindingNode that were created for
+ // databinding expressions inside the XML
+ traverse(node, context);
}
/**
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLXMLListNode.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLXMLListNode.java
index 4e3fdb4..6764a36 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLXMLListNode.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/MXMLXMLListNode.java
@@ -25,10 +25,13 @@ import org.apache.royale.compiler.mxml.IMXMLTagData;
import org.apache.royale.compiler.mxml.IMXMLTextData;
import org.apache.royale.compiler.problems.MXMLXMLListMixedContentProblem;
import org.apache.royale.compiler.tree.ASTNodeID;
+import org.apache.royale.compiler.tree.mxml.IMXMLBindingNode;
+import org.apache.royale.compiler.tree.mxml.IMXMLNode;
import org.apache.royale.compiler.tree.mxml.IMXMLXMLListNode;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.List;
/**
* Implementation of the {@code IMXMLXMLListNode} interface.
@@ -54,6 +57,8 @@ class MXMLXMLListNode extends MXMLInstanceNode implements IMXMLXMLListNode
private ArrayList<IMXMLTagData> childTags = new ArrayList<IMXMLTagData>();
private String xmlString;
+
+ private List<IMXMLBindingNode> bindings = new ArrayList<IMXMLBindingNode>();
@Override
public ASTNodeID getNodeID()
@@ -106,6 +111,17 @@ class MXMLXMLListNode extends MXMLInstanceNode implements IMXMLXMLListNode
super.initializationComplete(builder, tag, info);
+ if (bindings.size() > 0)
+ {
+ int childCount = getChildCount();
+ List<IMXMLNode> children = new ArrayList<IMXMLNode>();
+ for (int i = 0; i < childCount; i++)
+ {
+ children.add((IMXMLNode)getChild(i));
+ }
+ children.addAll(bindings);
+ setChildren(children.toArray(new IMXMLNode[] {}));
+ }
// don't pin the MXMLTagDatas
childTags = null;
}
@@ -115,7 +131,11 @@ class MXMLXMLListNode extends MXMLInstanceNode implements IMXMLXMLListNode
StringWriter sw = new StringWriter();
for (IMXMLTagData tag : childTags)
{
- new XMLBuilder(this, tag, tag.getCompositePrefixMap(), builder).processNode(tag, sw);
+ IMXMLTagData parentTagData = tag.getParentTag();
+ XMLBuilder xmlBuilder = new XMLBuilder(this, parentTagData, tag.getCompositePrefixMap(), builder);
+ xmlBuilder.processNode(tag, sw);
+ List<IMXMLBindingNode> bindings = xmlBuilder.getDatabindings();
+ this.bindings.addAll(bindings);
}
xmlString = sw.toString();
}
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java
index b428289..9b96951 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/tree/mxml/XMLBuilder.java
@@ -444,7 +444,9 @@ class XMLBuilder
}
else
{
- il.addInstruction(ABCConstants.OP_getproperty, getNameForTag(tag));
+ String rootTagName = rootTag.getName();
+ if (!rootTagName.contentEquals("fx:XMLList"))
+ il.addInstruction(ABCConstants.OP_getproperty, getNameForTag(tag));
int index = getIndexOfTag(tag);
il.addInstruction(ABCConstants.OP_getproperty, new Name(String.valueOf(index)));
}