Repository: flex-falcon
Updated Branches:
  refs/heads/develop 9c05264f8 -> 47cf23cd6


functions with [JSX] metadata register appropriate dependencies in the graph 
for their tags


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

Branch: refs/heads/develop
Commit: 58f31971851e98bfdd5652b5c1626be9bfc9f6c6
Parents: 9c05264
Author: Josh Tynjala <joshtynj...@gmail.com>
Authored: Sun Oct 16 17:00:10 2016 -0700
Committer: Josh Tynjala <joshtynj...@gmail.com>
Committed: Sun Oct 16 17:00:10 2016 -0700

----------------------------------------------------------------------
 .../internal/codegen/js/jx/LiteralEmitter.java  |  42 ++----
 .../internal/units/ASCompilationUnit.java       |  50 +++++++
 .../java/org/apache/flex/utils/JSXUtil.java     | 129 +++++++++++++++++++
 3 files changed, 188 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58f31971/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
index 176eb35..518c3a5 100644
--- 
a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/LiteralEmitter.java
@@ -19,13 +19,11 @@
 
 package org.apache.flex.compiler.internal.codegen.js.jx;
 
-import java.util.ArrayList;
 import java.util.Stack;
 
 import org.apache.flex.compiler.codegen.ISubEmitter;
 import org.apache.flex.compiler.codegen.js.IJSEmitter;
 import org.apache.flex.compiler.common.IMetaInfo;
-import org.apache.flex.compiler.common.Multiname;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
 import 
org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
@@ -34,10 +32,9 @@ 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.IFunctionNode;
-import org.apache.flex.compiler.tree.as.IImportNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode.LiteralType;
-import org.apache.flex.compiler.tree.as.IScopedNode;
+import org.apache.flex.utils.JSXUtil;
 
 public class LiteralEmitter extends JSSubEmitter implements
         ISubEmitter<ILiteralNode>
@@ -255,7 +252,7 @@ public class LiteralEmitter extends JSSubEmitter implements
                         {
                             //the close tag of the current element
                             elementName = elementName.substring(1);
-                            elementName = getQualifiedElementName(elementName, 
node);
+                            elementName = getElementNameToEmit(elementName, 
node);
                             if (elementStack.size() > 0)
                             {
                                 indentPop();
@@ -275,7 +272,7 @@ public class LiteralEmitter extends JSSubEmitter implements
                                 indentPush();
                                 writeNewline(ASEmitterTokens.COMMA);
                             }
-                            elementName = getQualifiedElementName(elementName, 
node);
+                            elementName = getElementNameToEmit(elementName, 
node);
                             elementStack.push(elementName);
                             write("React.createElement");
                             write(ASEmitterTokens.PAREN_OPEN);
@@ -421,35 +418,14 @@ public class LiteralEmitter extends JSSubEmitter 
implements
         write(ASEmitterTokens.SINGLE_QUOTE);
     }
 
-    private String getQualifiedElementName(String elementName, IASNode node)
+    private String getElementNameToEmit(String elementName, IASNode node)
     {
-        String firstChar = elementName.substring(0, 1);
-        boolean isHTMLTag = firstChar.toLowerCase().equals(firstChar);
-        if (isHTMLTag)
+        String qualifiedTypeName = 
JSXUtil.getQualifiedTypeForElementName(elementName, node);
+        if (qualifiedTypeName != null)
         {
-            return ASEmitterTokens.SINGLE_QUOTE.getToken() + elementName + 
ASEmitterTokens.SINGLE_QUOTE.getToken();
+            return qualifiedTypeName;
         }
-        ArrayList<IImportNode> importNodes = new ArrayList<IImportNode>();
-        IScopedNode scopedNode = node.getContainingScope();
-        scopedNode.getAllImportNodes(importNodes);
-        for (IImportNode importNode : importNodes)
-        {
-            if (importNode.isWildcardImport())
-            {
-                continue;
-            }
-            String importName = importNode.getImportName();
-            String importAlias = importNode.getImportAlias();
-            if (importAlias != null && importAlias.equals(elementName))
-            {
-                return importName;
-            }
-            String baseName = Multiname.getBaseNameForQName(importName);
-            if (baseName.equals(elementName))
-            {
-                return importName;
-            }
-        }
-        return elementName;
+        //it's a basic HTML tag
+        return ASEmitterTokens.SINGLE_QUOTE.getToken() + elementName + 
ASEmitterTokens.SINGLE_QUOTE.getToken();
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58f31971/compiler/src/main/java/org/apache/flex/compiler/internal/units/ASCompilationUnit.java
----------------------------------------------------------------------
diff --git 
a/compiler/src/main/java/org/apache/flex/compiler/internal/units/ASCompilationUnit.java
 
b/compiler/src/main/java/org/apache/flex/compiler/internal/units/ASCompilationUnit.java
index c44e95b..6dc8951 100644
--- 
a/compiler/src/main/java/org/apache/flex/compiler/internal/units/ASCompilationUnit.java
+++ 
b/compiler/src/main/java/org/apache/flex/compiler/internal/units/ASCompilationUnit.java
@@ -29,6 +29,8 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.flex.compiler.clients.ASC;
+import org.apache.flex.compiler.common.DependencyType;
+import org.apache.flex.compiler.common.IMetaInfo;
 import org.apache.flex.compiler.definitions.IDefinition;
 import org.apache.flex.compiler.filespecs.FileSpecification;
 import org.apache.flex.compiler.filespecs.IFileSpecification;
@@ -41,6 +43,8 @@ import org.apache.flex.compiler.internal.scopes.ASFileScope;
 import org.apache.flex.compiler.internal.semantics.PostProcessStep;
 import org.apache.flex.compiler.internal.tree.as.ClassNode;
 import org.apache.flex.compiler.internal.tree.as.FileNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.internal.tree.as.XMLLiteralNode;
 import 
org.apache.flex.compiler.internal.units.requests.ASFileScopeRequestResult;
 import org.apache.flex.compiler.internal.units.requests.SWFTagsRequestResult;
 import org.apache.flex.compiler.problems.ICompilerProblem;
@@ -55,6 +59,7 @@ import 
org.apache.flex.compiler.units.requests.IOutgoingDependenciesRequestResul
 import org.apache.flex.compiler.units.requests.IRequest;
 import org.apache.flex.compiler.units.requests.ISWFTagsRequestResult;
 import org.apache.flex.compiler.units.requests.ISyntaxTreeRequestResult;
+import org.apache.flex.utils.JSXUtil;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableSet;
@@ -466,6 +471,7 @@ public class ASCompilationUnit extends CompilationUnitBase
         getABCBytesRequest().get();
 
         updateEmbedCompilationUnitDependencies(fn.getEmbedNodes(), problems);
+        updateJSXDependencies(fn);
 
         IOutgoingDependenciesRequestResult result = new 
IOutgoingDependenciesRequestResult()
         {
@@ -480,6 +486,50 @@ public class ASCompilationUnit extends CompilationUnitBase
         return result;
     }
 
+    /**
+     * Iterate through all methods with [JSX] metadata, adding the
+     * ICompilationUnit dependencies
+     * 
+     * @throws InterruptedException
+     */
+    private void updateJSXDependencies(IASNode node) throws 
InterruptedException
+    {
+        if (node instanceof FunctionNode)
+        {
+            FunctionNode functionNode = (FunctionNode) node;
+            for (IMetaInfo metaInfo : functionNode.getMetaInfos())
+            {
+                if (metaInfo.getTagName().equals("JSX"))
+                {
+                    //we need to parse XML in this function's body
+                    functionNode.parseFunctionBody(new 
ArrayList<ICompilerProblem>());
+                }
+            }
+        }
+        if (node instanceof XMLLiteralNode)
+        {
+            XMLLiteralNode xmlNode = (XMLLiteralNode) node;
+            CompilerProject project = getProject();
+            ArrayList<String> qualifiedNames = new ArrayList<String>();
+            JSXUtil.findQualifiedNamesInXMLLiteral(xmlNode, qualifiedNames);
+            for (String qualifiedName : qualifiedNames)
+            {
+                ICompilationUnit cu = 
project.resolveQNameToCompilationUnit(qualifiedName);
+                if (cu != null)
+                {
+                    project.addDependency(this, cu, DependencyType.EXPRESSION, 
cu.getQualifiedNames().get(0));
+                }
+            }
+        }
+        else
+        {
+            for (int i = 0, count = node.getChildCount(); i < count; i++)
+            {
+                updateJSXDependencies(node.getChild(i));
+            }
+        }
+    }
+
     @Override
     protected void removeAST()
     {

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/58f31971/compiler/src/main/java/org/apache/flex/utils/JSXUtil.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/utils/JSXUtil.java 
b/compiler/src/main/java/org/apache/flex/utils/JSXUtil.java
new file mode 100644
index 0000000..0e8940f
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/utils/JSXUtil.java
@@ -0,0 +1,129 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.flex.compiler.common.Multiname;
+import org.apache.flex.compiler.internal.tree.as.XMLLiteralNode;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IImportNode;
+import org.apache.flex.compiler.tree.as.ILiteralNode;
+import org.apache.flex.compiler.tree.as.IScopedNode;
+
+/**
+ * Utilities for parsing XML in functions with [JSX] metadata.
+ */
+public class JSXUtil
+{
+    public static void findQualifiedNamesInXMLLiteral(XMLLiteralNode node, 
List<String> qualifiedNames)
+    {
+        int childCount = node.getContentsNode().getChildCount();
+        for (int i = 0; i < childCount; i++)
+        {
+            IASNode child = node.getContentsNode().getChild(i);
+            if (child instanceof ILiteralNode)
+            {
+                ILiteralNode literalChild = (ILiteralNode) child;
+                if (literalChild.getLiteralType() == 
ILiteralNode.LiteralType.XML)
+                {
+                    findQualifiedNamesInXMLLiteralChild(literalChild, 
qualifiedNames);
+                }
+            }
+        }
+    }
+    
+    private static void findQualifiedNamesInXMLLiteralChild(ILiteralNode node, 
List<String> qualifiedNames)
+    {
+        String value = node.getValue();
+        while (true)
+        {
+            int index = value.indexOf("<");
+            if (index == -1)
+            {
+                break;
+            }
+            value = value.substring(index + 1);
+            index = value.indexOf(">");
+            int spaceIndex = value.indexOf(" ");
+            if (spaceIndex == -1)
+            {
+                spaceIndex = value.length();
+            }
+            if (index == -1 || index > spaceIndex)
+            {
+                index = spaceIndex;
+            }
+            String elementName = value.substring(0, index);
+            if (elementName.endsWith("/"))
+            {
+                //strip the / from self-closing tags
+                elementName = elementName.substring(0, elementName.length() - 
1);
+            }
+            //ignore end tags
+            if (!elementName.startsWith("/"))
+            {
+                String qualifiedElementName = 
getQualifiedTypeForElementName(elementName, node);
+                if (qualifiedElementName != null)
+                {
+                    qualifiedNames.add(qualifiedElementName);
+                }
+            }
+            value = value.substring(index + 1);
+        }
+    }
+
+    /**
+     * Finds the qualified type name for an <element> in JSX. Returns null if
+     * the element name is a basic HTML tag.
+     */
+    public static String getQualifiedTypeForElementName(String elementName, 
IASNode node)
+    {
+        String firstChar = elementName.substring(0, 1);
+        boolean isHTMLTag = firstChar.toLowerCase().equals(firstChar);
+        if (isHTMLTag)
+        {
+            return null;
+        }
+        ArrayList<IImportNode> importNodes = new ArrayList<IImportNode>();
+        IScopedNode scopedNode = node.getContainingScope();
+        scopedNode.getAllImportNodes(importNodes);
+        for (IImportNode importNode : importNodes)
+        {
+            if (importNode.isWildcardImport())
+            {
+                continue;
+            }
+            String importName = importNode.getImportName();
+            String importAlias = importNode.getImportAlias();
+            if (importAlias != null && importAlias.equals(elementName))
+            {
+                return importName;
+            }
+            String baseName = Multiname.getBaseNameForQName(importName);
+            if (baseName.equals(elementName))
+            {
+                return importName;
+            }
+        }
+        return elementName;
+    }
+}

Reply via email to