FLEX-35239 fix constant databinding output
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/a5c260dd Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/a5c260dd Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/a5c260dd Branch: refs/heads/master Commit: a5c260dd68216f3230fdee161c00a9879ae2891e Parents: 64e1a17 Author: Alex Harui <[email protected]> Authored: Fri Jan 6 09:47:50 2017 -0800 Committer: Alex Harui <[email protected]> Committed: Fri Jan 6 09:47:50 2017 -0800 ---------------------------------------------------------------------- .../codegen/mxml/flexjs/MXMLFlexJSEmitter.java | 36 ++- .../mxml/flexjs/TestFlexJSMXMLApplication.java | 229 +++++++++++++++++++ .../codegen/databinding/BindingInfo.java | 14 ++ .../databinding/MXMLBindingDirectiveHelper.java | 12 +- 4 files changed, 279 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c260dd/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java index 4bea612..232d2e7 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java @@ -973,16 +973,32 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements } else if (s.contains(".")) { - String[] parts = s.split("\\."); - write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() + - parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken()); - int n = parts.length; - for (int i = 1; i < n; i++) - { - String part = parts[i]; - write(", " + ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken()); - } - writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken()); + if (bi.classDef != null) + { + String[] parts = s.split("\\."); + write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() + + bi.classDef.getQualifiedName() + ASEmitterTokens.DOUBLE_QUOTE.getToken()); + int n = parts.length; + for (int i = 1; i < n; i++) + { + String part = parts[i]; + write(", " + ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken()); + } + writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken()); + } + else + { + String[] parts = s.split("\\."); + write(ASEmitterTokens.SQUARE_OPEN.getToken() + ASEmitterTokens.DOUBLE_QUOTE.getToken() + + parts[0] + ASEmitterTokens.DOUBLE_QUOTE.getToken()); + int n = parts.length; + for (int i = 1; i < n; i++) + { + String part = parts[i]; + write(", " + ASEmitterTokens.DOUBLE_QUOTE.getToken() + part + ASEmitterTokens.DOUBLE_QUOTE.getToken()); + } + writeNewline(ASEmitterTokens.SQUARE_CLOSE.getToken() + ASEmitterTokens.COMMA.getToken()); + } } else writeNewline(ASEmitterTokens.DOUBLE_QUOTE.getToken() + s + http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c260dd/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java index 95f5476..d09ca6b 100644 --- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java +++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java @@ -290,4 +290,233 @@ public class TestFlexJSMXMLApplication extends FlexJSTestBase assertOutWithMetadata(outTemplate.replaceAll("AppName", appName)); } + @Test + public void testConstantBinding() + { + String code = "<basic:Application xmlns:fx=\"http://ns.adobe.com/mxml/2009\" xmlns:basic=\"library://ns.apache.org/flexjs/basic\">" + + "<fx:Script><![CDATA[" + + " import org.apache.flex.events.ValueChangeEvent;" + + "]]></fx:Script><basic:initialView><basic:Label text=\"{ValueChangeEvent.VALUE_CHANGE}\"/></basic:initialView></basic:Application>"; + + IMXMLDocumentNode dnode = (IMXMLDocumentNode) getNode(code, + IMXMLDocumentNode.class, FlexJSTestBase.WRAP_LEVEL_NONE); + + ((JSFlexJSEmitter)(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.flex.core.Application');\n" + + "goog.require('org.apache.flex.html.Label');\n" + + "goog.require('org.apache.flex.events.ValueChangeEvent');\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @constructor\n" + + " * @extends {org.apache.flex.core.Application}\n" + + " */\n" + + "AppName = function() {\n" + + " AppName.base(this, 'constructor');\n" + + " \n" + + " /**\n" + + " * @private\n" + + " * @type {org.apache.flex.html.Label}\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.flex.html.Label, 1, '_id', true, '$ID0', 0, 0, null],\n" + + "0,\n" + + "0\n" + + " ]);\n" + + " \n" + + "};\n" + + "goog.inherits(AppName, org.apache.flex.core.Application);\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @export\n" + + " */\n" + + "AppName.prototype._bindings = [\n" + + "1,\n" + + "[\"org.apache.flex.events.ValueChangeEvent\", \"VALUE_CHANGE\"],\n" + + "null,\n" + + "[\"$ID0\", \"text\"],\n" + + "];\n" + + "/**\n" + + " * Metadata\n" + + " *\n" + + " * @type {Object.<string, Array.<Object>>}\n" + + " */\n" + + "AppName.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'AppName', qName: 'AppName', kind: 'class' }] };\n" + + "\n" + + "\n" + + "/**\n" + + " * Prevent renaming of class. Needed for reflection.\n" + + " */\n" + + "goog.exportSymbol('AppName', AppName);\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * Reflection\n" + + " *\n" + + " * @return {Object.<string, Function>}\n" + + " */\n" + + "AppName.prototype.FLEXJS_REFLECTION_INFO = function () {\n" + + " return {\n" + + " variables: function () {return {};},\n" + + " accessors: function () {return {};},\n" + + " methods: function () {\n" + + " return {\n" + + " 'AppName': { type: '', declaredBy: 'AppName'}\n"+ + " };\n" + + " }\n" + + " };\n" + + "};\n" + + "\n" + + "\n"; + + assertOutWithMetadata(outTemplate.replaceAll("AppName", appName)); + } + + @Test + public void testConstantBindingQname() + { + String code = "<basic:Application xmlns:fx=\"http://ns.adobe.com/mxml/2009\" xmlns:basic=\"library://ns.apache.org/flexjs/basic\">" + + "<fx:Script><![CDATA[" + + " import org.apache.flex.events.ValueChangeEvent;" + + "]]></fx:Script><basic:initialView><basic:Label text=\"{org.apache.flex.events.ValueChangeEvent.VALUE_CHANGE}\"/></basic:initialView></basic:Application>"; + + IMXMLDocumentNode dnode = (IMXMLDocumentNode) getNode(code, + IMXMLDocumentNode.class, FlexJSTestBase.WRAP_LEVEL_NONE); + + ((JSFlexJSEmitter)(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.flex.core.Application');\n" + + "goog.require('org.apache.flex.html.Label');\n" + + "goog.require('org.apache.flex.events.ValueChangeEvent');\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @constructor\n" + + " * @extends {org.apache.flex.core.Application}\n" + + " */\n" + + "AppName = function() {\n" + + " AppName.base(this, 'constructor');\n" + + " \n" + + " /**\n" + + " * @private\n" + + " * @type {org.apache.flex.html.Label}\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.flex.html.Label, 1, '_id', true, '$ID0', 0, 0, null],\n" + + "0,\n" + + "0\n" + + " ]);\n" + + " \n" + + "};\n" + + "goog.inherits(AppName, org.apache.flex.core.Application);\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @export\n" + + " */\n" + + "AppName.prototype._bindings = [\n" + + "1,\n" + + "[\"org.apache.flex.events.ValueChangeEvent\", \"VALUE_CHANGE\"],\n" + + "null,\n" + + "[\"$ID0\", \"text\"],\n" + + "];\n" + + "/**\n" + + " * Metadata\n" + + " *\n" + + " * @type {Object.<string, Array.<Object>>}\n" + + " */\n" + + "AppName.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'AppName', qName: 'AppName', kind: 'class' }] };\n" + + "\n" + + "\n" + + "/**\n" + + " * Prevent renaming of class. Needed for reflection.\n" + + " */\n" + + "goog.exportSymbol('AppName', AppName);\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * Reflection\n" + + " *\n" + + " * @return {Object.<string, Function>}\n" + + " */\n" + + "AppName.prototype.FLEXJS_REFLECTION_INFO = function () {\n" + + " return {\n" + + " variables: function () {return {};},\n" + + " accessors: function () {return {};},\n" + + " methods: function () {\n" + + " return {\n" + + " 'AppName': { type: '', declaredBy: 'AppName'}\n"+ + " };\n" + + " }\n" + + " };\n" + + "};\n" + + "\n" + + "\n"; + + assertOutWithMetadata(outTemplate.replaceAll("AppName", appName)); + } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c260dd/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/BindingInfo.java ---------------------------------------------------------------------- diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/BindingInfo.java b/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/BindingInfo.java index 330b159..2946dd4 100644 --- a/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/BindingInfo.java +++ b/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/BindingInfo.java @@ -184,6 +184,7 @@ public class BindingInfo implements Comparable<BindingInfo> private String sourceString; private int twoWayCounterpart = -1; // index of two way counterpart, or -1 public IMXMLNode node; + public ClassDefinition classDef; // non-null if binding to static const or var // The expression node that represents the destination // this is used for more complex destinations, like inside an XML object @@ -496,6 +497,19 @@ public class BindingInfo implements Comparable<BindingInfo> IDefinition leftDef = leftSide.resolve(project); if (leftDef.isPublic()) { + if (leftDef instanceof ClassDefinition) + classDef = (ClassDefinition)leftDef; + sourceString = leftDef.getBaseName() + "." + def.getBaseName(); + isSimplePublicProperty = true; + } + } + else if (leftSide instanceof MemberAccessExpressionNode) + { + IDefinition leftDef = leftSide.resolve(project); + if (leftDef.isPublic()) + { + if (leftDef instanceof ClassDefinition) + classDef = (ClassDefinition)leftDef; sourceString = leftDef.getBaseName() + "." + def.getBaseName(); isSimplePublicProperty = true; } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/a5c260dd/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java ---------------------------------------------------------------------- diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java b/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java index 2551260..54369de 100644 --- a/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java +++ b/compiler/src/main/java/org/apache/flex/compiler/internal/codegen/databinding/MXMLBindingDirectiveHelper.java @@ -214,8 +214,16 @@ public class MXMLBindingDirectiveHelper else if (s.contains(".") && !isFlexSDK) { String[] parts = s.split("\\."); - for (String part : parts) - ret.addInstruction(OP_pushstring, part); + if (bi.classDef != null) + { + ret.addInstruction(OP_pushstring, bi.classDef.getQualifiedName()); + ret.addInstruction(OP_pushstring, parts[1]); + } + else + { + for (String part : parts) + ret.addInstruction(OP_pushstring, part); + } ret.addInstruction(OP_newarray, parts.length); } else
