switch XML member access to child() calls

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

Branch: refs/heads/develop
Commit: 1fb6f371f836f4871f6afbecf8ec31332f555ccc
Parents: f6e619c
Author: Alex Harui <[email protected]>
Authored: Wed Nov 18 14:44:15 2015 -0800
Committer: Alex Harui <[email protected]>
Committed: Wed Nov 18 14:44:15 2015 -0800

----------------------------------------------------------------------
 .../js/flexjs/TestFlexJSGlobalClasses.java      | 48 +++++++++++++---
 .../codegen/js/flexjs/JSFlexJSEmitter.java      |  8 +--
 .../codegen/js/jx/MemberAccessEmitter.java      | 58 +++++++++++++-------
 3 files changed, 81 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/1fb6f371/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSGlobalClasses.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSGlobalClasses.java
 
b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSGlobalClasses.java
index ffe44b1..c837390 100644
--- 
a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSGlobalClasses.java
+++ 
b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSGlobalClasses.java
@@ -190,6 +190,26 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     }
     
     @Test
+    public void testXMLSingleDot()
+    {
+        IVariableNode node = getVariable("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:XMLList = a.child;");
+        IASNode parentNode = node.getParent();
+        node = (IVariableNode) parentNode.getChild(1);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {XMLList} */ b = a.child('child')");
+    }
+    
+    @Test
+    public void testXMLSingleDotChain()
+    {
+        IVariableNode node = getVariable("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:XMLList = 
a.child.grandchild;");
+        IASNode parentNode = node.getParent();
+        node = (IVariableNode) parentNode.getChild(1);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {XMLList} */ b = 
a.child('child').child('grandchild')");
+    }
+    
+    @Test
     public void testXMLDelete()
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");delete a.child;");
@@ -202,7 +222,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");delete a.child.grandchild;");
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("a.child.removeChild('grandchild')");
+        assertOut("a.child('child').removeChild('grandchild')");
     }
 
     @Test
@@ -211,7 +231,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
         IUnaryOperatorNode node = getUnaryNode("public var a:XML = new 
XML(\"<top attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");private function foo() { delete 
this.a.child.grandchild;}",
                        WRAP_LEVEL_CLASS);
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("this.a.child.removeChild('grandchild')");
+        assertOut("this.a.child('child').removeChild('grandchild')");
     }
     
     @Test
@@ -219,7 +239,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:Object = { xml: a};delete 
XML(b.xml).child.grandchild;");
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("org.apache.flex.utils.Language.as(b.xml, XML, 
true).child.removeChild('grandchild')");
+        assertOut("org.apache.flex.utils.Language.as(b.xml, XML, 
true).child('child').removeChild('grandchild')");
     }
     
     @Test
@@ -227,7 +247,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:Object = { xml: a};delete 
(b.xml as XML).child.grandchild;");
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("org.apache.flex.utils.Language.as(b.xml, 
XML).child.removeChild('grandchild')");
+        assertOut("org.apache.flex.utils.Language.as(b.xml, 
XML).child('child').removeChild('grandchild')");
     }    
 
     @Test
@@ -235,7 +255,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");delete a.child[0];");
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("a.child.removeChildAt(0)");
+        assertOut("a.child('child').removeChildAt(0)");
     }
     
     @Test
@@ -243,7 +263,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");delete a.child.grandchild[0];");
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("a.child.grandchild.removeChildAt(0)");
+        assertOut("a.child('child').child('grandchild').removeChildAt(0)");
     }
     
     @Test
@@ -252,7 +272,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
         IUnaryOperatorNode node = getUnaryNode("public var a:XML = new 
XML(\"<top attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");private function foo() { delete 
this.a.child.grandchild[0];}",
                        WRAP_LEVEL_CLASS);
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("this.a.child.grandchild.removeChildAt(0)");
+        
assertOut("this.a.child('child').child('grandchild').removeChildAt(0)");
     }
     
     @Test
@@ -260,7 +280,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:Object = { xml: a};delete 
XML(b.xml).child.grandchild[0];");
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("org.apache.flex.utils.Language.as(b.xml, XML, 
true).child.grandchild.removeChildAt(0)");
+        assertOut("org.apache.flex.utils.Language.as(b.xml, XML, 
true).child('child').child('grandchild').removeChildAt(0)");
     }
     
     @Test
@@ -268,7 +288,7 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     {
         IUnaryOperatorNode node = getUnaryNode("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:Object = { xml: a};delete 
(b.xml as XML).child.grandchild[0];");
         asBlockWalker.visitUnaryOperator(node);
-        assertOut("org.apache.flex.utils.Language.as(b.xml, 
XML).child.grandchild.removeChildAt(0)");
+        assertOut("org.apache.flex.utils.Language.as(b.xml, 
XML).child('child').child('grandchild').removeChildAt(0)");
     }
     
     @Test
@@ -282,6 +302,16 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     }
     
     @Test
+    public void testXMLListLengthFunction()
+    {
+       IVariableNode node = getVariable("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:int = a.child.length();");
+        IASNode parentNode = node.getParent();
+        node = (IVariableNode) parentNode.getChild(1);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {number} */ b = a.child('child').length()");
+    }
+    
+    @Test
     public void testXMLDoubleDot()
     {
         IVariableNode node = getVariable("var a:XML = new XML(\"<top 
attr1='cat'><child attr2='dog'><grandchild 
attr3='fish'>text</grandchild></child></top>\");var b:XMLList = a..child;");

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/1fb6f371/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index 2677035..c87cadc 100644
--- 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@ -495,11 +495,11 @@ public class JSFlexJSEmitter extends JSGoogEmitter 
implements IJSFlexJSEmitter
                        if (ASNodeUtils.hasParenOpen(node))
                            write(ASEmitterTokens.PAREN_OPEN);
                        
-                   String s = stringifyNode(node.getChild(0));
-                   int c = s.lastIndexOf(".");
-                   write(s.substring(0, c));
+                   String s = stringifyNode(obj.getLeftOperandNode());
+                   write(s);
                    write(".removeChild('");
-                   write(s.substring(c + 1));
+                   s = stringifyNode(obj.getRightOperandNode());
+                   write(s);
                    write("')");
                        if (ASNodeUtils.hasParenClose(node))
                            write(ASEmitterTokens.PAREN_CLOSE);

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/1fb6f371/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
index b572e8d..2f5aa55 100644
--- 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
@@ -29,7 +29,10 @@ import 
org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens
 import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
 import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
 import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
 import org.apache.flex.compiler.internal.tree.as.GetterNode;
+import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
+import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
 import org.apache.flex.compiler.internal.tree.as.UnaryOperatorAtNode;
 import org.apache.flex.compiler.projects.ICompilerProject;
 import org.apache.flex.compiler.tree.ASTNodeID;
@@ -63,29 +66,44 @@ public class MemberAccessEmitter extends JSSubEmitter 
implements
         IDefinition def = node.resolve(getProject());
         if (def == null)
         {
+               IASNode parentNode = node.getParent();
                // could be XML
                JSFlexJSEmitter fjs = (JSFlexJSEmitter)getEmitter();
-               if (fjs.isXML((IExpressionNode) leftNode) &&
-                               node.getOperator() == 
OperatorType.DESCENDANT_ACCESS)
+               boolean isXML = false;
+               if (leftNode instanceof MemberAccessExpressionNode)
+                       isXML = 
fjs.isXMLList((MemberAccessExpressionNode)leftNode);
+               else if (leftNode instanceof IExpressionNode)
+                       isXML = fjs.isXML((IExpressionNode)leftNode);
+               if (isXML)
                {
-                       writeLeftSide(node, leftNode, rightNode);
-                       write(".descendants('");
-                       String s = fjs.stringifyNode(rightNode);
-                       int dot = s.indexOf('.');
-                       if (dot != -1)
-                       {
-                               String name = s.substring(0, dot);
-                               String afterDot = s.substring(dot);
-                               write(name);
-                               write("')");
-                               write(afterDot);
-                       }
-                       else
-                       {
-                               write(s);
-                               write("')");
-                       }
-                       return;
+                       boolean descendant = (node.getOperator() == 
OperatorType.DESCENDANT_ACCESS);
+                       boolean child = (node.getOperator() == 
OperatorType.MEMBER_ACCESS) && 
+                                                               (!(parentNode 
instanceof FunctionCallNode)) &&
+                                                               
rightNode.getNodeID() != ASTNodeID.Op_AtID;
+                       if (descendant || child)
+                       {
+                               writeLeftSide(node, leftNode, rightNode);
+                               if (descendant)
+                                       write(".descendants('");
+                               if (child)
+                                       write(".child('");                      
                
+                               String s = fjs.stringifyNode(rightNode);
+                               int dot = s.indexOf('.');
+                               if (dot != -1)
+                               {
+                                       String name = s.substring(0, dot);
+                                       String afterDot = s.substring(dot);
+                                       write(name);
+                                       write("')");
+                                       write(afterDot);
+                               }
+                               else
+                               {
+                                       write(s);
+                                       write("')");
+                               }
+                               return;
+                       }
                }
         }
         boolean isStatic = false;

Reply via email to