You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by jo...@apache.org on 2020/12/21 19:30:16 UTC

[royale-compiler] 02/03: MXMLRoyaleEmitter: created an emitter interface for MXML specifiers so that their generated JS output may have different implementations

This is an automated email from the ASF dual-hosted git repository.

joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git

commit 3046c63832f8fb88f6c95e3cac748acdd23c5042
Author: Josh Tynjala <jo...@apache.org>
AuthorDate: Mon Dec 21 10:49:49 2020 -0800

    MXMLRoyaleEmitter: created an emitter interface for MXML specifiers so that their generated JS output may have different implementations
---
 .../compiler/codegen/mxml/js/IMXMLJSEmitter.java   |  27 ++
 .../royale/JSRoyaleBasicMXMLDescriptorEmitter.java | 312 +++++++++++++++++++++
 .../internal/codegen/mxml/MXMLSubEmitter.java      | 125 +++++++++
 .../mxml/royale/MXMLDescriptorSpecifier.java       | 282 -------------------
 .../codegen/mxml/royale/MXMLEventSpecifier.java    |  18 +-
 .../codegen/mxml/royale/MXMLNodeSpecifier.java     | 114 --------
 .../codegen/mxml/royale/MXMLRoyaleEmitter.java     |  37 +--
 7 files changed, 485 insertions(+), 430 deletions(-)

diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/mxml/js/IMXMLJSEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/mxml/js/IMXMLJSEmitter.java
new file mode 100644
index 0000000..4d4dde4
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/mxml/js/IMXMLJSEmitter.java
@@ -0,0 +1,27 @@
+/*
+ *
+ *  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.royale.compiler.codegen.mxml.js;
+
+import org.apache.royale.compiler.codegen.js.IMappingEmitter;
+import org.apache.royale.compiler.codegen.mxml.IMXMLEmitter;
+
+public interface IMXMLJSEmitter extends IMXMLEmitter, IMappingEmitter {
+	
+}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleBasicMXMLDescriptorEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleBasicMXMLDescriptorEmitter.java
new file mode 100644
index 0000000..ea11bf7
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleBasicMXMLDescriptorEmitter.java
@@ -0,0 +1,312 @@
+/*
+ *
+ *  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.royale.compiler.internal.codegen.js.royale;
+
+import org.apache.royale.compiler.codegen.ISubEmitter;
+import org.apache.royale.compiler.codegen.mxml.js.IMXMLJSEmitter;
+import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.royale.compiler.internal.codegen.mxml.MXMLSubEmitter;
+import org.apache.royale.compiler.internal.codegen.mxml.royale.MXMLDescriptorSpecifier;
+import org.apache.royale.compiler.internal.codegen.mxml.royale.MXMLEventSpecifier;
+
+public class JSRoyaleBasicMXMLDescriptorEmitter extends MXMLSubEmitter implements ISubEmitter<MXMLDescriptorSpecifier>
+{
+    public JSRoyaleBasicMXMLDescriptorEmitter(IMXMLJSEmitter emitter)
+    {
+        super(emitter);
+    }
+
+    @Override
+    public void emit(MXMLDescriptorSpecifier root)
+    {
+		outputDescriptorSpecifier(root, true);
+	}
+
+    //---------------------------------
+    //    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);
+    }
+
+    //---------------------------------
+    //    writeDelimiter
+    //---------------------------------
+
+    protected void writeDelimiter(boolean writeNewline)
+    {
+        if (writeNewline)
+            writeNewline(ASEmitterTokens.COMMA);
+        else
+            writeToken(ASEmitterTokens.COMMA);
+	}
+
+    //---------------------------------
+    //    outputDescriptorSpecifier
+    //---------------------------------
+
+	private void outputDescriptorSpecifier(MXMLDescriptorSpecifier root, boolean writeNewline)
+    {
+        if (root.isTopNode)
+        {
+            int count = 0;
+            for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
+            {
+                if (md.name != null)
+                    count++;
+            }
+
+            write(count + "");
+            writeNewline(ASEmitterTokens.COMMA);
+        }
+
+		outputPropertySpecifiers(root, writeNewline);
+
+        if (!root.isProperty)
+        {
+            outputStyleSpecifiers(root, writeNewline);
+
+            // TODO (erikdebruin) not yet implemented in Royale
+            //outputEffectSpecifiers(writeNewline);
+
+            outputEventSpecifiers(root, writeNewline);
+
+            if (!root.isTopNode)
+            {
+                writeDelimiter(writeNewline);
+
+                if (root.childrenSpecifier == null)
+                    write(ASEmitterTokens.NULL);
+                else
+                    outputChildren(root.childrenSpecifier, writeNewline);
+            }
+
+            boolean isLastChild = root.parent != null
+                    && root.parent.propertySpecifiers.indexOf(root) == root.parent.propertySpecifiers
+                            .size() - 1;
+
+            if (!isLastChild && !root.isTopNode)
+                writeDelimiter(writeNewline);
+        }
+    }
+
+    //---------------------------------
+    //    outputPropertySpecifiers
+    //---------------------------------
+	
+	private void outputPropertySpecifiers(MXMLDescriptorSpecifier root, boolean writeNewline)
+	{
+        MXMLDescriptorSpecifier model = null; // model goes first
+        MXMLDescriptorSpecifier beads = null; // beads go last
+
+        for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
+        {
+            if (md.name != null && md.name.equals("model"))
+            {
+                model = md;
+                break;
+            }
+        }
+
+        if (model != null)
+        {
+            outputPropertySpecifier(model, writeNewline);
+        }
+
+        for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
+        {
+            if (md.name != null)
+            {
+                if (!md.name.equals("model") && !md.name.equals("beads"))
+                    outputPropertySpecifier(md, writeNewline);
+                else if (md.name.equals("beads"))
+                    beads = md;
+            }
+        }
+
+        if (beads != null)
+        {
+            outputPropertySpecifier(beads, writeNewline);
+        }
+	}
+
+    //---------------------------------
+    //    outputEventSpecifiers
+    //---------------------------------
+
+    private void outputEventSpecifiers(MXMLDescriptorSpecifier root, boolean writeNewline)
+    {
+        // number of events
+        int count = 0;
+        for (MXMLEventSpecifier me : root.eventSpecifiers)
+        {
+            if (me.name != null)
+                count++;
+        }
+        write(count + "");
+
+        for (MXMLEventSpecifier me : root.eventSpecifiers)
+        {
+			writeDelimiter(writeNewline);
+			outputEventSpecifier(me, writeNewline);
+        }
+    }
+
+    //---------------------------------
+    //    outputStyleSpecifiers
+    //---------------------------------
+
+    private void outputStyleSpecifiers(MXMLDescriptorSpecifier root, boolean writeNewline)
+    {
+        // TODO (erikdebruin) not yet implemented in Royale
+
+        write("0");
+        writeDelimiter(writeNewline);
+    }
+
+    //---------------------------------
+    //    outputPropertySpecifier
+    //---------------------------------
+
+    private void outputPropertySpecifier(MXMLDescriptorSpecifier specifier, boolean writeNewline)
+    {
+        write((specifier.isProperty) ? ASEmitterTokens.SINGLE_QUOTE.getToken() : "");
+        write(specifier.name);
+        write((specifier.isProperty) ? ASEmitterTokens.SINGLE_QUOTE.getToken() : "");
+        writeDelimiter(writeNewline);
+
+        if (specifier.isProperty)
+        {
+            if (specifier.value != null)
+            {
+                write(ASEmitterTokens.TRUE);
+                writeDelimiter(writeNewline);
+                // need to do other escaping here?
+                // restrict="0-9.\"
+                if (specifier.value.endsWith("\\'") && !specifier.value.endsWith("\\\\'"))
+                {
+                	specifier.value = specifier.value.substring(0, specifier.value.length() - 1) + "\\'";
+                }
+                write(specifier.value);
+            }
+            else
+            {
+                write((specifier.hasArray) ? ASEmitterTokens.NULL : ASEmitterTokens.FALSE);
+                writeDelimiter(writeNewline);
+                write(ASEmitterTokens.SQUARE_OPEN);
+                indentPush();
+                writeNewline();
+                outputDescriptorSpecifier(specifier, writeNewline);
+                indentPop();
+                writeNewline();
+                write(ASEmitterTokens.SQUARE_CLOSE);
+            }
+
+            if (specifier.parent != null)
+                writeDelimiter(writeNewline);
+        }
+        else
+        {
+            for (MXMLDescriptorSpecifier md : specifier.propertySpecifiers)
+            {
+                if (md.name != null && md.name.equals("mxmlContent"))
+                {
+                    specifier.childrenSpecifier = md;
+                    specifier.propertySpecifiers.remove(md);
+                    break;
+                }
+            }
+
+            if (specifier.id != null || specifier.effectiveId != null)
+            {
+                write(specifier.propertySpecifiers.size() + 1 + "");
+                writeDelimiter(writeNewline);
+                String idPropName = (specifier.effectiveId != null) ? "_id"
+                        : "id";
+                writeSimpleDescriptor(idPropName, ASEmitterTokens.TRUE.getToken(),
+                        ASEmitterTokens.SINGLE_QUOTE.getToken()
+                                + ((specifier.id != null) ? specifier.id : specifier.effectiveId) + ASEmitterTokens.SINGLE_QUOTE.getToken(),
+                        writeNewline);
+
+                writeDelimiter(writeNewline);
+            }
+            else
+            {
+                write(specifier.propertySpecifiers.size() + "");
+                writeDelimiter(writeNewline);
+            }
+
+            outputDescriptorSpecifier(specifier, writeNewline);
+        }
+    }
+
+    //---------------------------------
+    //    outputEventSpecifier
+    //---------------------------------
+
+    public void outputEventSpecifier(MXMLEventSpecifier specifier, boolean writeNewline)
+    {
+        String handler = ASEmitterTokens.THIS.getToken()
+                + ASEmitterTokens.MEMBER_ACCESS.getToken() + specifier.eventHandler;
+        if (MXMLEventSpecifier.nameMap.contains(specifier.name))
+			specifier.name = specifier.name.toLowerCase();
+		else if (specifier.name.equals("doubleClick"))
+			specifier.name = "dblclick";
+		else if (specifier.name.equals("mouseWheel"))
+			specifier.name = "wheel";
+        writeSimpleDescriptor(specifier.name, null, handler, writeNewline);
+    }
+
+    //---------------------------------
+    //    outputChildren
+    //---------------------------------
+
+    private void outputChildren(MXMLDescriptorSpecifier children, boolean writeNewline)
+    {
+        write(ASEmitterTokens.SQUARE_OPEN.getToken());
+        if(writeNewline)
+        {
+            indentPush();
+            writeNewline();
+		}
+		outputDescriptorSpecifier(children, writeNewline);
+        if(writeNewline)
+        {
+            indentPop();
+            writeNewline();
+        }
+        write(ASEmitterTokens.SQUARE_CLOSE.getToken());
+	}
+	
+}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLSubEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLSubEmitter.java
new file mode 100644
index 0000000..25d7ae2
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLSubEmitter.java
@@ -0,0 +1,125 @@
+/*
+ *
+ *  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.royale.compiler.internal.codegen.mxml;
+
+import org.apache.royale.compiler.codegen.IEmitterTokens;
+import org.apache.royale.compiler.codegen.mxml.js.IMXMLJSEmitter;
+import org.apache.royale.compiler.common.ISourceLocation;
+import org.apache.royale.compiler.projects.ICompilerProject;
+import org.apache.royale.compiler.visitor.IBlockWalker;
+
+public class MXMLSubEmitter {
+    private IMXMLJSEmitter emitter;
+
+    protected IMXMLJSEmitter getEmitter()
+    {
+        return emitter; 
+    }
+
+    protected IBlockWalker getMXMLWalker()
+    {
+        return emitter.getMXMLWalker();
+    }
+    
+    protected ICompilerProject getProject()
+    {
+        return emitter.getMXMLWalker().getProject();
+    }
+
+    public MXMLSubEmitter(IMXMLJSEmitter emitter)
+    {
+        this.emitter = emitter;
+    }
+
+    protected void write(IEmitterTokens value)
+    {
+        emitter.write(value);
+    }
+
+    protected void write(String value)
+    {
+        emitter.write(value);
+    }
+
+    protected void writeToken(IEmitterTokens value)
+    {
+        emitter.writeToken(value);
+    }
+
+    protected void writeToken(String value)
+    {
+        emitter.writeToken(value);
+    }
+
+    protected void writeNewline()
+    {
+        emitter.writeNewline();
+    }
+
+    protected void writeNewline(IEmitterTokens value)
+    {
+        emitter.writeNewline(value);
+    }
+
+    protected void writeNewline(String value)
+    {
+        emitter.writeNewline(value);
+    }
+
+    protected void writeNewline(IEmitterTokens value, boolean pushIndent)
+    {
+        emitter.writeNewline(value, pushIndent);
+    }
+
+    protected void writeNewline(String value, boolean pushIndent)
+    {
+        emitter.writeNewline(value, pushIndent);
+    }
+
+    protected void indentPush()
+    {
+        emitter.indentPush();
+    }
+
+    protected void indentPop()
+    {
+        emitter.indentPop();
+    }
+
+    protected void startMapping(ISourceLocation node)
+    {
+        emitter.startMapping(node);
+    }
+
+    protected void startMapping(ISourceLocation node, int line, int column)
+    {
+        emitter.startMapping(node, line, column);
+    }
+
+    protected void startMapping(ISourceLocation node, ISourceLocation afterNode)
+    {
+        emitter.startMapping(node, afterNode);
+    }
+
+    protected void endMapping(ISourceLocation node)
+    {
+        emitter.endMapping(node);
+    }
+}
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLDescriptorSpecifier.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLDescriptorSpecifier.java
index 2208f3a..617b4ed 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLDescriptorSpecifier.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLDescriptorSpecifier.java
@@ -21,10 +21,6 @@ package org.apache.royale.compiler.internal.codegen.mxml.royale;
 
 import java.util.ArrayList;
 
-import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
-import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
-import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
-
 /**
  * @author Erik de Bruin
  */
@@ -118,282 +114,4 @@ public class MXMLDescriptorSpecifier extends MXMLNodeSpecifier
     //---------------------------------
 
     public MXMLDescriptorSpecifier parent;
-
-    //---------------------------------
-    //    currentIndent
-    //---------------------------------
- 
-    private int currentIndent = 0;
-
-    //--------------------------------------------------------------------------
-    //
-    //    Methods
-    //
-    //--------------------------------------------------------------------------
-
-    //---------------------------------
-    //    indent
-    //---------------------------------
-
-    protected String getIndent()
-    {
-        return getIndent(currentIndent);
-    }
-
-    protected String getIndent(int numIndent)
-    {
-        final StringBuilder sb = new StringBuilder();
-        if (parent != null)
-        {
-            sb.append(parent.getIndent());
-        }
-        for (int i = 0; i < numIndent; i++)
-            sb.append(JSRoyaleEmitterTokens.INDENT.getToken());
-        return sb.toString();
-    }
-
-    public void indentPush()
-    {
-        currentIndent++;
-    }
-
-    public void indentPop()
-    {
-        if (currentIndent > 0)
-        {
-            currentIndent--;
-        }
-    }
-
-    @Override
-    protected void writeNewline()
-    {
-        write(ASEmitterTokens.NEW_LINE);
-        write(getIndent(currentIndent));
-    }
-
-    //---------------------------------
-    //    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);
-                // need to do other escaping here?
-                // restrict="0-9.\"
-                if (value.endsWith("\\'") && !value.endsWith("\\\\'"))
-                {
-                	value = value.substring(0, value.length() - 1) + "\\'";
-                }
-                write(value);
-            }
-            else
-            {
-                write((hasArray) ? ASEmitterTokens.NULL : ASEmitterTokens.FALSE);
-                writeDelimiter(writeNewline);
-                write(ASEmitterTokens.SQUARE_OPEN);
-                indentPush();
-                writeNewline();
-                output(writeNewline);
-                indentPop();
-                writeNewline();
-                write(ASEmitterTokens.SQUARE_CLOSE);
-            }
-
-            if (parent != null)
-                writeDelimiter(writeNewline);
-        }
-        else
-        {
-            for (MXMLDescriptorSpecifier md : propertySpecifiers)
-            {
-                if (md.name != null && md.name.equals("mxmlContent"))
-                {
-                    childrenSpecifier = md;
-                    propertySpecifiers.remove(md);
-                    break;
-                }
-            }
-
-            if (id != null || effectiveId != null)
-            {
-                write(propertySpecifiers.size() + 1 + "");
-                writeDelimiter(writeNewline);
-                String idPropName = (effectiveId != null) ? "_id"
-                        : "id";
-                writeSimpleDescriptor(idPropName, ASEmitterTokens.TRUE.getToken(),
-                        ASEmitterTokens.SINGLE_QUOTE.getToken()
-                                + ((id != null) ? id : effectiveId) + ASEmitterTokens.SINGLE_QUOTE.getToken(),
-                        writeNewline);
-
-                writeDelimiter(writeNewline);
-            }
-            else
-            {
-                write(propertySpecifiers.size() + "");
-                writeDelimiter(writeNewline);
-            }
-
-            output(writeNewline);
-        }
-
-        return sb.toString();
-    }
-
-    //---------------------------------
-    //    outputStyleSpecifier
-    //---------------------------------
-
-    private void outputStyleSpecifier(boolean writeNewline)
-    {
-        // TODO (erikdebruin) not yet implemented in Royale
-
-        write("0");
-        writeDelimiter(writeNewline);
-    }
-
-    //---------------------------------
-    //    output
-    //---------------------------------
-
-    @Override
-    public String output(boolean writeNewline)
-    {
-        if (isTopNode)
-        {
-            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(writeNewline));
-        }
-
-        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 Royale
-            //outputEffectSpecifier(writeNewline);
-
-            outputEventSpecifier(writeNewline);
-
-            if (!isTopNode)
-            {
-                writeDelimiter(writeNewline);
-
-                if (childrenSpecifier == null)
-                    write(ASEmitterTokens.NULL);
-                else
-                    outputChildren(childrenSpecifier, writeNewline);
-            }
-
-            boolean isLastChild = parent != null
-                    && parent.propertySpecifiers.indexOf(this) == parent.propertySpecifiers
-                            .size() - 1;
-
-            if (!isLastChild && !isTopNode)
-                writeDelimiter(writeNewline);
-        }
-
-        return sb.toString();
-    }
-
-    private void outputChildren(MXMLDescriptorSpecifier children, boolean writeNewline)
-    {
-        write(ASEmitterTokens.SQUARE_OPEN.getToken());
-        if(writeNewline)
-        {
-            indentPush();
-            writeNewline();
-        }
-        write(children.output(writeNewline));
-        if(writeNewline)
-        {
-            indentPop();
-            writeNewline();
-        }
-        write(ASEmitterTokens.SQUARE_CLOSE.getToken());
-    }
-
-    public String outputStateDescriptors(boolean writeNewLine)
-    {
-        for (MXMLDescriptorSpecifier md : propertySpecifiers)
-        {
-            write(ASEmitterTokens.SQUARE_OPEN);
-            write(md.output(writeNewLine));
-            write(ASEmitterTokens.SQUARE_CLOSE);
-            writeNewline(ASEmitterTokens.COMMA);
-        }
-        return sb.toString();
-    }
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLEventSpecifier.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLEventSpecifier.java
index 4c0f777..1e9de21 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLEventSpecifier.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLEventSpecifier.java
@@ -22,7 +22,6 @@ package org.apache.royale.compiler.internal.codegen.mxml.royale;
 import java.util.Arrays;
 import java.util.List;
 
-import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
 import org.apache.royale.compiler.tree.mxml.IMXMLEventSpecifierNode;
 
 /**
@@ -48,7 +47,7 @@ public class MXMLEventSpecifier extends MXMLNodeSpecifier
     //
     //--------------------------------------------------------------------------
 
-    static List<String> nameMap = Arrays.asList(
+    public static List<String> nameMap = Arrays.asList(
     		"rollOver",
     		"rollOut",
     		"mouseDown",
@@ -82,21 +81,6 @@ public class MXMLEventSpecifier extends MXMLNodeSpecifier
     //    output
     //---------------------------------
 
-    public String output(boolean writeNewline)
-    {
-        String handler = ASEmitterTokens.THIS.getToken()
-                + ASEmitterTokens.MEMBER_ACCESS.getToken() + eventHandler;
-        if (nameMap.contains(name))
-        	name = name.toLowerCase();
-		else if (name.equals("doubleClick"))
-			name = "dblclick";
-		else if (name.equals("mouseWheel"))
-			name = "wheel";
-        writeSimpleDescriptor(name, null, handler, writeNewline);
-
-        return sb.toString();
-    }
-
     public static String getJSEventName(String name)
     {
     	if (nameMap.contains(name))
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLNodeSpecifier.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLNodeSpecifier.java
index 62d4b6e..df66d69 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLNodeSpecifier.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLNodeSpecifier.java
@@ -19,9 +19,6 @@
 
 package org.apache.royale.compiler.internal.codegen.mxml.royale;
 
-import org.apache.royale.compiler.codegen.IEmitterTokens;
-import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
-
 /**
  * @author Erik de Bruin
  */
@@ -36,20 +33,7 @@ public class MXMLNodeSpecifier
 
     public MXMLNodeSpecifier()
     {
-        sb = new StringBuilder();
     }
-
-    //--------------------------------------------------------------------------
-    //
-    //    Variables
-    //
-    //--------------------------------------------------------------------------
-
-    //---------------------------------
-    //    sb
-    //---------------------------------
-
-    protected StringBuilder sb;
     
     //--------------------------------------------------------------------------
     //
@@ -74,102 +58,4 @@ public class MXMLNodeSpecifier
     //---------------------------------
 
     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);
-        writeNewline();
-    }
-
-    protected void writeNewline()
-    {
-        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);
-    }
-
 }
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
index 85a0032..820d26a 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java
@@ -38,13 +38,13 @@ import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.royale.abc.ABCConstants;
 import org.apache.royale.abc.instructionlist.InstructionList;
 import org.apache.royale.abc.semantics.Instruction;
-import org.apache.royale.abc.semantics.MethodInfo;
 import org.apache.royale.abc.semantics.Name;
 import org.apache.royale.abc.semantics.Namespace;
 import org.apache.royale.abc.semantics.OneOperandInstruction;
+import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.as.IASEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
-import org.apache.royale.compiler.codegen.js.IMappingEmitter;
+import org.apache.royale.compiler.codegen.mxml.js.IMXMLJSEmitter;
 import org.apache.royale.compiler.codegen.mxml.royale.IMXMLRoyaleEmitter;
 import org.apache.royale.compiler.common.ASModifier;
 import org.apache.royale.compiler.common.DependencyType;
@@ -71,13 +71,13 @@ import org.apache.royale.compiler.internal.codegen.js.JSSessionModel.PropertyNod
 import org.apache.royale.compiler.internal.codegen.js.JSSessionModel.BindableVarInfo;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
 import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
+import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleBasicMXMLDescriptorEmitter;
 import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
 import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
 import org.apache.royale.compiler.internal.codegen.js.jx.BindableEmitter;
 import org.apache.royale.compiler.internal.codegen.js.jx.PackageFooterEmitter;
 import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
 import org.apache.royale.compiler.internal.codegen.mxml.MXMLEmitter;
-import org.apache.royale.compiler.internal.codegen.mxml.MXMLEmitterTokens;
 import org.apache.royale.compiler.internal.driver.js.royale.JSCSSCompilationSession;
 import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
 import org.apache.royale.compiler.internal.projects.RoyaleProject;
@@ -102,7 +102,6 @@ import org.apache.royale.compiler.tree.metadata.IMetaTagNode;
 import org.apache.royale.compiler.tree.metadata.IMetaTagsNode;
 import org.apache.royale.compiler.tree.mxml.*;
 import org.apache.royale.compiler.units.ICompilationUnit;
-import org.apache.royale.compiler.utils.DefinitionUtils;
 import org.apache.royale.compiler.utils.NativeUtils;
 import org.apache.royale.compiler.visitor.mxml.IMXMLBlockWalker;
 import org.apache.royale.swc.ISWC;
@@ -115,7 +114,7 @@ import com.google.debugging.sourcemap.FilePosition;
  * @author Erik de Bruin
  */
 public class MXMLRoyaleEmitter extends MXMLEmitter implements
-        IMXMLRoyaleEmitter, IMappingEmitter
+        IMXMLRoyaleEmitter, IMXMLJSEmitter
 {
 
 	// the instances in a container
@@ -154,6 +153,8 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements
     private String interfaceList;
     private boolean emitExports = true;
 
+    private ISubEmitter<MXMLDescriptorSpecifier> mxmlDescriptorEmitter;
+
     /**
      * This keeps track of the entries in our temporary array of
      * DeferredInstanceFromFunction objects that we CG to help with
@@ -179,6 +180,8 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements
     {
         super(out);
         sourceMapMappings = new ArrayList<SourceMapMapping>();
+
+        mxmlDescriptorEmitter = new JSRoyaleBasicMXMLDescriptorEmitter(this);
     }
 
     @Override
@@ -840,6 +843,7 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements
 
         descriptorTree = new ArrayList<MXMLDescriptorSpecifier>();
         propertiesTree = new MXMLDescriptorSpecifier();
+        propertiesTree.name = node.getQualifiedName();
 
         events = new ArrayList<MXMLEventSpecifier>();
         instances = new ArrayList<MXMLDescriptorSpecifier>();
@@ -1112,8 +1116,15 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements
 	        writeNewline(" * @type {Array}");
 	        writeNewline(" */");
 	        writeNewline("this.mxmlsd = " + ASEmitterTokens.SQUARE_OPEN.getToken());
-	        indentPush();
-	        write(root.outputStateDescriptors(false));
+            indentPush();
+            
+            for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
+            {
+                write(ASEmitterTokens.SQUARE_OPEN);
+                mxmlDescriptorEmitter.emit(md);
+                write(ASEmitterTokens.SQUARE_CLOSE);
+                writeNewline(ASEmitterTokens.COMMA);
+            }
 	        write("null");
 	        write(ASEmitterTokens.SQUARE_CLOSE);
 	        indentPop();
@@ -1141,11 +1152,7 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements
 
             MXMLDescriptorSpecifier root = propertiesTree;
             root.isTopNode = true;
-            for(int i = 0; i < getCurrentIndent(); i++)
-            {
-                root.indentPush();
-            }
-            write(root.output(true));
+            mxmlDescriptorEmitter.emit(root);
             indentPop();
             writeNewline();
 
@@ -2205,11 +2212,7 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements
             indentPush();
             writeNewline("var data = [");
 
-            for(int i = 0; i < getCurrentIndent(); i++)
-            {
-                root.indentPush();
-            }
-            write(root.output(true));
+            mxmlDescriptorEmitter.emit(root);
             indentPop();
             writeNewline();