Repository: flex-falcon
Updated Branches:
  refs/heads/develop cc7de9c3c -> 448df1764


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/develop
Commit: 448df176471251106639ea2c2af52d8c77bf54f0
Parents: cc7de9c
Author: Alex Harui <aha...@apache.org>
Authored: Thu Jan 12 15:12:38 2017 -0800
Committer: Alex Harui <aha...@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"))

Reply via email to