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/08 21:54:56 UTC

svn commit: r1430524 - in /flex/whiteboard/mschmalle/falconjx: compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/ compiler.jx/src/org/apache/flex/compiler/as/codegen/ compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ c...

Author: erikdebruin
Date: Tue Jan  8 20:54:55 2013
New Revision: 1430524

URL: http://svn.apache.org/viewvc?rev=1430524&view=rev
Log:
- refactored a bit to give control over 'class' handling to the emitter instead of the walker
- created TestGoogClass and made overrides for JS (and/or 'goog') specific implementations
- implemented basic support for 'goog' style inheritance in JS output

Added:
    flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java   (with props)
Modified:
    flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogEmiter.java
    flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java
    flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java
    flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java
    flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
    flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java

Added: flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java?rev=1430524&view=auto
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java (added)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java Tue Jan  8 20:54:55 2013
@@ -0,0 +1,231 @@
+/*
+ *
+ *  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.compiler.internal.js.codegen.goog;
+
+import org.apache.flex.compiler.clients.IBackend;
+import org.apache.flex.compiler.internal.as.codegen.TestClass;
+import org.apache.flex.compiler.internal.js.codegen.JSSharedData;
+import org.apache.flex.compiler.internal.js.driver.goog.GoogBackend;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IFileNode;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This class tests the production of 'goog' JS code for Classes.
+ * 
+ * @author Michael Schmalle
+ * @author Erik de Bruin
+ */
+public class TestGoogClass extends TestClass
+{
+	@Override
+	@Test
+    public void testSimple()
+    {
+        IClassNode node = getClassNode("public class A{}");
+        visitor.visitClass(node);
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.A = function() {\n};\n\n");
+    }
+
+	@Override
+    @Test
+    public void testSimpleInternal()
+    {
+		// TODO (erikdebruin) is there a 'goog' equivalent for the 
+		//                    'internal' namespace?
+        IClassNode node = getClassNode("internal class A{}");
+        visitor.visitClass(node);
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.A = function() {\n};\n\n");
+    }
+
+	@Override
+    @Test
+    public void testSimpleFinal()
+    {
+		// TODO (erikdebruin) is there a 'goog' equivalent for the 
+		//                    'final' keyword?
+        IClassNode node = getClassNode("public final class A{}");
+        visitor.visitClass(node);
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.A = function() {\n};\n\n");
+    }
+
+	@Override
+    @Test
+    public void testSimpleExtends()
+    {
+        IClassNode node = getClassNode("public class A extends B {public function A() {}}");
+        visitor.visitClass(node);
+        assertOut("/**\n * @constructor\n */\norg.apache.flex.A = function() {\n\tgoog.base(this, optArgs);\n\n}\ngoog.inherits('childClass', 'parentClass');\n\n");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testSimpleImplements()
+    {
+        IClassNode node = getClassNode("public class A implements IA {}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testSimpleImplementsMultiple()
+    {
+        IClassNode node = getClassNode("public class A implements IA, IB, IC {}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testSimpleExtendsImplements()
+    {
+        IClassNode node = getClassNode("public class A extends B implements IA {}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testSimpleExtendsImplementsMultiple()
+    {
+        IClassNode node = getClassNode("public class A extends B implements IA, IB, IC {}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testSimpleFinalExtendsImplementsMultiple()
+    {
+        IClassNode node = getClassNode("public final class A extends B implements IA, IB, IC {}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testQualifiedExtendsImplementsMultiple()
+    {
+        IClassNode node = getClassNode("public class A extends goo.B implements foo.bar.IA, goo.foo.IB, baz.boo.IC {}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testConstructor()
+    {
+		// TODO (erikdebruin) replace 'super' call with 'goog.base()'... Can you
+		//                    call 'super' if the class doesn't extend any other?
+        IClassNode node = getClassNode("public class A {public function A() {super('foo', 42);}}");
+        JSSharedData.OUTPUT_JSDOC = false;
+        visitor.visitClass(node);
+        JSSharedData.OUTPUT_JSDOC = true;
+        assertOut("org.apache.flex.A = function() {\n\tsuper('foo', 42);\n};\n\n");
+    }
+    
+	@Ignore
+	@Override
+    @Test
+    public void testFields()
+    {
+        IClassNode node = getClassNode("public class A {public var a:Object;protected var b:String; "
+                + "private var c:int; internal var d:uint; var e:Number}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testConstants()
+    {
+        IClassNode node = getClassNode("public class A {" +
+        		"public static const A:int = 42;" +
+        		"protected static const B:Number = 42;" +
+                "private static const C:Number = 42;" +
+                "foo_bar static const C:String = 'me' + 'you';");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+    
+	@Ignore
+	@Override
+    @Test
+    public void testAccessors()
+    {
+        IClassNode node = getClassNode("public class A {"
+                + "public function get foo1():Object{return null;}"
+                + "public function set foo1(value:Object):void{}"
+                + "protected function get foo2():Object{return null;}"
+                + "protected function set foo2(value:Object):void{}"
+                + "private function get foo3():Object{return null;}"
+                + "private function set foo3(value:Object):void{}"
+                + "internal function get foo5():Object{return null;}"
+                + "internal function set foo5(value:Object):void{}"
+                + "foo_bar function get foo6():Object{return null;}"
+                + "foo_bar function set foo6(value:Object):void{}" + "}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Ignore
+	@Override
+    @Test
+    public void testMethods()
+    {
+        IClassNode node = getClassNode("public class A {"
+                + "public function foo1():Object{return null;}"
+                + "public final function foo1a():Object{return null;}"
+                + "override public function foo1b():Object{return super.foo1b();}"
+                + "protected function foo2(value:Object):void{}"
+                + "private function foo3(value:Object):void{}"
+                + "internal function foo5(value:Object):void{}"
+                + "foo_bar function foo6(value:Object):void{}"
+                + "public static function foo7(value:Object):void{}"
+                + "foo_bar static function foo7(value:Object):void{}" + "}");
+        visitor.visitClass(node);
+        //assertOut("");
+    }
+
+	@Override
+    protected IClassNode getClassNode(String code)
+    {
+        String source = "package org.apache.flex {" + code + "}";
+        IFileNode node = getFileNode(source);
+        IClassNode child = (IClassNode) findFirstDescendantOfType(node, IClassNode.class);
+        return child;
+    }
+    
+    protected IBackend createBackend()
+    {
+        return new GoogBackend();
+    }
+
+}

Propchange: flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogClass.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogEmiter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogEmiter.java?rev=1430524&r1=1430523&r2=1430524&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogEmiter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogEmiter.java Tue Jan  8 20:54:55 2013
@@ -54,7 +54,7 @@ public class TestGoogEmiter extends Test
                 + "return \"Don't \" + _privateVar + value; }";
         IFileNode node = getFileNode(code);
         visitor.visitFile(node);
-        assertOutDebug("goog.provide('com.example.components.MyTextButton');\n\ngoog.require('org.apache.flex.html.staticControls.TextButton');\n\n/**\n * @constructor\n */\ncom.example.components.MyTextButton = function() {\n\tif (foo() != 42) {\n\t\tbar();\n\t}\n};\n\n/**\n * @private\n * @type {string}\n */\ncom.example.components.MyTextButton.prototype._privateVar = \"do \";\n\n/**\n * @type {number}\n */\ncom.example.components.MyTextButton.prototype.publicProperty = 100;\n\n/**\n * @param {string} value\n * @return {string}\n */\ncom.example.components.MyTextButton.prototype.myFunction = function(value) {\n\treturn \"Don't \" + _privateVar + value;\n};\n\n");
+        assertOutDebug("goog.provide('com.example.components.MyTextButton');\n\ngoog.require('org.apache.flex.html.staticControls.TextButton');\n\n/**\n * @constructor\n */\ncom.example.components.MyTextButton = function() {\n\tgoog.base(this, optArgs);\n\n\tif (foo() != 42) {\n\t\tbar();\n\t}\n}\ngoog.inherits('childClass', 'parentClass');\n\n/**\n * @private\n * @type {string}\n */\ncom.example.components.MyTextButton.prototype._privateVar = \"do \";\n\n/**\n * @type {number}\n */\ncom.example.components.MyTextButton.prototype.publicProperty = 100;\n\n/**\n * @param {string} value\n * @return {string}\n */\ncom.example.components.MyTextButton.prototype.myFunction = function(value) {\n\tgoog.base(this, optArgs);\n\n\treturn \"Don't \" + _privateVar + value;\n};\n\n");
     }
 
     @Test

Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java?rev=1430524&r1=1430523&r2=1430524&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx.tests/src/org/apache/flex/compiler/internal/js/codegen/goog/TestGoogExpressions.java Tue Jan  8 20:54:55 2013
@@ -84,7 +84,7 @@ public class TestGoogExpressions extends
                 "var a:Object = function(foo:int, bar:String = 'goo'):int{return -1;};",
                 IVariableNode.class);
         visitor.visitVariable(node);
-        assertOutDebug("var a = function(foo, bar) {\n\tbar = typeof bar !== 'undefined' ? bar : 'goo';\n\treturn -1;\n}");
+        assertOut("var a = function(foo, bar) {\n\tbar = typeof bar !== 'undefined' ? bar : 'goo';\n\treturn -1;\n}");
     }
 
     @Override

Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java?rev=1430524&r1=1430523&r2=1430524&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/as/codegen/IASEmitter.java Tue Jan  8 20:54:55 2013
@@ -23,6 +23,7 @@ import java.io.Writer;
 
 import org.apache.flex.compiler.internal.tree.as.FunctionObjectNode;
 import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
 import org.apache.flex.compiler.tree.as.IExpressionNode;
 import org.apache.flex.compiler.tree.as.IFunctionNode;
 import org.apache.flex.compiler.tree.as.IGetterNode;
@@ -82,6 +83,13 @@ public interface IASEmitter
     void emitPackageFooter(IPackageNode node);
 
     /**
+     * Emit a Class.
+     * 
+     * @param node The {@link IClassNode} class.
+     */
+    void emitClass(IClassNode node);
+
+    /**
      * Emit a documentation comment for a Class field or constant
      * {@link IVariableNode}.
      * 

Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java?rev=1430524&r1=1430523&r2=1430524&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASBlockWalker.java Tue Jan  8 20:54:55 2013
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.Stack;
 
 import org.apache.flex.compiler.as.codegen.IASEmitter;
-import org.apache.flex.compiler.common.ASModifier;
 import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.definitions.IInterfaceDefinition;
 import org.apache.flex.compiler.definitions.ITypeDefinition;
@@ -278,100 +277,9 @@ public class ASBlockWalker implements IA
     @Override
     public void visitClass(IClassNode node)
     {
-        typeDefinition = node.getDefinition();
-
         debug("visitClass()");
 
-        emitter.write(node.getNamespace());
-        emitter.write(" ");
-
-        if (node.hasModifier(ASModifier.FINAL))
-        {
-            emitter.write("final");
-            emitter.write(" ");
-        }
-        emitter.write("class");
-        emitter.write(" ");
-        walk(node.getNameExpressionNode());
-        emitter.write(" ");
-
-        IExpressionNode bnode = node.getBaseClassExpressionNode();
-        if (bnode != null)
-        {
-            emitter.write("extends");
-            emitter.write(" ");
-            walk(bnode);
-            emitter.write(" ");
-        }
-
-        IExpressionNode[] inodes = node.getImplementedInterfaceNodes();
-        final int ilen = inodes.length;
-        if (ilen != 0)
-        {
-            emitter.write("implements");
-            emitter.write(" ");
-            for (int i = 0; i < ilen; i++)
-            {
-                walk(inodes[i]);
-                if (i < ilen - 1)
-                {
-                    emitter.write(",");
-                    emitter.write(" ");
-                }
-            }
-            emitter.write(" ");
-        }
-
-        emitter.write("{");
-
-        // fields, methods, namespaces
-        final IDefinitionNode[] members = node.getAllMemberNodes();
-        if (members.length > 0)
-        {
-            emitter.indentPush();
-            emitter.write("\n");
-
-            // there is always an implicit constructor if not explicit
-            currentConstructor = getConstructor(members);
-            if (currentConstructor == null)
-            {
-                // TODO (mschmalle) handle null constructor
-            }
-
-            // TODO (mschmalle) Check to see if the node order is the order of member parsed
-            final int len = members.length;
-            int i = 0;
-            for (IDefinitionNode mnode : members)
-            {
-                walk(mnode);
-                if (mnode.getNodeID() == ASTNodeID.VariableID)
-                {
-                    emitter.write(";");
-                    if (i < len - 1)
-                        emitter.write("\n");
-                }
-                else if (mnode.getNodeID() == ASTNodeID.FunctionID)
-                {
-                    if (i < len - 1)
-                        emitter.write("\n");
-                }
-                else if (mnode.getNodeID() == ASTNodeID.GetterID
-                        || mnode.getNodeID() == ASTNodeID.SetterID)
-                {
-                    if (i < len - 1)
-                        emitter.write("\n");
-                }
-                i++;
-            }
-
-            emitter.indentPop();
-        }
-
-        emitter.write("\n");
-        emitter.write("}");
-
-        typeDefinition = null;
-        currentConstructor = null;
+        emitter.emitClass(node);
     }
 
     @Override

Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java?rev=1430524&r1=1430523&r2=1430524&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/as/codegen/ASEmitter.java Tue Jan  8 20:54:55 2013
@@ -39,6 +39,7 @@ import org.apache.flex.compiler.tree.AST
 import org.apache.flex.compiler.tree.as.IASNode;
 import org.apache.flex.compiler.tree.as.IAccessorNode;
 import org.apache.flex.compiler.tree.as.IBinaryOperatorNode;
+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.IFunctionNode;
@@ -231,6 +232,97 @@ public class ASEmitter implements IASEmi
     //--------------------------------------------------------------------------
 
     @Override
+    public void emitClass(IClassNode node)
+    {
+        write(node.getNamespace());
+        write(" ");
+
+        if (node.hasModifier(ASModifier.FINAL))
+        {
+            write("final");
+            write(" ");
+        }
+        write("class");
+        write(" ");
+        getWalker().walk(node.getNameExpressionNode());
+        write(" ");
+
+        IExpressionNode bnode = node.getBaseClassExpressionNode();
+        if (bnode != null)
+        {
+            write("extends");
+            write(" ");
+            getWalker().walk(bnode);
+            write(" ");
+        }
+
+        IExpressionNode[] inodes = node.getImplementedInterfaceNodes();
+        final int ilen = inodes.length;
+        if (ilen != 0)
+        {
+            write("implements");
+            write(" ");
+            for (int i = 0; i < ilen; i++)
+            {
+            	getWalker().walk(inodes[i]);
+                if (i < ilen - 1)
+                {
+                    write(",");
+                    write(" ");
+                }
+            }
+            write(" ");
+        }
+
+        write("{");
+
+        // fields, methods, namespaces
+        final IDefinitionNode[] members = node.getAllMemberNodes();
+        if (members.length > 0)
+        {
+            indentPush();
+            write("\n");
+
+            // TODO (mschmalle) handle null constructor
+
+            // TODO (mschmalle) Check to see if the node order is the order of member parsed
+            final int len = members.length;
+            int i = 0;
+            for (IDefinitionNode mnode : members)
+            {
+                getWalker().walk(mnode);
+                if (mnode.getNodeID() == ASTNodeID.VariableID)
+                {
+                    write(";");
+                    if (i < len - 1)
+                        write("\n");
+                }
+                else if (mnode.getNodeID() == ASTNodeID.FunctionID)
+                {
+                    if (i < len - 1)
+                        write("\n");
+                }
+                else if (mnode.getNodeID() == ASTNodeID.GetterID
+                        || mnode.getNodeID() == ASTNodeID.SetterID)
+                {
+                    if (i < len - 1)
+                        write("\n");
+                }
+                i++;
+            }
+
+            indentPop();
+        }
+
+        write("\n");
+        write("}");
+    }
+    
+    //--------------------------------------------------------------------------
+    // 
+    //--------------------------------------------------------------------------
+
+    @Override
     public void emitVarDeclaration(IVariableNode node)
     {
         if (!(node instanceof ChainedVariableNode))

Modified: flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java
URL: http://svn.apache.org/viewvc/flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java?rev=1430524&r1=1430523&r2=1430524&view=diff
==============================================================================
--- flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java (original)
+++ flex/whiteboard/mschmalle/falconjx/compiler.jx/src/org/apache/flex/compiler/internal/js/codegen/goog/JSGoogEmitter.java Tue Jan  8 20:54:55 2013
@@ -156,14 +156,26 @@ public class JSGoogEmitter extends JSEmi
             return;
 
         IClassNode cnode = (IClassNode) type;
-        IClassDefinition definition = cnode.getDefinition();
+        
+        emitClass(cnode);
+    }
+
+    @Override
+    public void emitPackageFooter(IPackageNode node)
+    {
+    }
+
+    @Override
+    public void emitClass(IClassNode node)
+    {
+        IClassDefinition definition = node.getDefinition();
 
         // constructor
         emitConstructor((IFunctionNode) definition.getConstructor().getNode());
         write(";\n");
         write("\n");
 
-        IDefinitionNode[] members = cnode.getAllMemberNodes();
+        IDefinitionNode[] members = node.getAllMemberNodes();
         for (IDefinitionNode dnode : members)
         {
             if (dnode instanceof IVariableNode)
@@ -186,17 +198,97 @@ public class JSGoogEmitter extends JSEmi
                 }
             }
         }
-    }
 
-    @Override
-    public void emitPackageFooter(IPackageNode node)
-    {
-    }
+        /*
+    	write(node.getNamespace());
+        write(" ");
 
-    @Override
-    public void emitConstructor(IFunctionNode node)
-    {
+        if (node.hasModifier(ASModifier.FINAL))
+        {
+            write("final");
+            write(" ");
+        }
+        write("class");
+        write(" ");
+        getWalker().walk(node.getNameExpressionNode());
+        write(" ");
+
+        IExpressionNode bnode = node.getBaseClassExpressionNode();
+        if (bnode != null)
+        {
+            write("extends");
+            write(" ");
+            getWalker().walk(bnode);
+            write(" ");
+        }
+
+        IExpressionNode[] inodes = node.getImplementedInterfaceNodes();
+        final int ilen = inodes.length;
+        if (ilen != 0)
+        {
+            write("implements");
+            write(" ");
+            for (int i = 0; i < ilen; i++)
+            {
+            	getWalker().walk(inodes[i]);
+                if (i < ilen - 1)
+                {
+                    write(",");
+                    write(" ");
+                }
+            }
+            write(" ");
+        }
+
+        write("{");
+
+        // fields, methods, namespaces
+        final IDefinitionNode[] members = node.getAllMemberNodes();
+        if (members.length > 0)
+        {
+            indentPush();
+            write("\n");
+
+            final int len = members.length;
+            int i = 0;
+            for (IDefinitionNode mnode : members)
+            {
+                getWalker().walk(mnode);
+                if (mnode.getNodeID() == ASTNodeID.VariableID)
+                {
+                    write(";");
+                    if (i < len - 1)
+                        write("\n");
+                }
+                else if (mnode.getNodeID() == ASTNodeID.FunctionID)
+                {
+                    if (i < len - 1)
+                        write("\n");
+                }
+                else if (mnode.getNodeID() == ASTNodeID.GetterID
+                        || mnode.getNodeID() == ASTNodeID.SetterID)
+                {
+                    if (i < len - 1)
+                        write("\n");
+                }
+                i++;
+            }
+
+            indentPop();
+        }
+
+        write("\n");
+        write("}");
+        */
+    }
+    
+	@Override
+	public void emitConstructor(IFunctionNode node)
+	{
         IClassDefinition definition = getClassDefinition(node);
+        IClassNode cnode = (IClassNode) definition.getNode();
+    	
+        IExpressionNode bnode = cnode.getBaseClassExpressionNode();
 
         FunctionNode fn = (FunctionNode) node;
         fn.parseFunctionBody(new ArrayList<ICompilerProblem>());
@@ -210,7 +302,19 @@ public class JSGoogEmitter extends JSEmi
         write(" ");
         write("function");
         emitParamters(node.getParameterNodes());
-        emitMethodScope(node.getScopedNode());
+        if (node.getScopedNode().getChildCount() > 0 || bnode != null)
+        	emitMethodScope(node.getScopedNode());
+        else
+        	write(" {\n}");
+        
+        if (bnode != null)
+        {
+            write("\ngoog.inherits('");
+            write("childClass");
+            write("', '");
+            write("parentClass");
+            write("')");
+        }
     }
 
     @Override
@@ -374,6 +478,23 @@ public class JSGoogEmitter extends JSEmi
     @Override
     public void emitFunctionBlockHeader(IFunctionNode node)
     {
+    	// TODO (erikdebruin) create helper method
+        IClassDefinition definition = getClassDefinition(node);
+
+        IClassNode cnode = (IClassNode) definition.getNode();
+    	
+        IExpressionNode bnode = cnode.getBaseClassExpressionNode();
+        if (bnode != null)
+        {
+            if (!hasBody(node))
+            {
+                write("\t");
+            }
+            
+        	// TODO (erikdebruin) handle arguments when calling super
+            write("goog.base(this, optArgs);\n\n");
+        }
+        
         emitRestParameterCodeBlock(node);
 
         emitDefaultParameterCodeBlock(node);