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

[2/2] git commit: [flex-falcon] [refs/heads/develop] - Initial commit of COMPCExterns - This is messy and I will clean it up, I need to add my tests as well.

Initial commit of COMPCExterns
- This is messy and I will clean it up, I need to add my tests as well.


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

Branch: refs/heads/develop
Commit: 4ca23e3b049ed0e1afc7a1523edde6646ea480eb
Parents: 8d0d623
Author: Michael Schmalle <ms...@apache.org>
Authored: Tue Jun 9 16:04:21 2015 -0400
Committer: Michael Schmalle <ms...@apache.org>
Committed: Tue Jun 9 16:04:21 2015 -0400

----------------------------------------------------------------------
 .../javascript/jscomp/JXCompilerOptions.java    |  34 ++
 .../codegen/externals/pass/AddMemberPass.java   | 347 ++++++++++++++
 .../externals/pass/CollectTypesPass.java        | 186 ++++++++
 .../externals/reference/BaseReference.java      | 176 ++++++++
 .../externals/reference/ClassReference.java     | 416 +++++++++++++++++
 .../externals/reference/ConstantReference.java  |  82 ++++
 .../externals/reference/FieldReference.java     | 122 +++++
 .../externals/reference/FunctionReference.java  | 144 ++++++
 .../externals/reference/MemberReference.java    |  50 +++
 .../externals/reference/MethodReference.java    | 138 ++++++
 .../externals/reference/ReferenceModel.java     | 450 +++++++++++++++++++
 .../codegen/externals/utils/FunctionUtils.java  | 124 +++++
 .../codegen/externals/utils/JSTypeUtils.java    | 198 ++++++++
 .../codegen/externals/utils/TypeUtils.java      | 402 +++++++++++++++++
 14 files changed, 2869 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/com/google/javascript/jscomp/JXCompilerOptions.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/com/google/javascript/jscomp/JXCompilerOptions.java b/compiler.jx/src/com/google/javascript/jscomp/JXCompilerOptions.java
new file mode 100644
index 0000000..c31c46d
--- /dev/null
+++ b/compiler.jx/src/com/google/javascript/jscomp/JXCompilerOptions.java
@@ -0,0 +1,34 @@
+/*
+ *
+ *  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 com.google.javascript.jscomp;
+
+public class JXCompilerOptions extends CompilerOptions
+{
+
+    private static final long serialVersionUID = 2021530437904249081L;
+
+    public JXCompilerOptions()
+    {
+        super();
+        
+        declaredGlobalExternsOnWindow = false;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
new file mode 100644
index 0000000..9df1fb3
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java
@@ -0,0 +1,347 @@
+/*
+ *
+ *  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.pass;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.javascript.jscomp.AbstractCompiler;
+import com.google.javascript.jscomp.CompilerPass;
+import com.google.javascript.jscomp.NodeTraversal;
+import com.google.javascript.jscomp.NodeTraversal.Callback;
+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 AddMemberPass implements CompilerPass, Callback
+{
+    private ReferenceModel model;
+    private AbstractCompiler compiler;
+
+    public AddMemberPass(ReferenceModel model, AbstractCompiler compiler)
+    {
+        this.model = model;
+        this.compiler = compiler;
+    }
+
+    @Override
+    public void process(Node externs, Node root)
+    {
+        //NodeTraversal.traverse(compiler, root, this);
+        NodeTraversal.traverseRoots(compiler, this, externs, root);
+    }
+
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent)
+    {
+        if (n.getParent() == null || n.isScript() || n.isSyntheticBlock())
+            return;
+
+        JSDocInfo jsDoc = n.getJSDocInfo(); //NodeUtil.getBestJSDocInfo(n);
+        if (jsDoc != null)
+        {
+            if (n.isVar())
+            {
+                visitVar(t, n);
+            }
+            else if (n.isFunction())
+            {
+                visitFunction(t, n);
+            }
+            else if (n.isAssign())
+            {
+                if (n.getFirstChild().isGetProp()
+                        && n.getLastChild().isFunction())
+                {
+                    // instance or static method
+                    visitMethod(t, n);
+                }
+                else
+                {
+                    // DOMException.INDEX_SIZE_ERR = 1;
+                    // The first child of the assign is the GetProp node,
+                    // if later you need the value, either change this or check
+                    // for a parent assign node when creating the FieldReference
+                    // which the value would be n.getLastChild()
+                    // XXX visitStaticField(t, n);
+                    //System.err.println(n.toStringTree());
+                }
+            }
+            else if (n.isGetProp())
+            {
+                if (n.getFirstChild().isName())
+                {
+                    visitStaticField(t, n);
+                    //System.err.println(n.toStringTree());
+                }
+                else if (n.getFirstChild().isGetProp())
+                {
+                    try
+                    {
+                        if (n.getFirstChild().getFirstChild().isGetProp())
+                        {
+                            // XXX TODO qualified class names 'chrome.runtime.lastError '
+                        }
+                        else
+                        {
+                            visitInstanceField(t, n);
+                        }
+
+                    }
+                    catch (Exception e)
+                    {
+
+                        /*
+                         * 
+                        GETPROP 438 [jsdoc_info: JSDocInfo] [source_file: [chrome]] [length: 32]
+                        GETPROP 438 [source_file: [chrome]] [length: 24]
+                        GETPROP 438 [source_file: [chrome]] [length: 14]
+                        NAME chrome 438 [source_file: [chrome]] [length: 6]
+                        STRING runtime 438 [source_file: [chrome]] [length: 7]
+                        STRING lastError 438 [source_file: [chrome]] [length: 9]
+                        STRING message 438 [source_file: [chrome]] [length: 7]
+                         * 
+                         */
+                        // TODO Auto-generated catch block
+                        System.err.println(n.toStringTree());
+                        e.printStackTrace();
+                    }
+                }
+
+                // System.err.println(n.toStringTree());
+            }
+        }
+
+    }
+
+    /*
+    ASSIGN 48 [jsdoc_info: JSDocInfo] [source_file: [w3c_dom1]] [length: 38]
+            GETPROP 48 [source_file: [w3c_dom1]] [length: 34]
+                NAME DOMException 48 [source_file: [w3c_dom1]] [length: 12]
+                STRING HIERARCHY_REQUEST_ERR 48 [source_file: [w3c_dom1]] [length: 21]
+            NUMBER 3.0 48 [source_file: [w3c_dom1]] [length: 1]
+    */
+
+    // Instance Field (prototype)
+    // GETPROP 2026 [jsdoc_info: JSDocInfo] [source_file: [es3]] [length: 27]
+    //        GETPROP 2026 [source_file: [es3]] [length: 16]
+    //            NAME RegExp 2026 [source_file: [es3]] [length: 6]
+    //            STRING prototype 2026 [source_file: [es3]] [length: 9]
+    //        STRING ignoreCase 2026 [source_file: [es3]] [length: 10]
+
+    private void visitInstanceField(NodeTraversal t, Node n)
+    {
+        Node className = n.getFirstChild().getFirstChild();
+        Node name = n.getLastChild();
+        model.addField(n, className.getString(), name.getString());
+    }
+
+    // Static Field
+    // GETPROP 1994 [jsdoc_info: JSDocInfo] [source_file: [es3]] [length: 9]
+    //       NAME RegExp 1994 [source_file: [es3]] [length: 6]
+    //        STRING $6 1994 [source_file: [es3]] [length: 2]
+
+    private void visitStaticField(NodeTraversal t, Node n)
+    {
+        Node className = n.getFirstChild();
+        Node name = n.getLastChild();
+        model.addStaticField(n, className.getString(), name.getString());
+    }
+
+    /*
+    
+    Instance
+    
+    ASSIGN 194 [jsdoc_info: JSDocInfo] [source_file: [es3]] [length: 44]
+        GETPROP 194 [source_file: [es3]] [length: 28]
+            GETPROP 194 [source_file: [es3]] [length: 16]
+                NAME Object 194 [source_file: [es3]] [length: 6]
+                STRING prototype 194 [source_file: [es3]] [length: 9]
+            STRING constructor 194 [source_file: [es3]] [length: 11]
+        FUNCTION  194 [source_file: [es3]] [length: 13]
+            NAME  194 [source_file: [es3]] [length: 13]
+            PARAM_LIST 194 [source_file: [es3]] [length: 2]
+            BLOCK 194 [source_file: [es3]] [length: 2]
+    
+    Static
+    
+    ASSIGN 770 [jsdoc_info: JSDocInfo] [source_file: [es3]] [length: 52]
+        GETPROP 770 [source_file: [es3]] [length: 10]
+            NAME Array 770 [source_file: [es3]] [length: 5]
+            STRING some 770 [source_file: [es3]] [length: 4]    
+    
+    
+    */
+
+    // n == ASSIGN
+    @SuppressWarnings("unused")
+    private void visitMethod(NodeTraversal t, Node n)
+    {
+        JSDocInfo jsDoc = n.getJSDocInfo();
+        if (jsDoc == null)
+        {
+            // XXX Waring
+            return;
+        }
+
+        //System.out.println(n.toStringTree());
+        Node getProp = n.getFirstChild();
+        Node getProp2 = getProp.getFirstChild();
+
+        Node function = n.getLastChild();
+
+        Node className = getProp2.getFirstChild();
+        Node prototype = getProp2.getLastChild(); // check for static
+        Node functionName = getProp.getLastChild();
+
+        //Node name = function.getChildAtIndex(0);
+        Node paramList = function.getChildAtIndex(1);
+        //        if (!getProp.isQualifiedName())
+        //        {
+        //
+        //        }
+
+        if (getProp.getFirstChild().isGetProp())
+        {
+            ClassReference classReference = model.getClassReference(className.getString());
+            if (classReference != null)
+            {
+                classReference.addMethod(n, functionName.getString(), jsDoc,
+                        false);
+            }
+            else
+            {
+                System.err.println(">>>> {AddMemberPass.addMethod()} Class ["
+                        + className + "] not found in " + n.getSourceFileName());
+            }
+        }
+        else if (getProp.getFirstChild().isName())
+        {
+            className = getProp.getFirstChild();
+            functionName = getProp.getLastChild(); // Same
+
+            //System.err.println(n.toStringTree());
+            ClassReference classReference = model.getClassReference(className.getString());
+            if (classReference != null)
+            {
+                classReference.addMethod(n, functionName.getString(), jsDoc,
+                        true);
+            }
+            else
+            {
+                System.err.println(">>>> {AddMemberPass.addMethod()} Class ["
+                        + className + "] not found in " + n.getSourceFileName());
+            }
+
+        }
+
+        //System.out.println(n.toStringTree());
+    }
+
+    /*
+    
+    FUNCTION Arguments 34 [jsdoc_info: JSDocInfo] [source_file: [test]] [length: 23]
+        NAME Arguments 34 [source_file: [test]] [length: 9]
+        PARAM_LIST 34 [source_file: [test]] [length: 2]
+        BLOCK 34 [source_file: [test]] [length: 2]
+    
+    */
+
+    @SuppressWarnings("unused")
+    private void visitFunction(NodeTraversal t, Node n)
+    {
+
+        JSDocInfo jsDoc = n.getJSDocInfo();
+
+        if (jsDoc != null)
+        {
+            if (jsDoc.isConstructor())
+            {
+                //System.out.println("---------------------------------------------");
+                Node name = n.getChildAtIndex(0);
+                //System.out.println("Class " + name.getString());
+
+                Node paramList = n.getChildAtIndex(1);
+
+                JSTypeExpression returnType = jsDoc.getReturnType();
+                if (returnType != null)
+                {
+                    JSType jsReturnType = returnType.evaluate(null,
+                            compiler.getTypeRegistry());
+                    //System.out.println("Returns: " + jsReturnType);
+                }
+
+                Node block = n.getChildAtIndex(2);
+                //System.out.println(">>>>>>--------------------------------------");
+                //System.out.println(n.toStringTree());
+            }
+            else
+            {
+                // XX Global function parseInt(num, base)
+                //System.out.println(n.toStringTree());
+            }
+        }
+    }
+
+    private void visitVar(NodeTraversal t, Node n)
+    {
+        JSDocInfo jsDoc = n.getJSDocInfo();
+
+        if (jsDoc != null)
+        {
+            if (jsDoc.isConstant())
+            {
+                Node first = n.getFirstChild();
+                if (first.isName())
+                {
+                    Node second = first.getFirstChild();
+                    if (second != null && second.isObjectLit())
+                    {
+                        // * @const
+                        // var Math = {};
+                        //System.out.println("Final Class "
+                        //       + n.getFirstChild().getString());
+                        //System.out.println(n.toStringTree());
+                    }
+                    else
+                    {
+                        // * @const
+                        // var Infinity;
+                        //System.out.println("var "
+                        //        + n.getFirstChild().getString());
+                        //System.out.println(n.toStringTree());
+                    }
+                }
+            }
+            else if (jsDoc.isConstructor())
+            {
+            }
+        }
+    }
+
+    @Override
+    public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n,
+            Node parent)
+    {
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java
new file mode 100644
index 0000000..9a20c54
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/CollectTypesPass.java
@@ -0,0 +1,186 @@
+/*
+ *
+ *  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.pass;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.javascript.jscomp.AbstractCompiler;
+import com.google.javascript.jscomp.CompilerPass;
+import com.google.javascript.jscomp.NodeTraversal;
+import com.google.javascript.jscomp.NodeTraversal.Callback;
+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 CollectTypesPass implements CompilerPass, Callback
+{
+    protected AbstractCompiler compiler;
+    private ReferenceModel model;
+
+    public CollectTypesPass(ReferenceModel model, AbstractCompiler compiler)
+    {
+        this.model = model;
+        this.compiler = compiler;
+    }
+
+    @Override
+    public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n,
+            Node parent)
+    {
+        return true;
+    }
+
+    @Override
+    public void visit(NodeTraversal t, Node n, Node parent)
+    {
+        JSDocInfo jsDoc = n.getJSDocInfo();
+        if (jsDoc != null)
+        {
+            if (n.isVar())
+            {
+                visitVar(t, n, jsDoc);
+            }
+            else if (n.isFunction())
+            {
+                visitFunction(t, n, jsDoc);
+            }
+            else if (n.isAssign())
+            {
+                if (n.getFirstChild().isGetProp()
+                        && n.getChildAtIndex(1).isFunction())
+                {
+                    // instance or static method
+                    visitMethod(t, n, jsDoc);
+                }
+            }
+
+        }
+
+    }
+
+    private void visitVar(NodeTraversal t, Node n, JSDocInfo jsDoc)
+    {
+
+        Node first = n.getFirstChild();
+        if (first.isName())
+        {
+            Node second = first.getFirstChild();
+            if (second != null && second.isObjectLit())
+            {
+                if (jsDoc.isConstant())
+                {
+                    // * @const
+                    // var Math = {};
+                    model.addFinalClass(n, n.getFirstChild().getQualifiedName());
+                }
+            }
+            else if (jsDoc.isConstructor())
+            {
+                /*
+                 VAR 241 [jsdoc_info: JSDocInfo] [source_file: [es5]] [length: 29]
+                    NAME JSONType 241 [source_file: [es5]] [length: 8]
+                        FUNCTION  241 [source_file: [es5]] [length: 13]
+                            NAME  241 [source_file: [es5]] [length: 13]
+                            PARAM_LIST 241 [source_file: [es5]] [length: 2]
+                            BLOCK 241 [source_file: [es5]] [length: 2]
+                 */
+                // * @constructor
+                // var JSONType = function() {};
+                Node name = n.getFirstChild();
+                if (name.getFirstChild().isFunction())
+                {
+                    model.addClass(n, name.getString());
+                }
+                //System.err.println(n.toStringTree());
+            }
+            else
+            {
+                if (jsDoc.isConstant())
+                {
+                    // * @const
+                    // var Infinity;
+                    model.addConstant(n, n.getFirstChild().getQualifiedName());
+                }
+                else if (jsDoc.getTypedefType() != null)
+                {
+                    // * @typedef {{prp(foo)}}
+                    // var MyStrcut;
+                    JSTypeExpression typedefType = jsDoc.getTypedefType();
+                    System.out.println("@typedef "
+                            + n.getFirstChild().getString());
+                    System.out.println(typedefType);
+
+                    JSType jsReturnType = typedefType.evaluate(null,
+                            compiler.getTypeRegistry());
+                    if (jsReturnType.isRecordType())
+                    {
+                        // property map of JSType
+                    }
+
+                    model.addClass(n, n.getFirstChild().getQualifiedName());
+
+                    //System.out.println("   : " + jsReturnType);
+                }
+            }
+        }
+
+    }
+
+    private void visitFunction(NodeTraversal t, Node n, JSDocInfo jsDoc)
+    {
+        if (jsDoc.isConstructor())
+        {
+            Node name = n.getChildAtIndex(0);
+            //System.out.println("Class " + name.getString());
+            //System.out.println(n.toStringTree());
+
+            model.addClass(n, name.getQualifiedName());
+        }
+        else if (jsDoc.isInterface())
+        {
+            Node name = n.getChildAtIndex(0);
+            //System.out.println("Interface " + name.getString());
+
+            model.addInterface(n, name.getQualifiedName());
+        }
+        else
+        {
+            // XX Global function parseInt(num, base)
+            //System.out.println(n.toStringTree());
+            Node name = n.getChildAtIndex(0);
+            //System.out.println("Function " + name.getString());
+
+            model.addFunction(n, name.getQualifiedName());
+        }
+    }
+
+    private void visitMethod(NodeTraversal t, Node n, JSDocInfo jsDoc)
+    {
+
+    }
+
+    @Override
+    public void process(Node externs, Node root)
+    {
+        NodeTraversal.traverseRoots(compiler, this, externs, root);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/BaseReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/BaseReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/BaseReference.java
new file mode 100644
index 0000000..2b235ef
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/BaseReference.java
@@ -0,0 +1,176 @@
+/*
+ *
+ *  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.io.File;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel.ExcludedMemeber;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSDocInfo.Marker;
+import com.google.javascript.rhino.JSDocInfo.StringPosition;
+import com.google.javascript.rhino.JSDocInfo.TypePosition;
+import com.google.javascript.rhino.Node;
+
+public abstract class BaseReference
+{
+    private String qualfiedName;
+
+    protected JSDocInfo comment;
+
+    private File currentFile;
+
+    private Node node;
+
+    private ReferenceModel model;
+
+    public File getCurrentFile()
+    {
+        return currentFile;
+    }
+
+    public void setCurrentFile(File currentFile)
+    {
+        this.currentFile = currentFile;
+    }
+
+    public String getCurrentFileBaseName()
+    {
+        return "";
+        // return FilenameUtils.getBaseName(currentFile.getAbsolutePath());
+    }
+
+    public String getQualifiedName()
+    {
+        return qualfiedName;
+    }
+
+    public Node getNode()
+    {
+        return node;
+    }
+
+    public void setNode(Node node)
+    {
+        this.node = node;
+    }
+
+    public void setComment(JSDocInfo comment)
+    {
+        this.comment = comment;
+    }
+
+    public JSDocInfo getComment()
+    {
+        return comment;
+    }
+
+    public ReferenceModel getModel()
+    {
+        return model;
+    }
+
+    public BaseReference(ReferenceModel model, Node node, String qualfiedName,
+            JSDocInfo comment)
+    {
+        this.model = model;
+        this.node = node;
+        this.qualfiedName = qualfiedName;
+        this.comment = comment;
+    }
+
+    public void printComment(StringBuilder sb)
+    {
+        sb.append("    /**\n");
+
+        String blockDescription = getComment().getBlockDescription();
+        if (blockDescription != null)
+        {
+            sb.append("     * ");
+            sb.append(blockDescription.replaceAll("\\n", "\n     * "));
+            sb.append("\n     *\n");
+        }
+
+        for (Marker marker : getComment().getMarkers())
+        {
+            StringPosition name = marker.getAnnotation();
+            TypePosition typePosition = marker.getType();
+            StringPosition descriptionPosition = marker.getDescription();
+            StringBuilder desc = new StringBuilder();
+
+            // XXX Figure out how to toString() a TypePosition Node for markers
+            // XXX Figure out how to get a @param name form the Marker
+            if (!name.getItem().equals("see"))
+                continue;
+
+            if (name != null)
+            {
+                desc.append(name.getItem());
+                desc.append(" ");
+            }
+
+            if (typePosition != null)
+            {
+                //desc.append(typePosition.getItem().getString());
+                //desc.append(" ");
+            }
+
+            if (descriptionPosition != null)
+            {
+                desc.append(descriptionPosition.getItem());
+                desc.append(" ");
+            }
+
+            sb.append("     * @" + desc.toString() + "\n");
+        }
+
+        sb.append("     * @see " + getNode().getSourceFileName() + "\n");
+        sb.append("     */\n");
+    }
+
+    public ExcludedMemeber isExcluded()
+    {
+        return null;
+    }
+
+    public abstract void emit(StringBuilder sb);
+
+    //    public DocletTag findDocTagByName(String tagName)
+    //    {
+    //        for (DocletTag tag : getComment().getTags())
+    //        {
+    //            if (tag.getName().equals(tagName))
+    //            {
+    //                return tag;
+    //            }
+    //        }
+    //        return null;
+    //    }
+    //
+    //    public boolean hasTag(String tagName)
+    //    {
+    //        for (DocletTag tag : getComment().getTags())
+    //        {
+    //            if (tag.getName().equals(tagName))
+    //                return true;
+    //        }
+    //        return false;
+    //    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
new file mode 100644
index 0000000..fe4898d
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java
@@ -0,0 +1,416 @@
+/*
+ *
+ *  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.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils;
+
+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 ClassReference extends BaseReference
+{
+
+    private boolean isFinal;
+
+    private Map<String, FieldReference> fields = new HashMap<String, FieldReference>();
+    private Map<String, MethodReference> methods = new HashMap<String, MethodReference>();
+
+    public Map<String, FieldReference> getFields()
+    {
+        return fields;
+    }
+
+    public Map<String, MethodReference> getMethods()
+    {
+        return methods;
+    }
+
+    public boolean isFinal()
+    {
+        return isFinal;
+    }
+
+    public void setFinal(boolean isFinal)
+    {
+        this.isFinal = isFinal;
+    }
+
+    public final boolean isInterface()
+    {
+        return getComment().isInterface();
+    }
+
+    public ClassReference(ReferenceModel model, Node node, String qualfiedName,
+            JSDocInfo comment)
+    {
+        super(model, node, qualfiedName, comment);
+    }
+
+    public FieldReference addField(Node node, String fieldName,
+            JSDocInfo comment, boolean isStatic)
+    {
+        if (hasField(fieldName))
+        {
+            // XXX Warning
+            return null;
+        }
+
+        FieldReference field = new FieldReference(getModel(), this, node,
+                fieldName, comment, isStatic);
+
+        fields.put(fieldName, field);
+        return field;
+    }
+
+    public boolean hasSuperField(String fieldName)
+    {
+        List<ClassReference> list = getSuperClasses();
+        for (ClassReference reference : list)
+        {
+            if (reference.hasField(fieldName))
+                return true;
+        }
+        return false;
+    }
+
+    public boolean hasSuperMethod(String methodName)
+    {
+        List<ClassReference> list = getSuperClasses();
+        for (ClassReference reference : list)
+        {
+            if (reference.hasMethod(methodName))
+                return true;
+        }
+        return false;
+    }
+
+    public List<ClassReference> getSuperClasses()
+    {
+        ArrayList<ClassReference> result = new ArrayList<>();
+        ClassReference superClass = getSuperClass();
+        while (superClass != null)
+        {
+            result.add(superClass);
+            superClass = superClass.getSuperClass();
+        }
+        return result;
+    }
+
+    public boolean hasField(String fieldName)
+    {
+        return fields.containsKey(fieldName);
+    }
+
+    public boolean hasMethod(String methodName)
+    {
+        return methods.containsKey(methodName);
+    }
+
+    public MethodReference addMethod(Node node, String functionName,
+            JSDocInfo comment, boolean isStatic)
+    {
+        MethodReference method = new MethodReference(getModel(), this, node,
+                functionName, comment, isStatic);
+        methods.put(functionName, method);
+        return method;
+    }
+
+    @Override
+    public void emit(StringBuilder sb)
+    {
+        String packageName = "";
+
+        sb.append("package ");
+        sb.append(packageName + " ");
+        sb.append("{\n");
+        sb.append("\n");
+
+        printImports();
+
+        boolean isInterface = isInterface();
+
+        if (isInterface)
+        {
+            printInterface(sb);
+        }
+        else
+        {
+            printClass(sb);
+        }
+
+        sb.append("{\n");
+        sb.append("\n");
+
+        if (!isInterface)
+        {
+            printConstructor(sb);
+            sb.append("\n");
+        }
+
+        //        for (Entry<String, FieldReference> fieldSet : getStaticFields().entrySet())
+        //        {
+        //            fieldSet.getValue().emit(sb);
+        //            sb.append("\n");
+        //        }
+
+        for (Entry<String, FieldReference> fieldSet : getFields().entrySet())
+        {
+            fieldSet.getValue().emit(sb);
+            sb.append("\n");
+        }
+
+        for (Entry<String, MethodReference> methodSet : getMethods().entrySet())
+        {
+            MethodReference method = methodSet.getValue();
+            //if (!method.isOverride())
+            //{
+            method.emit(sb);
+            sb.append("\n");
+            //}
+        }
+
+        sb.append("}\n");
+        sb.append("}\n"); // package
+
+        //System.out.println(sb.toString());
+    }
+
+    private void printClass(StringBuilder sb)
+    {
+        boolean isDynamic = false;
+
+        sb.append("public ");
+        if (isDynamic)
+        {
+            sb.append("dynamic ");
+        }
+
+        if (isFinal)
+        {
+            sb.append("final ");
+        }
+
+        sb.append("class ");
+        sb.append(getQualifiedName() + " ");
+
+        if (getComment().hasBaseType())
+        {
+            printSuperClass(sb);
+            sb.append(" ");
+        }
+        //
+        //        if (TagUtils.hasTags(this, "implements"))
+        //        {
+        //            printImplements(sb);
+        //            sb.append(" ");
+        //        }
+    }
+
+    private void printInterface(StringBuilder sb)
+    {
+        sb.append("public interface ");
+
+        sb.append(getQualifiedName() + " ");
+
+        //        if (TagUtils.hasTags(this, "extends"))
+        //        {
+        //            printSuperClass(sb);
+        //            sb.append(" ");
+        //        }
+    }
+
+    private void printSuperClass(StringBuilder sb)
+    {
+        sb.append("extends ");
+        String value = JSTypeUtils.toTypeJsType(getModel().getCompiler(),
+                getComment().getBaseType()).toString();
+        sb.append(value);
+    }
+
+    @SuppressWarnings("unused")
+    private void printImplements(StringBuilder sb)
+    {
+        //        if (TagUtils.hasTags(this, "implements"))
+        //        {
+        //            sb.append("implements ");
+        //            List<DocletTag> impls = TagUtils.getTags(this, "implements");
+        //            int len = impls.size();
+        //            for (int i = 0; i < len; i++)
+        //            {
+        //                String value = impls.get(0).getValue();
+        //                sb.append(value.substring(1, value.length() - 1));
+        //                if (i < len - 1)
+        //                    sb.append(", ");
+        //            }
+        //        }
+    }
+
+    private void printConstructor(StringBuilder sb)
+    {
+        sb.append("    native public function " + getQualifiedName() + "();\n");
+    }
+
+    private void printImports()
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+    public File getFile(File asSourceRoot)
+    {
+        String packageName = "";
+
+        return new File(asSourceRoot, packageName + File.separator
+                + getQualifiedName() + ".as");
+    }
+
+    public boolean isMethodOverrideFromInterface(MethodReference reference)
+    {
+        //        if (!hasImplementations())
+        //            return false;
+        //
+        //        List<DocletTag> impls = TagUtils.getTags(this, "implements");
+        //        for (DocletTag docletTag : impls)
+        //        {
+        //            String interfaceName = docletTag.getValue().trim();
+        //            interfaceName = interfaceName.substring(1,
+        //                    interfaceName.length() - 1);
+        //            ClassReference2 classReference = model.getClassReference(interfaceName);
+        //            return classReference.hasMethod(reference.getName());
+        //        }
+
+        return false;
+    }
+
+    public MethodReference getMethodOverrideFromInterface(
+            MethodReference reference)
+    {
+        //        if (!hasImplementations())
+        //            return null;
+        //
+        //        List<DocletTag> impls = TagUtils.getTags(this, "implements");
+        //        for (DocletTag docletTag : impls)
+        //        {
+        //            String interfaceName = docletTag.getValue().trim();
+        //            interfaceName = interfaceName.substring(1,
+        //                    interfaceName.length() - 1);
+        //            ClassReference2 classReference = model.getClassReference(interfaceName);
+        //            return classReference.getMethods().get(reference.getName());
+        //        }
+
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    private boolean hasImplementations()
+    {
+        return getComment().getImplementedInterfaceCount() > 0;
+    }
+
+    public boolean hasImplements(String interfaceName)
+    {
+        //        boolean hasImplements = TagUtils.hasTags(this, "implements");
+        //        if (hasImplements)
+        //        {
+        //            List<DocletTag> impls = TagUtils.getTags(this, "implements");
+        //            for (DocletTag tag : impls)
+        //            {
+        //                String value = tag.getValue();
+        //                value = value.substring(1, value.indexOf("}"));
+        //                return value.equals(interfaceName);
+        //            }
+        //        }
+        return false;
+    }
+
+    public ClassReference getSuperClass()
+    {
+        JSTypeExpression baseType = getComment().getBaseType();
+        if (baseType != null)
+        {
+            JSType jsType = baseType.evaluate(null,
+                    getModel().getCompiler().getTypeRegistry());
+            if (jsType != null)
+                return getModel().getClassReference(jsType.getDisplayName());
+        }
+        return null;
+    }
+
+    public boolean hasSuperFieldConflict(FieldReference reference)
+    {
+        //        ClassReference2 superClass = getSuperClass();
+        //        if (superClass != null)
+        //            return superClass.getInstanceFields().containsKey(
+        //                    reference.getName());
+        return false;
+    }
+
+    public boolean isPropertyInterfaceImplementation(FieldReference reference)
+    {
+        //        List<ClassReference2> superInterfaces = getSuperInterfaces();
+        //        for (ClassReference2 interfaceRef : superInterfaces)
+        //        {
+        //            if (interfaceRef == null)
+        //            {
+        //                System.err.println("isPropertyInterfaceImplementation() null");
+        //                continue;
+        //            }
+        //            if (interfaceRef.hasFieldConflict(reference))
+        //                return true;
+        //        }
+        return false;
+    }
+
+    @SuppressWarnings("unused")
+    private List<ClassReference> getSuperInterfaces()
+    {
+        ArrayList<ClassReference> result = new ArrayList<>();
+        //        if (!TagUtils.hasTags(this, "implements"))
+        //            return result;
+        //
+        //        List<DocletTag> impls = TagUtils.getTags(this, "implements");
+        //        for (DocletTag tag : impls)
+        //        {
+        //            String type = TagUtils.getType(tag);
+        //            result.add(model.getClassReference(type));
+        //        }
+        return result;
+    }
+
+    public boolean hasLocalMethodConflict(String functionName)
+    {
+        return methods.containsKey(functionName);
+    }
+
+    public boolean hasFieldConflict(FieldReference reference)
+    {
+        return getFields().containsKey(reference.getQualifiedName());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ConstantReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ConstantReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ConstantReference.java
new file mode 100644
index 0000000..f920fff
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ConstantReference.java
@@ -0,0 +1,82 @@
+/*
+ *
+ *  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.HashMap;
+
+import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+
+public class ConstantReference extends ClassReference
+{
+
+    public ConstantReference(ReferenceModel model, Node node, String name,
+            JSDocInfo comment)
+    {
+        super(model, node, name, comment);
+    }
+
+    @Override
+    public void emit(StringBuilder sb)
+    {
+        @SuppressWarnings("unused")
+        String packageName = "";
+
+        sb.append("package ");
+
+        //sb.append(packageName + " ");
+
+        sb.append("{\n");
+        sb.append("\n");
+
+        String type = JSTypeUtils.toConstantTypeString(this);
+        String value = resolveValue(type);
+
+        //        String type = TypeUtils.getType(findDocTagByName("type"));
+        //        String value = resolveValue(type);
+
+        if (getQualifiedName().equals("undefined"))
+        {
+            sb.append("    public const undefined:* = 0;\n");
+        }
+        else
+        {
+            sb.append("    public const " + getQualifiedName() + ":" + type
+                    + " = " + value + ";\n");
+        }
+
+        sb.append("}\n"); // package
+    }
+
+    private String resolveValue(String type)
+    {
+        HashMap<String, String> map = new HashMap<>();
+        map.put("Number", "0");
+        map.put("undefined", "0");
+
+        if (map.containsKey(type))
+            return map.get(type);
+
+        return "undefined";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
new file mode 100644
index 0000000..5d8e849
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java
@@ -0,0 +1,122 @@
+/*
+ *
+ *  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 org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel.ExcludedMemeber;
+import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils;
+import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+
+public class FieldReference extends MemberReference
+{
+
+    private boolean isStatic;
+
+    public boolean isStatic()
+    {
+        return isStatic;
+    }
+
+    public void setStatic(boolean isStatic)
+    {
+        this.isStatic = isStatic;
+    }
+
+    public FieldReference(ReferenceModel model, ClassReference classReference,
+            Node node, String name, JSDocInfo comment, boolean isStatic)
+    {
+        super(model, classReference, node, name, comment);
+        this.isStatic = isStatic;
+    }
+
+    @Override
+    public void emit(StringBuilder sb)
+    {
+        // Window has a global var Window that conflicts with the constructor.
+        if (getQualifiedName().equals(getClassReference().getQualifiedName()))
+            return;
+
+        if (getClassReference().hasSuperField(getQualifiedName()))
+            return;
+
+        printComment(sb);
+
+        ExcludedMemeber excluded = isExcluded();
+        if (excluded != null)
+        {
+            excluded.print(sb);
+        }
+
+        if (!getClassReference().isInterface() && !getComment().isOverride())
+        //&& !getClassReference().isPropertyInterfaceImplementation(this))
+        {
+            printVar(sb);
+        }
+        else
+        {
+            printAccessor(sb);
+        }
+
+    }
+
+    private void printAccessor(StringBuilder sb)
+    {
+        String staticValue = "";//(isStatic) ? "static " : "";
+
+        String isPublic = getClassReference().isInterface() ? "" : "public ";
+
+        sb.append("    " + isPublic + staticValue + "function get "
+                + getQualifiedName() + "():" + toReturnString() + ";\n");
+        sb.append("    " + isPublic + staticValue + "function set "
+                + getQualifiedName() + "(" + toPrameterString() + "):void"
+                + ";\n");
+    }
+
+    private void printVar(StringBuilder sb)
+    {
+        String staticValue = (isStatic) ? "static " : "";
+
+        String type = toTypeString();
+        if (type.indexOf("|") != -1 || type.indexOf("?") != -1)
+            type = "*";
+
+        sb.append("    public " + staticValue + "var " + getQualifiedName()
+                + ":" + type + ";\n");
+    }
+
+    private String toTypeString()
+    {
+        return JSTypeUtils.toFieldString(this);
+    }
+
+    private String toReturnString()
+    {
+        return toPrameterString().replace("value:", "");
+    }
+
+    private String toPrameterString()
+    {
+        return FunctionUtils.toParameter(this, getComment(), "value",
+                getComment().getType());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FunctionReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FunctionReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FunctionReference.java
new file mode 100644
index 0000000..3cda1c1
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FunctionReference.java
@@ -0,0 +1,144 @@
+/*
+ *
+ *  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.io.File;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel.ExcludedMemeber;
+import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+
+public class FunctionReference extends BaseReference
+{
+    private boolean isStatic;
+    private FunctionReference override;
+    private Node paramNode;
+
+    public File getFile(File asSourceRoot)
+    {
+        String packageName = "";
+
+        return new File(asSourceRoot, packageName + File.separator
+                + getQualifiedName() + ".as");
+    }
+
+    private FunctionReference getContext()
+    {
+        return override == null ? this : override;
+    }
+
+    public boolean isStatic()
+    {
+        return isStatic;
+    }
+
+    public void setStatic(boolean isStatic)
+    {
+        this.isStatic = isStatic;
+    }
+
+    /*
+    FUNCTION [node] Scope:Global
+        NAME
+        PARAM_LIST
+            NAME
+            NAME
+        BLOCK
+    */
+
+    public FunctionReference(ReferenceModel model, Node node,
+            String qualifiedName, JSDocInfo comment)
+    {
+        super(model, node, qualifiedName, comment);
+        this.paramNode = node.getChildAtIndex(1);
+    }
+
+    @Override
+    public void emit(StringBuilder sb)
+    {
+        String packageName = "";
+
+        sb.append("package ");
+        sb.append(packageName + " ");
+        sb.append("{\n");
+        sb.append("\n");
+
+        printImports();
+
+        printComment(sb);
+
+        ExcludedMemeber excluded = isExcluded();
+        if (excluded != null)
+        {
+            excluded.print(sb);
+        }
+
+        String staticValue = (isStatic) ? "static " : "";
+
+        String publicModifier = "public ";
+        String braces = "";
+
+        String returns = "";
+        if (!transformReturnString().equals("void"))
+        {
+            returns = " return null;";
+        }
+
+        braces = " { " + returns + " }";
+
+        sb.append("    ");
+        sb.append(publicModifier);
+        sb.append(staticValue);
+        sb.append("function ");
+        sb.append(getQualifiedName());
+        sb.append(toPrameterString());
+        sb.append(":");
+        sb.append(transformReturnString());
+        sb.append(braces);
+        sb.append("\n");
+
+        sb.append("}\n"); // package
+    }
+
+    private void printImports()
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+    private String transformReturnString()
+    {
+        return FunctionUtils.transformReturnString(getContext(), getComment());
+    }
+
+    private String toPrameterString()
+    {
+        return FunctionUtils.toPrameterString(getContext(), getComment(),
+                paramNode);
+    }
+
+    public boolean isOverride()
+    {
+        return getComment().isOverride();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MemberReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MemberReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MemberReference.java
new file mode 100644
index 0000000..2cb78e5
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MemberReference.java
@@ -0,0 +1,50 @@
+/*
+ *
+ *  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 org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel.ExcludedMemeber;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+
+public abstract class MemberReference extends BaseReference
+{
+
+    private ClassReference classReference;
+
+    public ClassReference getClassReference()
+    {
+        return classReference;
+    }
+
+    public MemberReference(ReferenceModel model, ClassReference classReference,
+            Node node, String name, JSDocInfo comment)
+    {
+        super(model, node, name, comment);
+        this.classReference = classReference;
+    }
+
+    public ExcludedMemeber isExcluded()
+    {
+        return getClassReference().getModel().isExcludedMember(
+                getClassReference(), this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
new file mode 100644
index 0000000..2a0db9c
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java
@@ -0,0 +1,138 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.externals.reference;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel.ExcludedMemeber;
+import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+
+public class MethodReference extends MemberReference
+{
+
+    private boolean isStatic;
+    private MethodReference override;
+    private Node paramNode;
+
+    private MethodReference getContext()
+    {
+        return override == null ? this : override;
+    }
+
+    public boolean isStatic()
+    {
+        return isStatic;
+    }
+
+    public void setStatic(boolean isStatic)
+    {
+        this.isStatic = isStatic;
+    }
+
+    public MethodReference(ReferenceModel model, ClassReference classReference,
+            Node node, String name, JSDocInfo comment, boolean isStatic)
+    {
+        super(model, classReference, node, name, comment);
+        this.isStatic = isStatic;
+        this.paramNode = node.getLastChild().getChildAtIndex(1);
+    }
+
+    @Override
+    public void emit(StringBuilder sb)
+    {
+        if (isOverride())
+            return;
+
+        if (getClassReference().hasSuperMethod(getQualifiedName()))
+            return;
+
+        printComment(sb);
+
+        ExcludedMemeber excluded = isExcluded();
+        if (excluded != null)
+        {
+            excluded.print(sb);
+        }
+
+        String staticValue = (isStatic) ? "static " : "";
+        if (getClassReference().isInterface())
+            staticValue = "";
+
+        String isOverride = "";
+        //        if (TagUtils.hasTags(this, "override"))
+        //        {
+        //            isOverride = "override ";
+        //            if (getClassReference().isMethodOverrideFromInterface(this))
+        //            {
+        //                override = getClassReference().getMethodOverrideFromInterface(
+        //                        this);
+        //
+        //                isOverride = "";
+        //            }
+        //        }
+
+        String publicModifier = "";
+        String braces = "";
+        String returns = "";
+
+        if (!transformReturnString().equals("void"))
+        {
+            returns = " return null;";
+        }
+
+        if (!getClassReference().isInterface())
+        {
+            publicModifier = "public ";
+            braces = " { " + returns + " }";
+        }
+
+        sb.append("    ");
+        sb.append(publicModifier);
+        sb.append(isOverride);
+        sb.append(staticValue);
+        sb.append("function ");
+        sb.append(getQualifiedName());
+        sb.append(toPrameterString());
+        sb.append(":");
+        sb.append(transformReturnString());
+        sb.append(braces);
+        sb.append("\n");
+
+        override = null;
+    }
+
+    private String transformReturnString()
+    {
+        return FunctionUtils.transformReturnString(getContext(), getComment());
+    }
+
+    private String toPrameterString()
+    {
+        return FunctionUtils.toPrameterString(getContext(), getComment(),
+                paramNode);
+    }
+
+    public boolean isOverride()
+    {
+        return getComment().isOverride();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
new file mode 100644
index 0000000..60f4bea
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java
@@ -0,0 +1,450 @@
+/*
+ *
+ *  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.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.internal.codegen.externals.pass.AddMemberPass;
+import org.apache.flex.compiler.internal.codegen.externals.pass.CollectTypesPass;
+
+import com.google.common.collect.ImmutableList;
+import com.google.javascript.jscomp.CustomPassExecutionTime;
+import com.google.javascript.jscomp.JXCompilerOptions;
+import com.google.javascript.jscomp.NodeUtil;
+import com.google.javascript.jscomp.Result;
+import com.google.javascript.jscomp.SourceFile;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.Node;
+
+public class ReferenceModel
+{
+    private static final List<SourceFile> EMPTY_EXTERNS = ImmutableList.of(SourceFile.fromCode(
+            "externs", ""));
+
+    private File jsRoot;
+    private File asRoot;
+    private File asFunctionRoot;
+    private File asConstantRoot;
+
+    private List<ExcludedMemeber> excludesClass = new ArrayList<>();
+    private List<ExcludedMemeber> excludesField = new ArrayList<>();
+    private List<ExcludedMemeber> excludes = new ArrayList<>();
+    private List<ExternalFile> externals = new ArrayList<>();
+
+    private HashMap<String, ClassReference> classes = new HashMap<String, ClassReference>();
+    //private HashMap<String, ClassReference2> interfaces = new HashMap<String, ClassReference2>();
+    private HashMap<String, FunctionReference> functions = new HashMap<String, FunctionReference>();
+    private HashMap<String, ConstantReference> constants = new HashMap<String, ConstantReference>();
+
+    private com.google.javascript.jscomp.Compiler compiler;
+
+    public void setJSRoot(File file)
+    {
+        this.jsRoot = file;
+    }
+
+    public void setASRoot(File file)
+    {
+        this.asRoot = file;
+
+        asFunctionRoot = new File(asRoot.getParent(), "as_functions");
+        asConstantRoot = new File(asRoot.getParent(), "as_constants");
+    }
+
+    public com.google.javascript.jscomp.Compiler getCompiler()
+    {
+        return compiler;
+    }
+
+    public ReferenceModel()
+    {
+        //walker = new JSBlockWalker(this);
+    }
+
+    public void addExclude(String className, String name)
+    {
+        excludes.add(new ExcludedMemeber(className, name));
+    }
+
+    public void addExclude(String className, String name, String description)
+    {
+        excludes.add(new ExcludedMemeber(className, name, description));
+    }
+
+    public void addFieldExclude(String className, String fieldName)
+    {
+        excludesField.add(new ExcludedMemeber(className, fieldName, ""));
+    }
+
+    public void addClassExclude(String className)
+    {
+        excludesClass.add(new ExcludedMemeber(className, null, ""));
+    }
+
+    public void addExternal(String name)
+    {
+        File file = new File(jsRoot, name + ".js");
+        externals.add(new ExternalFile(file));
+    }
+
+    public ClassReference getClassReference(String qualifiedName)
+    {
+        return classes.get(qualifiedName);
+    }
+
+    public void addClass(Node node, String qualfiedName)
+    {
+        if (classes.containsKey(qualfiedName))
+        {
+            // XXX Record warning;
+            return;
+        }
+
+        System.out.println("Model.addClass(" + qualfiedName + ")");
+
+        ClassReference reference = new ClassReference(this, node, qualfiedName,
+                node.getJSDocInfo());
+        classes.put(qualfiedName, reference);
+    }
+
+    public void addInterface(Node node, String qualfiedName)
+    {
+        if (classes.containsKey(qualfiedName))
+        {
+            // XXX Record warning;
+            return;
+        }
+
+        System.out.println("Model.addInterface(" + qualfiedName + ")");
+
+        ClassReference reference = new ClassReference(this, node, qualfiedName,
+                node.getJSDocInfo());
+        classes.put(qualfiedName, reference);
+    }
+
+    public void addFinalClass(Node node, String qualfiedName)
+    {
+        if (classes.containsKey(qualfiedName))
+        {
+            // XXX Record warning;
+            return;
+        }
+
+        System.out.println("Model.addFinalClass(" + qualfiedName + ")");
+
+        ClassReference reference = new ClassReference(this, node, qualfiedName,
+                node.getJSDocInfo());
+        reference.setFinal(true);
+        classes.put(qualfiedName, reference);
+    }
+
+    public void addFunction(Node node, String qualfiedName)
+    {
+        if (functions.containsKey(qualfiedName))
+        {
+            // XXX Record warning;
+            return;
+        }
+
+        System.out.println("Model.addFunction(" + qualfiedName + ")");
+        //System.err.println(node.toStringTree());
+        FunctionReference reference = new FunctionReference(this, node,
+                qualfiedName, node.getJSDocInfo());
+        functions.put(qualfiedName, reference);
+    }
+
+    public void addConstant(Node node, String qualfiedName)
+    {
+        if (constants.containsKey(qualfiedName))
+        {
+            // XXX Record warning;
+            return;
+        }
+
+        System.out.println("Model.addConstant(" + qualfiedName + ")");
+
+        ConstantReference reference = new ConstantReference(this, node,
+                qualfiedName, node.getJSDocInfo());
+        constants.put(qualfiedName, reference);
+    }
+
+    public void addField(Node node, String className, String qualfiedName)
+    {
+        ClassReference classReference = getClassReference(className);
+        classReference.addField(node, qualfiedName, node.getJSDocInfo(), false);
+    }
+
+    public void addStaticField(Node node, String className, String qualfiedName)
+    {
+        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, qualfiedName, comment, true);
+        }
+        else
+        {
+            System.err.println(">>>> {ReferenceModel} Class [" + className
+                    + "] not found in " + node.getSourceFileName());
+        }
+    }
+
+    //----------------------------------------------------
+
+    public void cleanOutput() throws IOException
+    {
+        FileUtils.deleteDirectory(asRoot);
+        asRoot.mkdirs();
+    }
+
+    public void emit() throws IOException
+    {
+        for (Entry<String, ClassReference> set : classes.entrySet())
+        {
+            StringBuilder sb = new StringBuilder();
+
+            ClassReference reference = set.getValue();
+            if (isExcludedClass(reference) != null)
+                continue;
+
+            if (!reference.isInterface())
+                continue;
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        for (Entry<String, ClassReference> set : classes.entrySet())
+        {
+            ClassReference reference = set.getValue();
+            if (isExcludedClass(reference) != null)
+                continue;
+
+            if (reference.isInterface())
+                continue;
+
+            StringBuilder sb = new StringBuilder();
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        for (Entry<String, FunctionReference> set : functions.entrySet())
+        {
+            StringBuilder sb = new StringBuilder();
+
+            FunctionReference reference = set.getValue();
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asFunctionRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        for (Entry<String, ConstantReference> set : constants.entrySet())
+        {
+            StringBuilder sb = new StringBuilder();
+
+            ConstantReference reference = set.getValue();
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asConstantRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        //        StringBuilder sb = new StringBuilder();
+        //        sb.append("package {\n");
+        //        for (Entry<String, ConstantReference2> set : constants.entrySet())
+        //        {
+        //            ConstantReference2 reference = set.getValue();
+        //            emit(reference, sb);
+        //        }
+        //        sb.append("\n}");
+        //        File sourceFile = new File(asRoot, "constants.as");
+        //        FileUtils.write(sourceFile, sb.toString());
+    }
+
+    public void emit(BaseReference reference, StringBuilder sb)
+    {
+        reference.emit(sb);
+    }
+
+    public String emit(BaseReference reference)
+    {
+        StringBuilder sb = new StringBuilder();
+        reference.emit(sb);
+        return sb.toString();
+    }
+
+    public void compile() throws IOException
+    {
+        JXCompilerOptions options = new JXCompilerOptions();
+        //options.setLanguageIn(LanguageMode.ECMASCRIPT6_TYPED);
+        //options.setLanguageOut(LanguageMode.ECMASCRIPT6_TYPED);
+        options.setPreserveTypeAnnotations(true);
+        options.setPrettyPrint(true);
+        options.setLineLengthThreshold(80);
+        options.setPreferSingleQuotes(true);
+        options.setIdeMode(true);
+        options.setParseJsDocDocumentation(true);
+        options.setExternExports(false);
+
+        compiler = new com.google.javascript.jscomp.Compiler();
+
+        options.addCustomPass(CustomPassExecutionTime.BEFORE_OPTIMIZATIONS,
+                new CollectTypesPass(this, compiler));
+        options.addCustomPass(CustomPassExecutionTime.BEFORE_OPTIMIZATIONS,
+                new AddMemberPass(this, compiler));
+
+        //compiler.setErrorManager(testErrorManager);
+        compiler.initOptions(options);
+
+        //Node script = compiler.parse(SourceFile.fromCode("[test]", source));
+
+        List<SourceFile> sources = new ArrayList<>();
+        for (ExternalFile externalFile : externals)
+        {
+            String name = externalFile.getName();
+            String source = FileUtils.readFileToString(externalFile.getFile());
+            sources.add(SourceFile.fromCode("[" + name + "]", source));
+        }
+
+        Result compile = compiler.compile(EMPTY_EXTERNS, sources, options);
+        if (!compile.success)
+        {
+
+        }
+    }
+
+    public ExcludedMemeber isExcludedClass(ClassReference classReference)
+    {
+        for (ExcludedMemeber memeber : excludesClass)
+        {
+            if (memeber.isExcluded(classReference, null))
+                return memeber;
+        }
+        return null;
+    }
+
+    public ExcludedMemeber isExcludedMember(ClassReference classReference,
+            MemberReference memberReference)
+    {
+        if (memberReference instanceof FieldReference)
+        {
+            for (ExcludedMemeber memeber : excludesField)
+            {
+                if (memeber.isExcluded(classReference, memberReference))
+                    return memeber;
+            }
+        }
+        for (ExcludedMemeber memeber : excludes)
+        {
+            if (memeber.isExcluded(classReference, memberReference))
+                return memeber;
+        }
+        return null;
+    }
+
+    public static class ExcludedMemeber
+    {
+        private String className;
+        private String name;
+        private String description;
+
+        public String getClassName()
+        {
+            return className;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public String getDescription()
+        {
+            return description;
+        }
+
+        public ExcludedMemeber(String className, String name)
+        {
+            this.className = className;
+            this.name = name;
+        }
+
+        public ExcludedMemeber(String className, String name, String description)
+        {
+            this.className = className;
+            this.name = name;
+            this.description = description;
+        }
+
+        public boolean isExcluded(ClassReference classReference,
+                MemberReference memberReference)
+        {
+            if (memberReference == null)
+            {
+                return classReference.getQualifiedName().equals(className);
+            }
+            return classReference.getQualifiedName().equals(className)
+                    && memberReference.getQualifiedName().equals(name);
+        }
+
+        public void print(StringBuilder sb)
+        {
+            if (description != null)
+                sb.append("// " + description + "\n");
+            sb.append("//");
+        }
+    }
+
+    public static class ExternalFile
+    {
+        private File file;
+
+        public File getFile()
+        {
+            return file;
+        }
+
+        public ExternalFile(File file)
+        {
+            this.file = file;
+        }
+
+        public String getName()
+        {
+            return FilenameUtils.getBaseName(getFile().getAbsolutePath());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
new file mode 100644
index 0000000..afb3996
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/FunctionUtils.java
@@ -0,0 +1,124 @@
+package org.apache.flex.compiler.internal.codegen.externals.utils;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.BaseReference;
+
+import com.google.common.collect.ImmutableList;
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.Node;
+
+public class FunctionUtils
+{
+    public static String transformReturnString(BaseReference reference,
+            JSDocInfo comment)
+    {
+        StringBuilder sb = new StringBuilder();
+        ImmutableList<String> names = comment.getTemplateTypeNames();
+        if (names.size() > 0)
+        {
+            sb.append("Object");
+        }
+        else
+        {
+            String type = JSTypeUtils.toReturnTypeString(reference);
+            if (type.indexOf("|") != -1 || type.indexOf('?') != -1)
+                type = "*";
+
+            if (type.indexOf("|") != -1)
+                type = "Object /* TODO " + type + "*/";
+
+            sb.append(type);
+            return sb.toString();
+        }
+
+        return sb.toString();
+    }
+
+    public static String toPrameterString(BaseReference reference,
+            JSDocInfo comment, Node paramNode)
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append("(");
+        int index = 0;
+        int len = comment.getParameterCount();
+
+        if (len == 0)
+        {
+            len = paramNode.getChildCount();
+            // Missing JSDocInf @param tags
+            if (len > 0)
+            {
+                for (Node param : paramNode.children())
+                {
+                    sb.append(param.getString() + ":Object");
+                    if (index < len - 1)
+                        sb.append(", ");
+                    index++;
+                }
+            }
+        }
+        else
+        {
+            for (String paramName : comment.getParameterNames())
+            {
+                sb.append(toParameter(reference, comment, paramName,
+                        comment.getParameterType(paramName)));
+
+                if (index < len - 1)
+                    sb.append(", ");
+                index++;
+            }
+        }
+
+        sb.append(")");
+
+        return sb.toString();
+    }
+
+    public static String toParameter(BaseReference reference,
+            JSDocInfo comment, String paramName, JSTypeExpression parameterType)
+    {
+        if (parameterType == null)
+        {
+            return "Object /* TODO is this correct? */";
+        }
+
+        StringBuilder sb = new StringBuilder();
+
+        //JSTypeExpression parameterType = comment.getParameterType(paramName);
+
+        ImmutableList<String> names = comment.getTemplateTypeNames();
+        if (names.size() > 0)
+        {
+            sb.append(paramName);
+            sb.append(":");
+            sb.append("Object");
+        }
+        else
+        {
+            if (parameterType.isVarArgs())
+            {
+                sb.append("...rest");
+            }
+            else
+            {
+                String paramType = JSTypeUtils.toParamTypeString(reference,
+                        paramName);
+
+                sb.append(paramName);
+                sb.append(":");
+                sb.append(paramType);
+
+                if (paramType.indexOf("|") != -1)
+                    paramType = "Object /* TODO " + paramType + "*/";
+
+                if (parameterType.isOptionalArg())
+                {
+                    sb.append(" = null");
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/4ca23e3b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
new file mode 100644
index 0000000..1add10b
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/JSTypeUtils.java
@@ -0,0 +1,198 @@
+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.ConstantReference;
+
+import com.google.javascript.jscomp.AbstractCompiler;
+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 toParamTypeString(BaseReference reference,
+            String paramName)
+    {
+        String type = "Object";
+
+        JSTypeExpression paramType = reference.getComment().getParameterType(
+                paramName);
+        if (paramType != null)
+        {
+            JSType jsType = JSTypeUtils.toParamJsType(
+                    reference.getModel().getCompiler(), paramType);
+            //System.err.println(jsType);
+
+            if (jsType != null)
+            {
+                type = jsType.toString();
+
+                if (jsType.isFunctionType())
+                {
+                    return "Function /* " + type + " */";
+                }
+                else
+                {
+                    if (type.indexOf("Array<") == 0)
+                    {
+                        return "Array";
+                    }
+                }
+
+            }
+            else
+            {
+                return "Object"; // TemplateType
+            }
+        }
+
+        type = TypeUtils.transformParamType(type);
+
+        return type;
+    }
+
+    private static JSType toParamJsType(AbstractCompiler compiler,
+            JSTypeExpression typeExpression)
+    {
+        JSType jsType = typeExpression.evaluate(null,
+                compiler.getTypeRegistry());
+
+        if (jsType.isUnionType())
+        {
+            UnionType ut = (UnionType) jsType;
+            JSType jsType2 = ut.restrictByNotNullOrUndefined();
+
+            //System.err.println(jsType2);
+
+            if (!jsType2.isUnionType())
+                jsType = jsType2;
+        }
+
+        return jsType;
+    }
+
+    public static String toConstantTypeString(ConstantReference reference)
+    {
+        JSTypeExpression typeExpression = reference.getComment().getType();
+        JSType jsType = typeExpression.evaluate(null,
+                reference.getModel().getCompiler().getTypeRegistry());
+        String type = jsType.toString();
+        type = TypeUtils.transformParamType(type);
+        return type;
+    }
+
+    public static String toReturnTypeString(BaseReference reference)
+    {
+        String type = "void";
+
+        JSTypeExpression returnType = reference.getComment().getReturnType();
+        if (returnType != null)
+        {
+            JSType jsType = JSTypeUtils.toReturnJsType(
+                    reference.getModel().getCompiler(), returnType);
+            //System.err.println(jsType);
+
+            if (jsType != null)
+            {
+                type = jsType.toString();
+
+                if (type.indexOf("Array<") == 0)
+                {
+                    return "Array";
+                }
+            }
+            else
+            {
+                return "Object"; // TemplateType
+            }
+        }
+
+        type = TypeUtils.transformReturnType(type);
+
+        return type;
+    }
+
+    private static JSType toReturnJsType(AbstractCompiler compiler,
+            JSTypeExpression typeExpression)
+    {
+        JSType jsType = typeExpression.evaluate(null,
+                compiler.getTypeRegistry());
+
+        if (jsType.isUnionType())
+        {
+            UnionType ut = (UnionType) jsType;
+            JSType jsType2 = ut.restrictByNotNullOrUndefined();
+
+            if (!jsType2.isUnionType())
+                jsType = jsType2;
+        }
+
+        return jsType;
+    }
+
+    public static String toFieldString(BaseReference reference)
+    {
+        String type = "Object";
+
+        JSTypeExpression ttype = reference.getComment().getType();
+
+        if (ttype != null)
+        {
+            JSType jsType = JSTypeUtils.toTypeJsType(
+                    reference.getModel().getCompiler(), ttype);
+            //System.err.println(jsType);
+
+            if (jsType != null)
+            {
+                if (jsType.isUnionType())
+                {
+                    UnionType ut = (UnionType) jsType;
+                    JSType jsType2 = ut.restrictByNotNullOrUndefined();
+
+                    if (!jsType2.isUnionType())
+                        jsType = jsType2;
+                }
+
+                type = jsType.toString();
+
+                if (jsType.isFunctionType())
+                {
+                    return "Function /* " + type + " */";
+                }
+                else
+                {
+                    if (type.indexOf("Array<") == 0)
+                    {
+                        return "Array";
+                    }
+                }
+            }
+            else
+            {
+                return "Object"; // TemplateType
+            }
+        }
+
+        type = TypeUtils.transformType(type);
+
+        return type;
+    }
+
+    public static JSType toTypeJsType(AbstractCompiler compiler,
+            JSTypeExpression typeExpression)
+    {
+        JSType jsType = typeExpression.evaluate(null,
+                compiler.getTypeRegistry());
+
+        if (jsType.isUnionType())
+        {
+            UnionType ut = (UnionType) jsType;
+            JSType jsType2 = ut.restrictByNotNullOrUndefined();
+
+            if (!jsType2.isUnionType())
+                jsType = jsType2;
+        }
+
+        return jsType;
+    }
+}