You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by er...@apache.org on 2013/01/19 16:57:01 UTC

svn commit: r1435576 - in /flex/falcon/trunk: compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/ compiler.jx.tests/test-files/ compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ compiler.jx/src/org/apache/flex/compiler/...

Author: erikdebruin
Date: Sat Jan 19 15:57:01 2013
New Revision: 1435576

URL: http://svn.apache.org/viewvc?rev=1435576&view=rev
Log:
- added support for 'super()' calls (through 'goog.base')

Added:
    flex/falcon/trunk/compiler.jx.tests/test-files/call-super.as   (with props)
    flex/falcon/trunk/compiler.jx.tests/test-files/call-super_result.js   (with props)
Modified:
    flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java
    flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
    flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
    flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java

Modified: flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java?rev=1435576&r1=1435575&r2=1435576&view=diff
==============================================================================
--- flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java (original)
+++ flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogAccessorMembers.java Sat Jan 19 15:57:01 2013
@@ -73,7 +73,7 @@ public class TestGoogAccessorMembers ext
     	//                    anonymous function...
     	IGetterNode node = (IGetterNode) getAccessor("public override function get foo():int{super.foo(); return -1;}");
         visitor.visitGetter(node);
-        assertOut("Object.defineProperty(\n\tA.prototype, \n\t'foo', \n\t{get:function() {\n\t\tsuper.foo();\n\t\treturn -1;\n\t}, configurable:true}\n)");
+        assertOut("Object.defineProperty(\n\tA.prototype, \n\t'foo', \n\t{get:function() {\n\t\tgoog.base(this, 'foo');\n\t\treturn -1;\n\t}, configurable:true}\n)");
     }
 
     @Override
@@ -121,7 +121,7 @@ public class TestGoogAccessorMembers ext
         // TODO (erikdebruin) see: testGetAccessor_withNamespaceOverride
     	ISetterNode node = (ISetterNode) getAccessor("public override function set foo(value:int):void{super.foo();}");
         visitor.visitSetter(node);
-        assertOut("Object.defineProperty(\n\tA.prototype, \n\t'foo', \n\t{set:function(value) {\n\t\tsuper.foo();\n\t}, configurable:true}\n)");
+        assertOut("Object.defineProperty(\n\tA.prototype, \n\t'foo', \n\t{set:function(value) {\n\t\tgoog.base(this, 'foo');\n\t}, configurable:true}\n)");
     }
 
     @Override

Modified: flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java?rev=1435576&r1=1435575&r2=1435576&view=diff
==============================================================================
--- flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java (original)
+++ flex/falcon/trunk/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java Sat Jan 19 15:57:01 2013
@@ -144,7 +144,6 @@ public class TestGoogClass extends TestC
         assertOut("/**\n * @constructor\n * @extends {spark.components.Button}\n * @implements {flash.events.IEventDispatcher}\n * @implements {mx.logging.ILogger}\n */\norg.apache.flex.A = function() {\n\tgoog.base(this);\n}\ngoog.inherits(org.apache.flex.A, spark.components.Button);");
     }
 
-	@Ignore
 	@Override
     @Test
     public void testConstructor()
@@ -153,7 +152,7 @@ public class TestGoogClass extends TestC
 		//                    call 'super' if the class doesn't extend any other?
         IClassNode node = getClassNode("public class A {public function A() {super('foo', 42);}}");
         visitor.visitClass(node);
-        assertOut("");
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.A = function() {\n\tgoog.base(this, 'foo', 42);\n};");
     }
     
 	@Override

Added: flex/falcon/trunk/compiler.jx.tests/test-files/call-super.as
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/test-files/call-super.as?rev=1435576&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx.tests/test-files/call-super.as (added)
+++ flex/falcon/trunk/compiler.jx.tests/test-files/call-super.as Sat Jan 19 15:57:01 2013
@@ -0,0 +1,20 @@
+package org.apache.flex
+{
+
+import spark.components.Button;
+
+public dynamic class A extends spark.components.Button
+{
+	public function A()
+	{
+		super();
+	}
+	
+	public function hasSuperCall(a:String, b:Number)
+	{
+		super.hasSuperCall(a, b, 100);
+		
+		var result:String = myRegularFunctionCall(-1);
+	}
+}
+}
\ No newline at end of file

Propchange: flex/falcon/trunk/compiler.jx.tests/test-files/call-super.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/falcon/trunk/compiler.jx.tests/test-files/call-super_result.js
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx.tests/test-files/call-super_result.js?rev=1435576&view=auto
==============================================================================
--- flex/falcon/trunk/compiler.jx.tests/test-files/call-super_result.js (added)
+++ flex/falcon/trunk/compiler.jx.tests/test-files/call-super_result.js Sat Jan 19 15:57:01 2013
@@ -0,0 +1,21 @@
+goog.provide('org.apache.flex.A');
+
+goog.require('spark.components.Button');
+
+/**
+ * @constructor
+ * @extends {spark.components.Button}
+ */
+org.apache.flex.A = function() {
+	goog.base(this);
+}
+goog.inherits(org.apache.flex.A, spark.components.Button);
+
+/**
+ * @param {string} a
+ * @param {number} b
+ */
+org.apache.flex.A.prototype.hasSuperCall = function(a, b) {
+	goog.base(this, 'hasSuperCall', a, b, 100);
+	var /** @type {string} */ result = myRegularFunctionCall(-1);
+};
\ No newline at end of file

Propchange: flex/falcon/trunk/compiler.jx.tests/test-files/call-super_result.js
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java?rev=1435576&r1=1435575&r2=1435576&view=diff
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java (original)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java Sat Jan 19 15:57:01 2013
@@ -1100,7 +1100,7 @@ public class ASEmitter implements IASEmi
         return null;
     }
 
-    private static boolean isLastStatement(IASNode node)
+    protected static boolean isLastStatement(IASNode node)
     {
         return getChildIndex(node.getParent(), node) == node.getParent()
                 .getChildCount() - 1;

Modified: flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java
URL: http://svn.apache.org/viewvc/flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java?rev=1435576&r1=1435575&r2=1435576&view=diff
==============================================================================
--- flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java (original)
+++ flex/falcon/trunk/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java Sat Jan 19 15:57:01 2013
@@ -34,6 +34,7 @@ import org.apache.flex.compiler.definiti
 import org.apache.flex.compiler.definitions.ITypeDefinition;
 import org.apache.flex.compiler.internal.js.codegen.JSEmitter;
 import org.apache.flex.compiler.internal.tree.as.ChainedVariableNode;
+import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
 import org.apache.flex.compiler.internal.tree.as.FunctionNode;
 import org.apache.flex.compiler.js.codegen.goog.IJSGoogDocEmitter;
 import org.apache.flex.compiler.js.codegen.goog.IJSGoogEmitter;
@@ -46,6 +47,7 @@ import org.apache.flex.compiler.tree.as.
 import org.apache.flex.compiler.tree.as.IClassNode;
 import org.apache.flex.compiler.tree.as.IDefinitionNode;
 import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.tree.as.IFunctionCallNode;
 import org.apache.flex.compiler.tree.as.IFunctionNode;
 import org.apache.flex.compiler.tree.as.IGetterNode;
 import org.apache.flex.compiler.tree.as.IIdentifierNode;
@@ -63,6 +65,10 @@ import org.apache.flex.compiler.tree.as.
  */
 public class JSGoogEmitter extends JSEmitter implements IJSGoogEmitter
 {
+	private static final String CONSTRUCTOR_EMPTY = "emptyConstructor";
+	private static final String CONSTRUCTOR_FULL = "fullConstructor";
+	private static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";
+	
     public static final String GOOG_BASE = "goog.base";
     public static final String GOOG_INHERITS = "goog.inherits";
     public static final String GOOG_PROVIDE = "goog.provide";
@@ -249,8 +255,8 @@ public class JSGoogEmitter extends JSEmi
     	
         if (avnode != null)
         {
-	        String opCode = avnode.getNodeID().getParaphrase();
-	        if (opCode != "AnonymousFunction")
+        	String opcode = avnode.getNodeID().getParaphrase();
+	        if (opcode != "AnonymousFunction")
 	        	getDoc().emitVarDoc(node);
         }
         else
@@ -349,72 +355,119 @@ public class JSGoogEmitter extends JSEmi
         
         emitParamters(node.getParameterNodes());
 
-        if (isConstructor)
-        {
-            boolean hasSuperClass = hasSuperClass(node, project);
+        boolean hasSuperClass = hasSuperClass(node);
 
-            if (node.getScopedNode().getChildCount() > 0 || hasSuperClass)
-            {
-            	emitMethodScope(node.getScopedNode());
-            }
-            else
-            {
-            	write(SPACE);
-            	write(CURLYBRACE_OPEN);
-                writeNewline();
-            	write(CURLYBRACE_CLOSE);
-            }
-            
+        if (isConstructor && node.getScopedNode().getChildCount() == 0)
+        {
+        	write(SPACE);
+        	write(CURLYBRACE_OPEN);
             if (hasSuperClass)
-            {
-                /* \ngoog.inherits(x, y) */
-                writeNewline();
-                write(GOOG_INHERITS);
-                write(PARENTHESES_OPEN);
-                write(qname);
-                write(COMMA);
-                write(SPACE);
-                String sname = getSuperClassDefinition(node, project).getQualifiedName();
-                write(sname);
-                write(PARENTHESES_CLOSE);
-            }
-            
-            return;
+        		emitSuperCall(node, CONSTRUCTOR_EMPTY);
+            writeNewline();
+        	write(CURLYBRACE_CLOSE);
         }
 
-        emitMethodScope(node.getScopedNode());
+        if (!isConstructor || node.getScopedNode().getChildCount() > 0)
+        	emitMethodScope(node.getScopedNode());
+
+        if (isConstructor && hasSuperClass)
+        {
+            /* \ngoog.inherits(x, y) */
+            writeNewline();
+            write(GOOG_INHERITS);
+            write(PARENTHESES_OPEN);
+            write(qname);
+            write(COMMA);
+            write(SPACE);
+            String sname = getSuperClassDefinition(node, project).getQualifiedName();
+            write(sname);
+            write(PARENTHESES_CLOSE);
+        }
+    }
+
+    @Override
+    public void emitFunctionCall(IFunctionCallNode node)
+    {
+    	ASTNodeID id = node.getChild(0).getNodeID();
+    	
+    	if (id == ASTNodeID.MemberAccessExpressionID)
+    		id = node.getChild(0).getChild(0).getNodeID();
+    	
+    	if (id != ASTNodeID.SuperID)
+    		super.emitFunctionCall(node);
+    	else
+    		emitSuperCall(node, SUPER_FUNCTION_CALL);
     }
 
     @Override
     public void emitFunctionBlockHeader(IFunctionNode node)
     {
-    	emitSuperCallCodeBlock(node);
+    	if (node.isConstructor() && hasSuperClass(node))
+    		emitSuperCall(node, CONSTRUCTOR_FULL);
         
         emitRestParameterCodeBlock(node);
 
         emitDefaultParameterCodeBlock(node);
     }
 
-    private void emitSuperCallCodeBlock(IFunctionNode node)
+    private void emitSuperCall(IASNode node, String type)
     {
-        IClassNode cnode = (IClassNode) node.getAncestorOfType(IClassNode.class);
-    	
-        IExpressionNode bnode = cnode.getBaseClassExpressionNode();
-        if (bnode != null && node.isConstructor())
-        {
-            if (!hasBody(node))
-                write(INDENT);
-            
-        	// TODO (erikdebruin) handle arguments when calling super
-            write(GOOG_BASE);
-            write(PARENTHESES_OPEN);
-            write(IASKeywordConstants.THIS);
-            write(PARENTHESES_CLOSE);
-            write(SEMICOLON);
-            writeNewline();
-        }
-    }
+    	IFunctionNode fnode = 
+    			(node instanceof IFunctionNode) ? (IFunctionNode) node : null;
+    	IFunctionCallNode fcnode = 
+    			(node instanceof IFunctionCallNode) ? (FunctionCallNode) node : null;
+
+    	if (type == CONSTRUCTOR_EMPTY)
+    	{
+        	indentPush();
+    		writeNewline();
+    		indentPop();
+    	}
+    	else if (type == SUPER_FUNCTION_CALL)
+    	{
+    		if (fnode == null)
+    			fnode = (IFunctionNode) fcnode.getAncestorOfType(IFunctionNode.class);
+    	}
+
+    	write(GOOG_BASE);
+    	write(PARENTHESES_OPEN);
+    	write(IASKeywordConstants.THIS);
+
+    	if (fnode != null && !fnode.isConstructor())
+    	{
+    		write(COMMA);
+    		write(SPACE);
+    		write(SINGLE_QUOTE);
+    		write(fnode.getName());
+    		write(SINGLE_QUOTE);
+    	}
+
+    	if (fcnode != null)
+    	{
+    		IExpressionNode[] enodes = fcnode.getArgumentNodes();
+    		int len = enodes.length;
+    		for (int i = 0; i < len; i++)
+    		{
+    			write(COMMA);
+    			write(SPACE);
+
+    			getWalker().walk(enodes[i]);
+    		}
+    	}
+
+    	write(PARENTHESES_CLOSE);
 
+    	if (type == CONSTRUCTOR_FULL)
+    	{
+        	write(SEMICOLON);
+        	writeNewline();
+    	}
+    	else if (type == CONSTRUCTOR_EMPTY)
+    	{
+        	write(SEMICOLON);
+    	}
+    }
+    
     private void emitDefaultParameterCodeBlock(IFunctionNode node)
     {
         IParameterNode[] pnodes = node.getParameterNodes();
@@ -580,8 +633,9 @@ public class JSGoogEmitter extends JSEmi
         return superClass;
     }
 
-    private static boolean hasSuperClass(IDefinitionNode node, ICompilerProject project)
+    private boolean hasSuperClass(IDefinitionNode node)
     {
+    	ICompilerProject project = getWalker().getProject();
     	IClassDefinition superClassDefinition = getSuperClassDefinition(node, project);
     	String qname = superClassDefinition.getQualifiedName();
     	return superClassDefinition != null && !qname.equals(IASLanguageConstants.Object);
@@ -647,9 +701,6 @@ public class JSGoogEmitter extends JSEmi
         write(FUNCTION);
         emitParamters(node.getParameterNodes());
 
-        // ToDo (erikdebruin/mschmalle) fix 'empty' function body when testing 
-        //                              accessors in the context of an entire
-        //                              class instead of only function definition
         emitMethodScope(node.getScopedNode());
         
         write(COMMA);