You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ms...@apache.org on 2015/05/31 01:24:09 UTC

git commit: [flex-falcon] [refs/heads/develop] - - Refactored member access expression to emitter. - Refactored Package header to emitter. - Refactored Package footer to emitter.

Repository: flex-falcon
Updated Branches:
  refs/heads/develop b8147d9c1 -> dbad22c99


- Refactored member access expression to emitter.
- Refactored Package header to emitter.
- Refactored Package footer to emitter.


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

Branch: refs/heads/develop
Commit: dbad22c9946806c437fda3ef30616c4e46932dc3
Parents: b8147d9
Author: Michael Schmalle <ms...@apache.org>
Authored: Sat May 30 19:23:46 2015 -0400
Committer: Michael Schmalle <ms...@apache.org>
Committed: Sat May 30 19:23:46 2015 -0400

----------------------------------------------------------------------
 .../compiler/internal/codegen/as/ASEmitter.java |   2 +-
 .../codegen/js/flexjs/JSFlexJSEmitter.java      | 567 +++----------------
 .../internal/codegen/js/jx/ClassEmitter.java    |   1 +
 .../internal/codegen/js/jx/GetSetEmitter.java   |  95 ++++
 .../codegen/js/jx/MemberAccessEmitter.java      | 148 +++++
 .../codegen/js/jx/PackageFooterEmitter.java     | 138 +++++
 .../codegen/js/jx/PackageHeaderEmitter.java     | 221 ++++++++
 .../internal/codegen/js/utils/EmitterUtils.java |  26 +-
 8 files changed, 718 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
index 84d1ac5..26b1100 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/as/ASEmitter.java
@@ -783,7 +783,7 @@ public class ASEmitter implements IASEmitter, IEmitter
         // nothing to do in AS
     }
 
-    protected void emitMethodScope(IScopedNode node)
+    public void emitMethodScope(IScopedNode node)
     {
         write(ASEmitterTokens.SPACE);
         getWalker().walk(node);

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
index 955e033..7aa4e2a 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java
@@ -20,15 +20,12 @@
 package org.apache.flex.compiler.internal.codegen.js.flexjs;
 
 import java.io.FilterWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
 
 import org.apache.flex.compiler.asdoc.flexjs.ASDocComment;
 import org.apache.flex.compiler.codegen.IDocEmitter;
 import org.apache.flex.compiler.codegen.js.flexjs.IJSFlexJSEmitter;
 import org.apache.flex.compiler.common.ASModifier;
 import org.apache.flex.compiler.common.IMetaInfo;
-import org.apache.flex.compiler.common.ModifiersSet;
 import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.definitions.IDefinition;
 import org.apache.flex.compiler.definitions.IFunctionDefinition;
@@ -36,7 +33,6 @@ import org.apache.flex.compiler.definitions.IPackageDefinition;
 import org.apache.flex.compiler.definitions.ITypeDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
-import org.apache.flex.compiler.internal.codegen.js.JSSessionModel.PropertyNodes;
 import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitter;
 import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.jx.BinaryOperatorEmitter;
@@ -44,18 +40,13 @@ import org.apache.flex.compiler.internal.codegen.js.jx.ClassEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.FieldEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.FunctionCallEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.IdentifierEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.MemberAccessEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.PackageFooterEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.PackageHeaderEmitter;
 import org.apache.flex.compiler.internal.codegen.js.jx.SuperCallEmitter;
-import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
-import org.apache.flex.compiler.internal.projects.FlexJSProject;
-import org.apache.flex.compiler.internal.scopes.ASProjectScope;
-import org.apache.flex.compiler.internal.scopes.PackageScope;
-import org.apache.flex.compiler.internal.tree.as.ClassNode;
 import org.apache.flex.compiler.internal.tree.as.FunctionNode;
-import org.apache.flex.compiler.internal.tree.as.GetterNode;
 import org.apache.flex.compiler.internal.tree.as.RegExpLiteralNode;
 import org.apache.flex.compiler.internal.tree.as.SetterNode;
-import org.apache.flex.compiler.internal.tree.as.UnaryOperatorAtNode;
-import org.apache.flex.compiler.scopes.IASScope;
 import org.apache.flex.compiler.tree.ASTNodeID;
 import org.apache.flex.compiler.tree.as.IASNode;
 import org.apache.flex.compiler.tree.as.IAccessorNode;
@@ -68,20 +59,14 @@ 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;
-import org.apache.flex.compiler.tree.as.IInterfaceNode;
-import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode;
 import org.apache.flex.compiler.tree.as.ILiteralNode.LiteralType;
 import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
 import org.apache.flex.compiler.tree.as.IParameterNode;
 import org.apache.flex.compiler.tree.as.ISetterNode;
-import org.apache.flex.compiler.tree.as.ITypeNode;
 import org.apache.flex.compiler.tree.as.ITypedExpressionNode;
 import org.apache.flex.compiler.tree.as.IVariableExpressionNode;
 import org.apache.flex.compiler.tree.as.IVariableNode;
-import org.apache.flex.compiler.units.ICompilationUnit;
-import org.apache.flex.compiler.utils.ASNodeUtils;
-import org.apache.flex.compiler.utils.NativeUtils;
 
 /**
  * Concrete implementation of the 'goog' JavaScript production.
@@ -93,27 +78,45 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
 {
 
     private int foreachLoopCounter = 0;
-    
+
+    private JSFlexJSDocEmitter docEmitter = null;
+
+    private PackageHeaderEmitter packageHeaderEmitter;
+    private PackageFooterEmitter packageFooterEmitter;
+
     private ClassEmitter classEmitter;
     private FieldEmitter fieldEmitter;
     private FunctionCallEmitter functionCallEmitter;
     private SuperCallEmitter superCallEmitter;
+    private MemberAccessEmitter memberAccessEmitter;
     private BinaryOperatorEmitter binaryOperatorEmitter;
     private IdentifierEmitter identifierEmitter;
-    
+
     public ClassEmitter getClassEmiter()
     {
         return classEmitter;
     }
 
+    @Override
+    public IDocEmitter getDocEmitter()
+    {
+        if (docEmitter == null)
+            docEmitter = new JSFlexJSDocEmitter(this);
+        return docEmitter;
+    }
+
     public JSFlexJSEmitter(FilterWriter out)
     {
         super(out);
 
+        packageHeaderEmitter = new PackageHeaderEmitter(this);
+        packageFooterEmitter = new PackageFooterEmitter(this);
+
         classEmitter = new ClassEmitter(this);
         fieldEmitter = new FieldEmitter(this);
         functionCallEmitter = new FunctionCallEmitter(this);
         superCallEmitter = new SuperCallEmitter(this);
+        memberAccessEmitter = new MemberAccessEmitter(this);
         binaryOperatorEmitter = new BinaryOperatorEmitter(this);
         identifierEmitter = new IdentifierEmitter(this);
     }
@@ -237,9 +240,9 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     public void emitIdentifier(IIdentifierNode node)
     {
         // TODO (mschmalle) remove when project field is removed
-      if (project == null)
-          project = getWalker().getProject();
-        
+        if (project == null)
+            project = getWalker().getProject();
+
         identifierEmitter.emit(node);
     }
 
@@ -329,178 +332,23 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
     @Override
     public void emitMemberAccessExpression(IMemberAccessExpressionNode node)
     {
-        if (ASNodeUtils.hasParenOpen(node))
-            write(ASEmitterTokens.PAREN_OPEN);
-
-        IASNode leftNode = node.getLeftOperandNode();
-        IASNode rightNode = node.getRightOperandNode();
-
+        // TODO (mschmalle) remove when project field is removed
         if (project == null)
             project = getWalker().getProject();
 
-        IDefinition def = node.resolve(project);
-        boolean isStatic = false;
-        if (def != null && def.isStatic())
-            isStatic = true;
-
-        boolean continueWalk = true;
-        if (!isStatic)
-        {
-            if (!(leftNode instanceof ILanguageIdentifierNode && ((ILanguageIdentifierNode) leftNode)
-                    .getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.THIS))
-            {
-                IDefinition rightDef = null;
-                if (rightNode instanceof IIdentifierNode)
-                    rightDef = ((IIdentifierNode) rightNode).resolve(project);
-
-                if (rightNode instanceof UnaryOperatorAtNode)
-                {
-                    // ToDo (erikdebruin): properly handle E4X
-
-                    write(ASEmitterTokens.THIS);
-                    write(ASEmitterTokens.MEMBER_ACCESS);
-                    getWalker().walk(node.getLeftOperandNode());
-                    write(ASEmitterTokens.SQUARE_OPEN);
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write("E4XOperator");
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write(ASEmitterTokens.SQUARE_CLOSE);
-                    continueWalk = false;
-                }
-                else if (node.getNodeID() == ASTNodeID.Op_DescendantsID)
-                {
-                    // ToDo (erikdebruin): properly handle E4X
-
-                    write(ASEmitterTokens.THIS);
-                    write(ASEmitterTokens.MEMBER_ACCESS);
-                    getWalker().walk(node.getLeftOperandNode());
-                    write(ASEmitterTokens.SQUARE_OPEN);
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write("E4XSelector");
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write(ASEmitterTokens.SQUARE_CLOSE);
-                    continueWalk = false;
-                }
-                else if (leftNode.getNodeID() != ASTNodeID.SuperID)
-                {
-                    getWalker().walk(node.getLeftOperandNode());
-                    write(node.getOperator().getOperatorText());
-                }
-                else if (leftNode.getNodeID() == ASTNodeID.SuperID
-                        && (rightNode.getNodeID() == ASTNodeID.GetterID || (rightDef != null && rightDef instanceof AccessorDefinition)))
-                {
-                    // setter is handled in binaryOperator
-                    write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
-                    write(ASEmitterTokens.MEMBER_ACCESS);
-                    write(JSFlexJSEmitterTokens.SUPERGETTER);
-                    write(ASEmitterTokens.PAREN_OPEN);
-                    IClassNode cnode = (IClassNode) node
-                            .getAncestorOfType(IClassNode.class);
-                    write(formatQualifiedName(cnode.getQualifiedName()));
-                    writeToken(ASEmitterTokens.COMMA);
-                    write(ASEmitterTokens.THIS);
-                    writeToken(ASEmitterTokens.COMMA);
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    if (rightDef != null)
-                        write(rightDef.getBaseName());
-                    else
-                        write(((GetterNode) rightNode).getName());
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write(ASEmitterTokens.PAREN_CLOSE);
-                    continueWalk = false;
-                }
-            }
-            else
-            {
-                write(ASEmitterTokens.THIS);
-                write(node.getOperator().getOperatorText());
-            }
-
-        }
-
-        if (continueWalk)
-            getWalker().walk(node.getRightOperandNode());
-
-        if (ASNodeUtils.hasParenClose(node))
-            write(ASEmitterTokens.PAREN_CLOSE);
+        memberAccessEmitter.emit(node);
     }
 
     @Override
     public void emitGetAccessor(IGetterNode node)
     {
-        ModifiersSet modifierSet = node.getDefinition().getModifiers();
-        boolean isStatic = (modifierSet != null && modifierSet
-                .hasModifier(ASModifier.STATIC));
-        HashMap<String, PropertyNodes> map = isStatic ? getModel()
-                .getStaticPropertyMap() : getModel().getPropertyMap();
-        String name = node.getName();
-        PropertyNodes p = map.get(name);
-        if (p == null)
-        {
-            p = new PropertyNodes();
-            map.put(name, p);
-        }
-        p.getter = node;
-        FunctionNode fn = (FunctionNode) node;
-        fn.parseFunctionBody(getProblems());
+       classEmitter.getGetSetEmitter().emitGet(node);
     }
 
     @Override
     public void emitSetAccessor(ISetterNode node)
     {
-        ModifiersSet modifierSet = node.getDefinition().getModifiers();
-        boolean isStatic = (modifierSet != null && modifierSet
-                .hasModifier(ASModifier.STATIC));
-        HashMap<String, PropertyNodes> map = isStatic ? getModel()
-                .getStaticPropertyMap() : getModel().getPropertyMap();
-        String name = node.getName();
-        PropertyNodes p = map.get(name);
-        if (p == null)
-        {
-            p = new PropertyNodes();
-            map.put(name, p);
-        }
-        p.setter = node;
-        FunctionNode fn = (FunctionNode) node;
-        fn.parseFunctionBody(getProblems());
-
-        boolean isBindableSetter = false;
-        if (node instanceof SetterNode)
-        {
-            IMetaInfo[] metaInfos = null;
-            metaInfos = node.getMetaInfos();
-            for (IMetaInfo metaInfo : metaInfos)
-            {
-                name = metaInfo.getTagName();
-                if (name.equals("Bindable")
-                        && metaInfo.getAllAttributes().length == 0)
-                {
-                    isBindableSetter = true;
-                    break;
-                }
-            }
-        }
-        if (isBindableSetter)
-        {
-            IFunctionDefinition definition = node.getDefinition();
-            ITypeDefinition type = (ITypeDefinition) definition.getParent();
-            getDoc().emitMethodDoc(fn, project);
-            write(formatQualifiedName(type.getQualifiedName()));
-            if (!node.hasModifier(ASModifier.STATIC))
-            {
-                write(ASEmitterTokens.MEMBER_ACCESS);
-                write(JSEmitterTokens.PROTOTYPE);
-            }
-
-            write(ASEmitterTokens.MEMBER_ACCESS);
-            write("__bindingWrappedSetter__");
-            writeToken(node.getName());
-            writeToken(ASEmitterTokens.EQUAL);
-            write(ASEmitterTokens.FUNCTION);
-            emitParameters(node.getParameterNodes());
-            //writeNewline();
-            emitMethodScope(node.getScopedNode());
-        }
+        classEmitter.getGetSetEmitter().emitSet(node);
     }
 
     @Override
@@ -631,260 +479,22 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
             super.emitDefinePropertyFunction(node);
     }
 
-    private JSFlexJSDocEmitter docEmitter = null;
-
-    @Override
-    public IDocEmitter getDocEmitter()
-    {
-        if (docEmitter == null)
-            docEmitter = new JSFlexJSDocEmitter(this);
-        return docEmitter;
-    }
-
     @Override
     public void emitPackageHeader(IPackageDefinition definition)
     {
-        IASScope containedScope = definition.getContainedScope();
-        ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
-        if (type == null)
-            return;
-
-        writeNewline("/**");
-        writeNewline(" * " + type.getQualifiedName());
-        writeNewline(" *");
-        writeNewline(" * @fileoverview");
-        writeNewline(" *");
-        writeNewline(" * @suppress {checkTypes}");
-        writeNewline(" */");
-        writeNewline();
-
-        /* goog.provide('x');\n\n */
-        write(JSGoogEmitterTokens.GOOG_PROVIDE);
-        write(ASEmitterTokens.PAREN_OPEN);
-        write(ASEmitterTokens.SINGLE_QUOTE);
-        write(formatQualifiedName(type.getQualifiedName()));
-        write(ASEmitterTokens.SINGLE_QUOTE);
-        write(ASEmitterTokens.PAREN_CLOSE);
-        writeNewline(ASEmitterTokens.SEMICOLON);
-        writeNewline();
+        packageHeaderEmitter.emit(definition);
     }
 
     @Override
     public void emitPackageHeaderContents(IPackageDefinition definition)
     {
-        PackageScope containedScope = (PackageScope) definition
-                .getContainedScope();
-
-        ArrayList<String> writtenRequires = new ArrayList<String>();
-
-        ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
-        if (type == null)
-            return;
-
-        ITypeNode typeNode = type.getNode();
-        if (typeNode instanceof ClassNode)
-        {
-            ClassNode classNode = (ClassNode) typeNode;
-            if (classNode != null)
-            {
-                ASDocComment asDoc = (ASDocComment) classNode.getASDocComment();
-                if (asDoc != null)
-                {
-                    String asDocString = asDoc.commentNoEnd();
-                    String ignoreToken = JSFlexJSEmitterTokens.IGNORE_IMPORT
-                            .getToken();
-                    int ignoreIndex = asDocString.indexOf(ignoreToken);
-                    while (ignoreIndex != -1)
-                    {
-                        String ignorable = asDocString.substring(ignoreIndex
-                                + ignoreToken.length());
-                        int endIndex = ignorable.indexOf("\n");
-                        ignorable = ignorable.substring(0, endIndex);
-                        ignorable = ignorable.trim();
-                        // pretend we've already written the goog.requires for this
-                        writtenRequires.add(ignorable);
-                        ignoreIndex = asDocString.indexOf(ignoreToken,
-                                ignoreIndex + ignoreToken.length());
-                    }
-                }
-            }
-        }
-
-        if (project == null)
-            project = getWalker().getProject();
-
-        FlexJSProject flexProject = (FlexJSProject) project;
-        ASProjectScope projectScope = (ASProjectScope) flexProject.getScope();
-        ICompilationUnit cu = projectScope
-                .getCompilationUnitForDefinition(type);
-        ArrayList<String> requiresList = flexProject.getRequires(cu);
-        ArrayList<String> interfacesList = flexProject.getInterfaces(cu);
-
-        String cname = type.getQualifiedName();
-        writtenRequires.add(cname); // make sure we don't add ourselves
-
-        boolean emitsRequires = false;
-        if (requiresList != null)
-        {
-            for (String imp : requiresList)
-            {
-                if (imp.indexOf(JSGoogEmitterTokens.AS3.getToken()) != -1)
-                    continue;
-
-                if (imp.equals(cname))
-                    continue;
-
-                if (NativeUtils.isNative(imp))
-                    continue;
-
-                if (writtenRequires.indexOf(imp) == -1)
-                {
-
-                    /* goog.require('x');\n */
-                    write(JSGoogEmitterTokens.GOOG_REQUIRE);
-                    write(ASEmitterTokens.PAREN_OPEN);
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write(formatQualifiedName(imp));
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write(ASEmitterTokens.PAREN_CLOSE);
-                    writeNewline(ASEmitterTokens.SEMICOLON);
-
-                    writtenRequires.add(imp);
-
-                    emitsRequires = true;
-                }
-            }
-        }
-
-        boolean emitsInterfaces = false;
-        if (interfacesList != null)
-        {
-            for (String imp : interfacesList)
-            {
-                if (writtenRequires.indexOf(imp) == -1)
-                {
-                    write(JSGoogEmitterTokens.GOOG_REQUIRE);
-                    write(ASEmitterTokens.PAREN_OPEN);
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write(formatQualifiedName(imp));
-                    write(ASEmitterTokens.SINGLE_QUOTE);
-                    write(ASEmitterTokens.PAREN_CLOSE);
-                    writeNewline(ASEmitterTokens.SEMICOLON);
-
-                    emitsInterfaces = true;
-                }
-            }
-        }
-
-        // erikdebruin: Add missing language feature support, with e.g. 'is' and 
-        //              'as' operators. We don't need to worry about requiring
-        //              this in every project: ADVANCED_OPTIMISATIONS will NOT
-        //              include any of the code if it is not used in the project.
-        boolean isMainCU = flexProject.mainCU != null
-                && cu.getName().equals(flexProject.mainCU.getName());
-        if (isMainCU)
-        {
-            write(JSGoogEmitterTokens.GOOG_REQUIRE);
-            write(ASEmitterTokens.PAREN_OPEN);
-            write(ASEmitterTokens.SINGLE_QUOTE);
-            write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
-            write(ASEmitterTokens.SINGLE_QUOTE);
-            write(ASEmitterTokens.PAREN_CLOSE);
-            writeNewline(ASEmitterTokens.SEMICOLON);
-        }
-
-        if (emitsRequires || emitsInterfaces || isMainCU)
-        {
-            writeNewline();
-        }
-
-        writeNewline();
-        writeNewline();
+        packageHeaderEmitter.emitContents(definition);
     }
 
     @Override
     public void emitPackageFooter(IPackageDefinition definition)
     {
-        IASScope containedScope = definition.getContainedScope();
-        ITypeDefinition type = findType(containedScope.getAllLocalDefinitions());
-        if (type == null)
-            return;
-
-        ITypeNode tnode = findTypeNode(definition.getNode());
-        if (tnode != null)
-        {
-            /*
-             * Metadata
-             * 
-             * @type {Object.<string, Array.<Object>>}
-             */
-            writeNewline();
-            writeNewline();
-            writeNewline();
-            getDoc().begin();
-            writeNewline(" * Metadata");
-            writeNewline(" *");
-            writeNewline(" * @type {Object.<string, Array.<Object>>}");
-            getDoc().end();
-
-            // a.B.prototype.AFJS_CLASS_INFO = {  };
-            write(formatQualifiedName(type.getQualifiedName()));
-            write(ASEmitterTokens.MEMBER_ACCESS);
-            write(JSEmitterTokens.PROTOTYPE);
-            write(ASEmitterTokens.MEMBER_ACCESS);
-            writeToken(JSFlexJSEmitterTokens.FLEXJS_CLASS_INFO);
-            writeToken(ASEmitterTokens.EQUAL);
-            writeToken(ASEmitterTokens.BLOCK_OPEN);
-
-            // names: [{ name: '', qName: '' }]
-            write(JSFlexJSEmitterTokens.NAMES);
-            writeToken(ASEmitterTokens.COLON);
-            write(ASEmitterTokens.SQUARE_OPEN);
-            writeToken(ASEmitterTokens.BLOCK_OPEN);
-            write(JSFlexJSEmitterTokens.NAME);
-            writeToken(ASEmitterTokens.COLON);
-            write(ASEmitterTokens.SINGLE_QUOTE);
-            write(tnode.getName());
-            write(ASEmitterTokens.SINGLE_QUOTE);
-            writeToken(ASEmitterTokens.COMMA);
-            write(JSFlexJSEmitterTokens.QNAME);
-            writeToken(ASEmitterTokens.COLON);
-            write(ASEmitterTokens.SINGLE_QUOTE);
-            write(formatQualifiedName(tnode.getQualifiedName()));
-            write(ASEmitterTokens.SINGLE_QUOTE);
-            write(ASEmitterTokens.BLOCK_CLOSE);
-            write(ASEmitterTokens.SQUARE_CLOSE);
-
-            IExpressionNode[] enodes;
-            if (tnode instanceof IClassNode)
-                enodes = ((IClassNode) tnode).getImplementedInterfaceNodes();
-            else
-                enodes = ((IInterfaceNode) tnode).getExtendedInterfaceNodes();
-
-            if (enodes.length > 0)
-            {
-                writeToken(ASEmitterTokens.COMMA);
-
-                // interfaces: [a.IC, a.ID]
-                write(JSFlexJSEmitterTokens.INTERFACES);
-                writeToken(ASEmitterTokens.COLON);
-                write(ASEmitterTokens.SQUARE_OPEN);
-                int i = 0;
-                for (IExpressionNode enode : enodes)
-                {
-                    write(formatQualifiedName(enode.resolve(project)
-                            .getQualifiedName()));
-                    if (i < enodes.length - 1)
-                        writeToken(ASEmitterTokens.COMMA);
-                    i++;
-                }
-                write(ASEmitterTokens.SQUARE_CLOSE);
-            }
-
-            write(ASEmitterTokens.SPACE);
-            write(ASEmitterTokens.BLOCK_CLOSE);
-            writeNewline(ASEmitterTokens.SEMICOLON);
-        }
+        packageFooterEmitter.emit(definition);
     }
 
     @Override
@@ -1075,61 +685,6 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter
         write(ASEmitterTokens.SINGLE_QUOTE);
     }
 
-    /*
-    @Override
-    public void emitUnaryOperator(IUnaryOperatorNode node)
-    {
-        if (node.getNodeID() == ASTNodeID.Op_PreIncrID
-                || node.getNodeID() == ASTNodeID.Op_PreDecrID
-                || node.getNodeID() == ASTNodeID.Op_PostIncrID
-                || node.getNodeID() == ASTNodeID.Op_PostDecrID)
-        {
-            IExpressionNode opNode = node.getOperandNode();
-            String getString = stringifyNode(opNode);
-            int index = getString.lastIndexOf("get_");
-            if (index != -1)
-            {
-                write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
-                write(ASEmitterTokens.MEMBER_ACCESS);
-            	if (node.getNodeID() == ASTNodeID.Op_PreIncrID)
-            		write(JSFlexJSEmitterTokens.PREINCREMENT);
-            	else if (node.getNodeID() == ASTNodeID.Op_PostIncrID)
-            		write(JSFlexJSEmitterTokens.POSTINCREMENT);
-            	else if (node.getNodeID() == ASTNodeID.Op_PreDecrID)
-            		write(JSFlexJSEmitterTokens.PREDECREMENT);
-            	else
-            		write(JSFlexJSEmitterTokens.POSTDECREMENT);
-                write(ASEmitterTokens.PAREN_OPEN);
-                String obj = getString.substring(0, index - 1);
-                write(obj);
-                write(ASEmitterTokens.COMMA);
-            	String prop = getString.substring(index + 4);            	
-            	int endIndex = prop.indexOf(ASEmitterTokens.PAREN_OPEN.getToken());
-            	prop = prop.substring(0, endIndex);
-                write(ASEmitterTokens.DOUBLE_QUOTE);
-            	write(prop);
-                write(ASEmitterTokens.DOUBLE_QUOTE);
-                write(ASEmitterTokens.PAREN_CLOSE);
-                return;
-            }
-            else
-            {
-            	IASNode parentNode = node.getParent();
-            	if (parentNode.getNodeID() == ASTNodeID.MemberAccessExpressionID &&
-            			((MemberAccessExpressionNode)parentNode).getLeftOperandNode() == node)
-            	{
-            		// GCC wanted parens around foo++.toString().  As in (foo++).toString();
-                    write(ASEmitterTokens.PAREN_OPEN);
-                    super.emitUnaryOperator(node);
-                    write(ASEmitterTokens.PAREN_CLOSE);
-                    return;
-            	}
-            }
-
-        }
-        super.emitUnaryOperator(node);
-    }
-    */
 
     @Override
     public String formatQualifiedName(String name)
@@ -1344,3 +899,59 @@ private void writeGetSetPrefix(boolean isGet)
     write("_");
 }
 */
+
+/*
+@Override
+public void emitUnaryOperator(IUnaryOperatorNode node)
+{
+    if (node.getNodeID() == ASTNodeID.Op_PreIncrID
+            || node.getNodeID() == ASTNodeID.Op_PreDecrID
+            || node.getNodeID() == ASTNodeID.Op_PostIncrID
+            || node.getNodeID() == ASTNodeID.Op_PostDecrID)
+    {
+        IExpressionNode opNode = node.getOperandNode();
+        String getString = stringifyNode(opNode);
+        int index = getString.lastIndexOf("get_");
+        if (index != -1)
+        {
+            write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            if (node.getNodeID() == ASTNodeID.Op_PreIncrID)
+                write(JSFlexJSEmitterTokens.PREINCREMENT);
+            else if (node.getNodeID() == ASTNodeID.Op_PostIncrID)
+                write(JSFlexJSEmitterTokens.POSTINCREMENT);
+            else if (node.getNodeID() == ASTNodeID.Op_PreDecrID)
+                write(JSFlexJSEmitterTokens.PREDECREMENT);
+            else
+                write(JSFlexJSEmitterTokens.POSTDECREMENT);
+            write(ASEmitterTokens.PAREN_OPEN);
+            String obj = getString.substring(0, index - 1);
+            write(obj);
+            write(ASEmitterTokens.COMMA);
+            String prop = getString.substring(index + 4);               
+            int endIndex = prop.indexOf(ASEmitterTokens.PAREN_OPEN.getToken());
+            prop = prop.substring(0, endIndex);
+            write(ASEmitterTokens.DOUBLE_QUOTE);
+            write(prop);
+            write(ASEmitterTokens.DOUBLE_QUOTE);
+            write(ASEmitterTokens.PAREN_CLOSE);
+            return;
+        }
+        else
+        {
+            IASNode parentNode = node.getParent();
+            if (parentNode.getNodeID() == ASTNodeID.MemberAccessExpressionID &&
+                    ((MemberAccessExpressionNode)parentNode).getLeftOperandNode() == node)
+            {
+                // GCC wanted parens around foo++.toString().  As in (foo++).toString();
+                write(ASEmitterTokens.PAREN_OPEN);
+                super.emitUnaryOperator(node);
+                write(ASEmitterTokens.PAREN_CLOSE);
+                return;
+            }
+        }
+
+    }
+    super.emitUnaryOperator(node);
+}
+*/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
index 1800afa..33f6f26 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/ClassEmitter.java
@@ -57,6 +57,7 @@ public class ClassEmitter extends JSSubEmitter implements
         super(emitter);
         
         bindableEmitter = new BindableEmitter(emitter);
+        // TODO (mschnalle) this is wrong
         getSetEmitter = new GetSetEmitter(emitter);
     }
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/GetSetEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/GetSetEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/GetSetEmitter.java
index c4db6fa..0f996ce 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/GetSetEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/GetSetEmitter.java
@@ -19,18 +19,29 @@
 
 package org.apache.flex.compiler.internal.codegen.js.jx;
 
+import java.util.HashMap;
 import java.util.Set;
 
 import org.apache.flex.compiler.codegen.ISubEmitter;
 import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.IMetaInfo;
+import org.apache.flex.compiler.common.ModifiersSet;
 import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.definitions.IFunctionDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSDocEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.js.JSSessionModel.PropertyNodes;
 import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSDocEmitter;
 import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
 import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.internal.tree.as.SetterNode;
+import org.apache.flex.compiler.tree.as.IGetterNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
 
 public class GetSetEmitter extends JSSubEmitter implements
         ISubEmitter<IClassDefinition>
@@ -192,4 +203,88 @@ public class GetSetEmitter extends JSSubEmitter implements
             write(ASEmitterTokens.SEMICOLON);
         }
     }
+    
+    
+    public void emitGet(IGetterNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+        
+        ModifiersSet modifierSet = node.getDefinition().getModifiers();
+        boolean isStatic = (modifierSet != null && modifierSet
+                .hasModifier(ASModifier.STATIC));
+        HashMap<String, PropertyNodes> map = isStatic ? getModel()
+                .getStaticPropertyMap() : getModel().getPropertyMap();
+        String name = node.getName();
+        PropertyNodes p = map.get(name);
+        if (p == null)
+        {
+            p = new PropertyNodes();
+            map.put(name, p);
+        }
+        p.getter = node;
+        FunctionNode fn = (FunctionNode) node;
+        fn.parseFunctionBody(fjs.getProblems());
+    }
+
+    public void emitSet(ISetterNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+        JSFlexJSDocEmitter doc = (JSFlexJSDocEmitter) fjs.getDocEmitter();
+        
+        ModifiersSet modifierSet = node.getDefinition().getModifiers();
+        boolean isStatic = (modifierSet != null && modifierSet
+                .hasModifier(ASModifier.STATIC));
+        HashMap<String, PropertyNodes> map = isStatic ? getModel()
+                .getStaticPropertyMap() : getModel().getPropertyMap();
+        String name = node.getName();
+        PropertyNodes p = map.get(name);
+        if (p == null)
+        {
+            p = new PropertyNodes();
+            map.put(name, p);
+        }
+        p.setter = node;
+        FunctionNode fn = (FunctionNode) node;
+        fn.parseFunctionBody(fjs.getProblems());
+
+        boolean isBindableSetter = false;
+        if (node instanceof SetterNode)
+        {
+            IMetaInfo[] metaInfos = null;
+            metaInfos = node.getMetaInfos();
+            for (IMetaInfo metaInfo : metaInfos)
+            {
+                name = metaInfo.getTagName();
+                if (name.equals("Bindable")
+                        && metaInfo.getAllAttributes().length == 0)
+                {
+                    isBindableSetter = true;
+                    break;
+                }
+            }
+        }
+        if (isBindableSetter)
+        {
+            IFunctionDefinition definition = node.getDefinition();
+            ITypeDefinition type = (ITypeDefinition) definition.getParent();
+            doc.emitMethodDoc(fn, getProject());
+            write(fjs.formatQualifiedName(type.getQualifiedName()));
+            if (!node.hasModifier(ASModifier.STATIC))
+            {
+                write(ASEmitterTokens.MEMBER_ACCESS);
+                write(JSEmitterTokens.PROTOTYPE);
+            }
+
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            write("__bindingWrappedSetter__");
+            writeToken(node.getName());
+            writeToken(ASEmitterTokens.EQUAL);
+            write(ASEmitterTokens.FUNCTION);
+            fjs.emitParameters(node.getParameterNodes());
+            //writeNewline();
+            fjs.emitMethodScope(node.getScopedNode());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
new file mode 100644
index 0000000..b582915
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MemberAccessEmitter.java
@@ -0,0 +1,148 @@
+/*
+ *
+ *  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.codegen.js.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IDefinition;
+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.JSFlexJSEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
+import org.apache.flex.compiler.internal.tree.as.GetterNode;
+import org.apache.flex.compiler.internal.tree.as.UnaryOperatorAtNode;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IIdentifierNode;
+import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
+import org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode;
+import org.apache.flex.compiler.utils.ASNodeUtils;
+
+public class MemberAccessEmitter extends JSSubEmitter implements
+        ISubEmitter<IMemberAccessExpressionNode>
+{
+
+    public MemberAccessEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IMemberAccessExpressionNode node)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        if (ASNodeUtils.hasParenOpen(node))
+            write(ASEmitterTokens.PAREN_OPEN);
+
+        IASNode leftNode = node.getLeftOperandNode();
+        IASNode rightNode = node.getRightOperandNode();
+
+        IDefinition def = node.resolve(getProject());
+        boolean isStatic = false;
+        if (def != null && def.isStatic())
+            isStatic = true;
+
+        boolean continueWalk = true;
+        if (!isStatic)
+        {
+            if (!(leftNode instanceof ILanguageIdentifierNode && ((ILanguageIdentifierNode) leftNode)
+                    .getKind() == ILanguageIdentifierNode.LanguageIdentifierKind.THIS))
+            {
+                IDefinition rightDef = null;
+                if (rightNode instanceof IIdentifierNode)
+                    rightDef = ((IIdentifierNode) rightNode)
+                            .resolve(getProject());
+
+                if (rightNode instanceof UnaryOperatorAtNode)
+                {
+                    // ToDo (erikdebruin): properly handle E4X
+
+                    write(ASEmitterTokens.THIS);
+                    write(ASEmitterTokens.MEMBER_ACCESS);
+                    getWalker().walk(node.getLeftOperandNode());
+                    write(ASEmitterTokens.SQUARE_OPEN);
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write("E4XOperator");
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write(ASEmitterTokens.SQUARE_CLOSE);
+                    continueWalk = false;
+                }
+                else if (node.getNodeID() == ASTNodeID.Op_DescendantsID)
+                {
+                    // ToDo (erikdebruin): properly handle E4X
+
+                    write(ASEmitterTokens.THIS);
+                    write(ASEmitterTokens.MEMBER_ACCESS);
+                    getWalker().walk(node.getLeftOperandNode());
+                    write(ASEmitterTokens.SQUARE_OPEN);
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write("E4XSelector");
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write(ASEmitterTokens.SQUARE_CLOSE);
+                    continueWalk = false;
+                }
+                else if (leftNode.getNodeID() != ASTNodeID.SuperID)
+                {
+                    getWalker().walk(node.getLeftOperandNode());
+                    write(node.getOperator().getOperatorText());
+                }
+                else if (leftNode.getNodeID() == ASTNodeID.SuperID
+                        && (rightNode.getNodeID() == ASTNodeID.GetterID || (rightDef != null && rightDef instanceof AccessorDefinition)))
+                {
+                    // setter is handled in binaryOperator
+                    write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+                    write(ASEmitterTokens.MEMBER_ACCESS);
+                    write(JSFlexJSEmitterTokens.SUPERGETTER);
+                    write(ASEmitterTokens.PAREN_OPEN);
+                    IClassNode cnode = (IClassNode) node
+                            .getAncestorOfType(IClassNode.class);
+                    write(fjs.formatQualifiedName(cnode.getQualifiedName()));
+                    writeToken(ASEmitterTokens.COMMA);
+                    write(ASEmitterTokens.THIS);
+                    writeToken(ASEmitterTokens.COMMA);
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    if (rightDef != null)
+                        write(rightDef.getBaseName());
+                    else
+                        write(((GetterNode) rightNode).getName());
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write(ASEmitterTokens.PAREN_CLOSE);
+                    continueWalk = false;
+                }
+            }
+            else
+            {
+                write(ASEmitterTokens.THIS);
+                write(node.getOperator().getOperatorText());
+            }
+        }
+
+        if (continueWalk)
+            getWalker().walk(node.getRightOperandNode());
+
+        if (ASNodeUtils.hasParenClose(node))
+            write(ASEmitterTokens.PAREN_CLOSE);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
new file mode 100644
index 0000000..86ac18d
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java
@@ -0,0 +1,138 @@
+/*
+ *
+ *  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.codegen.js.jx;
+
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IPackageDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSDocEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.scopes.IASScope;
+import org.apache.flex.compiler.tree.as.IClassNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.tree.as.IInterfaceNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+
+public class PackageFooterEmitter extends JSSubEmitter implements
+        ISubEmitter<IPackageDefinition>
+{
+
+    public PackageFooterEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IPackageDefinition definition)
+    {
+        IASScope containedScope = definition.getContainedScope();
+        ITypeDefinition type = EmitterUtils.findType(containedScope
+                .getAllLocalDefinitions());
+        if (type == null)
+            return;
+
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+        JSFlexJSDocEmitter doc = (JSFlexJSDocEmitter) fjs.getDocEmitter();
+
+        ITypeNode tnode = EmitterUtils.findTypeNode(definition.getNode());
+        if (tnode != null)
+        {
+            /*
+             * Metadata
+             * 
+             * @type {Object.<string, Array.<Object>>}
+             */
+            writeNewline();
+            writeNewline();
+            writeNewline();
+            doc.begin();
+            writeNewline(" * Metadata");
+            writeNewline(" *");
+            writeNewline(" * @type {Object.<string, Array.<Object>>}");
+            doc.end();
+
+            // a.B.prototype.AFJS_CLASS_INFO = {  };
+            write(fjs.formatQualifiedName(type.getQualifiedName()));
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            write(JSEmitterTokens.PROTOTYPE);
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            writeToken(JSFlexJSEmitterTokens.FLEXJS_CLASS_INFO);
+            writeToken(ASEmitterTokens.EQUAL);
+            writeToken(ASEmitterTokens.BLOCK_OPEN);
+
+            // names: [{ name: '', qName: '' }]
+            write(JSFlexJSEmitterTokens.NAMES);
+            writeToken(ASEmitterTokens.COLON);
+            write(ASEmitterTokens.SQUARE_OPEN);
+            writeToken(ASEmitterTokens.BLOCK_OPEN);
+            write(JSFlexJSEmitterTokens.NAME);
+            writeToken(ASEmitterTokens.COLON);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(tnode.getName());
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            writeToken(ASEmitterTokens.COMMA);
+            write(JSFlexJSEmitterTokens.QNAME);
+            writeToken(ASEmitterTokens.COLON);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(fjs.formatQualifiedName(tnode.getQualifiedName()));
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(ASEmitterTokens.BLOCK_CLOSE);
+            write(ASEmitterTokens.SQUARE_CLOSE);
+
+            IExpressionNode[] enodes;
+            if (tnode instanceof IClassNode)
+                enodes = ((IClassNode) tnode).getImplementedInterfaceNodes();
+            else
+                enodes = ((IInterfaceNode) tnode).getExtendedInterfaceNodes();
+
+            if (enodes.length > 0)
+            {
+                writeToken(ASEmitterTokens.COMMA);
+
+                // interfaces: [a.IC, a.ID]
+                write(JSFlexJSEmitterTokens.INTERFACES);
+                writeToken(ASEmitterTokens.COLON);
+                write(ASEmitterTokens.SQUARE_OPEN);
+                int i = 0;
+                for (IExpressionNode enode : enodes)
+                {
+                    write(fjs.formatQualifiedName(enode.resolve(getProject())
+                            .getQualifiedName()));
+                    if (i < enodes.length - 1)
+                        writeToken(ASEmitterTokens.COMMA);
+                    i++;
+                }
+                write(ASEmitterTokens.SQUARE_CLOSE);
+            }
+
+            write(ASEmitterTokens.SPACE);
+            write(ASEmitterTokens.BLOCK_CLOSE);
+            writeNewline(ASEmitterTokens.SEMICOLON);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
new file mode 100644
index 0000000..cd82cf2
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageHeaderEmitter.java
@@ -0,0 +1,221 @@
+/*
+ *
+ *  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.codegen.js.jx;
+
+import java.util.ArrayList;
+
+import org.apache.flex.compiler.asdoc.flexjs.ASDocComment;
+import org.apache.flex.compiler.codegen.ISubEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.definitions.IPackageDefinition;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+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.JSFlexJSEmitter;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.scopes.ASProjectScope;
+import org.apache.flex.compiler.internal.scopes.PackageScope;
+import org.apache.flex.compiler.internal.tree.as.ClassNode;
+import org.apache.flex.compiler.scopes.IASScope;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.utils.NativeUtils;
+
+public class PackageHeaderEmitter extends JSSubEmitter implements
+        ISubEmitter<IPackageDefinition>
+{
+
+    public PackageHeaderEmitter(IJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(IPackageDefinition definition)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        IASScope containedScope = definition.getContainedScope();
+        ITypeDefinition type = EmitterUtils.findType(containedScope
+                .getAllLocalDefinitions());
+        if (type == null)
+            return;
+
+        writeNewline("/**");
+        writeNewline(" * " + type.getQualifiedName());
+        writeNewline(" *");
+        writeNewline(" * @fileoverview");
+        writeNewline(" *");
+        writeNewline(" * @suppress {checkTypes}");
+        writeNewline(" */");
+        writeNewline();
+
+        /* goog.provide('x');\n\n */
+        write(JSGoogEmitterTokens.GOOG_PROVIDE);
+        write(ASEmitterTokens.PAREN_OPEN);
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        write(fjs.formatQualifiedName(type.getQualifiedName()));
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        write(ASEmitterTokens.PAREN_CLOSE);
+        writeNewline(ASEmitterTokens.SEMICOLON);
+        writeNewline();
+    }
+
+    public void emitContents(IPackageDefinition definition)
+    {
+        // TODO (mschmalle) will remove this cast as more things get abstracted
+        JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter();
+
+        PackageScope containedScope = (PackageScope) definition
+                .getContainedScope();
+
+        ArrayList<String> writtenRequires = new ArrayList<String>();
+
+        ITypeDefinition type = EmitterUtils.findType(containedScope
+                .getAllLocalDefinitions());
+        if (type == null)
+            return;
+
+        ITypeNode typeNode = type.getNode();
+        if (typeNode instanceof ClassNode)
+        {
+            ClassNode classNode = (ClassNode) typeNode;
+            if (classNode != null)
+            {
+                ASDocComment asDoc = (ASDocComment) classNode.getASDocComment();
+                if (asDoc != null)
+                {
+                    String asDocString = asDoc.commentNoEnd();
+                    String ignoreToken = JSFlexJSEmitterTokens.IGNORE_IMPORT
+                            .getToken();
+                    int ignoreIndex = asDocString.indexOf(ignoreToken);
+                    while (ignoreIndex != -1)
+                    {
+                        String ignorable = asDocString.substring(ignoreIndex
+                                + ignoreToken.length());
+                        int endIndex = ignorable.indexOf("\n");
+                        ignorable = ignorable.substring(0, endIndex);
+                        ignorable = ignorable.trim();
+                        // pretend we've already written the goog.requires for this
+                        writtenRequires.add(ignorable);
+                        ignoreIndex = asDocString.indexOf(ignoreToken,
+                                ignoreIndex + ignoreToken.length());
+                    }
+                }
+            }
+        }
+
+        //        if (project == null)
+        //            project = getWalker().getProject();
+
+        FlexJSProject flexProject = (FlexJSProject) getProject();
+        ASProjectScope projectScope = (ASProjectScope) flexProject.getScope();
+        ICompilationUnit cu = projectScope
+                .getCompilationUnitForDefinition(type);
+        ArrayList<String> requiresList = flexProject.getRequires(cu);
+        ArrayList<String> interfacesList = flexProject.getInterfaces(cu);
+
+        String cname = type.getQualifiedName();
+        writtenRequires.add(cname); // make sure we don't add ourselves
+
+        boolean emitsRequires = false;
+        if (requiresList != null)
+        {
+            for (String imp : requiresList)
+            {
+                if (imp.indexOf(JSGoogEmitterTokens.AS3.getToken()) != -1)
+                    continue;
+
+                if (imp.equals(cname))
+                    continue;
+
+                if (NativeUtils.isNative(imp))
+                    continue;
+
+                if (writtenRequires.indexOf(imp) == -1)
+                {
+
+                    /* goog.require('x');\n */
+                    write(JSGoogEmitterTokens.GOOG_REQUIRE);
+                    write(ASEmitterTokens.PAREN_OPEN);
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write(fjs.formatQualifiedName(imp));
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write(ASEmitterTokens.PAREN_CLOSE);
+                    writeNewline(ASEmitterTokens.SEMICOLON);
+
+                    writtenRequires.add(imp);
+
+                    emitsRequires = true;
+                }
+            }
+        }
+
+        boolean emitsInterfaces = false;
+        if (interfacesList != null)
+        {
+            for (String imp : interfacesList)
+            {
+                if (writtenRequires.indexOf(imp) == -1)
+                {
+                    write(JSGoogEmitterTokens.GOOG_REQUIRE);
+                    write(ASEmitterTokens.PAREN_OPEN);
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write(fjs.formatQualifiedName(imp));
+                    write(ASEmitterTokens.SINGLE_QUOTE);
+                    write(ASEmitterTokens.PAREN_CLOSE);
+                    writeNewline(ASEmitterTokens.SEMICOLON);
+
+                    emitsInterfaces = true;
+                }
+            }
+        }
+
+        // erikdebruin: Add missing language feature support, with e.g. 'is' and 
+        //              'as' operators. We don't need to worry about requiring
+        //              this in every project: ADVANCED_OPTIMISATIONS will NOT
+        //              include any of the code if it is not used in the project.
+        boolean isMainCU = flexProject.mainCU != null
+                && cu.getName().equals(flexProject.mainCU.getName());
+        if (isMainCU)
+        {
+            write(JSGoogEmitterTokens.GOOG_REQUIRE);
+            write(ASEmitterTokens.PAREN_OPEN);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(JSFlexJSEmitterTokens.LANGUAGE_QNAME);
+            write(ASEmitterTokens.SINGLE_QUOTE);
+            write(ASEmitterTokens.PAREN_CLOSE);
+            writeNewline(ASEmitterTokens.SEMICOLON);
+        }
+
+        if (emitsRequires || emitsInterfaces || isMainCU)
+        {
+            writeNewline();
+        }
+
+        writeNewline();
+        writeNewline();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/dbad22c9/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
index 69acf2d..07da145 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/utils/EmitterUtils.java
@@ -30,9 +30,9 @@ import org.apache.flex.compiler.constants.IASLanguageConstants;
 import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.definitions.IDefinition;
 import org.apache.flex.compiler.definitions.IFunctionDefinition;
+import org.apache.flex.compiler.definitions.IFunctionDefinition.FunctionClassification;
 import org.apache.flex.compiler.definitions.INamespaceDefinition;
 import org.apache.flex.compiler.definitions.ITypeDefinition;
-import org.apache.flex.compiler.definitions.IFunctionDefinition.FunctionClassification;
 import org.apache.flex.compiler.internal.codegen.js.JSSessionModel;
 import org.apache.flex.compiler.internal.definitions.AccessorDefinition;
 import org.apache.flex.compiler.internal.definitions.ClassDefinition;
@@ -49,13 +49,37 @@ import org.apache.flex.compiler.tree.as.IClassNode;
 import org.apache.flex.compiler.tree.as.IDefinitionNode;
 import org.apache.flex.compiler.tree.as.IFunctionNode;
 import org.apache.flex.compiler.tree.as.IIdentifierNode;
+import org.apache.flex.compiler.tree.as.IPackageNode;
 import org.apache.flex.compiler.tree.as.IScopedNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
 
 /**
  * Various static methods used in shared emitter logic.
  */
 public class EmitterUtils
 {
+    public static ITypeNode findTypeNode(IPackageNode node)
+    {
+        IScopedNode scope = node.getScopedNode();
+        for (int i = 0; i < scope.getChildCount(); i++)
+        {
+            IASNode child = scope.getChild(i);
+            if (child instanceof ITypeNode)
+                return (ITypeNode) child;
+        }
+        return null;
+    }
+
+    public static ITypeDefinition findType(Collection<IDefinition> definitions)
+    {
+        for (IDefinition definition : definitions)
+        {
+            if (definition instanceof ITypeDefinition)
+                return (ITypeDefinition) definition;
+        }
+        return null;
+    }
+
     public static boolean isSameClass(IDefinition pdef, IDefinition thisClass,
             ICompilerProject project)
     {