You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2016/04/13 20:56:36 UTC

[44/51] [partial] git commit: [flex-falcon] [refs/heads/feature/maven-migration-test] - - Check-In of the migrated project to make error analysis easier

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
new file mode 100644
index 0000000..090eb63
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
@@ -0,0 +1,357 @@
+/*
+ *
+ *  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.externals.reference;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.flex.compiler.clients.ExternCConfiguration;
+import org.apache.flex.compiler.clients.ExternCConfiguration.ExcludedMember;
+import org.apache.flex.compiler.internal.codegen.externals.utils.DebugLogUtils;
+
+import com.google.javascript.jscomp.Compiler;
+import com.google.javascript.jscomp.NodeUtil;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.jstype.JSType;
+
+public class ReferenceModel
+{
+    private ExternCConfiguration configuration;
+    private Compiler jscompiler;
+
+    private List<String> namespaces = new ArrayList<String>();
+
+    private HashMap<String, ClassReference> typedefs = new HashMap<String, ClassReference>();
+    private HashMap<String, ClassReference> classes = new HashMap<String, ClassReference>();
+    private HashMap<String, FunctionReference> functions = new HashMap<String, FunctionReference>();
+    private HashMap<String, ConstantReference> constants = new HashMap<String, ConstantReference>();
+
+    //    public Compiler getJSCompiler()
+    //    {
+    //        return jscompiler;
+    //    }
+
+    public void setJSCompiler(Compiler compiler)
+    {
+        this.jscompiler = compiler;
+    }
+
+    public ExternCConfiguration getConfiguration()
+    {
+        return configuration;
+    }
+
+    public ClassReference getObjectReference()
+    {
+        return classes.get("Object");
+    }
+
+    public Collection<String> getNamespaces()
+    {
+        return namespaces;
+    }
+
+    public Collection<ClassReference> getTypedefs()
+    {
+        return typedefs.values();
+    }
+
+    public Collection<ClassReference> getClasses()
+    {
+        return classes.values();
+    }
+
+    public Collection<FunctionReference> getFunctions()
+    {
+        return functions.values();
+    }
+
+    public Collection<ConstantReference> getConstants()
+    {
+        return constants.values();
+    }
+
+    public ReferenceModel(ExternCConfiguration config)
+    {
+        this.configuration = config;
+    }
+
+    public ClassReference getClassReference(String qualifiedName)
+    {
+        return classes.get(qualifiedName);
+    }
+
+    public ClassReference getInterfaceReference(String qualifiedName)
+    {
+        ClassReference reference = classes.get(qualifiedName);
+        if (reference != null && reference.isInterface())
+            return reference;
+        return null;
+    }
+
+    public void addNamespace(Node node, String qualifiedName)
+    {
+        if (namespaces.contains(qualifiedName))
+        {
+            err("Duplicate namesapce [" + qualifiedName + "]");
+            return;
+        }
+
+        log("Model.addNamespace(" + qualifiedName + ")");
+
+        namespaces.add(qualifiedName);
+    }
+
+    public void addClass(Node node, String qualifiedName)
+    {
+        if (getConfiguration().isClassToFunctions(qualifiedName))
+        {
+            addFunction(node, qualifiedName);
+            return;
+        }
+
+        if (classes.containsKey(qualifiedName))
+        {
+            err("Duplicate class [" + qualifiedName + "]");
+            return;
+        }
+
+        log("Model.addClass(" + qualifiedName + ")");
+        ClassReference reference = new ClassReference(this, node, qualifiedName);
+
+        // TODO (mschmalle) Figure out if gcc makes any decisions about what is final or dynamic
+        if (reference.getQualifiedName().equals("Object"))
+            reference.setDynamic(true);
+
+        classes.put(qualifiedName, reference);
+    }
+
+    public void addEnum(Node node, String qualifiedName)
+    {
+        if (classes.containsKey(qualifiedName))
+        {
+            err("Duplicate class, @enum conflict [" + qualifiedName + "]");
+            return;
+        }
+
+        log("Model.addEnum(" + qualifiedName + ")");
+        ClassReference reference = new ClassReference(this, node, qualifiedName);
+        classes.put(qualifiedName, reference);
+    }
+
+    public void addTypeDef(Node node, String qualifiedName)
+    {
+        if (typedefs.containsKey(qualifiedName))
+        {
+            err("Duplicate @typedef [" + qualifiedName + "]");
+            return;
+        }
+
+        log("Model.addTypeDef(" + qualifiedName + ")");
+
+        ClassReference reference = new ClassReference(this, node, qualifiedName);
+        typedefs.put(qualifiedName, reference);
+    }
+
+    public void addInterface(Node node, String qualifiedName)
+    {
+        if (classes.containsKey(qualifiedName))
+        {
+            err("Duplicate @interface [" + qualifiedName + "]");
+            return;
+        }
+
+        log("Model.addInterface(" + qualifiedName + ")");
+
+        ClassReference reference = new ClassReference(this, node, qualifiedName);
+        classes.put(qualifiedName, reference);
+    }
+
+    public void addFinalClass(Node node, String qualifiedName)
+    {
+        if (classes.containsKey(qualifiedName))
+        {
+            err("Duplicate final class [" + qualifiedName + "]");
+            return;
+        }
+
+        log("Model.addFinalClass(" + qualifiedName + ")");
+
+        ClassReference reference = new ClassReference(this, node, qualifiedName);
+        reference.setFinal(true);
+        classes.put(qualifiedName, reference);
+    }
+
+    public void addFunction(Node node, String qualifiedName)
+    {
+        if (functions.containsKey(qualifiedName))
+        {
+            err("Duplicate global function [" + qualifiedName + "]");
+            return;
+        }
+
+        log("Model.addFunction(" + qualifiedName + ")");
+
+        FunctionReference reference = new FunctionReference(this, node, qualifiedName, node.getJSDocInfo());
+        functions.put(qualifiedName, reference);
+    }
+
+    public boolean hasClass(String className)
+    {
+        return classes.containsKey(className);
+    }
+
+    public boolean hasConstant(String qualifiedName)
+    {
+        return constants.containsKey(qualifiedName);
+    }
+
+    public void addConstant(Node node, String qualifiedName)
+    {
+        if (constants.containsKey(qualifiedName))
+        {
+            // XXX Record warning;
+            return;
+        }
+
+        log("Model.addConstant(" + qualifiedName + ")");
+
+        ConstantReference reference = new ConstantReference(this, node, qualifiedName, node.getJSDocInfo());
+        constants.put(qualifiedName, reference);
+    }
+
+    public void addConstantType(Node node, String qualifiedName, JSType type)
+    {
+        if (constants.containsKey(qualifiedName))
+        {
+            // XXX Record warning;
+            return;
+        }
+
+        log("Model.addConstantType(" + qualifiedName + ")");
+
+        ConstantReference reference = new ConstantReference(this, node, qualifiedName, node.getJSDocInfo(), type);
+        constants.put(qualifiedName, reference);
+    }
+
+    public void addField(Node node, String className, String memberName)
+    {
+        ClassReference classReference = getClassReference(className);
+        if (classReference != null)
+            classReference.addField(node, memberName, node.getJSDocInfo(), false);
+    }
+
+    public void addStaticField(Node node, String className, String memberName)
+    {
+        ClassReference classReference = getClassReference(className);
+        // XXX this is here because for now, the doc might be on the parent ASSIGN node
+        // if it's a static property with a value
+        JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
+        if (classReference != null)
+        {
+            classReference.addField(node, memberName, comment, true);
+        }
+        else
+        {
+            err(">>>> {ReferenceModel} Class [" + className + "] not found in " + node.getSourceFileName());
+        }
+    }
+
+    public void addMethod(Node node, String className, String memberName)
+    {
+        JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
+        ClassReference classReference = getClassReference(className);
+        if (classReference != null)
+            classReference.addMethod(node, memberName, comment, false);
+    }
+
+    public void addStaticMethod(Node node, String className, String memberName)
+    {
+        ClassReference classReference = getClassReference(className);
+        // XXX this is here because for now, the doc might be on the parent ASSIGN node
+        // if it's a static property with a value
+        JSDocInfo comment = NodeUtil.getBestJSDocInfo(node);
+        if (classReference != null)
+        {
+            classReference.addMethod(node, memberName, comment, true);
+        }
+        else
+        {
+            err(">>>> {ReferenceModel} Class [" + className + "] not found in " + node.getSourceFileName());
+        }
+    }
+
+    public final JSType evaluate(JSTypeExpression expression)
+    {
+        JSType jsType = null;
+
+        if (expression != null)
+        {
+            try
+            {
+                jsType = expression.evaluate(null, jscompiler.getTypeRegistry());
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+        return jsType;
+    }
+
+    //--------------------------------------------------------------------------
+
+    public ExcludedMember isExcludedClass(ClassReference classReference)
+    {
+        return getConfiguration().isExcludedClass(classReference);
+    }
+
+    public ExcludedMember isExcludedMember(ClassReference classReference, MemberReference memberReference)
+    {
+        return getConfiguration().isExcludedMember(classReference, memberReference);
+    }
+
+    //--------------------------------------------------------------------------
+
+    protected void log(Node n)
+    {
+        DebugLogUtils.err(n);
+    }
+
+    protected void err(Node n)
+    {
+        DebugLogUtils.err(n);
+    }
+
+    protected void log(String message)
+    {
+        DebugLogUtils.log(message);
+    }
+
+    protected void err(String message)
+    {
+        DebugLogUtils.err(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
new file mode 100644
index 0000000..5dcdc48
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java
@@ -0,0 +1,52 @@
+/*
+ *
+ *  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.externals.utils;
+
+import com.google.javascript.rhino.Node;
+
+public final class DebugLogUtils
+{
+    private static boolean logEnabled = false;
+    private static boolean errEnabled = false;
+
+    public static void log(Node n)
+    {
+        log("StringTree -------------------------------------");
+        log(n.toStringTree());
+    }
+
+    public static void log(String message)
+    {
+        if (logEnabled)
+            System.out.println(message);
+    }
+
+    public static void err(String message)
+    {
+        if (errEnabled)
+            System.err.println(message);
+    }
+
+    public static void err(Node n)
+    {
+        err("StringTree -------------------------------------");
+        err(n.toStringTree());
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
new file mode 100644
index 0000000..473e42c
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
@@ -0,0 +1,232 @@
+/*
+ *
+ *  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.externals.utils;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.BaseReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.common.base.Strings;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.Node;
+
+public class FunctionUtils
+{
+    /**
+     * Compute the type of a function or method parameter.
+     * 
+     * @param reference The FunctionReference or MethodReference the parameter belongs to
+     * @param name The name of the parameter
+     * @return the type of a function or method parameter
+     */
+    public static String toParameterType(final BaseReference reference, final String name)
+    {
+
+        String parameterType;
+        if (FunctionUtils.hasTemplate(reference) && FunctionUtils.containsTemplate(reference, name))
+        {
+            parameterType = "Object";
+        }
+        else
+        {
+            parameterType = JSTypeUtils.toParamTypeString(reference, name);
+        }
+
+        return parameterType;
+    }
+
+    public static String toReturnString(BaseReference reference)
+    {
+        final StringBuilder sb = new StringBuilder();
+
+        String returnType;
+
+        if (hasTemplate(reference))
+        {
+            returnType = JSTypeUtils.toReturnTypeString(reference);
+            if (containsTemplate(reference, returnType))
+            	returnType = "*";
+            else if (returnType.equals("RESULT"))
+            	returnType = "Object";
+        }
+        else
+        {
+            returnType = JSTypeUtils.toReturnTypeString(reference);
+        }
+
+        sb.append(returnType);
+
+        return sb.toString();
+    }
+
+    public static String toParameterString(BaseReference reference, JSDocInfo comment, Node paramNode, boolean outputJS)
+    {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append("(");
+
+        if (paramNode != null)
+        {
+            int index = 0;
+            int len = comment.getParameterCount();
+            if (len == 0)
+            {
+                // Missing JSDocInf @param tags, so instead of using the @param tags
+                // we use the actual Node list from the AST
+                len = paramNode.getChildCount();
+                if (len > 0)
+                {
+                    for (Node param : paramNode.children())
+                    {
+                        sb.append(param.getString());
+                        if (!outputJS)
+                        	sb.append(":Object");
+                        if (index < len - 1)
+                            sb.append(", ");
+                        index++;
+                    }
+                }
+            }
+            else
+            {
+                for (String paramName : comment.getParameterNames())
+                {
+                    sb.append(toParameter(reference, comment, paramName, comment.getParameterType(paramName), outputJS));
+
+                    if (index < len - 1)
+                        sb.append(", ");
+
+                    index++;
+                }
+            }
+        }
+
+        sb.append(")");
+
+        return sb.toString();
+    }
+
+    /**
+     * Check we can import the given type into the given package.
+     *
+     * @param model The containing reference model
+     * @param node The containing node
+     * @param typeName The type we want check
+     * @param packageName The current package
+     * @return true if we can import the given type into the given package
+     */
+    public static boolean canBeImported(final ReferenceModel model, final Node node, final String typeName,
+            final String packageName)
+    {
+        boolean canImport = false;
+
+        if (model != null && node != null && !Strings.isNullOrEmpty(typeName))
+        {
+            final ClassReference reference = new ClassReference(null, node, typeName);
+
+            final int lastDotPosition = typeName.lastIndexOf(".");
+
+            // Can import when the type to import does not belong to the current package.
+            canImport = lastDotPosition > -1 && !typeName.substring(0, lastDotPosition).equals(packageName);
+
+            // And is not excluded.
+            canImport &= model.isExcludedClass(reference) == null;
+        }
+
+        return canImport;
+    }
+
+    private static String toParameter(BaseReference reference, JSDocInfo comment, String paramName,
+            JSTypeExpression parameterType, boolean outputJS)
+    {
+        final StringBuilder sb = new StringBuilder();
+
+        String paramType;
+
+        if (parameterType == null)
+        {
+        	System.out.println("no parameter type for " + paramName + " " + reference.getQualifiedName());
+            paramType = "Object";
+            if (outputJS)
+            	sb.append(paramName);
+        }
+        else if (parameterType.isVarArgs())
+        {
+        	if (outputJS)
+        		sb.append("var_").append(paramName);
+        	else
+        		sb.append("...").append(paramName);
+        }
+        else
+        {
+            paramType = JSTypeUtils.toParamTypeString(reference, paramName);
+            if (hasTemplate(reference) && containsTemplate(reference, paramType))
+            {
+                paramType = "Object";
+            }
+
+            sb.append(paramName);
+            if (!outputJS)
+            {
+                sb.append(":");
+                sb.append(paramType);            	
+	            if (parameterType.isOptionalArg())
+	            {
+	                sb.append(" = ");
+	                sb.append(toDefaultParameterValue(paramType));
+	            }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    private static String toDefaultParameterValue(String paramType)
+    {
+        if (paramType.equals("Function"))
+            return "null";
+        else if (paramType.equals("Number"))
+            return "0";
+        else if (paramType.equals("String"))
+            return "''";
+        else if (paramType.equals("Boolean"))
+            return "false";
+        return "null";
+    }
+
+    public static boolean hasTemplate(BaseReference reference)
+    {
+        return reference.getComment().getTemplateTypeNames().size() > 0;
+    }
+    
+    public static boolean containsTemplate(BaseReference reference, String name)
+    {
+    	for (String template : reference.getComment().getTemplateTypeNames())
+    	{
+    		if (name.contains("<" + template + ">"))
+    			return true;
+    		if (name.equals(template))
+    			return true;
+    	}
+    	return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
new file mode 100644
index 0000000..c14ddb8
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
@@ -0,0 +1,169 @@
+/*
+ *
+ *  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.externals.utils;
+
+import java.util.HashMap;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.BaseReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ConstantReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.jstype.JSType;
+import com.google.javascript.rhino.jstype.UnionType;
+
+public class JSTypeUtils
+{
+    public static String toClassTypeString(ClassReference reference)
+    {
+        String type = getJsType(reference.getModel(), reference.getComment().getBaseType()).toString();
+        return type;
+    }
+
+    public static String toParamTypeString(BaseReference reference, String paramName)
+    {
+        JSTypeExpression expression = reference.getComment().getParameterType(paramName);
+        if (expression == null)
+            return "Object";
+
+        String type = toTypeExpressionString(reference, expression);
+        type = transformType(type);
+
+        return type;
+    }
+
+    public static String toReturnTypeString(BaseReference reference)
+    {
+        JSTypeExpression expression = reference.getComment().getReturnType();
+        if (expression == null)
+            return "void";
+
+        String type = toTypeExpressionString(reference, expression);
+        type = transformType(type);
+
+        return type;
+    }
+
+    public static String toFieldTypeString(BaseReference reference)
+    {
+        JSTypeExpression expression = reference.getComment().getType();
+        if (expression == null)
+            return "Object";
+
+        String type = toTypeExpressionString(reference, expression);
+        type = transformType(type);
+
+        return type;
+    }
+
+    public static String toEnumTypeString(BaseReference reference)
+    {
+        JSTypeExpression enumParameterType = reference.getComment().getEnumParameterType();
+        String overrideStringType = transformType(reference.getModel().evaluate(enumParameterType).toAnnotationString());
+
+        return overrideStringType;
+    }
+
+    public static String toConstantTypeString(ConstantReference reference)
+    {
+        JSTypeExpression expression = reference.getComment().getType();
+        if (expression == null)
+            return "Object";
+
+        String type = toTypeExpressionString(reference, expression);
+        type = transformType(type);
+
+        return type;
+    }
+
+    //--------------------------------------------------------------------------
+
+    public static String transformType(String type)
+    {
+        // XXX This is an error but, needs to be reduced in @param union
+        if (type.indexOf("|") != -1)
+            return "Object";
+
+        HashMap<String, String> map = new HashMap<String, String>();
+        map.put("?", "Object /* ? */");
+        map.put("*", "*");
+        map.put("string", "String");
+        map.put("number", "Number");
+        map.put("boolean", "Boolean");
+        map.put("undefined", "Object /* undefined */");
+        map.put("null", "Object /* null */");
+
+        if (map.containsKey(type))
+            return map.get(type);
+
+        return type;
+    }
+
+    private static String toTypeExpressionString(BaseReference reference, JSTypeExpression expression)
+    {
+        JSType jsType = getJsType(reference.getModel(), expression);
+        String type = toTypeString(jsType);
+        return type;
+    }
+
+    private static String toTypeString(JSType jsType)
+    {
+        String type = jsType.toString();
+
+        if (jsType.isFunctionType())
+        {
+            return "Function /* " + type + " */";
+        }
+        else if (jsType.isRecordType())
+        {
+            return "Object /* " + type + " */";
+        }
+        else
+        {
+            if (type.indexOf("Array<") == 0)
+            {
+                return "Array";
+            }
+            else if (type.indexOf("Object<") == 0)
+            {
+                return "Object";
+            }
+        }
+
+        return type;
+    }
+
+    private static JSType getJsType(ReferenceModel model, JSTypeExpression typeExpression)
+    {
+        JSType jsType = model.evaluate(typeExpression);
+
+        if (jsType.isUnionType())
+        {
+            UnionType ut = (UnionType) jsType;
+            JSType jsType2 = ut.restrictByNotNullOrUndefined();
+
+            if (!jsType2.isUnionType())
+                jsType = jsType2;
+        }
+
+        return jsType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java
new file mode 100644
index 0000000..743ecce
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitter.java
@@ -0,0 +1,174 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import org.apache.flex.compiler.codegen.IDocEmitter;
+import org.apache.flex.compiler.codegen.IEmitter;
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.tree.as.IASNode;
+
+public class JSDocEmitter implements IDocEmitter, IEmitter
+{
+
+    private int currentIndent = 0;
+
+    protected IEmitter emitter;
+
+    private StringBuilder builder;
+
+    protected StringBuilder getBuilder()
+    {
+        return builder;
+    }
+
+    private boolean bufferWrite;
+
+    public boolean isBufferWrite()
+    {
+        return bufferWrite;
+    }
+
+    public void setBufferWrite(boolean value)
+    {
+        bufferWrite = value;
+    }
+
+    public String flushBuffer()
+    {
+        setBufferWrite(false);
+        String result = builder.toString();
+        builder.setLength(0);
+        return result;
+    }
+
+    public JSDocEmitter(IJSEmitter emitter)
+    {
+        this.emitter = (IEmitter) emitter;
+        
+        builder = new StringBuilder();
+    }
+
+    @Override
+    public void indentPush()
+    {
+        currentIndent++;
+    }
+
+    @Override
+    public void indentPop()
+    {
+        currentIndent--;
+    }
+
+    @Override
+    public void write(IEmitterTokens value)
+    {
+        write(value.getToken());
+    }
+
+    @Override
+    public void write(String value)
+    {
+        if (!bufferWrite)
+            emitter.write(value);
+        else
+            builder.append(value);
+    }
+
+    @Override
+    public void writeNewline()
+    {
+        write(ASEmitterTokens.NEW_LINE);
+    }
+
+    @Override
+    public void writeNewline(String value)
+    {
+        write(value);
+        writeNewline();
+    }
+
+    @Override
+    public void writeNewline(IEmitterTokens value)
+    {
+        writeNewline(value.getToken());
+    }
+
+    @Override
+    public void writeNewline(String value, boolean pushIndent)
+    {
+        if (pushIndent)
+            indentPush();
+        else
+            indentPop();
+        write(value);
+        writeNewline();
+    }
+
+    @Override
+    public void writeNewline(IEmitterTokens value, boolean pushIndent)
+    {
+        writeNewline(value.getToken(), pushIndent);
+    }
+
+    @Override
+    public void writeToken(IEmitterTokens value)
+    {
+        writeToken(value.getToken());
+    }
+
+    @Override
+    public void writeToken(String value)
+    {
+        write(value);
+        write(ASEmitterTokens.SPACE);
+    }
+
+    public void writeBlockClose()
+    {
+        write(ASEmitterTokens.BLOCK_CLOSE);
+    }
+
+    public void writeBlockOpen()
+    {
+        write(ASEmitterTokens.BLOCK_OPEN);
+    }
+
+    @Override
+    public void begin()
+    {
+        writeNewline(JSDocEmitterTokens.JSDOC_OPEN);
+    }
+
+    @Override
+    public void end()
+    {
+        write(ASEmitterTokens.SPACE);
+        writeNewline(JSDocEmitterTokens.JSDOC_CLOSE);
+    }
+    
+    @Override
+    public String stringifyNode(IASNode node)
+    {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java
new file mode 100644
index 0000000..813e36b
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSDocEmitterTokens.java
@@ -0,0 +1,38 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.flex.compiler.internal.codegen.js;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+public enum JSDocEmitterTokens implements IEmitterTokens
+{
+    JSDOC_CLOSE("*/"), JSDOC_OPEN("/**");
+
+    private String token;
+
+    private JSDocEmitterTokens(String value)
+    {
+        token = value;
+    }
+
+    public String getToken()
+    {
+        return token;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
new file mode 100644
index 0000000..a50e288
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitter.java
@@ -0,0 +1,453 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import java.io.FilterWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ASModifier;
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.definitions.ITypeDefinition;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitter;
+import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens;
+import org.apache.flex.compiler.internal.codegen.js.jx.DoWhileLoopEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.DynamicAccessEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ForLoopEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.FunctionCallArgumentsEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.IfEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.IterationFlowEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.LanguageIdentifierEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.LiteralContainerEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.MemberKeywordEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.NumericLiteralEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ObjectLiteralValuePairEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ParameterEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ParametersEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.ReturnEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.SourceMapDirectiveEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.StatementEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.TernaryOperatorEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.UnaryOperatorEmitter;
+import org.apache.flex.compiler.internal.codegen.js.jx.WhileLoopEmitter;
+import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils;
+import org.apache.flex.compiler.internal.tree.as.FunctionNode;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IContainerNode;
+import org.apache.flex.compiler.tree.as.IDefinitionNode;
+import org.apache.flex.compiler.tree.as.IDynamicAccessNode;
+import org.apache.flex.compiler.tree.as.IForLoopNode;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IFunctionObjectNode;
+import org.apache.flex.compiler.tree.as.IIfNode;
+import org.apache.flex.compiler.tree.as.IIterationFlowNode;
+import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
+import org.apache.flex.compiler.tree.as.ILiteralContainerNode;
+import org.apache.flex.compiler.tree.as.INumericLiteralNode;
+import org.apache.flex.compiler.tree.as.IObjectLiteralValuePairNode;
+import org.apache.flex.compiler.tree.as.IPackageNode;
+import org.apache.flex.compiler.tree.as.IParameterNode;
+import org.apache.flex.compiler.tree.as.IReturnNode;
+import org.apache.flex.compiler.tree.as.ITernaryOperatorNode;
+import org.apache.flex.compiler.tree.as.ITypeNode;
+import org.apache.flex.compiler.tree.as.ITypedExpressionNode;
+import org.apache.flex.compiler.tree.as.IUnaryOperatorNode;
+import org.apache.flex.compiler.tree.as.IWhileLoopNode;
+
+import com.google.debugging.sourcemap.FilePosition;
+
+/**
+ * @author Michael Schmalle
+ */
+public class JSEmitter extends ASEmitter implements IJSEmitter
+{
+    private JSSessionModel model;
+    
+    public NumericLiteralEmitter numericLiteralEmitter;
+    public ParametersEmitter parametersEmitter;
+    public ParameterEmitter parameterEmitter;
+    public FunctionCallArgumentsEmitter functionCallArgumentsEmitter;
+    public LiteralContainerEmitter literalContainerEmitter;
+    public ObjectLiteralValuePairEmitter objectLiteralValuePairEmitter;
+    public ReturnEmitter returnEmitter;
+    public DynamicAccessEmitter dynamicAccessEmitter;
+    public UnaryOperatorEmitter unaryOperatorEmitter;
+    public TernaryOperatorEmitter ternaryOperatorEmitter;
+    public MemberKeywordEmitter memberKeywordEmitter;
+    public IfEmitter ifEmitter;
+    public WhileLoopEmitter whileLoopEmitter;
+    public DoWhileLoopEmitter doWhileLoopEmitter;
+    public ForLoopEmitter forLoopEmitter;
+    public IterationFlowEmitter interationFlowEmitter;
+    public StatementEmitter statementEmitter;
+    public LanguageIdentifierEmitter languageIdentifierEmitter;
+    public SourceMapDirectiveEmitter sourceMapDirectiveEmitter;
+    
+    @Override
+    public JSSessionModel getModel()
+    {
+        return model;
+    }
+    
+    private SourceMapMapping lastMapping;
+    
+    private Stack<String> nameStack = new Stack<String>();
+    
+    private List<SourceMapMapping> sourceMapMappings;
+    
+    public List<SourceMapMapping> getSourceMapMappings()
+    {
+        return sourceMapMappings;
+    }
+
+    public JSEmitter(FilterWriter out)
+    {
+        super(out);
+        
+        model = new JSSessionModel();
+        sourceMapMappings = new ArrayList<SourceMapMapping>();
+
+        numericLiteralEmitter = new NumericLiteralEmitter(this);
+        parametersEmitter = new ParametersEmitter(this);
+        parameterEmitter = new ParameterEmitter(this);
+        functionCallArgumentsEmitter = new FunctionCallArgumentsEmitter(this);
+        literalContainerEmitter = new LiteralContainerEmitter(this);
+        objectLiteralValuePairEmitter = new ObjectLiteralValuePairEmitter(this);
+        returnEmitter = new ReturnEmitter(this);
+        dynamicAccessEmitter = new DynamicAccessEmitter(this);
+        unaryOperatorEmitter = new UnaryOperatorEmitter(this);
+        ternaryOperatorEmitter = new TernaryOperatorEmitter(this);
+        memberKeywordEmitter = new MemberKeywordEmitter(this);
+        ifEmitter = new IfEmitter(this);
+        whileLoopEmitter = new WhileLoopEmitter(this);
+        doWhileLoopEmitter = new DoWhileLoopEmitter(this);
+        forLoopEmitter = new ForLoopEmitter(this);
+        interationFlowEmitter = new IterationFlowEmitter(this);
+        statementEmitter = new StatementEmitter(this);
+        languageIdentifierEmitter = new LanguageIdentifierEmitter(this);
+        sourceMapDirectiveEmitter = new SourceMapDirectiveEmitter(this);
+    }
+
+    @Override
+    public String formatQualifiedName(String name)
+    {
+        return name;
+    }
+    
+    @Override
+    public void emitLocalNamedFunction(IFunctionNode node)
+    {
+        startMapping(node);
+        FunctionNode fnode = (FunctionNode)node;
+        write(ASEmitterTokens.FUNCTION);
+        write(ASEmitterTokens.SPACE);
+        write(fnode.getName());
+        endMapping(node);
+        emitParameters(fnode.getParametersContainerNode());
+        emitFunctionScope(fnode.getScopedNode());
+    }
+    
+    @Override
+    public void emitFunctionObject(IFunctionObjectNode node)
+    {
+        startMapping(node);
+        FunctionNode fnode = node.getFunctionNode();
+        write(ASEmitterTokens.FUNCTION);
+        endMapping(node);
+        emitParameters(fnode.getParametersContainerNode());
+        emitFunctionScope(fnode.getScopedNode());
+    }
+
+    public void emitClosureStart()
+    {
+    	
+    }
+
+    public void emitClosureEnd(IASNode node)
+    {
+    	
+    }
+    
+    public void emitSourceMapDirective(ITypeNode node)
+    {
+        sourceMapDirectiveEmitter.emit(node);
+    }
+
+    public void emitParameters(IContainerNode node)
+    {
+        parametersEmitter.emit(node);
+    }
+
+    @Override
+    public void emitParameter(IParameterNode node)
+    {
+        parameterEmitter.emit(node);
+    }
+
+    @Override
+    public void emitArguments(IContainerNode node)
+    {
+        functionCallArgumentsEmitter.emit(node);
+    }
+
+    @Override
+    public void emitNumericLiteral(INumericLiteralNode node)
+    {
+        numericLiteralEmitter.emit(node);
+    }
+
+    @Override
+    public void emitLiteralContainer(ILiteralContainerNode node)
+    {
+        literalContainerEmitter.emit(node);
+    }
+
+    @Override
+    public void emitObjectLiteralValuePair(IObjectLiteralValuePairNode node)
+    {
+        objectLiteralValuePairEmitter.emit(node);
+    }
+
+    @Override
+    public void emitReturn(IReturnNode node)
+    {
+        returnEmitter.emit(node);
+    }
+
+    @Override
+    public void emitTypedExpression(ITypedExpressionNode node)
+    {
+        write(JSEmitterTokens.ARRAY);
+    }
+
+    @Override
+    public void emitDynamicAccess(IDynamicAccessNode node)
+    {
+        dynamicAccessEmitter.emit(node);
+    }
+
+    @Override
+    public void emitMemberKeyword(IDefinitionNode node)
+    {
+        memberKeywordEmitter.emit(node);
+    }
+
+    @Override
+    public void emitUnaryOperator(IUnaryOperatorNode node)
+    {
+        unaryOperatorEmitter.emit(node);
+    }
+
+    @Override
+    public void emitTernaryOperator(ITernaryOperatorNode node)
+    {
+        ternaryOperatorEmitter.emit(node);
+    }
+
+    @Override
+    public void emitLanguageIdentifier(ILanguageIdentifierNode node)
+    {
+        languageIdentifierEmitter.emit(node);
+    }
+
+    @Override
+    public void emitStatement(IASNode node)
+    {
+        statementEmitter.emit(node);
+    }
+
+    @Override
+    public void emitIf(IIfNode node)
+    {
+        ifEmitter.emit(node);
+    }
+
+    @Override
+    public void emitWhileLoop(IWhileLoopNode node)
+    {
+        whileLoopEmitter.emit(node);
+    }
+
+    @Override
+    public void emitDoLoop(IWhileLoopNode node)
+    {
+        doWhileLoopEmitter.emit(node);
+    }
+
+    @Override
+    public void emitForLoop(IForLoopNode node)
+    {
+        forLoopEmitter.emit(node);
+    }
+
+    @Override
+    public void emitIterationFlow(IIterationFlowNode node)
+    {
+        interationFlowEmitter.emit(node);
+    }
+
+    public void pushSourceMapName(ISourceLocation node)
+    {
+        boolean isValidMappingScope = node instanceof ITypeNode
+                || node instanceof IPackageNode
+                || node instanceof IFunctionNode;
+        if(!isValidMappingScope)
+        {
+            throw new IllegalStateException("A source mapping scope must be a package, type, or function.");
+        }
+        
+        IDefinitionNode definitionNode = (IDefinitionNode) node;
+        String nodeName = definitionNode.getQualifiedName();
+        ITypeDefinition typeDef = EmitterUtils.getTypeDefinition(definitionNode);
+        if (typeDef != null)
+        {
+            boolean isConstructor = node instanceof IFunctionNode &&
+                    ((IFunctionNode) node).isConstructor();
+            boolean isStatic = definitionNode.hasModifier(ASModifier.STATIC);
+            if (isConstructor)
+            {
+                nodeName = typeDef.getQualifiedName() + ".constructor";
+            }
+            else if (isStatic)
+            {
+                nodeName = typeDef.getQualifiedName() + "." + nodeName;
+            }
+            else
+            {
+                nodeName = typeDef.getQualifiedName() + ".prototype." + nodeName;
+            }
+        }
+        nameStack.push(nodeName);
+    }
+    
+    public void popSourceMapName()
+    {
+        nameStack.pop();
+    }
+
+    public void startMapping(ISourceLocation node)
+    {
+        startMapping(node, node.getLine(), node.getColumn());
+    }
+
+    public void startMapping(ISourceLocation node, ISourceLocation nodeBeforeMapping)
+    {
+        startMapping(node, nodeBeforeMapping.getLine(), nodeBeforeMapping.getColumn() + nodeBeforeMapping.getAbsoluteEnd() - nodeBeforeMapping.getAbsoluteStart());
+    }
+    
+    public void startMapping(ISourceLocation node, int line, int column)
+    {
+        if (lastMapping != null)
+        {
+            FilePosition sourceStartPosition = lastMapping.sourceStartPosition;
+            throw new IllegalStateException("Cannot start new mapping when another mapping is already started. "
+                    + "Previous mapping at Line " + sourceStartPosition.getLine()
+                    + " and Column " + sourceStartPosition.getColumn()
+                    + " in file " + lastMapping.sourcePath);
+        }
+        
+        String sourcePath = node.getSourcePath();
+        if (sourcePath == null)
+        {
+            //if the source path is null, this node may have been generated by
+            //the compiler automatically. for example, an untyped variable will
+            //have a node for the * type.
+            if (node instanceof IASNode)
+            {
+                IASNode parentNode = ((IASNode) node).getParent();
+                if (parentNode != null)
+                {
+                    //try the parent node
+                    startMapping(parentNode, line, column);
+                    return;
+                }
+            }
+        }
+        
+        String nodeName = null;
+        if (nameStack.size() > 0)
+        {
+            nodeName = nameStack.lastElement();
+        }
+        SourceMapMapping mapping = new SourceMapMapping();
+        mapping.sourcePath = sourcePath;
+        mapping.name = nodeName;
+        mapping.sourceStartPosition = new FilePosition(line, column);
+        mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
+        lastMapping = mapping;
+    }
+
+    public void endMapping(ISourceLocation node)
+    {
+        if (lastMapping == null)
+        {
+            throw new IllegalStateException("Cannot end mapping when a mapping has not been started");
+        }
+
+        lastMapping.destEndPosition = new FilePosition(getCurrentLine(), getCurrentColumn());
+        sourceMapMappings.add(lastMapping);
+        lastMapping = null;
+    }
+
+    /**
+     * Adjusts the line numbers saved in the source map when a line should be
+     * added during post processing.
+     *
+     * @param lineIndex
+     */
+    protected void addLineToMappings(int lineIndex)
+    {
+        for (SourceMapMapping mapping : sourceMapMappings)
+        {
+            FilePosition destStartPosition = mapping.destStartPosition;
+            int startLine = destStartPosition.getLine();
+            if(startLine > lineIndex)
+            {
+                mapping.destStartPosition = new FilePosition(startLine + 1, destStartPosition.getColumn());
+                FilePosition destEndPosition = mapping.destEndPosition;
+                mapping.destEndPosition = new FilePosition(destEndPosition.getLine() + 1, destEndPosition.getColumn());
+            }
+        }
+    }
+
+    /**
+     * Adjusts the line numbers saved in the source map when a line should be
+     * removed during post processing.
+     * 
+     * @param lineIndex
+     */
+    protected void removeLineFromMappings(int lineIndex)
+    {
+        for (SourceMapMapping mapping : sourceMapMappings)
+        {
+            FilePosition destStartPosition = mapping.destStartPosition;
+            int startLine = destStartPosition.getLine();
+            if(startLine > lineIndex)
+            {
+                mapping.destStartPosition = new FilePosition(startLine - 1, destStartPosition.getColumn());
+                FilePosition destEndPosition = mapping.destEndPosition;
+                mapping.destEndPosition = new FilePosition(destEndPosition.getLine() - 1, destEndPosition.getColumn());
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java
new file mode 100644
index 0000000..82935af
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSEmitterTokens.java
@@ -0,0 +1,47 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.flex.compiler.internal.codegen.js;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+
+public enum JSEmitterTokens implements IEmitterTokens
+{
+    ARGUMENTS("arguments"),
+    CALL("call"),
+    CONFIGURABLE("configurable"),
+    CONSTRUCTOR("constructor"),
+    DEFINE_PROPERTY("defineProperty"),
+    DEFINE_PROPERTIES("defineProperties"),
+    INTERFACE("interface"),
+    PROTOTYPE("prototype"),
+    SLICE("slice"),
+    ARRAY("Array");
+
+    private String token;
+
+    private JSEmitterTokens(String value)
+    {
+        token = value;
+    }
+
+    public String getToken()
+    {
+        return token;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSFilterWriter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSFilterWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSFilterWriter.java
new file mode 100644
index 0000000..bf17a87
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSFilterWriter.java
@@ -0,0 +1,43 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import java.io.Writer;
+
+import org.apache.flex.compiler.internal.codegen.as.ASFilterWriter;
+
+/**
+ * @author Michael Schmalle
+ */
+public class JSFilterWriter extends ASFilterWriter
+{
+
+    public JSFilterWriter(Writer out)
+    {
+        super(out);
+    }
+
+    @Override
+    public String toString()
+    {
+        return out.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java
new file mode 100644
index 0000000..cc49504
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSPublisher.java
@@ -0,0 +1,85 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.config.Configuration;
+
+public class JSPublisher implements IJSPublisher
+{
+
+    public JSPublisher(Configuration config)
+    {
+        this.configuration = config;
+    }
+
+    protected File outputFolder;
+    protected File outputParentFolder;
+
+
+    protected Configuration configuration;
+
+    public File getOutputFolder()
+    {
+        outputFolder = new File(getOutputFilePath());
+        if (!outputFolder.isDirectory())
+            outputFolder = outputFolder.getParentFile();
+
+        outputParentFolder = outputFolder;
+
+        setupOutputFolder();
+
+        return outputFolder;
+    }
+
+    protected void setupOutputFolder()
+    {
+        if (outputParentFolder.exists())
+            org.apache.commons.io.FileUtils.deleteQuietly(outputParentFolder);
+
+        if (!outputFolder.exists())
+            outputFolder.mkdirs();
+    }
+
+    private String getOutputFilePath()
+    {
+        if (configuration.getOutput() == null)
+        {
+            final String extension = "." + JSSharedData.OUTPUT_EXTENSION;
+            return FilenameUtils.removeExtension(configuration.getTargetFile())
+                    .concat(extension);
+        }
+        else
+            return configuration.getOutput();
+    }
+
+    public boolean publish(ProblemQuery problems) throws IOException
+    {
+        System.out
+                .println("The project has been successfully compiled and optimized.");
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
new file mode 100644
index 0000000..5c45227
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java
@@ -0,0 +1,180 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.flex.compiler.definitions.IClassDefinition;
+import org.apache.flex.compiler.tree.as.IFunctionNode;
+import org.apache.flex.compiler.tree.as.IGetterNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+
+/**
+ * @author Michael Schmalle
+ */
+public class JSSessionModel
+{
+    public static final String CONSTRUCTOR_EMPTY = "emptyConstructor";
+    public static final String CONSTRUCTOR_FULL = "fullConstructor";
+    public static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";
+
+    private IClassDefinition currentClass;
+
+    public static class PropertyNodes
+    {
+        public IGetterNode getter;
+        public ISetterNode setter;
+    }
+
+    private static class Context
+    {
+    	public LinkedHashMap<String, PropertyNodes> propertyMap;
+    	public List<String> interfacePropertyMap;
+    	public LinkedHashMap<String, PropertyNodes> staticPropertyMap;
+    	public ArrayList<String> bindableVars;
+    	public ArrayList<IVariableNode> vars;
+    	public ArrayList<IFunctionNode> methods;
+    	public IClassDefinition classDefinition;
+    }
+    private Stack<Context> stack = new Stack<Context>();
+    
+    private LinkedHashMap<String, PropertyNodes> propertyMap = new LinkedHashMap<String, PropertyNodes>();
+
+    private List<String> interfacePropertyMap = new ArrayList<String>();
+
+    private LinkedHashMap<String, PropertyNodes> staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
+
+    private ArrayList<String> bindableVars = new ArrayList<String>();
+
+    private ArrayList<IVariableNode> vars = new ArrayList<IVariableNode>();
+    
+    private ArrayList<IFunctionNode> methods = new ArrayList<IFunctionNode>();
+    
+    private HashMap<String, String> internalClasses;
+    
+    private int foreachLoopCount = 0;
+
+    public IClassDefinition getCurrentClass()
+    {
+        return currentClass;
+    }
+
+    public void setCurrentClass(IClassDefinition currentClass)
+    {
+        this.currentClass = currentClass;
+    }
+
+    public void pushClass(IClassDefinition currentClass)
+    {
+    	Context context = new Context();
+    	context.bindableVars = bindableVars;
+    	context.interfacePropertyMap = interfacePropertyMap;
+    	context.propertyMap = propertyMap;
+    	context.staticPropertyMap = staticPropertyMap;
+    	context.classDefinition = this.currentClass;
+    	context.vars = vars;
+    	context.methods = methods;
+    	stack.push(context);
+        this.currentClass = currentClass;
+        bindableVars = new ArrayList<String>();
+        staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
+        interfacePropertyMap = new ArrayList<String>();
+        propertyMap = new LinkedHashMap<String, PropertyNodes>();
+        vars = new ArrayList<IVariableNode>();
+        methods = new ArrayList<IFunctionNode>();
+    }
+
+    public void popClass()
+    {
+    	Context context = stack.pop();
+    	this.currentClass = context.classDefinition;
+    	bindableVars = context.bindableVars;
+    	staticPropertyMap = context.staticPropertyMap;
+    	propertyMap = context.propertyMap;
+    	interfacePropertyMap = context.interfacePropertyMap;
+    	vars = context.vars;
+    	methods = context.methods;
+    }
+    
+    public HashMap<String, PropertyNodes> getPropertyMap()
+    {
+        return propertyMap;
+    }
+
+    public List<String> getInterfacePropertyMap()
+    {
+        return interfacePropertyMap;
+    }
+
+    public HashMap<String, PropertyNodes> getStaticPropertyMap()
+    {
+        return staticPropertyMap;
+    }
+
+    public boolean hasBindableVars()
+    {
+        return bindableVars.size() > 0;
+    }
+
+    public List<String> getBindableVars()
+    {
+        return bindableVars;
+    }
+
+    public List<IVariableNode> getVars()
+    {
+        return vars;
+    }
+
+    public List<IFunctionNode> getMethods()
+    {
+        return methods;
+    }
+
+    public HashMap<String, String> getInternalClasses()
+    {
+    	if (internalClasses == null)
+    		internalClasses = new HashMap<String, String>();
+        return internalClasses;
+    }
+
+    public boolean isInternalClass(String className)
+    {
+    	if (internalClasses == null) return false;
+    	
+        return internalClasses.containsKey(className);
+    }
+
+    public final void incForeachLoopCount()
+    {
+        foreachLoopCount++;
+    }
+
+    public String getCurrentForeachName()
+    {
+        return "foreachiter" + Integer.toString(foreachLoopCount);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java
new file mode 100644
index 0000000..e430a03
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSharedData.java
@@ -0,0 +1,116 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+
+// TODO (mschmalle) This class sucks, figure out some other way instead of using
+// a static singleton class like this, change when implementing Configuration
+public class JSSharedData
+{
+
+    public static final String COMPILER_NAME = "MXMLJSC";
+    public static final boolean OUTPUT_TIMESTAMPS = true;
+    public static final String COMPILER_VERSION = "329449.1";
+
+    public final static JSSharedData instance = new JSSharedData();
+
+    public static IBackend backend;
+    public static String OUTPUT_EXTENSION;
+    public static Workspace workspace;
+
+    public static PrintStream STDOUT = System.out;
+    public static PrintStream STDERR = System.err;
+
+    @SuppressWarnings("unused")
+    private Boolean m_verbose = false;
+    private final ReadWriteLock m_verboseLock = new ReentrantReadWriteLock();
+
+    private Object m_codeGenMonitor = new Object();
+    private long m_codeGenCounter = 0;
+    private final ReadWriteLock m_codeGenCounterLock = new ReentrantReadWriteLock();
+
+    public static String now()
+    {
+        final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
+        Calendar cal = Calendar.getInstance();
+        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
+        return sdf.format(cal.getTime());
+    }
+
+    public void stdout(String s)
+    {
+        if (STDOUT != null)
+        {
+            m_verboseLock.writeLock().lock();
+            STDOUT.println(s);
+            m_verboseLock.writeLock().unlock();
+        }
+    }
+
+    public void stderr(String s)
+    {
+        if (STDERR != null)
+        {
+            m_verboseLock.writeLock().lock();
+            STDERR.println(s);
+            m_verboseLock.writeLock().unlock();
+        }
+    }
+
+    public void beginCodeGen()
+    {
+        m_codeGenCounterLock.writeLock().lock();
+        m_codeGenCounter++;
+        m_codeGenCounterLock.writeLock().unlock();
+    }
+
+    public void endCodeGen()
+    {
+        m_codeGenCounterLock.writeLock().lock();
+        final long currentCounter = --m_codeGenCounter;
+        m_codeGenCounterLock.writeLock().unlock();
+
+        if (currentCounter == 0)
+        {
+            synchronized (m_codeGenMonitor)
+            {
+                m_codeGenMonitor.notifyAll();
+            }
+        }
+    }
+
+    public static String getTimeStampString()
+    {
+        if (JSSharedData.OUTPUT_TIMESTAMPS)
+            return "CROSS-COMPILED BY " + JSSharedData.COMPILER_NAME + " ("
+                    + JSSharedData.COMPILER_VERSION + ") ON "
+                    + JSSharedData.now() + "\n";
+        else
+            return "CROSS-COMPILED BY " + JSSharedData.COMPILER_NAME + "\n";
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.java
new file mode 100644
index 0000000..bcdeed5
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSourceMapEmitter.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.js;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+
+import com.google.debugging.sourcemap.SourceMapGeneratorV3;
+
+public class JSSourceMapEmitter implements ISourceMapEmitter
+{
+    private IJSEmitter emitter;
+    private SourceMapGeneratorV3 sourceMapGenerator;
+
+    public JSSourceMapEmitter(IJSEmitter emitter)
+    {
+        this.emitter = emitter;
+        sourceMapGenerator = new SourceMapGeneratorV3();
+    }
+    
+    public String emitSourceMap(String fileName, String sourceMapPath, String sourceRoot)
+    {
+        List<IJSEmitter.SourceMapMapping> mappings = this.emitter.getSourceMapMappings();
+        for (IJSEmitter.SourceMapMapping mapping : mappings)
+        {
+            sourceMapGenerator.addMapping(mapping.sourcePath, mapping.name,
+                    mapping.sourceStartPosition,
+                    mapping.destStartPosition, mapping.destEndPosition);
+        }
+        if (sourceRoot != null)
+        {
+            sourceMapGenerator.setSourceRoot(sourceRoot);
+        }
+
+        StringBuilder builder = new StringBuilder();
+        try
+        {
+            sourceMapGenerator.appendTo(builder, fileName);
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+        
+        return builder.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
new file mode 100644
index 0000000..be0b9d1
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSSubEmitter.java
@@ -0,0 +1,126 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import org.apache.flex.compiler.codegen.IEmitterTokens;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.visitor.IBlockWalker;
+
+public class JSSubEmitter
+{
+    private IJSEmitter emitter;
+
+    protected IJSEmitter getEmitter()
+    {
+        return emitter; 
+    }
+
+    protected IBlockWalker getWalker()
+    {
+        return emitter.getWalker();
+    }
+    
+    protected ICompilerProject getProject()
+    {
+        return emitter.getWalker().getProject();
+    }
+
+    protected JSSessionModel getModel()
+    {
+        return emitter.getModel();
+    }
+
+    public JSSubEmitter(IJSEmitter 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(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 nodeBeforeMapping)
+    {
+        emitter.startMapping(node, nodeBeforeMapping);
+    }
+
+    protected void endMapping(ISourceLocation node)
+    {
+        emitter.endMapping(node);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
----------------------------------------------------------------------
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
new file mode 100644
index 0000000..e984eda
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/JSWriter.java
@@ -0,0 +1,166 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.flex.compiler.codegen.ISourceMapEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.driver.js.IJSBackend;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.projects.IASProject;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.visitor.as.IASBlockWalker;
+
+public class JSWriter implements IJSWriter
+{
+    protected IASProject project;
+
+    protected List<ICompilerProblem> problems;
+
+    protected ICompilationUnit compilationUnit;
+
+    @SuppressWarnings("unused")
+    private boolean enableDebug;
+
+    /**
+     * Create a JSApplication writer.
+     * 
+     * @param application the JSApplication model to be encoded
+     * @param useCompression use ZLIB compression if true
+     */
+    public JSWriter(IASProject project, List<ICompilerProblem> problems,
+            ICompilationUnit compilationUnit, boolean enableDebug)
+    {
+        this.project = project;
+        this.problems = problems;
+        this.compilationUnit = compilationUnit;
+        this.enableDebug = enableDebug;
+    }
+
+    @Override
+    public void close() throws IOException
+    {
+        //outputBuffer.close();
+    }
+
+    @Override
+    public void writeTo(OutputStream out)
+    {
+        writeTo(out, null);
+    }
+
+    @Override
+    public int writeTo(File out) throws FileNotFoundException, IOException
+    {
+        return 0;
+    }
+
+    public void writeTo(OutputStream jsOut, File sourceMapOut)
+    {
+        IJSBackend backend = (IJSBackend) JSSharedData.backend;
+        JSFilterWriter writer = (JSFilterWriter) backend.createWriterBuffer(project);
+        IJSEmitter emitter = (IJSEmitter) backend.createEmitter(writer);
+        IASBlockWalker walker = backend.createWalker(project,
+                problems, emitter);
+
+        walker.visitCompilationUnit(compilationUnit);
+
+        try
+        {
+            jsOut.write(emitter.postProcess(writer.toString()).getBytes());
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+
+        if (sourceMapOut != null)
+        {
+            convertMappingSourcePathsToRelative(emitter, sourceMapOut);
+
+            File compilationUnitFile = new File(compilationUnit.getAbsoluteFilename());
+            ISourceMapEmitter sourceMapEmitter = backend.createSourceMapEmitter(emitter);
+            try
+            {
+                String fileName = compilationUnitFile.getName();
+                fileName = fileName.replace(".as", ".js");
+                String sourceMap = sourceMapEmitter.emitSourceMap(fileName, sourceMapOut.getAbsolutePath(), null);
+                BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(sourceMapOut));
+                outStream.write(sourceMap.getBytes());
+                outStream.flush();
+                outStream.close();
+            } catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    protected void convertMappingSourcePathsToRelative(IJSEmitter emitter, File relativeToFile)
+    {
+        List<IJSEmitter.SourceMapMapping> mappings = emitter.getSourceMapMappings();
+        for (IJSEmitter.SourceMapMapping mapping : mappings)
+        {
+            mapping.sourcePath = relativePath(mapping.sourcePath, relativeToFile.getAbsolutePath());
+        }
+    }
+
+    //if we ever support Java 7, the java.nio.file.Path relativize() method
+    //should be able to replace this method
+    private String relativePath(String filePath, String relativeToFilePath)
+    {
+        File currentFile = new File(filePath);
+        Stack<String> stack = new Stack<String>();
+        stack.push(currentFile.getName());
+        currentFile = currentFile.getParentFile();
+        while (currentFile != null)
+        {
+            String absoluteCurrentFile = currentFile.getAbsolutePath() + File.separator;
+            if (relativeToFilePath.startsWith(absoluteCurrentFile))
+            {
+                String relativeRelativeToFile = relativeToFilePath.substring(absoluteCurrentFile.length());
+                int separatorCount = relativeRelativeToFile.length() - relativeRelativeToFile.replace(File.separator, "").length();
+                String result = "";
+                while (separatorCount > 0)
+                {
+                    result += ".." + File.separator;
+                    separatorCount--;
+                }
+                while (stack.size() > 0)
+                {
+                    result += stack.pop();
+                }
+                return result;
+            }
+            stack.push(currentFile.getName() + File.separator);
+            currentFile = currentFile.getParentFile();
+        }
+        return null;
+    }
+}