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
The following commit(s) were added to refs/heads/develop by this push:
new 09340cb handle primitive types in fx:Declarations. The primitive
types expect a different instantiation lifecycle. XML and XMLList have a
constructor parameter, for example.
09340cb is described below
commit 09340cbcb8b8ae5cd34d08ab8dd0169cd231ac26
Author: Alex Harui <[email protected]>
AuthorDate: Tue Sep 25 10:13:22 2018 -0700
handle primitive types in fx:Declarations. The primitive types expect a
different instantiation lifecycle. XML and XMLList have a constructor
parameter, for example.
---
.../codegen/mxml/royale/MXMLRoyaleEmitter.java | 178 +++++++-
.../mxml/royale/TestRoyaleMXMLApplication.java | 483 +++++++++++++++++++++
.../royale/compiler/tree/mxml/IMXMLXMLNode.java | 2 +-
3 files changed, 657 insertions(+), 6 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 cd76d61..75de94d 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
@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import org.apache.commons.lang.StringEscapeUtils;
import org.apache.royale.abc.semantics.MethodInfo;
import org.apache.royale.abc.semantics.Name;
import org.apache.royale.abc.semantics.Namespace;
@@ -53,10 +54,12 @@ import
org.apache.royale.compiler.internal.codegen.databinding.StaticPropertyWat
import org.apache.royale.compiler.internal.codegen.databinding.WatcherInfoBase;
import
org.apache.royale.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType;
import org.apache.royale.compiler.internal.codegen.databinding.XMLWatcherInfo;
+import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
import
org.apache.royale.compiler.internal.codegen.js.JSSessionModel.PropertyNodes;
import
org.apache.royale.compiler.internal.codegen.js.JSSessionModel.BindableVarInfo;
import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
import
org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
+import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.jx.BindableEmitter;
import org.apache.royale.compiler.internal.codegen.js.jx.PackageFooterEmitter;
@@ -112,6 +115,8 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
private ArrayList<String> usedNames = new ArrayList<String>();
private ArrayList<String> staticUsedNames = new ArrayList<String>();
private ArrayList<IMXMLMetadataNode> metadataNodes = new
ArrayList<IMXMLMetadataNode>();
+ // separately track all fx:Declarations that are primitive types
(fx:String, fx:Array)
+ private ArrayList<IMXMLInstanceNode> primitiveDeclarationNodes = new
ArrayList<IMXMLInstanceNode>();
private int eventCounter;
private int idCounter;
@@ -624,6 +629,8 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
emitClassDeclEnd(cname, node.getBaseClassName());
+ emitDeclarationVariables();
+
// emitMetaData(cdef);
write(subDocuments.toString());
@@ -646,6 +653,27 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
emitSourceMapDirective(node);
}
+
+ public void emitDeclarationVariables()
+ {
+ for (IMXMLInstanceNode node : primitiveDeclarationNodes)
+ {
+ String id = node.getEffectiveID();
+ writeNewline();
+ writeNewline("/**");
+ writeNewline(" * @export");
+ writeNewline(" * @type {" +
JSGoogDocEmitter.convertASTypeToJSType(formatQualifiedName(node.getName()), "")
+ "}");
+ writeNewline(" */");
+ String cname = node.getFileNode().getName();
+ write(cname);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(JSEmitterTokens.PROTOTYPE);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(id);
+ writeNewline(ASEmitterTokens.SEMICOLON);
+
+ }
+ }
public void emitSubDocument(IMXMLComponentNode node)
{
@@ -940,7 +968,16 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
if (fjs.config != null)
exportMetadata = fjs.config.getCompilerKeepCodeWithMetadata();
ArrayList<PackageFooterEmitter.VariableData> varData = new
ArrayList<PackageFooterEmitter.VariableData>();
- // vars can only come from script blocks?
+ // vars can only come from script blocks and decls?
+ for (IMXMLInstanceNode declNode : primitiveDeclarationNodes)
+ {
+ PackageFooterEmitter.VariableData data =
asEmitter.packageFooterEmitter.new VariableData();
+ varData.add(data);
+ data.name = declNode.getEffectiveID();
+ data.isStatic = false;
+ String qualifiedTypeName = declNode.getName();
+ data.type = (qualifiedTypeName);
+ }
List<IVariableNode> vars = asEmitter.getModel().getVars();
for (IVariableNode varNode : vars)
{
@@ -1669,7 +1706,8 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
n++;
}
}
- if (n == 0 && descriptorTree.size() == 0)
+ if (n == 0 && (descriptorTree.size() == 0 ||
+ descriptorTree.size() == 1 &&
descriptorTree.get(0).propertySpecifiers.size() == 0))
return;
String formattedCName = formatQualifiedName(cname);
@@ -1729,6 +1767,8 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
RoyaleJSProject project = (RoyaleJSProject)
getMXMLWalker().getProject();
project.needLanguage = true;
MXMLDescriptorSpecifier root = descriptorTree.get(0);
+ if (root.propertySpecifiers.size() == 0)
+ return; // all declarations were primitives
root.isTopNode = false;
collectExportedNames(root);
@@ -1848,6 +1888,14 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
if (isStateDependent(node) && !inStatesOverride)
return;
+ ASTNodeID nodeID = node.getNodeID();
+ if ((nodeID == ASTNodeID.MXMLXMLID || nodeID ==
ASTNodeID.MXMLXMLListID) &&
+ node.getParent().getNodeID() ==
ASTNodeID.MXMLDeclarationsID)
+ {
+ primitiveDeclarationNodes.add(node);
+ return;
+ }
+
IClassDefinition cdef = node
.getClassReference((ICompilerProject) getMXMLWalker()
.getProject());
@@ -2458,10 +2506,9 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
@Override
public void emitArray(IMXMLArrayNode node)
{
- if (node.getParent() instanceof IMXMLDeclarationsNode)
+ if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
{
- // treat this like an instance. fx:Array at the top level of a
Declaration defines a new property with a structure
- emitInstance(node);
+ primitiveDeclarationNodes.add(node);
return;
}
moveDown(false, null, null);
@@ -2503,6 +2550,11 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
@Override
public void emitString(IMXMLStringNode node)
{
+ if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID)
+ {
+ primitiveDeclarationNodes.add(node);
+ return;
+ }
getCurrentDescriptor("ps").valueNeedsQuotes = true;
emitAttributeValue(node);
@@ -2884,6 +2936,122 @@ public class MXMLRoyaleEmitter extends MXMLEmitter
implements
}
}
}
+ n = primitiveDeclarationNodes.size();
+ for (int i = 0; i < n; i++)
+ {
+ IMXMLInstanceNode declNode = primitiveDeclarationNodes.get(i);
+ ASTNodeID nodeId = declNode.getNodeID();
+ String varname;
+
+ switch (nodeId)
+ {
+ case MXMLStringID:
+ {
+ IMXMLStringNode stringNode =
(IMXMLStringNode)declNode;
+ varname = stringNode.getEffectiveID();
+ writeNewline();
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(varname);
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ IMXMLLiteralNode valueNode =
(IMXMLLiteralNode)(stringNode.getExpressionNode());
+ Object value = valueNode.getValue();
+ write(objectToString(value));
+ write(ASEmitterTokens.SEMICOLON);
+ break;
+ }
+ case MXMLArrayID:
+ {
+ IMXMLArrayNode arrayNode =
(IMXMLArrayNode)declNode;
+ varname = arrayNode.getEffectiveID();
+ writeNewline();
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(varname);
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write("[");
+ int m = arrayNode.getChildCount();
+ boolean firstOne = true;
+ for (int j = 0; j < m; j++)
+ {
+ IMXMLInstanceNode valueNode =
(IMXMLInstanceNode)(arrayNode.getChild(j));
+ if (firstOne)
+ firstOne = false;
+ else
+ writeToken(",");
+ write(instanceToString(valueNode));
+ }
+ write("]");
+ write(ASEmitterTokens.SEMICOLON);
+ break;
+ }
+ case MXMLXMLID:
+ {
+ IMXMLXMLNode xmlNode =
(IMXMLXMLNode)declNode;
+ String valueString =
xmlNode.getXMLString();
+ if (valueString != null)
+ {
+ varname =
xmlNode.getEffectiveID();
+ writeNewline();
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(varname);
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write("new XML('");
+
write(StringEscapeUtils.escapeJavaScript(valueString));
+ write("')");
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ break;
+ }
+ case MXMLXMLListID:
+ {
+ IMXMLXMLListNode xmlNode =
(IMXMLXMLListNode)declNode;
+ String valueString =
xmlNode.getXMLString();
+ if (valueString != null)
+ {
+ varname =
xmlNode.getEffectiveID();
+ writeNewline();
+ write(ASEmitterTokens.THIS);
+ write(ASEmitterTokens.MEMBER_ACCESS);
+ write(varname);
+ write(ASEmitterTokens.SPACE);
+ writeToken(ASEmitterTokens.EQUAL);
+ write("new XMLList('");
+
write(StringEscapeUtils.escapeJavaScript(valueString));
+ write("')");
+ write(ASEmitterTokens.SEMICOLON);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private String objectToString(Object value)
+ {
+ if (value instanceof String)
+ {
+ String s = (String)value;
+ s = StringEscapeUtils.escapeJavaScript(s);
+ return "'" + s + "'";
+ }
+ return "";
+ }
+
+ private String instanceToString(IMXMLInstanceNode instanceNode)
+ {
+ if (instanceNode instanceof IMXMLStringNode)
+ {
+ IMXMLStringNode stringNode = (IMXMLStringNode)instanceNode;
+ IMXMLLiteralNode valueNode =
(IMXMLLiteralNode)(stringNode.getExpressionNode());
+ Object value = valueNode.getValue();
+ return objectToString(value);
+ }
+ return "";
}
public void emitComplexStaticInitializers(IASNode node){
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java
index d983ea8..c5c3750 100644
---
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java
@@ -826,6 +826,489 @@ public class TestRoyaleMXMLApplication extends
RoyaleTestBase
}
@Test
+ public void testFXStringDeclaration()
+ {
+ String code = "<basic:Application
xmlns:fx=\"http://ns.adobe.com/mxml/2009\"
xmlns:basic=\"library://ns.apache.org/royale/basic\">"
+ + "<fx:Declarations><fx:String
id=\"foo\">Ro'ale</fx:String>"
+ +
"</fx:Declarations><basic:initialView><basic:View><basic:DropDownList
dataProvider=\"['Hello',
'World']\"/></basic:View></basic:initialView></basic:Application>";
+
+ IMXMLDocumentNode dnode = (IMXMLDocumentNode) getNode(code,
+ IMXMLDocumentNode.class,
RoyaleTestBase.WRAP_LEVEL_NONE);
+
+
((JSRoyaleEmitter)(mxmlBlockWalker.getASEmitter())).getModel().setCurrentClass(dnode.getDefinition());
+ mxmlBlockWalker.visitDocument(dnode);
+ String appName = dnode.getQualifiedName();
+ String outTemplate = "/**\n" +
+ " * AppName\n" +
+ " *\n" +
+ " * @fileoverview\n" +
+ " *\n" +
+ " * @suppress {checkTypes|accessControls}\n" +
+ " */\n" +
+ "\n" +
+ "goog.provide('AppName');\n" +
+ "\n" +
+ "goog.require('org.apache.royale.core.Application');\n"
+
+ "goog.require('org.apache.royale.core.View');\n" +
+
"goog.require('org.apache.royale.html.DropDownList');\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @constructor\n" +
+ " * @extends {org.apache.royale.core.Application}\n" +
+ " */\n" +
+ "AppName = function() {\n" +
+ " AppName.base(this, 'constructor');\n" +
+ " \n" +
+ " this.foo = 'Ro\\'ale';\n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.core.View}\n" +
+ " */\n" +
+ " this.$ID1_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.html.DropDownList}\n" +
+ " */\n" +
+ " this.$ID0_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldd;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldp;\n" +
+ "\n" +
+ " this.generateMXMLAttributes\n" +
+ " ([1,\n" +
+ "'initialView',\n" +
+ "false,\n" +
+ "[org.apache.royale.core.View, 1, '_id', true, '$ID1',
0, 0, [org.apache.royale.html.DropDownList, 2, '_id', true, '$ID0',
'dataProvider', true, ['Hello','World'], 0, 0, null]],\n" +
+ "0,\n" +
+ "0\n" +
+ " ]);\n" +
+ " \n" +
+ "};\n" +
+ "goog.inherits(AppName,
org.apache.royale.core.Application);\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Prevent renaming of class. Needed for
reflection.\n" +
+ " */\n" +
+ "goog.exportSymbol('AppName', AppName);\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @export\n" +
+ " * @type {string}\n" +
+ " */\n" +
+ "AppName.prototype.foo;\n" +
+ "\n" +
+ "/**\n" +
+ " * Metadata\n" +
+ " *\n" +
+ " * @type {Object.<string, Array.<Object>>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_CLASS_INFO = { names: [{
name: 'AppName', qName: 'AppName', kind: 'class' }] };\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Reflection\n" +
+ " *\n" +
+ " * @return {Object.<string, Function>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_REFLECTION_INFO = function ()
{\n" +
+ " return {\n" +
+ " variables: function () {\n" +
+ " return {\n" +
+ " 'foo': { type: 'String'}\n" +
+ " };\n" +
+ " },\n" +
+ " accessors: function () {return {};},\n" +
+ " methods: function () {\n" +
+ " return {\n" +
+ " 'AppName': { type: '', declaredBy:
'AppName'}\n"+
+ " };\n" +
+ " }\n" +
+ " };\n" +
+ "};";
+
+ assertOutMXMLPostProcess(outTemplate.replaceAll("AppName", appName),
true);
+ }
+
+ @Test
+ public void testFXArrayDeclaration()
+ {
+ String code = "<basic:Application
xmlns:fx=\"http://ns.adobe.com/mxml/2009\"
xmlns:basic=\"library://ns.apache.org/royale/basic\">"
+ + "<fx:Declarations><fx:Array
id=\"foo\"><fx:String>Royale</fx:String><fx:String>Rules</fx:String></fx:Array>"
+ +
"</fx:Declarations><basic:initialView><basic:View><basic:DropDownList
dataProvider=\"['Hello',
'World']\"/></basic:View></basic:initialView></basic:Application>";
+
+ IMXMLDocumentNode dnode = (IMXMLDocumentNode) getNode(code,
+ IMXMLDocumentNode.class,
RoyaleTestBase.WRAP_LEVEL_NONE);
+
+
((JSRoyaleEmitter)(mxmlBlockWalker.getASEmitter())).getModel().setCurrentClass(dnode.getDefinition());
+ mxmlBlockWalker.visitDocument(dnode);
+ String appName = dnode.getQualifiedName();
+ String outTemplate = "/**\n" +
+ " * AppName\n" +
+ " *\n" +
+ " * @fileoverview\n" +
+ " *\n" +
+ " * @suppress {checkTypes|accessControls}\n" +
+ " */\n" +
+ "\n" +
+ "goog.provide('AppName');\n" +
+ "\n" +
+ "goog.require('org.apache.royale.core.Application');\n"
+
+ "goog.require('org.apache.royale.core.View');\n" +
+
"goog.require('org.apache.royale.html.DropDownList');\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @constructor\n" +
+ " * @extends {org.apache.royale.core.Application}\n" +
+ " */\n" +
+ "AppName = function() {\n" +
+ " AppName.base(this, 'constructor');\n" +
+ " \n" +
+ " this.foo = ['Royale', 'Rules'];\n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.core.View}\n" +
+ " */\n" +
+ " this.$ID3_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.html.DropDownList}\n" +
+ " */\n" +
+ " this.$ID2_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldd;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldp;\n" +
+ "\n" +
+ " this.generateMXMLAttributes\n" +
+ " ([1,\n" +
+ "'initialView',\n" +
+ "false,\n" +
+ "[org.apache.royale.core.View, 1, '_id', true, '$ID3',
0, 0, [org.apache.royale.html.DropDownList, 2, '_id', true, '$ID2',
'dataProvider', true, ['Hello','World'], 0, 0, null]],\n" +
+ "0,\n" +
+ "0\n" +
+ " ]);\n" +
+ " \n" +
+ "};\n" +
+ "goog.inherits(AppName,
org.apache.royale.core.Application);\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Prevent renaming of class. Needed for
reflection.\n" +
+ " */\n" +
+ "goog.exportSymbol('AppName', AppName);\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @export\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ "AppName.prototype.foo;\n" +
+ "\n" +
+ "/**\n" +
+ " * Metadata\n" +
+ " *\n" +
+ " * @type {Object.<string, Array.<Object>>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_CLASS_INFO = { names: [{
name: 'AppName', qName: 'AppName', kind: 'class' }] };\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Reflection\n" +
+ " *\n" +
+ " * @return {Object.<string, Function>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_REFLECTION_INFO = function ()
{\n" +
+ " return {\n" +
+ " variables: function () {\n" +
+ " return {\n" +
+ " 'foo': { type: 'Array'}\n" +
+ " };\n" +
+ " },\n" +
+ " accessors: function () {return {};},\n" +
+ " methods: function () {\n" +
+ " return {\n" +
+ " 'AppName': { type: '', declaredBy:
'AppName'}\n"+
+ " };\n" +
+ " }\n" +
+ " };\n" +
+ "};";
+
+ assertOutMXMLPostProcess(outTemplate.replaceAll("AppName", appName),
true);
+ }
+
+ @Test
+ public void testFXXMLDeclaration()
+ {
+ String code = "<basic:Application
xmlns:fx=\"http://ns.adobe.com/mxml/2009\"
xmlns:basic=\"library://ns.apache.org/royale/basic\">"
+ + "<fx:Declarations><fx:XML id=\"foo\"><root><menuitem
label=\"foo\"/><menuitem label=\"bar\"/></root></fx:XML>"
+ +
"</fx:Declarations><basic:initialView><basic:View><basic:DropDownList
dataProvider=\"['Hello',
'World']\"/></basic:View></basic:initialView></basic:Application>";
+
+ IMXMLDocumentNode dnode = (IMXMLDocumentNode) getNode(code,
+ IMXMLDocumentNode.class,
RoyaleTestBase.WRAP_LEVEL_NONE);
+
+
((JSRoyaleEmitter)(mxmlBlockWalker.getASEmitter())).getModel().setCurrentClass(dnode.getDefinition());
+ mxmlBlockWalker.visitDocument(dnode);
+ String appName = dnode.getQualifiedName();
+ String outTemplate = "/**\n" +
+ " * AppName\n" +
+ " *\n" +
+ " * @fileoverview\n" +
+ " *\n" +
+ " * @suppress {checkTypes|accessControls}\n" +
+ " */\n" +
+ "\n" +
+ "goog.provide('AppName');\n" +
+ "\n" +
+ "goog.require('org.apache.royale.core.Application');\n"
+
+ "goog.require('org.apache.royale.core.View');\n" +
+
"goog.require('org.apache.royale.html.DropDownList');\n" +
+ "goog.require('XML');\n" +
+ "goog.require('XML');\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @constructor\n" +
+ " * @extends {org.apache.royale.core.Application}\n" +
+ " */\n" +
+ "AppName = function() {\n" +
+ " AppName.base(this, 'constructor');\n" +
+ " \n" +
+ " this.foo = new XML('<root><menuitem
label=\\\"foo\\\"\\/><menuitem label=\\\"bar\\\"\\/><\\/root>');\n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.core.View}\n" +
+ " */\n" +
+ " this.$ID1_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.html.DropDownList}\n" +
+ " */\n" +
+ " this.$ID0_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldd;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldp;\n" +
+ "\n" +
+ " this.generateMXMLAttributes\n" +
+ " ([1,\n" +
+ "'initialView',\n" +
+ "false,\n" +
+ "[org.apache.royale.core.View, 1, '_id', true, '$ID1',
0, 0, [org.apache.royale.html.DropDownList, 2, '_id', true, '$ID0',
'dataProvider', true, ['Hello','World'], 0, 0, null]],\n" +
+ "0,\n" +
+ "0\n" +
+ " ]);\n" +
+ " \n" +
+ "};\n" +
+ "goog.inherits(AppName,
org.apache.royale.core.Application);\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Prevent renaming of class. Needed for
reflection.\n" +
+ " */\n" +
+ "goog.exportSymbol('AppName', AppName);\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @export\n" +
+ " * @type {XML}\n" +
+ " */\n" +
+ "AppName.prototype.foo;\n" +
+ "\n" +
+ "/**\n" +
+ " * Metadata\n" +
+ " *\n" +
+ " * @type {Object.<string, Array.<Object>>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_CLASS_INFO = { names: [{
name: 'AppName', qName: 'AppName', kind: 'class' }] };\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Reflection\n" +
+ " *\n" +
+ " * @return {Object.<string, Function>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_REFLECTION_INFO = function ()
{\n" +
+ " return {\n" +
+ " variables: function () {\n" +
+ " return {\n" +
+ " 'foo': { type: 'XML'}\n" +
+ " };\n" +
+ " },\n" +
+ " accessors: function () {return {};},\n" +
+ " methods: function () {\n" +
+ " return {\n" +
+ " 'AppName': { type: '', declaredBy:
'AppName'}\n"+
+ " };\n" +
+ " }\n" +
+ " };\n" +
+ "};";
+
+ assertOutMXMLPostProcess(outTemplate.replaceAll("AppName", appName),
true);
+ }
+
+ @Test
+ public void testFXXMLListDeclaration()
+ {
+ String code = "<basic:Application
xmlns:fx=\"http://ns.adobe.com/mxml/2009\"
xmlns:basic=\"library://ns.apache.org/royale/basic\">"
+ + "<fx:Declarations><fx:XMLList
id=\"foo\"><item><name>foo</name></item><item><name>bar</name></item></fx:XMLList>"
+ +
"</fx:Declarations><basic:initialView><basic:View><basic:DropDownList
dataProvider=\"['Hello',
'World']\"/></basic:View></basic:initialView></basic:Application>";
+
+ IMXMLDocumentNode dnode = (IMXMLDocumentNode) getNode(code,
+ IMXMLDocumentNode.class,
RoyaleTestBase.WRAP_LEVEL_NONE);
+
+
((JSRoyaleEmitter)(mxmlBlockWalker.getASEmitter())).getModel().setCurrentClass(dnode.getDefinition());
+ mxmlBlockWalker.visitDocument(dnode);
+ String appName = dnode.getQualifiedName();
+ String outTemplate = "/**\n" +
+ " * AppName\n" +
+ " *\n" +
+ " * @fileoverview\n" +
+ " *\n" +
+ " * @suppress {checkTypes|accessControls}\n" +
+ " */\n" +
+ "\n" +
+ "goog.provide('AppName');\n" +
+ "\n" +
+ "goog.require('org.apache.royale.core.Application');\n"
+
+ "goog.require('org.apache.royale.core.View');\n" +
+
"goog.require('org.apache.royale.html.DropDownList');\n" +
+ "goog.require('XMLList');\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @constructor\n" +
+ " * @extends {org.apache.royale.core.Application}\n" +
+ " */\n" +
+ "AppName = function() {\n" +
+ " AppName.base(this, 'constructor');\n" +
+ " \n" +
+ " this.foo = new
XMLList('<item><name>foo<\\/name><\\/item><item><name>bar<\\/name><\\/item>');\n"
+
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.core.View}\n" +
+ " */\n" +
+ " this.$ID1_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {org.apache.royale.html.DropDownList}\n" +
+ " */\n" +
+ " this.$ID0_;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldd;\n" +
+ " \n" +
+ " /**\n" +
+ " * @private\n" +
+ " * @type {Array}\n" +
+ " */\n" +
+ " this.mxmldp;\n" +
+ "\n" +
+ " this.generateMXMLAttributes\n" +
+ " ([1,\n" +
+ "'initialView',\n" +
+ "false,\n" +
+ "[org.apache.royale.core.View, 1, '_id', true, '$ID1',
0, 0, [org.apache.royale.html.DropDownList, 2, '_id', true, '$ID0',
'dataProvider', true, ['Hello','World'], 0, 0, null]],\n" +
+ "0,\n" +
+ "0\n" +
+ " ]);\n" +
+ " \n" +
+ "};\n" +
+ "goog.inherits(AppName,
org.apache.royale.core.Application);\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Prevent renaming of class. Needed for
reflection.\n" +
+ " */\n" +
+ "goog.exportSymbol('AppName', AppName);\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * @export\n" +
+ " * @type {XMLList}\n" +
+ " */\n" +
+ "AppName.prototype.foo;\n" +
+ "\n" +
+ "/**\n" +
+ " * Metadata\n" +
+ " *\n" +
+ " * @type {Object.<string, Array.<Object>>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_CLASS_INFO = { names: [{
name: 'AppName', qName: 'AppName', kind: 'class' }] };\n" +
+ "\n" +
+ "\n" +
+ "\n" +
+ "/**\n" +
+ " * Reflection\n" +
+ " *\n" +
+ " * @return {Object.<string, Function>}\n" +
+ " */\n" +
+ "AppName.prototype.ROYALE_REFLECTION_INFO = function ()
{\n" +
+ " return {\n" +
+ " variables: function () {\n" +
+ " return {\n" +
+ " 'foo': { type: 'XMLList'}\n" +
+ " };\n" +
+ " },\n" +
+ " accessors: function () {return {};},\n" +
+ " methods: function () {\n" +
+ " return {\n" +
+ " 'AppName': { type: '', declaredBy:
'AppName'}\n"+
+ " };\n" +
+ " }\n" +
+ " };\n" +
+ "};";
+
+ assertOutMXMLPostProcess(outTemplate.replaceAll("AppName", appName),
true);
+ }
+
+ @Test
public void testRoyaleMainFileDual()
{
MXMLJSC mxmlc = new MXMLJSC();
diff --git
a/compiler/src/main/java/org/apache/royale/compiler/tree/mxml/IMXMLXMLNode.java
b/compiler/src/main/java/org/apache/royale/compiler/tree/mxml/IMXMLXMLNode.java
index 6cd65e5..3c6b018 100644
---
a/compiler/src/main/java/org/apache/royale/compiler/tree/mxml/IMXMLXMLNode.java
+++
b/compiler/src/main/java/org/apache/royale/compiler/tree/mxml/IMXMLXMLNode.java
@@ -28,7 +28,7 @@ import org.apache.royale.compiler.mxml.IMXMLTagData;
* {@link IMXMLTagData} object which represents the single XML tag inside the
* <code><XML></code> tag.
*/
-public interface IMXMLXMLNode extends IMXMLNode
+public interface IMXMLXMLNode extends IMXMLInstanceNode
{
// name used to lookup type for format="xml"
String XML_NODE_NAME = "flash.xml.XMLNode";