handle complex static initializers especially when the initializer is defined 
after the variable


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

Branch: refs/heads/feature-autobuild/maven-archetypes
Commit: 73fd82c7ce826857fd30d4201459c64d856ff7c7
Parents: ecd8e1c
Author: Alex Harui <aha...@apache.org>
Authored: Thu Oct 6 21:21:51 2016 -0700
Committer: Alex Harui <aha...@apache.org>
Committed: Thu Oct 6 21:22:03 2016 -0700

----------------------------------------------------------------------
 .../codegen/js/flexjs/JSFlexJSEmitter.java      |  5 ++
 .../internal/codegen/js/jx/ClassEmitter.java    | 19 +++++
 .../internal/codegen/js/jx/FieldEmitter.java    | 78 +++++++++++++++++---
 .../internal/codegen/js/utils/EmitterUtils.java | 12 +++
 .../codegen/js/flexjs/TestFlexJSClass.java      |  9 +++
 .../js/flexjs/TestFlexJSFieldMembers.java       |  2 +-
 6 files changed, 114 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/73fd82c7/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index 443bbbd..a74b346 100644
--- 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@ -293,6 +293,11 @@ public class JSFlexJSEmitter extends JSGoogEmitter 
implements IJSFlexJSEmitter
         return bindableEmitter;
     }
 
+    public FieldEmitter getFieldEmitter()
+    {
+        return fieldEmitter;
+    }
+
     public ClassEmitter getClassEmitter()
     {
         return classEmitter;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/73fd82c7/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
index fe0bc7e..3b28e5f 100644
--- 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
@@ -146,6 +146,25 @@ public class ClassEmitter extends JSSubEmitter implements
         fjs.getBindableEmitter().emit(definition);
         fjs.getAccessorEmitter().emit(definition);
         
+        if (fjs.getFieldEmitter().hasComplexStaticInitializers)
+        {
+            writeNewline();
+            
+               for (IDefinitionNode dnode : dnodes)
+               {
+                   if (dnode.getNodeID() == ASTNodeID.VariableID)
+                   {
+                       writeNewline();
+                       
fjs.getFieldEmitter().emitFieldInitializer((IVariableNode) dnode);
+                   }
+                   else if (dnode.getNodeID() == ASTNodeID.BindableVariableID)
+                   {
+                       writeNewline();
+                       
fjs.getFieldEmitter().emitFieldInitializer((IVariableNode) dnode);
+                   }
+               }
+        }
+        
         fjs.getPackageFooterEmitter().emitClassInfo(node);
 
         getEmitter().popSourceMapName();

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/73fd82c7/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
index 1906b21..23459c4 100644
--- 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/FieldEmitter.java
@@ -51,6 +51,8 @@ public class FieldEmitter extends JSSubEmitter implements
         super(emitter);
     }
 
+    public boolean hasComplexStaticInitializers = false;
+    
     @Override
     public void emit(IVariableNode node)
     {
@@ -71,13 +73,15 @@ public class FieldEmitter extends JSSubEmitter implements
 
         IDefinition ndef = node.getDefinition();
 
+        String className = null;
         String root = "";
         IVariableDefinition.VariableClassification classification = 
node.getVariableClassification();
         boolean isPackageOrFileMember = classification == 
IVariableDefinition.VariableClassification.PACKAGE_MEMBER ||
                 classification == 
IVariableDefinition.VariableClassification.FILE_MEMBER;
         if (isPackageOrFileMember)
         {
-            write(getEmitter().formatQualifiedName(node.getQualifiedName()));
+               className = 
getEmitter().formatQualifiedName(node.getQualifiedName());
+            write(className);
         }
         else
         {
@@ -92,7 +96,8 @@ public class FieldEmitter extends JSSubEmitter implements
                 definition = ndef.getContainingScope().getDefinition();
 
             startMapping(node.getNameExpressionNode());
-            
write(getEmitter().formatQualifiedName(definition.getQualifiedName())
+            className = 
getEmitter().formatQualifiedName(definition.getQualifiedName());
+            write(className
                     + ASEmitterTokens.MEMBER_ACCESS.getToken() + root);
             write(node.getName());
             endMapping(node.getNameExpressionNode());
@@ -105,15 +110,24 @@ public class FieldEmitter extends JSSubEmitter implements
             write("_");
         }
         IExpressionNode vnode = node.getAssignedValueNode();
-        if (vnode != null &&
-                (ndef.isStatic() || EmitterUtils.isScalar(vnode) || 
isPackageOrFileMember))
+        if (vnode != null)
         {
-            startMapping(node);
-            write(ASEmitterTokens.SPACE);
-            writeToken(ASEmitterTokens.EQUAL);
-            endMapping(node);
-            getEmitter().getWalker().walk(vnode);
-        }
+            String vnodeString = getEmitter().stringifyNode(vnode);
+               if ((ndef.isStatic() && 
!EmitterUtils.needsStaticInitializer(vnodeString, className)) || 
+                               (!ndef.isStatic() && 
EmitterUtils.isScalar(vnode)) ||
+                               isPackageOrFileMember)
+               {
+                   startMapping(node);
+                   write(ASEmitterTokens.SPACE);
+                   writeToken(ASEmitterTokens.EQUAL);
+                   endMapping(node);
+                   write(vnodeString);
+               }
+               else if (ndef.isStatic() && 
EmitterUtils.needsStaticInitializer(vnodeString, className))
+               {
+                       hasComplexStaticInitializers = true;
+               }
+        }        
         if (vnode == null && def != null)
         {
             String defName = def.getQualifiedName();
@@ -157,4 +171,48 @@ public class FieldEmitter extends JSSubEmitter implements
         }
     }
 
+    public void emitFieldInitializer(IVariableNode node)
+    {
+        IDefinition definition = EmitterUtils.getClassDefinition(node);
+
+        IDefinition def = null;
+        IExpressionNode enode = 
node.getVariableTypeNode();//getAssignedValueNode();
+        if (enode != null)
+        {
+            def = enode.resolveType(getProject());
+        }
+
+        IDefinition ndef = node.getDefinition();
+        String className = null;
+
+        IVariableDefinition.VariableClassification classification = 
node.getVariableClassification();
+        boolean isPackageOrFileMember = classification == 
IVariableDefinition.VariableClassification.PACKAGE_MEMBER ||
+                classification == 
IVariableDefinition.VariableClassification.FILE_MEMBER;
+        IExpressionNode vnode = node.getAssignedValueNode();
+        if (vnode != null)
+        {
+            String vnodeString = getEmitter().stringifyNode(vnode);
+            if (definition == null)
+                definition = ndef.getContainingScope().getDefinition();
+            className = 
getEmitter().formatQualifiedName(definition.getQualifiedName());
+               if (ndef.isStatic() && 
EmitterUtils.needsStaticInitializer(vnodeString, className) && 
!isPackageOrFileMember)
+               {
+                write(className
+                        + ASEmitterTokens.MEMBER_ACCESS.getToken());
+                write(node.getName());
+       
+                   if (node.getNodeID() == ASTNodeID.BindableVariableID)
+                   {
+                       // add an underscore to convert this var to be the
+                       // backing var for the get/set pair that will be 
generated later.
+                       write("_");
+                   }
+                   write(ASEmitterTokens.SPACE);
+                   writeToken(ASEmitterTokens.EQUAL);
+                   write(vnodeString);
+                   write(ASEmitterTokens.SEMICOLON);
+       
+               }
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/73fd82c7/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
index 9ca2829..635c6c0 100644
--- 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
+++ 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
@@ -464,6 +464,18 @@ public class EmitterUtils
         return false;
     }
 
+    // return true if the node is an expression that may not work
+    // as the initial value of a static var at
+    // static initialization time.  Such as a function call to
+    // another static method in the class.
+    // Non-static initializers have different rules: even simple object
+    // and arrays need to be created for each instance, but for statics
+    // simple objects and arras are ok.
+    public static boolean needsStaticInitializer(String node, String className)
+    {
+       return node.contains(className);
+    }
+
     public static IContainerNode insertArgumentsBefore(IContainerNode 
argumentsNode, IASNode... nodes)
     {
         int originalLength = argumentsNode.getChildCount();

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/73fd82c7/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 f03414d..8b91070 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
@@ -224,6 +224,15 @@ public class TestFlexJSClass extends TestGoogClass
         assertOut("/**\n * @constructor\n */\norg.apache.flex.A = function() 
{\n};\n\n\n/**\n * @export\n * @type {Object}\n 
*/\norg.apache.flex.A.prototype.a;\n\n\n/**\n * @protected\n * @type {string}\n 
*/\norg.apache.flex.A.prototype.b;\n\n\n/**\n * @private\n * @type {number}\n 
*/\norg.apache.flex.A.prototype.c = 0;\n\n\n/**\n * @export\n * @type 
{number}\n */\norg.apache.flex.A.prototype.d = 0;\n\n\n/**\n * @export\n * 
@type {number}\n */\norg.apache.flex.A.prototype.e;");
     }
 
+    @Test
+    public void testFieldsWithStaticInitializers()
+    {
+        IClassNode node = getClassNode("public class A {public static var 
a:int = 10;public static var b:String = initStatic(); "
+                + "private static function initStatic():String { return 
\"foo\"; }}");
+        asBlockWalker.visitClass(node);
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.A = function() 
{\n};\n\n\n/**\n * @export\n * @type {number}\n */\norg.apache.flex.A.a = 
10;\n\n\n/**\n * @export\n * @type {string}\n 
*/\norg.apache.flex.A.b;\n\n\n/**\n * @private\n * @return {string}\n 
*/\norg.apache.flex.A.initStatic = function() {\n  return 
\"foo\";\n};\n\n\norg.apache.flex.A.b = org.apache.flex.A.initStatic();");
+    }
+    
     @Override
     @Test
     public void testConstants()

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/73fd82c7/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSFieldMembers.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSFieldMembers.java
 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSFieldMembers.java
index cee8429..dddfab6 100644
--- 
a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSFieldMembers.java
+++ 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSFieldMembers.java
@@ -185,7 +185,7 @@ public class TestFlexJSFieldMembers extends 
TestGoogFieldMembers
        IClassNode node = (IClassNode) getNode("import 
flash.utils.flash_proxy;use namespace flash_proxy;public static var foo:Object 
= initFoo(); flash_proxy static function initFoo():Object { return null; }",
                        IClassNode.class, WRAP_LEVEL_CLASS);
         asBlockWalker.visitClass(node);
-        assertOut("/**\n * @constructor\n */\nFalconTest_A = function() 
{\n};\n\n\n/**\n * @export\n * @type {Object}\n */\nFalconTest_A.foo = 
FalconTest_A[\"http://www.adobe.com/2006/actionscript/flash/proxy::initFoo\";]();\n\n\n/**\n
 * @export\n * @return {Object}\n 
*/\nFalconTest_A[\"http://www.adobe.com/2006/actionscript/flash/proxy::initFoo\";]
 = function() {\n  return null;\n};");
+        assertOut("/**\n * @constructor\n */\nFalconTest_A = function() 
{\n};\n\n\n/**\n * @export\n * @type {Object}\n 
*/\nFalconTest_A.foo;\n\n\n/**\n * @export\n * @return {Object}\n 
*/\nFalconTest_A[\"http://www.adobe.com/2006/actionscript/flash/proxy::initFoo\";]
 = function() {\n  return null;\n};\n\nFalconTest_A.foo = 
FalconTest_A[\"http://www.adobe.com/2006/actionscript/flash/proxy::initFoo\";]();");
     }
     
     @Test

Reply via email to