Repository: flex-falcon
Updated Branches:
  refs/heads/develop d868ffda1 -> 9d605f29b


handle XML initializers in XML literals


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

Branch: refs/heads/develop
Commit: 9d605f29bb21ca9a9eb9f5cdbddb1608eb7b65b4
Parents: d868ffd
Author: Alex Harui <[email protected]>
Authored: Wed Jan 6 12:21:29 2016 -0800
Committer: Alex Harui <[email protected]>
Committed: Wed Jan 6 12:21:29 2016 -0800

----------------------------------------------------------------------
 .../js/flexjs/TestFlexJSGlobalClasses.java      | 14 +++++++
 .../internal/codegen/js/jx/LiteralEmitter.java  | 42 +++++++++++++++++---
 .../compiler/internal/parsing/as/ASParser.g     | 25 +++++++++++-
 .../internal/parsing/as/BaseASParser.java       | 27 +++++++++++++
 4 files changed, 102 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/9d605f29/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 815d997..35f6823 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
@@ -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.TestGoogGlobalClasses;
 import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
+import org.apache.flex.compiler.internal.tree.as.VariableNode;
 import org.apache.flex.compiler.tree.as.IASNode;
 import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
 import org.apache.flex.compiler.tree.as.IForLoopNode;
@@ -192,6 +193,19 @@ public class TestFlexJSGlobalClasses extends 
TestGoogGlobalClasses
     }
     
     @Test
+    public void testXMLLiteralWithTemplate()
+    {
+        VariableNode node = (VariableNode)getNode("private function get 
tagname():String { return 'name'; };\n" +
+                                                                "private 
function get attributename():String { return 'id'; };\n" +
+                                                                "private 
function get attributevalue():Number { return 5; };\n" +
+                                                                "private 
function get content():String { return 'Fred'; };\n" +
+                                                                "private 
function test() { var a:XML = <{tagname} 
{attributename}={attributevalue}>{content}</{tagname}>;}",
+                                                                
VariableNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {XML} */ a = new XML( '<' + this.tagname + ' 
' + this.attributename + '=' + this.attributevalue + '>' + this.content + '</' 
+ this.tagname + '>') ");
+    }
+    
+    @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;");

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/9d605f29/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
index 6945772..a4b276c 100644
--- 
a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
+++ 
b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
@@ -22,7 +22,11 @@ package org.apache.flex.compiler.internal.codegen.js.jx;
 import org.apache.flex.compiler.codegen.ISubEmitter;
 import org.apache.flex.compiler.codegen.js.IJSEmitter;
 import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
+import org.apache.flex.compiler.internal.tree.as.LiteralNode;
 import org.apache.flex.compiler.internal.tree.as.RegExpLiteralNode;
+import org.apache.flex.compiler.internal.tree.as.XMLLiteralNode;
+import org.apache.flex.compiler.tree.as.IASNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode.LiteralType;
 
@@ -45,12 +49,40 @@ public class LiteralEmitter extends JSSubEmitter implements
         {
             if (node.getLiteralType() == LiteralType.XML)
             {
-               if (s.contains("'"))
-                       write("\"" + s + "\"");
+               XMLLiteralNode xmlNode = (XMLLiteralNode)node;
+               if (xmlNode.getContentsNode().getChildCount() == 1)
+               {
+                       if (s.contains("'"))
+                               write("\"" + s + "\"");
+                       else
+                               write("'" + s + "'");
+                       isWritten = true;
+               }
                else
-                       write("'" + s + "'");
-
-                isWritten = true;
+               {
+                       // probably contains {initializers}
+                       int n = xmlNode.getContentsNode().getChildCount();
+                       for (int i = 0; i < n; i++)
+                       {
+                               if (i > 0)
+                                       write(" + ");
+                               IASNode child = 
xmlNode.getContentsNode().getChild(i);
+                               if (child instanceof LiteralNode)
+                               {
+                                       s = ((LiteralNode)child).getValue(true);
+                               if (s.contains("'"))
+                                       write("\"" + s + "\"");
+                               else
+                                       write("'" + s + "'");
+                               isWritten = true;
+                               }
+                               else if (child instanceof IdentifierNode)
+                               {
+                                       s = getEmitter().stringifyNode(child);
+                                       write(s);
+                               }
+                       }
+               }
             }
             s = s.replaceAll("\n", "__NEWLINE_PLACEHOLDER__");
             s = s.replaceAll("\r", "__CR_PLACEHOLDER__");

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/9d605f29/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
----------------------------------------------------------------------
diff --git 
a/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g 
b/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
index 9b21966..c84a089 100644
--- a/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
+++ b/compiler/src/org/apache/flex/compiler/internal/parsing/as/ASParser.g
@@ -2713,7 +2713,8 @@ xmlTag [BaseLiteralContainerNode n]
                )
         )
         xmlWhitespace[n]
-        (   ( xmlAttribute[n] | xmlContentBlock[n] )
+        (   ( { isXMLAttribute() }? xmlAttribute[n] 
+           | xmlContentBlock[n] )
             xmlWhitespace[n]
         )*
         (   endT:TOKEN_E4X_TAG_END                  // >
@@ -2732,12 +2733,16 @@ xmlTag [BaseLiteralContainerNode n]
  *     name="value"
  *     name='value'
  *     name={value}
+ *     {name}="value"
+ *     {name}='value'
+ *     {name}={value}
  */
 xmlAttribute [BaseLiteralContainerNode n]
     :   (   nT:TOKEN_E4X_NAME  
             { n.appendLiteralToken((ASToken)nT); }
         |   nsT:TOKEN_E4X_XMLNS 
             { n.appendLiteralToken((ASToken)nsT); }
+        |   xmlAttributeBlock[n]
         ) 
         (   dT:TOKEN_E4X_NAME_DOT 
             { n.appendLiteralToken((ASToken)dT); }
@@ -2806,6 +2811,24 @@ xmlContentBlock[BaseLiteralContainerNode n]
     
 
 /**
+ * Matches a binding expression in an XML literal attribute name.
+ */
+xmlAttributeBlock[BaseLiteralContainerNode n]
+{ 
+       ExpressionNodeBase e = null; 
+}
+    :   TOKEN_E4X_BINDING_OPEN 
+        e=lhsExpr 
+       { 
+            if(e != null) 
+                n.getContentsNode().addItem(e); 
+       }
+        TOKEN_E4X_BINDING_CLOSE
+    ;
+    exception catch [RecognitionException ex] { handleParsingError(ex); }
+    
+
+/**
  * Matches a left-hand side (of asssignment) expression.
  */
 lhsExpr returns [ExpressionNodeBase n]

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/9d605f29/compiler/src/org/apache/flex/compiler/internal/parsing/as/BaseASParser.java
----------------------------------------------------------------------
diff --git 
a/compiler/src/org/apache/flex/compiler/internal/parsing/as/BaseASParser.java 
b/compiler/src/org/apache/flex/compiler/internal/parsing/as/BaseASParser.java
index fb57848..83c9084 100644
--- 
a/compiler/src/org/apache/flex/compiler/internal/parsing/as/BaseASParser.java
+++ 
b/compiler/src/org/apache/flex/compiler/internal/parsing/as/BaseASParser.java
@@ -1312,6 +1312,33 @@ abstract class BaseASParser extends LLkParser implements 
IProblemReporter
     }
 
     /**
+     * Check if the look-ahead can be matched as a "XMLAttribute".
+     * 
+     * @return True if the following input is "XMLAttribute".
+     */
+    protected final boolean isXMLAttribute()
+    {
+        return LA(1) == TOKEN_E4X_NAME ||
+               LA(1) == TOKEN_E4X_XMLNS ||
+               (LA(1) == TOKEN_E4X_BINDING_OPEN && hasEqualsAfterClose());
+    }
+
+    /** 
+     * See if there is an assignment right after the close of the binding expr.
+     * If there is, then it is an attribute name otherwise no
+     */
+    private final boolean hasEqualsAfterClose()
+    {
+        int i = 2;
+        while (true)
+        {
+            if (LA(i) == TOKEN_E4X_BINDING_CLOSE)
+                return LA(i+1) == TOKEN_E4X_EQUALS;
+            i++;
+        }
+    }
+    
+    /**
      * Stores decorations on the given variable definition. This will set any
      * collected modifiers, namespace, metadata or comment we've encountered
      * 

Reply via email to