You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by jo...@apache.org on 2017/03/21 23:10:47 UTC

[10/50] git commit: [flex-falcon] [refs/heads/master] - FLEX-35227 and FLEX-35236 handle more [Bindable] scenarios

FLEX-35227 and FLEX-35236 handle more [Bindable] scenarios


Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/448df176
Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/448df176
Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/448df176

Branch: refs/heads/master
Commit: 448df176471251106639ea2c2af52d8c77bf54f0
Parents: cc7de9c
Author: Alex Harui <ah...@apache.org>
Authored: Thu Jan 12 15:12:38 2017 -0800
Committer: Alex Harui <ah...@apache.org>
Committed: Thu Jan 12 15:12:38 2017 -0800

----------------------------------------------------------------------
 .../js/flexjs/JSFlexJSEmitterTokens.java        |   1 +
 .../internal/codegen/js/jx/AccessorEmitter.java |  90 ++++++++++++
 .../codegen/js/flexjs/TestFlexJSAccessors.java  |  41 ++++++
 .../codegen/js/flexjs/TestFlexJSClass.java      | 144 +++++++++++++++++++
 .../flex/compiler/internal/test/TestBase.java   |   8 ++
 5 files changed, 284 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/448df176/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java
index 50e612b..cff0a58 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java
@@ -52,6 +52,7 @@ public enum JSFlexJSEmitterTokens implements IEmitterTokens
     SUPERSETTER("superSetter"),
     GETTER_PREFIX("get__"),
     SETTER_PREFIX("set__"),
+    BINDABLE_PREFIX("bindable__"),
     CLOSURE_FUNCTION_NAME("org.apache.flex.utils.Language.closure"),
     SKIP_AS_COERCIONS("skipAsCoercions"),
     SKIP_FUNCTION_COERCIONS("skipFunctionCoercions"),

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/448df176/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java
index abba383..c060381 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/AccessorEmitter.java
@@ -32,6 +32,7 @@ import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.definitions.IFunctionDefinition;
 import org.apache.flex.compiler.definitions.INamespaceDefinition;
 import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.definitions.metadata.IMetaTag;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSSessionModel.PropertyNodes;
@@ -121,6 +122,36 @@ public class AccessorEmitter extends JSSubEmitter implements
                 }
                 if (setterNode != null)
                 {
+                	boolean isBindable = false;                
+                	IAccessorDefinition setterDef = (IAccessorDefinition)setterNode.getDefinition();
+                	IAccessorDefinition getterDef = null;
+                	if (getterNode != null)
+                		getterDef = (IAccessorDefinition)getterNode.getDefinition();
+                	if (setterDef.isBindable() || (getterDef != null && getterDef.isBindable()))
+                	{
+                		if (setterDef.isBindable())
+                		{
+                			IMetaTag[] tags = setterDef.getMetaTagsByName("Bindable");
+                			if (tags.length > 1)
+                        		isBindable = true;
+                			else if (tags.length == 1)
+                			{
+                				if (tags[0].getAllAttributes().length == 0)
+                					isBindable = true;
+                			}
+                		}
+                		else if (getterDef != null && getterDef.isBindable())
+                		{
+                			IMetaTag[] tags = getterDef.getMetaTagsByName("Bindable");
+                			if (tags.length > 1)
+                        		isBindable = true;
+                			else if (tags.length == 1)
+                			{
+                				if (tags[0].getAllAttributes().length == 0)
+                					isBindable = true;
+                			}                			
+                		}
+                	}
                     writeNewline();
                     writeNewline();
                     writeNewline();
@@ -139,6 +170,8 @@ public class AccessorEmitter extends JSSubEmitter implements
                     else
                     {
                         write(ASEmitterTokens.MEMBER_ACCESS);
+                        if (isBindable)
+                        	write(JSFlexJSEmitterTokens.BINDABLE_PREFIX);
                         write(JSFlexJSEmitterTokens.SETTER_PREFIX);
                     	write(propName);
                     }
@@ -151,6 +184,63 @@ public class AccessorEmitter extends JSSubEmitter implements
                     fjs.emitDefinePropertyFunction(setterNode);
                     
                     write(ASEmitterTokens.SEMICOLON);
+                    
+                    if (isBindable)
+                    {
+                    	writeNewline();
+                    	writeNewline();
+                    	writeNewline();
+                        write(getEmitter().formatQualifiedName(qname));
+                        write(ASEmitterTokens.MEMBER_ACCESS);
+                        write(JSEmitterTokens.PROTOTYPE);
+                        write(ASEmitterTokens.MEMBER_ACCESS);
+                        write(JSFlexJSEmitterTokens.SETTER_PREFIX);
+                    	write(propName);
+                        write(ASEmitterTokens.SPACE);
+                        write(ASEmitterTokens.EQUAL);
+                        write(ASEmitterTokens.SPACE);
+                        write(ASEmitterTokens.FUNCTION);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        write("value");
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                        write(ASEmitterTokens.SPACE);
+                        writeNewline(ASEmitterTokens.BLOCK_OPEN);
+                        write(ASEmitterTokens.VAR);
+                        write(ASEmitterTokens.SPACE);
+                        write("oldValue");
+                        write(ASEmitterTokens.SPACE);
+                        write(ASEmitterTokens.EQUAL);
+                        write(ASEmitterTokens.SPACE);
+                        write(ASEmitterTokens.THIS);
+                        write(ASEmitterTokens.MEMBER_ACCESS);
+                        write(JSFlexJSEmitterTokens.GETTER_PREFIX);
+                    	write(propName);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                        writeNewline(ASEmitterTokens.SEMICOLON);
+                        write(ASEmitterTokens.IF);
+                        write(ASEmitterTokens.SPACE);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        write("oldValue != value");
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                        write(ASEmitterTokens.SPACE);
+                        writeNewline(ASEmitterTokens.BLOCK_OPEN);
+                        write(ASEmitterTokens.THIS);
+                        write(ASEmitterTokens.MEMBER_ACCESS);
+                        write(JSFlexJSEmitterTokens.BINDABLE_PREFIX);
+                        write(JSFlexJSEmitterTokens.SETTER_PREFIX);
+                    	write(propName);
+                        write(ASEmitterTokens.PAREN_OPEN);
+                        write("value");
+                        write(ASEmitterTokens.PAREN_CLOSE);
+                        writeNewline(ASEmitterTokens.SEMICOLON);
+                        writeNewline("    this.dispatchEvent("+fjs.formatQualifiedName(BindableEmitter.VALUECHANGE_EVENT_QNAME)+".createUpdateEvent(");
+                        writeNewline("         this, \"" + propName + "\", oldValue, value));");
+                        writeNewline(ASEmitterTokens.BLOCK_CLOSE);
+                        write(ASEmitterTokens.BLOCK_CLOSE);
+                        write(ASEmitterTokens.SEMICOLON);                        
+                        
+                    }
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/448df176/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSAccessors.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSAccessors.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSAccessors.java
index eb27626..1f88fe4 100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSAccessors.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSAccessors.java
@@ -21,6 +21,8 @@ package org.apache.flex.compiler.internal.codegen.js.flexjs;
 
 import org.apache.flex.compiler.driver.IBackend;
 import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
 import org.apache.flex.compiler.internal.test.ASTestBase;
 import org.apache.flex.compiler.tree.as.IClassNode;
 import org.junit.Test;
@@ -30,6 +32,12 @@ import org.junit.Test;
  */
 public class TestFlexJSAccessors extends ASTestBase
 {
+    @Override
+    public void setUp()
+    {
+        super.setUp();
+    	((FlexJSProject)project).config = new JSGoogConfiguration();
+    }
     
     @Test
     public void testGetAndSetAccessor()
@@ -105,6 +113,39 @@ public class TestFlexJSAccessors extends ASTestBase
         assertOut(expected);
     }
 
+    @Test
+    public void testBindableGetAndSetAccessor()
+    {
+        IClassNode node = (IClassNode) getNode(
+                "public function doStuff():void {label = 'hello, bye'; var theLabel:String = label;}; private var _label:String; [Bindable] public function get label():String {return _label}; public function set label(value:String):void {_label = value}; ",
+                IClassNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\nFalconTest_A = function() {\n};\n\n\n/**\n * @export\n */\nFalconTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nFalconTest_A.prototype._label;\n\n\n" +
+        		"FalconTest_A.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
+				"FalconTest_A.prototype.bindable__set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
+        		"FalconTest_A.prototype.set__label = function(value) {\nvar oldValue = this.get__label();\nif (oldValue != value) {\nthis.bindable__set__label(value);\n" +
+        		"    this.dispatchEvent(org.apache.flex.events.ValueChangeEvent.createUpdateEvent(\n" +
+        		"         this, \"label\", oldValue, value));\n}\n};\n\n\n" +
+        		"Object.defineProperties(FalconTest_A.prototype, /** @lends {FalconTest_A.prototype} */ {\n/** @export */\n" +
+        		"label: {\nget: FalconTest_A.prototype.get__label,\nset: FalconTest_A.prototype.set__label}}\n);";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testBindableWithEventGetAndSetAccessor()
+    {
+        IClassNode node = (IClassNode) getNode(
+                "public function doStuff():void {label = 'hello, bye'; var theLabel:String = label;}; private var _label:String; [Bindable(\"change\")] public function get label():String {return _label}; public function set label(value:String):void {_label = value}; ",
+                IClassNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\nFalconTest_A = function() {\n};\n\n\n/**\n * @export\n */\nFalconTest_A.prototype.doStuff = function() {\n  this.label = 'hello, bye';\n  var /** @type {string} */ theLabel = this.label;\n};\n\n\n/**\n * @private\n * @type {string}\n */\nFalconTest_A.prototype._label;\n\n\n" +
+				"FalconTest_A.prototype.get__label = function() {\n  return this._label;\n};\n\n\n" +
+				"FalconTest_A.prototype.set__label = function(value) {\n  this._label = value;\n};\n\n\n" +
+        		"Object.defineProperties(FalconTest_A.prototype, /** @lends {FalconTest_A.prototype} */ {\n/** @export */\n" +
+        		"label: {\nget: FalconTest_A.prototype.get__label,\nset: FalconTest_A.prototype.set__label}}\n);";
+        assertOut(expected);
+    }
+
     @Override
     protected IBackend createBackend()
     {

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/448df176/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
index a8e88d9..a6f4787 100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSClass.java
@@ -22,6 +22,7 @@ package org.apache.flex.compiler.internal.codegen.js.flexjs;
 import org.apache.flex.compiler.driver.IBackend;
 import org.apache.flex.compiler.internal.codegen.js.goog.TestGoogClass;
 import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
 import org.apache.flex.compiler.internal.projects.FlexJSProject;
 import org.apache.flex.compiler.internal.tree.as.FileNode;
 import org.apache.flex.compiler.tree.as.IClassNode;
@@ -37,6 +38,7 @@ public class TestFlexJSClass extends TestGoogClass
     {
         backend = createBackend();
         project = new FlexJSProject(workspace, backend);
+    	((FlexJSProject)project).config = new JSGoogConfiguration();
         super.setUp();
     }
     
@@ -220,6 +222,148 @@ public class TestFlexJSClass extends TestGoogClass
     }
 
     @Test
+    public void testBindableFields()
+    {
+        IClassNode node = getClassNode("public class A {[Bindable] public var a:Object;[Bindable] protected var b:String; "
+                + "[Bindable] private var c:int; internal var d:uint; var e:Number}");
+        asBlockWalker.visitClass(node);
+        assertOut("/**\n * @constructor\n" +
+        		  " */\norg.apache.flex.A = function() {\n" +
+        		  "};\n\n\n" +
+        		  "/**\n" +
+        		  " * @export\n" +
+        		  " * @type {Object}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.a_;\n\n\n" +
+        		  "/**\n" +
+        		  " * @protected\n" +
+        		  " * @type {string}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.b_;\n\n\n" +
+        		  "/**\n" +
+        		  " * @private\n" +
+        		  " * @type {number}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.c_ = 0;\n\n\n" +
+        		  "/**\n" +
+        		  " * @export\n" +
+        		  " * @type {number}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.d = 0;\n\n\n" +
+        		  "/**\n" +
+        		  " * @export\n" +
+        		  " * @type {number}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.e;Object.defineProperties(org.apache.flex.A.prototype, /** @lends {org.apache.flex.A.prototype} */ {\n" +
+        		  "/** @export\n" +
+        		  "  * @private\n" +
+        		  "  * @type {string} */\n" +
+        		  "b: {\n" +
+        		  "/** @this {org.apache.flex.A} */\n" +
+        		  "  get: function() {\n" +
+        		  "  return this.b_;\n" +
+    			  "  },\n" +
+    			  "\n" +
+    			  "/** @this {org.apache.flex.A} */\n" +
+    			  "set: function(value) {\n" +
+    			  "if (value != this.b_) {\n" +
+    			  "    var oldValue = this.b_;\n" +
+    			  "    this.b_ = value;\n" +
+    			  "    this.dispatchEvent(org.apache.flex.events.ValueChangeEvent.createUpdateEvent(\n" +
+    			  "         this, \"b\", oldValue, value));\n" +
+    			  "}\n" +
+    			  "}},/** @export\n" +
+    			  "  * @private\n" +
+    			  "  * @type {number} */\n" +
+    			  "c: {\n" +
+    			  "/** @this {org.apache.flex.A} */\n" +
+    			  "  get: function() {\n" +
+    			  "  return this.c_;\n" +
+    			  "  },\n" +
+    			  "\n" +
+    			  "/** @this {org.apache.flex.A} */\n" +
+    			  "set: function(value) {\n" +
+    			  "if (value != this.c_) {\n" +
+    			  "    var oldValue = this.c_;\n" +
+    			  "    this.c_ = value;\n" +
+    			  "    this.dispatchEvent(org.apache.flex.events.ValueChangeEvent.createUpdateEvent(\n" +
+    			  "         this, \"c\", oldValue, value));\n" +
+    			  "}\n" +
+    			  "}},/** @export\n" +
+    			  "  * @type {Object} */\n" +
+    			  "a: {\n" +
+    			  "/** @this {org.apache.flex.A} */\n" +
+    			  "  get: function() {\n" +
+    			  "  return this.a_;\n" +
+    			  "  },\n" +
+    			  "\n" +
+    			  "/** @this {org.apache.flex.A} */\n" +
+    			  "set: function(value) {\n" +
+    			  "if (value != this.a_) {\n" +
+    			  "    var oldValue = this.a_;\n" +
+    			  "    this.a_ = value;\n" +
+    			  "    this.dispatchEvent(org.apache.flex.events.ValueChangeEvent.createUpdateEvent(\n" +
+    			  "         this, \"a\", oldValue, value));\n" +
+    			  "}\n" +
+    			  "}}}\n" +
+        		  ");");
+    }
+
+    @Test
+    public void testBindableClass()
+    {
+        IClassNode node = getClassNode("[Bindable] public class A {public var a:Object;protected var b:String; "
+                + "private var c:int; internal var d:uint; var e:Number}");
+        asBlockWalker.visitClass(node);
+        assertOut("/**\n * @constructor\n" +
+        		  " */\norg.apache.flex.A = function() {\n" +
+        		  "};\n\n\n" +
+        		  "/**\n" +
+        		  " * @export\n" +
+        		  " * @type {Object}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.a_;\n\n\n" +
+        		  "/**\n" +
+        		  " * @protected\n" +
+        		  " * @type {string}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.b;\n\n\n" +
+        		  "/**\n" +
+        		  " * @private\n" +
+        		  " * @type {number}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.c = 0;\n\n\n" +
+        		  "/**\n" +
+        		  " * @export\n" +
+        		  " * @type {number}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.d = 0;\n\n\n" +
+        		  "/**\n" +
+        		  " * @export\n" +
+        		  " * @type {number}\n" +
+        		  " */\n" +
+        		  "org.apache.flex.A.prototype.e;Object.defineProperties(org.apache.flex.A.prototype, /** @lends {org.apache.flex.A.prototype} */ {\n" +
+        		  "/** @export\n" +
+        		  "  * @type {Object} */\n" +
+    			  "a: {\n" +
+    			  "/** @this {org.apache.flex.A} */\n" +
+    			  "  get: function() {\n" +
+    			  "  return this.a_;\n" +
+    			  "  },\n" +
+    			  "\n" +
+    			  "/** @this {org.apache.flex.A} */\n" +
+    			  "set: function(value) {\n" +
+    			  "if (value != this.a_) {\n" +
+    			  "    var oldValue = this.a_;\n" +
+    			  "    this.a_ = value;\n" +
+    			  "    this.dispatchEvent(org.apache.flex.events.ValueChangeEvent.createUpdateEvent(\n" +
+    			  "         this, \"a\", oldValue, value));\n" +
+    			  "}\n" +
+    			  "}}}\n" +
+        		  ");");
+    }
+
+    @Test
     public void testFieldsWithStaticInitializers()
     {
         IClassNode node = getClassNode("public class A {public static var a:int = 10;public static var b:String = initStatic(); "

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/448df176/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/TestBase.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/TestBase.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/TestBase.java
index 346ee10..53cf426 100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/TestBase.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/TestBase.java
@@ -183,6 +183,10 @@ public class TestBase implements ITestBase
     			continue;
     		if (problem.toString().equals("An externally-visible definition with the name 'TypeError' was unexpectedly found."))
     			continue;
+    		if (problem.toString().equals("An externally-visible definition with the name 'int' was unexpectedly found."))
+    			continue;
+    		if (problem.toString().equals("An externally-visible definition with the name 'uint' was unexpectedly found."))
+    			continue;
     		if (problem.toString().equals("No externally-visible definition with the name 'externals.as.classes.Object' was found."))
     			continue;
     		if (problem.toString().equals("No externally-visible definition with the name 'externals.as.classes.String' was found."))
@@ -199,6 +203,10 @@ public class TestBase implements ITestBase
     			continue;
     		if (problem.toString().equals("No externally-visible definition with the name 'externals.as.classes.TypeError' was found."))
     			continue;
+    		if (problem.toString().equals("No externally-visible definition with the name 'externals.as.classes.int' was found."))
+    			continue;
+    		if (problem.toString().equals("No externally-visible definition with the name 'externals.as.classes.uint' was found."))
+    			continue;
     		if (problem.toString().equals("An externally-visible definition with the name 'FalconTest_A' was unexpectedly found."))
     			continue;
     		if (problem.toString().startsWith("No externally-visible definition with the name 'TestFlexJSGlobalFunctions"))