flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mschma...@apache.org
Subject svn commit: r1426038 - in /incubator/flex/whiteboard/mschmalle/falconjx: compiler.jx.tests/src/org/apache/flex/js/internal/js/codegen/ compiler.jx/src/org/apache/flex/compiler/as/ compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ compiler.j...
Date Wed, 26 Dec 2012 21:57:17 GMT
Author: mschmalle
Date: Wed Dec 26 21:57:16 2012
New Revision: 1426038

URL: http://svn.apache.org/viewvc?rev=1426038&view=rev
Log:
Flex:FalconJx
- implemented function block header for default parameters

Modified:
    incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/js/internal/js/codegen/TestGoogEmiter.java
    incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/IASEmitter.java
    incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
    incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/ASBlockWalker.java
    incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/JSGoogEmitter.java

Modified: incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/js/internal/js/codegen/TestGoogEmiter.java
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/js/internal/js/codegen/TestGoogEmiter.java?rev=1426038&r1=1426037&r2=1426038&view=diff
==============================================================================
--- incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/js/internal/js/codegen/TestGoogEmiter.java
(original)
+++ incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/js/internal/js/codegen/TestGoogEmiter.java
Wed Dec 26 21:57:16 2012
@@ -94,6 +94,72 @@ public class TestGoogEmiter extends Test
                 + "function(bar, baz, goo) {\n}");
     }
 
+    @Test
+    public void testDefaultParameter_NoBody()
+    {
+        /*
+        foo.bar.A = function(bar, bax) {
+            if (arguments.length < 2) {
+                if (arguments.length < 1) {
+                    bar = 42;
+                }
+                bax = 4;
+            }
+        }
+        */
+        JSSharedData.OUTPUT_JSDOC = false;
+        IFunctionNode node = getMethod("function foo(bar:int = 42, bax:int = 4):void{\n}");
+        visitor.visitFunction(node);
+        assertOut("foo.bar.A = function(bar, bax) {\n\tif (arguments.length < 2) {\n\t\t"
+                + "if (arguments.length < 1) {\n\t\t\tbar = 42;\n\t\t}\n\t\tbax = 4;\n\t}\n}");
+        JSSharedData.OUTPUT_JSDOC = true;
+    }
+
+    @Test
+    public void testDefaultParameter_Body()
+    {
+        /*
+        foo.bar.A = function(bar, bax) {
+            if (arguments.length < 2) {
+                if (arguments.length < 1) {
+                    bar = 42;
+                }
+                bax = 4;
+            }
+        }
+        */
+        JSSharedData.OUTPUT_JSDOC = false;
+        IFunctionNode node = getMethod("function foo(bar:int = 42, bax:int = 4):void{if (a)
foo();}");
+        visitor.visitFunction(node);
+        assertOut("foo.bar.A = function(bar, bax) {\n\tif (arguments.length < 2) {\n\t\t"
+                + "if (arguments.length < 1) {\n\t\t\tbar = 42;\n\t\t}\n\t\tbax = 4;\n\t}\n\t"
+                + "if (a)\n\t\tfoo();\n}");
+        JSSharedData.OUTPUT_JSDOC = true;
+    }
+
+    @Test
+    public void testDefaultParameter()
+    {
+        /*
+         foo.bar.A = function(p1, p2, p3, p4) {
+            if (arguments.length < 4) {
+                if (arguments.length < 3) {
+                    p3 = 3;
+                }
+                p4 = 4;
+            }
+            return p1 + p2 + p3 + p4;
+         }
+         */
+        JSSharedData.OUTPUT_JSDOC = false;
+        IFunctionNode node = getMethod("function foo(p1:int, p2:int, p3:int = 3, p4:int =
4):int{return p1 + p2 + p3 + p4;}");
+        visitor.visitFunction(node);
+        assertOut("foo.bar.A = function(p1, p2, p3, p4) {\n\tif (arguments.length < 4)
"
+                + "{\n\t\tif (arguments.length < 3) {\n\t\t\tp3 = 3;\n\t\t}\n\t\tp4 =
4;\n\t}"
+                + "\n\treturn p1 + p2 + p3 + p4;\n}");
+        JSSharedData.OUTPUT_JSDOC = true;
+    }
+
     protected IBackend createBackend()
     {
         return new GoogBackend();

Modified: incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/IASEmitter.java
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/IASEmitter.java?rev=1426038&r1=1426037&r2=1426038&view=diff
==============================================================================
--- incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/IASEmitter.java
(original)
+++ incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/IASEmitter.java
Wed Dec 26 21:57:16 2012
@@ -150,4 +150,6 @@ public interface IASEmitter
      */
     void emitFunctionObject(IExpressionNode node);
 
+    void emitFunctionBlockHeader(IFunctionNode node);
+
 }

Modified: incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java?rev=1426038&r1=1426037&r2=1426038&view=diff
==============================================================================
--- incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
(original)
+++ incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
Wed Dec 26 21:57:16 2012
@@ -64,6 +64,11 @@ public class ASEmitter implements IASEmi
     private final FilterWriter out;
 
     private int currentIndent = 0;
+    
+    protected int getCurrentIndent()
+    {
+        return currentIndent;
+    }
 
     private IASBlockWalker walker;
 
@@ -104,7 +109,15 @@ public class ASEmitter implements IASEmi
             throw new RuntimeException(e);
         }
     }
-
+    
+    protected String getIndent(int numIndent)
+    {
+        String indent = "";
+        for (int i = 0; i < numIndent; i++)
+            indent += INDENT_STRING;
+        return indent;
+    }
+    
     @Override
     public void indentPush()
     {
@@ -456,7 +469,7 @@ public class ASEmitter implements IASEmi
             getWalker().walk(anode);
         }
     }
-    
+
     protected void emitType(IExpressionNode node)
     {
         // TODO (mschmalle) node.getVariableTypeNode() will return "*" if undefined, what
to use?
@@ -479,6 +492,12 @@ public class ASEmitter implements IASEmi
         }
     }
 
+    @Override
+    public void emitFunctionBlockHeader(IFunctionNode node)
+    {
+        // nothing to do in AS
+    }
+
     protected void emitMethodScope(IScopedNode node)
     {
         write(" ");
@@ -508,7 +527,7 @@ public class ASEmitter implements IASEmi
         }
         return null;
     }
-    
+
     protected static IFunctionNode getConstructor(IDefinitionNode[] members)
     {
         for (IDefinitionNode node : members)
@@ -523,5 +542,4 @@ public class ASEmitter implements IASEmi
         return null;
     }
 
-
 }

Modified: incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/ASBlockWalker.java
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/ASBlockWalker.java?rev=1426038&r1=1426037&r2=1426038&view=diff
==============================================================================
--- incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/ASBlockWalker.java
(original)
+++ incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/ASBlockWalker.java
Wed Dec 26 21:57:16 2012
@@ -545,6 +545,11 @@ public class ASBlockWalker implements IA
     public void visitBlock(IBlockNode node)
     {
         debug("visitBlock()");
+        if (node.getParent().getNodeID() == ASTNodeID.FunctionID)
+        {
+            emitter.emitFunctionBlockHeader((IFunctionNode) node.getParent());
+        }
+        
         final int len = node.getChildCount();
         for (int i = 0; i < len; i++)
         {

Modified: incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/JSGoogEmitter.java
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/JSGoogEmitter.java?rev=1426038&r1=1426037&r2=1426038&view=diff
==============================================================================
--- incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/JSGoogEmitter.java
(original)
+++ incubator/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codgen/JSGoogEmitter.java
Wed Dec 26 21:57:16 2012
@@ -21,6 +21,10 @@ package org.apache.flex.compiler.interna
 
 import java.io.FilterWriter;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.definitions.IPackageDefinition;
@@ -34,6 +38,7 @@ import org.apache.flex.compiler.tree.as.
 import org.apache.flex.compiler.tree.as.IFunctionNode;
 import org.apache.flex.compiler.tree.as.IPackageNode;
 import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.IScopedNode;
 import org.apache.flex.compiler.tree.as.ITypeNode;
 import org.apache.flex.compiler.tree.as.IVariableNode;
 
@@ -197,6 +202,70 @@ public class JSGoogEmitter extends JSEmi
     }
 
     @Override
+    public void emitFunctionBlockHeader(IFunctionNode node)
+    {
+        emitDefaultParameterCodeBlock(node);
+    }
+
+    private void emitDefaultParameterCodeBlock(IFunctionNode node)
+    {
+        // TODO (mschmalle) test for ... rest 
+        // if default parameters exist, produce the init code
+        IParameterNode[] pnodes = node.getParameterNodes();
+        Map<Integer, IParameterNode> defaults = getDefaults(pnodes);
+        final StringBuilder code = new StringBuilder();
+        if (defaults != null)
+        {
+            List<IParameterNode> parameters = new ArrayList<IParameterNode>(
+                    defaults.values());
+            Collections.reverse(parameters);
+            
+            int len = defaults.size();
+            int numDefaults = 0;
+            // make the header in reverse order
+            for (IParameterNode pnode : parameters)
+            {
+                if (pnode != null)
+                {
+                    code.append(getIndent(numDefaults));
+                    code.append("if (arguments.length < " + len + ") {\n");
+                    numDefaults++;
+                }
+                len--;
+            }
+            
+            Collections.reverse(parameters);
+            for (IParameterNode pnode : parameters)
+            {
+                if (pnode != null)
+                {
+                    code.append(getIndent(numDefaults));
+                    code.append(pnode.getName());
+                    code.append(" = ");
+                    code.append(pnode.getDefaultValue());
+                    code.append(";\n");
+                    code.append(getIndent(numDefaults - 1));
+                    code.append("}");
+                    if (numDefaults > 1)
+                        code.append("\n");
+                    numDefaults--;
+                }
+            }
+            IScopedNode sbn = node.getScopedNode();
+            boolean hasBody = sbn.getChildCount() > 0;
+            // adds the current block indent to the generated code
+            String indent = getIndent(getCurrentIndent() + (!hasBody ? 1 : 0));
+            String result = code.toString().replaceAll("\n", "\n" + indent);
+            // if the block dosn't have a body (children), need to add indent to head
+            if (!hasBody)
+                result = indent + result;
+            // have to add newline after the replace or we get an extra indent
+            result += "\n";
+            write(result);
+        }
+    }
+
+    @Override
     public void emitParameter(IParameterNode node)
     {
         // only the name gets output in JS
@@ -217,4 +286,29 @@ public class JSGoogEmitter extends JSEmi
         return (ITypeDefinition) tnode.getDefinition();
     }
 
+    private Map<Integer, IParameterNode> getDefaults(IParameterNode[] nodes)
+    {
+        Map<Integer, IParameterNode> result = new HashMap<Integer, IParameterNode>();
+        int i = 0;
+        boolean hasDefaults = false;
+        for (IParameterNode node : nodes)
+        {
+            if (node.hasDefaultValue())
+            {
+                hasDefaults = true;
+                result.put(i, node);
+            }
+            else
+            {
+                result.put(i, null);
+            }
+            i++;
+        }
+
+        if (!hasDefaults)
+            return null;
+
+        return result;
+    }
+
 }



Mime
View raw message