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/03/22 08:05:37 UTC

[12/13] git commit: FlexJS MXML in FalconJx

FlexJS MXML in FalconJx

This is the implementation of the first step towards full FlexJS support in FalconJx. I started with the MXML because that needed the most work. In this version there are some workarounds, particularly when dealing with 'scripts' (getter, event handlers), but those will be addressed when the JS emitter for FlexJS is implemented. For now, have a look at this contribution and provide some feedback, please.


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

Branch: refs/heads/develop
Commit: 77f657d7a367ca0d97c8163b341bd4b3e7880ecc
Parents: ffa50d1
Author: Erik de Bruin <er...@ixsoftware.nl>
Authored: Wed Mar 13 14:47:17 2013 +0100
Committer: Erik de Bruin <er...@ixsoftware.nl>
Committed: Wed Mar 13 14:47:17 2013 +0100

----------------------------------------------------------------------
 .../flex/compiler/codegen/mxml/IMXMLEmitter.java   |    8 +-
 .../codegen/mxml/flexjs/IMXMLFlexJSEmitter.java    |    3 +
 .../internal/codegen/mxml/MXMLBlockWalker.java     |    8 +-
 .../internal/codegen/mxml/MXMLEmitter.java         |   17 +-
 .../mxml/flexjs/MXMLDescriptorSpecifier.java       |  280 +++++++
 .../codegen/mxml/flexjs/MXMLEventSpecifier.java    |   78 ++
 .../codegen/mxml/flexjs/MXMLFlexJSBlockWalker.java |   25 +-
 .../codegen/mxml/flexjs/MXMLFlexJSEmitter.java     |  623 +++++++++++++--
 .../mxml/flexjs/MXMLFlexJSEmitterTokens.java       |   42 +
 .../codegen/mxml/flexjs/MXMLNodeSpecifier.java     |  170 ++++
 .../codegen/mxml/flexjs/MXMLScriptSpecifier.java   |   67 ++
 .../driver/mxml/flexjs/MXMLFlexJSBackend.java      |    7 +
 12 files changed, 1251 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/IMXMLEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/IMXMLEmitter.java b/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/IMXMLEmitter.java
index df22ceb..8f78e88 100644
--- a/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/IMXMLEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/IMXMLEmitter.java
@@ -25,8 +25,8 @@ import org.apache.flex.compiler.codegen.IEmitter;
 import org.apache.flex.compiler.tree.mxml.IMXMLArrayNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLBooleanNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLClassDefinitionNode;
-import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLIntNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLLiteralNode;
@@ -36,8 +36,8 @@ import org.apache.flex.compiler.tree.mxml.IMXMLScriptNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLStringNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLStyleSpecifierNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLUintNode;
-import org.apache.flex.compiler.visitor.IBlockWalker;
 import org.apache.flex.compiler.visitor.IASNodeStrategy;
+import org.apache.flex.compiler.visitor.IBlockWalker;
 
 /**
  * The {@link IMXMLEmitter} interface allows abstraction between the
@@ -55,9 +55,9 @@ public interface IMXMLEmitter extends IEmitter
 
     //--------------------------------------------------------------------------
 
-    void emitDocumentHeader(IMXMLDocumentNode node);
+    void emitDocumentHeader(IMXMLFileNode node);
 
-    void emitDocumentFooter(IMXMLDocumentNode node);
+    void emitDocumentFooter(IMXMLFileNode node);
 
     //--------------------------------------------------------------------------
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/flexjs/IMXMLFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/flexjs/IMXMLFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/flexjs/IMXMLFlexJSEmitter.java
index 3628cb5..333aa00 100644
--- a/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/flexjs/IMXMLFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/codegen/mxml/flexjs/IMXMLFlexJSEmitter.java
@@ -22,6 +22,7 @@ package org.apache.flex.compiler.codegen.mxml.flexjs;
 import java.io.Writer;
 
 import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter;
+import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
 import org.apache.flex.compiler.visitor.IASNodeStrategy;
 
 /**
@@ -33,4 +34,6 @@ import org.apache.flex.compiler.visitor.IASNodeStrategy;
 public interface IMXMLFlexJSEmitter extends IMXMLEmitter
 {
 
+    void emitDocument(IMXMLDocumentNode node);
+
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLBlockWalker.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLBlockWalker.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLBlockWalker.java
index 00688bd..b155b72 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLBlockWalker.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLBlockWalker.java
@@ -44,8 +44,8 @@ import org.apache.flex.compiler.tree.mxml.IMXMLScriptNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLStringNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLStyleSpecifierNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLUintNode;
-import org.apache.flex.compiler.visitor.IBlockWalker;
 import org.apache.flex.compiler.visitor.IASNodeStrategy;
+import org.apache.flex.compiler.visitor.IBlockWalker;
 import org.apache.flex.compiler.visitor.mxml.IMXMLBlockVisitor;
 import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker;
 
@@ -174,9 +174,11 @@ public class MXMLBlockWalker implements IMXMLBlockVisitor, IMXMLBlockWalker
     {
         debug("visitDocument()");
 
-        mxmlEmitter.emitDocumentHeader(node);
+        IMXMLFileNode fnode = (IMXMLFileNode) node.getParent();
+        
+        mxmlEmitter.emitDocumentHeader(fnode);
         visitClassDefinition(node);
-        mxmlEmitter.emitDocumentFooter(node);
+        mxmlEmitter.emitDocumentFooter(fnode);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLEmitter.java
index b02e04a..988763f 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/MXMLEmitter.java
@@ -33,6 +33,7 @@ import org.apache.flex.compiler.tree.mxml.IMXMLClassDefinitionNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLDeclarationsNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLIntNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLLiteralNode;
@@ -80,22 +81,26 @@ public class MXMLEmitter extends Emitter implements IMXMLEmitter
     //--------------------------------------------------------------------------
 
     @Override
-    public void emitDocumentHeader(IMXMLDocumentNode node)
+    public void emitDocumentHeader(IMXMLFileNode node)
     {
-        IClassDefinition cdef = node
+        IMXMLDocumentNode dnode = node.getDocumentNode();
+        
+        IClassDefinition cdef = dnode
                 .getClassReference((ICompilerProject) walker.getProject());
 
         write("<" + cdef.getBaseName());
 
-        emitPropertySpecifiers(node.getPropertySpecifierNodes(), true);
+        emitPropertySpecifiers(dnode.getPropertySpecifierNodes(), true);
 
         writeNewline(">", true);
     }
 
     @Override
-    public void emitDocumentFooter(IMXMLDocumentNode node)
+    public void emitDocumentFooter(IMXMLFileNode node)
     {
-        IClassDefinition cdef = node
+        IMXMLDocumentNode dnode = node.getDocumentNode();
+        
+        IClassDefinition cdef = dnode
                 .getClassReference((ICompilerProject) walker.getProject());
 
         writeNewline("", false);
@@ -280,7 +285,7 @@ public class MXMLEmitter extends Emitter implements IMXMLEmitter
     }
 
     //--------------------------------------------------------------------------
-    //  utils
+    //  Utils
     //--------------------------------------------------------------------------
 
     public void emitPropertySpecifiers(IMXMLPropertySpecifierNode[] nodes,

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLDescriptorSpecifier.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLDescriptorSpecifier.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLDescriptorSpecifier.java
new file mode 100644
index 0000000..c8fd737
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLDescriptorSpecifier.java
@@ -0,0 +1,280 @@
+/*
+ *
+ *  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.mxml.flexjs;
+
+import java.util.ArrayList;
+
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+
+/**
+ * @author Erik de Bruin
+ */
+public class MXMLDescriptorSpecifier extends MXMLNodeSpecifier
+{
+
+    //--------------------------------------------------------------------------
+    //
+    //    Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    public MXMLDescriptorSpecifier()
+    {
+        super();
+        
+        eventSpecifiers = new ArrayList<MXMLEventSpecifier>();
+        propertySpecifiers = new ArrayList<MXMLDescriptorSpecifier>();
+
+        valueNeedsQuotes = false;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //    Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    children
+    //---------------------------------
+
+    public ArrayList<MXMLDescriptorSpecifier> propertySpecifiers;
+
+    //---------------------------------
+    //    events
+    //---------------------------------
+
+    public ArrayList<MXMLEventSpecifier> eventSpecifiers;
+
+    //---------------------------------
+    //    hasArray
+    //---------------------------------
+
+    public boolean hasArray;
+
+    //---------------------------------
+    //    id
+    //---------------------------------
+
+    public String id;
+
+    //---------------------------------
+    //    isTopNodeInMainFile
+    //---------------------------------
+
+    public boolean isTopNodeInMainFile;
+
+    //---------------------------------
+    //    isProperty
+    //---------------------------------
+    
+    public boolean isProperty;
+    
+    //---------------------------------
+    //    name
+    //---------------------------------
+
+    public String name;
+
+    //---------------------------------
+    //    parent
+    //---------------------------------
+
+    public MXMLDescriptorSpecifier parent;
+
+    //---------------------------------
+    //    value
+    //---------------------------------
+
+    public String value;
+
+    //--------------------------------------------------------------------------
+    //
+    //    Methods
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    outputEventSpecifier
+    //---------------------------------
+
+    private void outputEventSpecifier(boolean writeNewline)
+    {
+        // number of events
+        int count = 0;
+        for (MXMLEventSpecifier me : eventSpecifiers)
+        {
+            if (me.name != null)
+                count++;
+        }
+        write(count + "");
+        
+        for (MXMLEventSpecifier me : eventSpecifiers)
+        {
+            writeDelimiter(writeNewline);
+            write(me.output(writeNewline));
+        }
+    }
+
+    //---------------------------------
+    //    outputPropertySpecifier
+    //---------------------------------
+
+    private String outputPropertySpecifier(boolean writeNewline)
+    {
+        write((isProperty) ? ASEmitterTokens.SINGLE_QUOTE.getToken() : "");
+        write(name);
+        write((isProperty) ? ASEmitterTokens.SINGLE_QUOTE.getToken() : "");
+        writeDelimiter(writeNewline);
+
+        if (isProperty)
+        {
+            if (value != null)
+            {
+                write(ASEmitterTokens.TRUE);
+                writeDelimiter(writeNewline);
+                write(value);
+            }
+            else
+            {
+                write((hasArray) ? ASEmitterTokens.NULL : ASEmitterTokens.FALSE);
+                writeDelimiter(writeNewline && !hasArray);
+
+                write(ASEmitterTokens.SQUARE_OPEN);
+                output(false);
+                write(ASEmitterTokens.SQUARE_CLOSE);
+            }
+
+            if (parent != null)
+                writeDelimiter(writeNewline);
+        }
+        else
+        {
+            write(propertySpecifiers.size() + 1 + "");
+            writeDelimiter(writeNewline);
+
+            String idPropName = (id
+                    .startsWith(MXMLFlexJSEmitterTokens.ID_PREFIX.getToken())) ? "_id"
+                    : "id";
+            writeSimpleDescriptor(idPropName, ASEmitterTokens.TRUE.getToken(),
+                    ASEmitterTokens.SINGLE_QUOTE.getToken()
+                            + id + ASEmitterTokens.SINGLE_QUOTE.getToken(),
+                    writeNewline);
+
+            writeDelimiter(writeNewline);
+
+            output(writeNewline);
+        }
+
+        return sb.toString();
+    }
+
+    //---------------------------------
+    //    outputStyleSpecifier
+    //---------------------------------
+
+    private void outputStyleSpecifier(boolean writeNewline)
+    {
+        // TODO (erikdebruin) not yet implemented in FlexJS
+
+        write("0");
+        writeDelimiter(writeNewline);
+    }
+
+    //---------------------------------
+    //    output
+    //---------------------------------
+
+    @Override
+    public String output(boolean writeNewline)
+    {
+        if (isTopNodeInMainFile)
+        {
+            int count = 0;
+            for (MXMLDescriptorSpecifier md : propertySpecifiers)
+            {
+                if (md.name != null)
+                    count++;
+            }
+
+            write(count + "");
+            writeNewline(ASEmitterTokens.COMMA);
+        }
+        
+        MXMLDescriptorSpecifier model = null; // model goes first
+        MXMLDescriptorSpecifier beads = null; // beads go last
+
+        for (MXMLDescriptorSpecifier md : propertySpecifiers)
+        {
+            if (md.name != null && md.name.equals("model"))
+            {
+                model = md;
+
+                break;
+            }
+        }
+
+        if (model != null)
+            write(model.outputPropertySpecifier(true));
+
+        for (MXMLDescriptorSpecifier md : propertySpecifiers)
+        {
+            if (md.name != null)
+            {
+                if (!md.name.equals("model") && !md.name.equals("beads"))
+                    write(md.outputPropertySpecifier(writeNewline));
+                else if (md.name.equals("beads"))
+                    beads = md;
+            }
+        }
+
+        if (beads != null)
+            write(beads.outputPropertySpecifier(writeNewline));
+
+        if (!isProperty)
+        {
+            outputStyleSpecifier(writeNewline);
+
+            // TODO (erikdebruin) not yet implemented in FlexJS
+            //outputEffectSpecifier(writeNewline);
+
+            outputEventSpecifier(writeNewline);
+            
+            if (!isTopNodeInMainFile)
+            {
+                writeDelimiter(writeNewline);
+                
+                // TODO (erikdebruin) handle child nodes in containers...
+                //                    not yet implemented in FlexJS
+                write(ASEmitterTokens.NULL);
+            }
+            
+            boolean isLastChild = parent != null
+                    && parent.propertySpecifiers.indexOf(this) == parent.propertySpecifiers
+                            .size() - 1;
+
+            if (!isLastChild && !isTopNodeInMainFile)
+                writeDelimiter(writeNewline);
+        }
+
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLEventSpecifier.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLEventSpecifier.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLEventSpecifier.java
new file mode 100644
index 0000000..44c04c3
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLEventSpecifier.java
@@ -0,0 +1,78 @@
+/*
+ *
+ *  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.mxml.flexjs;
+
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+
+/**
+ * @author Erik de Bruin
+ */
+public class MXMLEventSpecifier extends MXMLNodeSpecifier
+{
+
+    //--------------------------------------------------------------------------
+    //
+    //    Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    public MXMLEventSpecifier()
+    {
+        super();
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //    Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    eventHandler
+    //---------------------------------
+
+    public String eventHandler;
+
+    //---------------------------------
+    //    type
+    //---------------------------------
+
+    public String type;
+
+    //--------------------------------------------------------------------------
+    //
+    //    Methods
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    output
+    //---------------------------------
+
+    public String output(boolean writeNewline)
+    {
+        String handler = ASEmitterTokens.THIS.getToken()
+                + ASEmitterTokens.MEMBER_ACCESS.getToken() + eventHandler;
+        writeSimpleDescriptor(name, null, handler, writeNewline);
+
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSBlockWalker.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSBlockWalker.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSBlockWalker.java
index 1f62611..70d99ed 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSBlockWalker.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSBlockWalker.java
@@ -23,12 +23,12 @@ import java.util.List;
 
 import org.apache.flex.compiler.codegen.as.IASEmitter;
 import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter;
+import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter;
 import org.apache.flex.compiler.internal.codegen.mxml.MXMLBlockWalker;
 import org.apache.flex.compiler.problems.ICompilerProblem;
 import org.apache.flex.compiler.projects.IASProject;
-import org.apache.flex.compiler.tree.as.IASNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
-import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
 import org.apache.flex.compiler.visitor.IBlockWalker;
 
 /**
@@ -52,22 +52,19 @@ public class MXMLFlexJSBlockWalker extends MXMLBlockWalker
     //--------------------------------------------------------------------------
 
     @Override
-    public void visitDocument(IMXMLDocumentNode node)
+    public void visitFile(IMXMLFileNode node)
     {
-        debug("visitDocument()");
+        debug("visitFile()");
 
-        mxmlEmitter.emitDocumentHeader(node);
-
-        final int len = node.getChildCount();
-        for (int i = 0; i < len; i++)
-        {
-            IASNode cnode = node.getChild(i);
+        walk(node.getDocumentNode());
+    }
 
-            if (!(cnode instanceof IMXMLEventSpecifierNode))
-                walk(cnode); // first level children
-        }
+    @Override
+    public void visitDocument(IMXMLDocumentNode node)
+    {
+        debug("visitDocument()");
 
-        mxmlEmitter.emitDocumentFooter(node);
+        ((IMXMLFlexJSEmitter) mxmlEmitter).emitDocument(node);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
index 88ca84d..de8db43 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java
@@ -20,28 +20,64 @@
 package org.apache.flex.compiler.internal.codegen.mxml.flexjs;
 
 import java.io.FilterWriter;
+import java.util.ArrayList;
 
+import org.apache.flex.compiler.codegen.as.IASEmitter;
 import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter;
 import org.apache.flex.compiler.definitions.IClassDefinition;
 import org.apache.flex.compiler.definitions.IDefinition;
 import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 import org.apache.flex.compiler.internal.codegen.mxml.MXMLEmitter;
 import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IScopedNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLArrayNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLLiteralNode;
 import org.apache.flex.compiler.tree.mxml.IMXMLPropertySpecifierNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLScriptNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLStringNode;
+import org.apache.flex.compiler.tree.mxml.IMXMLStyleSpecifierNode;
+import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker;
 
 /**
- * The base implementation for an MXML emitter.
- * 
  * @author Erik de Bruin
  */
 public class MXMLFlexJSEmitter extends MXMLEmitter implements
         IMXMLFlexJSEmitter
 {
 
+    // list of all current instance and it's ancestors
+    private ArrayList<MXMLDescriptorSpecifier> currentInstances;
+
+    // list of all current property specifier and it's ancestors
+    private ArrayList<MXMLDescriptorSpecifier> currentPropertySpecifiers;
+
+    // tree of all contents
+    private ArrayList<MXMLDescriptorSpecifier> descriptorTree;
+
+    // linear list of all events
+    private ArrayList<MXMLEventSpecifier> events;
+
+    // linear list of all instances
+    private ArrayList<MXMLDescriptorSpecifier> instances;
+
+    // linear list of all scripts
+    private ArrayList<MXMLScriptSpecifier> scripts;
+
+    // linear list of all styles
+    //private ArrayList<MXMLStyleSpecifier> styles;
+
+    private int eventCounter;
+    private int idCounter;
+
+    private boolean isMainFile;
+
     public MXMLFlexJSEmitter(FilterWriter out)
     {
         super(out);
@@ -50,26 +86,252 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
     //--------------------------------------------------------------------------
 
     @Override
-    public void emitDocumentHeader(IMXMLDocumentNode node)
+    public void emitDocument(IMXMLDocumentNode node)
     {
-        IClassDefinition cdef = node
-                .getClassReference((ICompilerProject) walker.getProject());
+        descriptorTree = new ArrayList<MXMLDescriptorSpecifier>();
 
-        System.out.println("Emit Document Header: " + cdef.getBaseName()
-                + " :: " + cdef.getQualifiedName());
+        events = new ArrayList<MXMLEventSpecifier>();
+        instances = new ArrayList<MXMLDescriptorSpecifier>();
+        scripts = new ArrayList<MXMLScriptSpecifier>();
+        //styles = new ArrayList<MXMLStyleSpecifier>();
 
-        write("<" + cdef.getBaseName());
+        currentInstances = new ArrayList<MXMLDescriptorSpecifier>();
+        currentPropertySpecifiers = new ArrayList<MXMLDescriptorSpecifier>();
 
-        IMXMLEventSpecifierNode[] enodes = node.getEventSpecifierNodes();
-        if (enodes != null)
+        isMainFile = !isMXMLContentNode((IMXMLPropertySpecifierNode) node
+                .getPropertySpecifierNodes()[0]);
+
+        eventCounter = 0;
+        idCounter = 0;
+
+        if (isMainFile)
         {
-            for (IMXMLEventSpecifierNode enode : enodes)
+            // fake a 'root' node, like 'mxmlContent'
+            MXMLDescriptorSpecifier fakeRoot = new MXMLDescriptorSpecifier();
+            fakeRoot.name = "mxmlContent";
+            descriptorTree.add(fakeRoot);
+            currentInstances.add(fakeRoot);
+        }
+
+        // visit tags
+        final int len = node.getChildCount();
+        for (int i = 0; i < len; i++)
+        {
+            getMXMLWalker().walk(node.getChild(i));
+        }
+
+        String cname = node.getFileNode().getName();
+        emitHeaderDoc(cname, "provide");
+
+        writeNewline();
+        emitHeaderDoc(node.getBaseClassName(), "require");
+        ArrayList<String> writtenInstances = new ArrayList<String>();
+        for (MXMLDescriptorSpecifier instance : instances)
+        {
+            String name = instance.name;
+            if (writtenInstances.indexOf(name) == -1)
+            {
+                emitHeaderDoc(name, "require");
+                writtenInstances.add(name);
+            }
+        }
+
+        writeNewline();
+        writeNewline("/**");
+        writeNewline(" * @constructor");
+        writeNewline(" * @extends {" + node.getBaseClassName() + "}");
+        writeNewline(" */");
+        writeToken(cname);
+        writeToken(ASEmitterTokens.EQUAL);
+        write(ASEmitterTokens.FUNCTION);
+        write(ASEmitterTokens.PAREN_OPEN);
+        writeToken(ASEmitterTokens.PAREN_CLOSE);
+        indentPush();
+        writeNewline(ASEmitterTokens.BLOCK_OPEN);
+        write(JSGoogEmitterTokens.GOOG_BASE);
+        write(ASEmitterTokens.PAREN_OPEN);
+        write(ASEmitterTokens.THIS);
+        write(ASEmitterTokens.PAREN_CLOSE);
+        writeNewline(ASEmitterTokens.SEMICOLON);
+
+        for (MXMLDescriptorSpecifier instance : instances)
+        {
+            writeNewline();
+            writeNewline("/**");
+            writeNewline(" * @private");
+            writeNewline(" * @type {" + instance.name + "}");
+            writeNewline(" */");
+            write(ASEmitterTokens.THIS);
+            write(ASEmitterTokens.MEMBER_ACCESS);
+            write(instance.id);
+            writeNewline(ASEmitterTokens.SEMICOLON);
+        }
+
+        writeNewline();
+        writeNewline("/**");
+        writeNewline(" * @private");
+        writeNewline(" * @type {Array}");
+        writeNewline(" */");
+        writeNewline("this.mxmldd;");
+
+        writeNewline();
+        writeNewline("/**");
+        writeNewline(" * @private");
+        writeNewline(" * @type {Array}");
+        writeNewline(" */");
+        indentPop();
+        writeNewline("this.mxmldp;");
+
+        write(ASEmitterTokens.BLOCK_CLOSE);
+        writeNewline(ASEmitterTokens.SEMICOLON);
+        write(JSGoogEmitterTokens.GOOG_INHERITS);
+        write(ASEmitterTokens.PAREN_OPEN);
+        write(cname);
+        writeToken(ASEmitterTokens.COMMA);
+        write(node.getBaseClassName());
+        write(ASEmitterTokens.PAREN_CLOSE);
+        writeNewline(ASEmitterTokens.SEMICOLON);
+        writeNewline();
+
+        for (MXMLScriptSpecifier script : scripts)
+        {
+            writeNewline(script.output());
+        }
+
+        for (MXMLEventSpecifier event : events)
+        {
+            writeNewline("/**");
+            writeNewline(" * @this {" + cname + "}");
+            writeNewline(" * @expose");
+            writeNewline(" * @param {" + event.type + "} event");
+            writeNewline(" */");
+            writeNewline(cname
+                    + ".prototype." + event.eventHandler + " = function(event)");
+            indentPush();
+            writeNewline("{");
+            indentPop();
+            writeNewline(event.value + ASEmitterTokens.SEMICOLON.getToken());
+            writeNewline("};");
+            writeNewline();
+        }
+
+        for (MXMLDescriptorSpecifier instance : instances)
+        {
+            if (!instance.id.startsWith(MXMLFlexJSEmitterTokens.ID_PREFIX
+                    .getToken()))
             {
-                getMXMLWalker().walk(enode);
+                writeNewline("/**");
+                writeNewline(" * @this {" + cname + "}");
+                writeNewline(" * @return {" + instance.name + "}");
+                writeNewline(" */");
+                writeNewline(cname
+                        + ".prototype.get_" + instance.id + " = function()");
+                indentPush();
+                writeNewline("{");
+                indentPop();
+                writeNewline("return this." + instance.id + ";");
+                writeNewline("};");
+                writeNewline();
+                writeNewline("/**");
+                writeNewline(" * @this {" + cname + "}");
+                writeNewline(" * @param {" + instance.name + "} value");
+                writeNewline(" */");
+                writeNewline(cname
+                        + ".prototype.set_" + instance.id
+                        + " = function(value)");
+                indentPush();
+                writeNewline("{");
+                indentPush();
+                writeNewline("if (value != this." + instance.id + ")");
+                indentPop();
+                indentPop();
+                writeNewline("this." + instance.id + " = value;");
+                writeNewline("};");
+                writeNewline();
             }
         }
 
-        write(">");
+        // top level is 'mxmlContent', skip it...
+        MXMLDescriptorSpecifier root = descriptorTree.get(0);
+        root.isTopNodeInMainFile = isMainFile;
+
+        writeNewline("/**");
+        writeNewline(" * @override");
+        writeNewline(" * @this {" + cname + "}");
+        writeNewline(" * @return {Array} the Array of UI element descriptors.");
+        writeNewline(" */");
+        writeNewline(cname + ".prototype.get_MXMLDescriptor = function()");
+        indentPush();
+        writeNewline("{");
+        writeNewline("if (this.mxmldd == undefined)");
+        indentPush();
+        writeNewline("{");
+        writeNewline("/** @type {Array} */");
+        writeNewline("var arr = goog.base(this, 'get_MXMLDescriptor');");
+        writeNewline("/** @type {Array} */");
+        indentPop();
+        indentPop();
+        writeNewline("var data = [");
+
+        if (!isMainFile)
+            writeNewline(root.output(true));
+
+        indentPush();
+        writeNewline("];");
+        indentPush();
+        writeNewline("");
+        indentPush();
+        writeNewline("if (arr)");
+        indentPop();
+        writeNewline("this.mxmldd = arr.concat(data);");
+        indentPush();
+        writeNewline("else");
+        indentPop();
+        indentPop();
+        writeNewline("this.mxmldd = data;");
+        writeNewline("}");
+        indentPop();
+        writeNewline("return this.mxmldd;");
+        writeNewline("};");
+        writeNewline();
+        writeNewline("/**");
+        writeNewline(" * @override");
+        writeNewline(" * @this {" + cname + "}");
+        writeNewline(" * @return {Array} the Array of UI element descriptors.");
+        writeNewline(" */");
+        writeNewline(cname + ".prototype.get_MXMLProperties = function()");
+        indentPush();
+        writeNewline("{");
+        writeNewline("if (this.mxmldp == undefined)");
+        indentPush();
+        writeNewline("{");
+        writeNewline("/** @type {Array} */");
+        writeNewline("var arr = goog.base(this, 'get_MXMLProperties');");
+        writeNewline("/** @type {Array} */");
+        indentPop();
+        indentPop();
+        writeNewline("var data = [");
+
+        if (isMainFile)
+            writeNewline(root.output(true));
+
+        indentPush();
+        writeNewline("];");
+        indentPush();
+        writeNewline("");
+        indentPush();
+        writeNewline("if (arr)");
+        indentPop();
+        writeNewline("this.mxmldp = arr.concat(data);");
+        indentPush();
+        writeNewline("else");
+        indentPop();
+        indentPop();
+        writeNewline("this.mxmldp = data;");
+        writeNewline("}");
+        indentPop();
+        writeNewline("return this.mxmldp;");
+        writeNewline("};");
     }
 
     //--------------------------------------------------------------------------
@@ -79,17 +341,67 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
     {
         IDefinition cdef = node.getDefinition();
 
-        System.out.println("Emit Event Specifier: " + cdef.getBaseName()
-                + " :: " + cdef.getQualifiedName());
+        MXMLDescriptorSpecifier currentDescriptor = getCurrentDescriptor("i");
+
+        MXMLEventSpecifier eventSpecifier = new MXMLEventSpecifier();
+        eventSpecifier.eventHandler = MXMLFlexJSEmitterTokens.EVENT_PREFIX
+                .getToken() + eventCounter++;
+        eventSpecifier.name = cdef.getBaseName();
+        eventSpecifier.type = node.getEventParameterDefinition()
+                .getTypeAsDisplayString();
 
-        write(ASEmitterTokens.SPACE);
-        write(cdef.getBaseName());
-        write(ASEmitterTokens.EQUAL);
-        write(ASEmitterTokens.DOUBLE_QUOTE);
+        // XXX (erikdebruin) "not really sure" the next bit is generic code ;-)
+        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
+                .getASEmitter();
+        String originalHandler = asEmitter.stringifyNode(node.getChild(0));
+
+        StringBuilder jsFormattedHandler = new StringBuilder();
+        String[] splitOnFirstMethod = originalHandler.split("\\(");
+        if (splitOnFirstMethod[0].equals("MyModel"))
+        {
+            // MyModel(model).labelText = 'Hello World';
+            // becomes:
+            // this.model.set_labelText("Hello World");
+            String[] classPropertyAndValue = splitOnFirstMethod[1].split("\\)");
+            String[] propertyAndValue = classPropertyAndValue[1].split(" = ");
 
-        getMXMLWalker().walk(node.getChild(0));
+            String className = classPropertyAndValue[0];
+            String property = propertyAndValue[0].substring(1);
+            String value = propertyAndValue[1];
 
-        write(ASEmitterTokens.DOUBLE_QUOTE);
+            jsFormattedHandler.append(ASEmitterTokens.THIS.getToken());
+            jsFormattedHandler.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+            jsFormattedHandler.append(className);
+            jsFormattedHandler.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+            jsFormattedHandler.append("set_");
+            jsFormattedHandler.append(property);
+            jsFormattedHandler.append(ASEmitterTokens.PAREN_OPEN.getToken());
+            jsFormattedHandler.append(value);
+            jsFormattedHandler.append(ASEmitterTokens.PAREN_CLOSE.getToken());
+        }
+        else if (splitOnFirstMethod[0].equals("dispatchEvent"))
+        {
+            // dispatchEvent(new Event('buttonClicked'));
+            // becomes:
+            // this.dispatchEvent(org.apache.flex.FlexGlobal.newObject(flash.events.Event, ["buttonClicked"]));
+            String[] eventNameMain = splitOnFirstMethod[2].split("'");
+
+            jsFormattedHandler.append(ASEmitterTokens.THIS.getToken());
+            jsFormattedHandler.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+            jsFormattedHandler.append(splitOnFirstMethod[0]);
+            jsFormattedHandler.append(ASEmitterTokens.PAREN_OPEN.getToken());
+            jsFormattedHandler
+                    .append("org.apache.flex.FlexGlobal.newObject(flash.events.Event, [\"");
+            jsFormattedHandler.append(eventNameMain[1]);
+            jsFormattedHandler.append("\"])");
+            jsFormattedHandler.append(ASEmitterTokens.PAREN_CLOSE.getToken());
+        }
+        eventSpecifier.value = jsFormattedHandler.toString();
+
+        if (currentDescriptor != null)
+            currentDescriptor.eventSpecifiers.add(eventSpecifier);
+
+        events.add(eventSpecifier);
     }
 
     @Override
@@ -99,40 +411,50 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
                 .getClassReference((ICompilerProject) getMXMLWalker()
                         .getProject());
 
-        System.out.println("Emit Instance: " + cdef.getBaseName() + " :: "
-                + cdef.getQualifiedName());
+        MXMLDescriptorSpecifier currentPropertySpecifier = getCurrentDescriptor("ps");
 
-        String cname = cdef.getBaseName();
+        String id = node.getID();
+        if (id == null)
+            id = MXMLFlexJSEmitterTokens.ID_PREFIX.getToken() + idCounter++;
 
-        writeNewline("", true);
-        write("<");
-        write(cname);
-        if (node.getID() != null && node.getID() != "")
-        {
-            write(ASEmitterTokens.SPACE);
-            write("id");
-            write(ASEmitterTokens.EQUAL);
-            write("\"");
-            write(node.getID());
-            write("\"");
-        }
-        write(">");
+        MXMLDescriptorSpecifier currentInstance = new MXMLDescriptorSpecifier();
+        currentInstance.isProperty = false;
+        currentInstance.id = id;
+        currentInstance.name = cdef.getQualifiedName();
+        currentInstance.parent = currentPropertySpecifier;
+
+        if (currentPropertySpecifier != null)
+            currentPropertySpecifier.propertySpecifiers.add(currentInstance);
+        else
+            descriptorTree.add(currentInstance);
+
+        instances.add(currentInstance);
 
         IMXMLPropertySpecifierNode[] pnodes = node.getPropertySpecifierNodes();
         if (pnodes != null)
         {
+            moveDown(false, currentInstance, null);
+
             for (IMXMLPropertySpecifierNode pnode : pnodes)
             {
-                if (!isMXMLContentNode(pnode))
-                    getMXMLWalker().walk(pnode); // Property Specifier
+                getMXMLWalker().walk(pnode); // Property Specifier
             }
+
+            moveUp(false, true);
         }
 
-        writeNewline("");
-        write("<");
-        write("/");
-        write(cname);
-        writeNewline(">", false);
+        IMXMLEventSpecifierNode[] enodes = node.getEventSpecifierNodes();
+        if (enodes != null)
+        {
+            moveDown(false, currentInstance, null);
+
+            for (IMXMLEventSpecifierNode enode : enodes)
+            {
+                getMXMLWalker().walk(enode); // Event Specifier
+            }
+
+            moveUp(false, true);
+        }
     }
 
     @Override
@@ -140,16 +462,106 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
     {
         IDefinition cdef = node.getDefinition();
 
-        System.out.println("Emit Property Specifier: " + cdef.getBaseName()
-                + " :: " + cdef.getQualifiedName());
+        IASNode cnode = node.getChild(0);
+
+        MXMLDescriptorSpecifier currentInstance = getCurrentDescriptor("i");
+
+        MXMLDescriptorSpecifier currentPropertySpecifier = new MXMLDescriptorSpecifier();
+        currentPropertySpecifier.isProperty = true;
+        currentPropertySpecifier.name = cdef.getQualifiedName();
+        currentPropertySpecifier.parent = currentInstance;
+
+        if (currentInstance != null)
+            currentInstance.propertySpecifiers.add(currentPropertySpecifier);
+        else
+            descriptorTree.add(currentPropertySpecifier);
+
+        boolean bypass = cnode != null && cnode instanceof IMXMLArrayNode;
+
+        currentPropertySpecifier.hasArray = bypass;
+
+        moveDown(bypass, null, currentPropertySpecifier);
+
+        getMXMLWalker().walk(cnode); // Array or Instance
+
+        moveUp(bypass, false);
+    }
+
+    @Override
+    public void emitScript(IMXMLScriptNode node)
+    {
+        String cname = node.getFileNode().getName();
 
-        writeNewline("", true);
-        write("<" + node.getName() + ">");
+        IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker())
+                .getASEmitter();
 
-        getMXMLWalker().walk(node.getChild(0)); // Array
+        StringBuilder sb = null;
+        MXMLScriptSpecifier scriptSpecifier = null;
 
-        write("</" + node.getName() + ">");
+        indentPush();
+        String nl = ASEmitterTokens.NEW_LINE.getToken();
+        String ci = getIndent(getCurrentIndent());
         indentPop();
+
+        IASNode[] asnodes = node.getASNodes();
+        for (IASNode asnode : asnodes)
+        {
+            sb = new StringBuilder();
+            scriptSpecifier = new MXMLScriptSpecifier();
+
+            String signature = asEmitter.stringifyNode(asnode)
+                    + ASEmitterTokens.NEW_LINE.getToken();
+
+            String[] breakOnGet = signature.split("get ");
+            String[] breakOnParenOpen = breakOnGet[1].split("\\(");
+            String propertyName = breakOnParenOpen[0];
+
+            sb.append("/**" + nl);
+            sb.append(" * @this {" + cname + "}" + nl);
+            sb.append(" * @expose" + nl);
+            sb.append(" * @return {string}" + nl);
+            sb.append(" */" + nl);
+            sb.append(cname
+                    + ".prototype.get_" + propertyName + " = function()" + nl);
+            sb.append("{" + nl);
+
+            ASTNodeID nodeId = asnode.getNodeID();
+            if (nodeId == ASTNodeID.FunctionID
+                    || nodeId == ASTNodeID.GetterID
+                    || nodeId == ASTNodeID.SetterID)
+            {
+                IScopedNode snode = ((IFunctionNode) asnode).getScopedNode();
+
+                String body = asEmitter.stringifyNode(snode.getChild(0));
+                String[] breakOnSpace = body.split(" ");
+                String[] breakOnMemberAccess = breakOnSpace[1].split("\\.");
+
+                sb.append(ci);
+                sb.append(ASEmitterTokens.RETURN.getToken());
+                sb.append(ASEmitterTokens.SPACE.getToken());
+                sb.append(ASEmitterTokens.THIS.getToken());
+                sb.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+                sb.append(breakOnMemberAccess[0]);
+                sb.append(ASEmitterTokens.MEMBER_ACCESS.getToken());
+                sb.append("get_");
+                sb.append(breakOnMemberAccess[1]);
+                sb.append(ASEmitterTokens.PAREN_OPEN.getToken());
+                sb.append(ASEmitterTokens.PAREN_CLOSE.getToken());
+                sb.append(ASEmitterTokens.SEMICOLON.getToken());
+                sb.append(nl);
+            }
+
+            sb.append("};" + nl);
+
+            scriptSpecifier.fragment = sb.toString();
+
+            scripts.add(scriptSpecifier);
+        }
+    }
+
+    @Override
+    public void emitStyleSpecifier(IMXMLStyleSpecifierNode node)
+    {
     }
 
     //--------------------------------------------------------------------------
@@ -157,11 +569,122 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements
     @Override
     public void emitArray(IMXMLArrayNode node)
     {
+        moveDown(false, null, null);
+
         final int len = node.getChildCount();
         for (int i = 0; i < len; i++)
         {
             getMXMLWalker().walk(node.getChild(i)); // Instance
         }
+
+        moveUp(false, false);
+    }
+
+    @Override
+    public void emitString(IMXMLStringNode node)
+    {
+        getCurrentDescriptor("ps").valueNeedsQuotes = true;
+
+        emitAttributeValue(node);
+    }
+
+    //--------------------------------------------------------------------------
+
+    @Override
+    public void emitLiteral(IMXMLLiteralNode node)
+    {
+        MXMLDescriptorSpecifier ps = getCurrentDescriptor("ps");
+        ps.value = "";
+
+        if (ps.valueNeedsQuotes)
+            ps.value += ASEmitterTokens.SINGLE_QUOTE.getToken();
+
+        ps.value += node.getValue().toString();
+
+        if (ps.valueNeedsQuotes)
+            ps.value += ASEmitterTokens.SINGLE_QUOTE.getToken();
+    }
+
+    //--------------------------------------------------------------------------
+    //    Utils
+    //--------------------------------------------------------------------------
+
+    @Override
+    protected void emitAttributeValue(IASNode node)
+    {
+        IMXMLLiteralNode cnode = (IMXMLLiteralNode) node.getChild(0);
+
+        if (cnode.getValue() != null)
+            getMXMLWalker().walk((IASNode) cnode); // Literal
+    }
+
+    private void emitHeaderDoc(String qname, String type)
+    {
+        write((type == "provide") ? JSGoogEmitterTokens.GOOG_PROVIDE
+                : JSGoogEmitterTokens.GOOG_REQUIRE);
+        write(ASEmitterTokens.PAREN_OPEN);
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        write(qname);
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        write(ASEmitterTokens.PAREN_CLOSE);
+        writeNewline(ASEmitterTokens.SEMICOLON);
+    }
+
+    private MXMLDescriptorSpecifier getCurrentDescriptor(String type)
+    {
+        MXMLDescriptorSpecifier currentDescriptor = null;
+
+        int index;
+
+        if (type.equals("i"))
+        {
+            index = currentInstances.size() - 1;
+            if (index > -1)
+                currentDescriptor = currentInstances.get(index);
+        }
+        else
+        {
+            index = currentPropertySpecifiers.size() - 1;
+            if (index > -1)
+                currentDescriptor = currentPropertySpecifiers.get(index);
+        }
+
+        return currentDescriptor;
+    }
+
+    protected void moveDown(boolean byPass,
+            MXMLDescriptorSpecifier currentInstance,
+            MXMLDescriptorSpecifier currentPropertySpecifier)
+    {
+        if (!byPass)
+        {
+            if (currentInstance != null)
+                currentInstances.add(currentInstance);
+        }
+
+        if (currentPropertySpecifier != null)
+            currentPropertySpecifiers.add(currentPropertySpecifier);
+    }
+
+    protected void moveUp(boolean byPass, boolean isInstance)
+    {
+        if (!byPass)
+        {
+            int index;
+
+            if (isInstance)
+            {
+                index = currentInstances.size() - 1;
+                if (index > -1)
+                    currentInstances.remove(index);
+            }
+            else
+            {
+                index = currentPropertySpecifiers.size() - 1;
+                if (index > -1)
+                    currentPropertySpecifiers.remove(index);
+            }
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitterTokens.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitterTokens.java
new file mode 100644
index 0000000..8aa737b
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitterTokens.java
@@ -0,0 +1,42 @@
+/*
+ *
+ *  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.mxml.flexjs;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+/**
+ * @author Erik de Bruin
+ */
+public enum MXMLFlexJSEmitterTokens implements IEmitterTokens
+{
+    EVENT_PREFIX("$EH"), ID_PREFIX("$ID");
+
+    private String token;
+
+    private MXMLFlexJSEmitterTokens(String value)
+    {
+        token = value;
+    }
+
+    public String getToken()
+    {
+        return token;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLNodeSpecifier.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLNodeSpecifier.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLNodeSpecifier.java
new file mode 100644
index 0000000..12fb7f6
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLNodeSpecifier.java
@@ -0,0 +1,170 @@
+/*
+ *
+ *  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.mxml.flexjs;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+
+/**
+ * @author Erik de Bruin
+ */
+public class MXMLNodeSpecifier
+{
+
+    //--------------------------------------------------------------------------
+    //
+    //    Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    public MXMLNodeSpecifier()
+    {
+        sb = new StringBuilder();
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //    Variables
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    sb
+    //---------------------------------
+
+    protected StringBuilder sb;
+    
+    //--------------------------------------------------------------------------
+    //
+    //    Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    name
+    //---------------------------------
+
+    public String name;
+
+    //---------------------------------
+    //    value
+    //---------------------------------
+
+    public String value;
+
+    //---------------------------------
+    //    valueNeedsQuotes
+    //---------------------------------
+
+    public boolean valueNeedsQuotes;
+
+    //--------------------------------------------------------------------------
+    //
+    //    Methods
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    output
+    //---------------------------------
+
+    public String output(boolean writeNewline)
+    {
+        return "";
+    }
+
+    //---------------------------------
+    //    write
+    //---------------------------------
+
+    protected void write(IEmitterTokens value)
+    {
+        write(value.getToken());
+    }
+
+    protected void write(String value)
+    {
+        sb.append(value);
+    }
+
+    //---------------------------------
+    //    writeDelimiter
+    //---------------------------------
+
+    protected void writeDelimiter(boolean writeNewline)
+    {
+        if (writeNewline)
+            writeNewline(ASEmitterTokens.COMMA);
+        else
+            writeToken(ASEmitterTokens.COMMA);
+    }
+
+    //---------------------------------
+    //    writeNewline
+    //---------------------------------
+
+    protected void writeNewline(IEmitterTokens value)
+    {
+        writeNewline(value.getToken());
+    }
+
+    protected void writeNewline(String value)
+    {
+        write(value);
+        write(ASEmitterTokens.NEW_LINE);
+    }
+
+    //---------------------------------
+    //    writeSimpleDescriptor
+    //---------------------------------
+
+    protected void writeSimpleDescriptor(String name, String type, String value,
+            boolean writeNewline)
+    {
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        write(name);
+        write(ASEmitterTokens.SINGLE_QUOTE);
+        writeDelimiter(writeNewline);
+
+        if (type != null)
+        {
+            write(type);
+            writeDelimiter(writeNewline);
+        }
+
+        write(value);
+    }
+
+    //---------------------------------
+    //    writeToken
+    //---------------------------------
+
+    protected void writeToken(IEmitterTokens value)
+    {
+        writeToken(value.getToken());
+    }
+
+    protected void writeToken(String value)
+    {
+        write(value);
+        write(ASEmitterTokens.SPACE);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLScriptSpecifier.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLScriptSpecifier.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLScriptSpecifier.java
new file mode 100644
index 0000000..c2f3824
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLScriptSpecifier.java
@@ -0,0 +1,67 @@
+/*
+ *
+ *  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.mxml.flexjs;
+
+
+/**
+ * @author Erik de Bruin
+ */
+public class MXMLScriptSpecifier extends MXMLNodeSpecifier
+{
+
+    //--------------------------------------------------------------------------
+    //
+    //    Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    public MXMLScriptSpecifier()
+    {
+        super();
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //    Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    fragment
+    //---------------------------------
+
+    public String fragment;
+
+    //--------------------------------------------------------------------------
+    //
+    //    Methods
+    //
+    //--------------------------------------------------------------------------
+
+    //---------------------------------
+    //    output
+    //---------------------------------
+
+    public String output()
+    {
+        return this.fragment;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/77f657d7/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
index 1035a77..375c80d 100644
--- a/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.flex.compiler.codegen.as.IASEmitter;
 import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter;
 import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitter;
 import org.apache.flex.compiler.internal.codegen.mxml.MXMLBlockWalker;
 import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSBlockWalker;
 import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSEmitter;
@@ -71,4 +72,10 @@ public class MXMLFlexJSBackend extends MXMLBackend
         return walker;
     }
 
+    @Override
+    public IASEmitter createEmitter(FilterWriter out)
+    {
+        return new ASEmitter(out);
+    }
+
 }