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/11 19:49:37 UTC

[1/2] git commit: [flex-falcon] [refs/heads/develop] - Major refactor into ExternalClient. - Added config, started testing base types. - Rewrote the Memeber compiler pass to traverse Script children.

Repository: flex-falcon
Updated Branches:
  refs/heads/develop 3870092bb -> 210535099


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index ccceab0..4fa7d89 100644
--- 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
@@ -19,439 +19,242 @@
 
 package org.apache.flex.compiler.internal.codegen.externals.reference;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 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 org.apache.flex.utils.FilenameNormalization;
+import org.apache.flex.compiler.internal.codegen.externals.ExternalsClientConfig;
+import org.apache.flex.compiler.internal.codegen.externals.ExternalsClientConfig.ExcludedMemeber;
 
-import com.google.common.collect.ImmutableList;
-import com.google.javascript.jscomp.CustomPassExecutionTime;
-import com.google.javascript.jscomp.JXCompilerOptions;
+import com.google.javascript.jscomp.Compiler;
 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;
+import com.google.javascript.rhino.jstype.JSType;
 
 public class ReferenceModel
 {
-    private static final List<SourceFile> EMPTY_EXTERNS = ImmutableList.of(SourceFile.fromCode(
-            "externs", ""));
-
-    private File asRoot;
-    private File asFunctionRoot;
-    private File asConstantRoot;
-
-    private List<ExcludedMemeber> excludesClass = new ArrayList<ExcludedMemeber>();
-    private List<ExcludedMemeber> excludesField = new ArrayList<ExcludedMemeber>();
-    private List<ExcludedMemeber> excludes = new ArrayList<ExcludedMemeber>();
-    private List<ExternalFile> externals = new ArrayList<ExternalFile>();
+    private ExternalsClientConfig configuration;
+    private Compiler compiler;
 
+    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>();
 
-    private com.google.javascript.jscomp.Compiler compiler;
-
-    public void setASRoot(File file)
+    public Compiler getCompiler()
     {
-        this.asRoot = file;
-
-        asFunctionRoot = new File(asRoot.getParent(), "as_functions");
-        asConstantRoot = new File(asRoot.getParent(), "as_constants");
+        return compiler;
     }
 
-    public com.google.javascript.jscomp.Compiler getCompiler()
+    public void setCompiler(Compiler compiler)
     {
-        return compiler;
+        this.compiler = compiler;
     }
 
-    public ReferenceModel()
+    public ExternalsClientConfig getConfiguration()
     {
-        //walker = new JSBlockWalker(this);
+        return configuration;
     }
 
-    public void addExclude(String className, String name)
+    public Collection<String> getNamespaces()
     {
-        excludes.add(new ExcludedMemeber(className, name));
+        return namespaces;
     }
 
-    public void addExclude(String className, String name, String description)
+    public Collection<ClassReference> getTypedefs()
     {
-        excludes.add(new ExcludedMemeber(className, name, description));
+        return typedefs.values();
     }
 
-    public void addFieldExclude(String className, String fieldName)
+    public Collection<ClassReference> getClasses()
     {
-        excludesField.add(new ExcludedMemeber(className, fieldName, ""));
+        return classes.values();
     }
 
-    public void addClassExclude(String className)
+    public Collection<FunctionReference> getFunctions()
     {
-        excludesClass.add(new ExcludedMemeber(className, null, ""));
+        return functions.values();
     }
 
-    public void addExternal(File file) throws IOException
+    public Collection<ConstantReference> getConstants()
     {
-        if (!file.exists())
-            throw new IOException(file.getAbsolutePath() + " does not exist.");
-        externals.add(new ExternalFile(file));
+        return constants.values();
     }
 
-    public void addExternal(String externalFile) throws IOException
+    public ReferenceModel(ExternalsClientConfig config)
     {
-        addExternal(new File(FilenameNormalization.normalize(externalFile)));
+        this.configuration = config;
     }
 
-    //    public void addExternal(String name)
-    //    {
-    //        File file = new File(jsRoot, name + ".js");
-    //        externals.add(new ExternalFile(file));
-    //    }
-
-    public ClassReference getClassReference(String qualifiedName)
+    public ClassReference getClassReference(String qName)
     {
-        return classes.get(qualifiedName);
+        return classes.get(qName);
     }
 
-    public void addClass(Node node, String qualfiedName)
+    public void addNamespace(Node node, String qName)
     {
-        if (classes.containsKey(qualfiedName))
+        if (namespaces.contains(qName))
         {
             // XXX Record warning;
             return;
         }
 
-        System.out.println("Model.addClass(" + qualfiedName + ")");
+        System.out.println("Model.addNamespace(" + qName + ")");
 
-        ClassReference reference = new ClassReference(this, node, qualfiedName,
-                node.getJSDocInfo());
-        classes.put(qualfiedName, reference);
+        namespaces.add(qName);
     }
 
-    public void addInterface(Node node, String qualfiedName)
+    public void addClass(Node node, String qName)
     {
-        if (classes.containsKey(qualfiedName))
+        if (classes.containsKey(qName))
         {
             // XXX Record warning;
             return;
         }
 
-        System.out.println("Model.addInterface(" + qualfiedName + ")");
+        System.out.println("Model.addClass(" + qName + ")");
 
-        ClassReference reference = new ClassReference(this, node, qualfiedName,
+        ClassReference reference = new ClassReference(this, node, qName,
                 node.getJSDocInfo());
-        classes.put(qualfiedName, reference);
+        classes.put(qName, reference);
     }
 
-    public void addFinalClass(Node node, String qualfiedName)
+    public void addTypeDef(Node node, String qName)
     {
-        if (classes.containsKey(qualfiedName))
+        if (typedefs.containsKey(qName))
         {
             // XXX Record warning;
             return;
         }
 
-        System.out.println("Model.addFinalClass(" + qualfiedName + ")");
+        System.out.println("Model.addTypeDef(" + qName + ")");
 
-        ClassReference reference = new ClassReference(this, node, qualfiedName,
+        ClassReference reference = new ClassReference(this, node, qName,
                 node.getJSDocInfo());
-        reference.setFinal(true);
-        classes.put(qualfiedName, reference);
+        typedefs.put(qName, reference);
     }
 
-    public void addFunction(Node node, String qualfiedName)
+    public void addInterface(Node node, String qName)
     {
-        if (functions.containsKey(qualfiedName))
+        if (classes.containsKey(qName))
         {
             // 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);
+        System.out.println("Model.addInterface(" + qName + ")");
+
+        ClassReference reference = new ClassReference(this, node, qName,
+                node.getJSDocInfo());
+        classes.put(qName, reference);
     }
 
-    public void addConstant(Node node, String qualfiedName)
+    public void addFinalClass(Node node, String qName)
     {
-        if (constants.containsKey(qualfiedName))
+        if (classes.containsKey(qName))
         {
             // XXX Record warning;
             return;
         }
 
-        System.out.println("Model.addConstant(" + qualfiedName + ")");
+        System.out.println("Model.addFinalClass(" + qName + ")");
 
-        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);
+        ClassReference reference = new ClassReference(this, node, qName,
+                node.getJSDocInfo());
+        reference.setFinal(true);
+        classes.put(qName, reference);
     }
 
-    public void addStaticField(Node node, String className, String qualfiedName)
+    public void addFunction(Node node, String qName)
     {
-        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)
+        if (functions.containsKey(qName))
         {
-            classReference.addField(node, qualfiedName, comment, true);
-        }
-        else
-        {
-            System.err.println(">>>> {ReferenceModel} Class [" + className
-                    + "] not found in " + node.getSourceFileName());
+            // XXX Record warning;
+            return;
         }
-    }
 
-    //----------------------------------------------------
+        System.out.println("Model.addFunction(" + qName + ")");
+        //System.err.println(node.toStringTree());
+        FunctionReference reference = new FunctionReference(this, node, qName,
+                node.getJSDocInfo());
+        functions.put(qName, reference);
+    }
 
-    public void cleanOutput() throws IOException
+    public boolean hasConstant(String qName)
     {
-        FileUtils.deleteDirectory(asRoot);
+        return constants.containsKey(qName);
     }
 
-    public void emit() throws IOException
+    public void addConstant(Node node, String qName)
     {
-        asRoot.mkdirs();
-
-        for (Entry<String, ClassReference> set : classes.entrySet())
+        if (constants.containsKey(qName))
         {
-            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());
+            // XXX Record warning;
+            return;
         }
 
-        for (Entry<String, ClassReference> set : classes.entrySet())
-        {
-            ClassReference reference = set.getValue();
-            if (isExcludedClass(reference) != null)
-                continue;
-
-            if (reference.isInterface())
-                continue;
+        System.out.println("Model.addConstant(" + qName + ")");
 
-            StringBuilder sb = new StringBuilder();
-
-            emit(reference, sb);
-
-            File sourceFile = reference.getFile(asRoot);
-            FileUtils.write(sourceFile, sb.toString());
-        }
+        ConstantReference reference = new ConstantReference(this, node, qName,
+                node.getJSDocInfo());
+        constants.put(qName, reference);
+    }
 
-        for (Entry<String, FunctionReference> set : functions.entrySet())
+    public void addConstantType(Node node, String qName, JSType type)
+    {
+        if (constants.containsKey(qName))
         {
-            StringBuilder sb = new StringBuilder();
-
-            FunctionReference reference = set.getValue();
-            emit(reference, sb);
-
-            File sourceFile = reference.getFile(asFunctionRoot);
-            FileUtils.write(sourceFile, sb.toString());
+            // XXX Record warning;
+            return;
         }
 
-        for (Entry<String, ConstantReference> set : constants.entrySet())
-        {
-            StringBuilder sb = new StringBuilder();
-
-            ConstantReference reference = set.getValue();
-            emit(reference, sb);
+        System.out.println("Model.addConstantType(" + qName + ")");
 
-            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());
+        ConstantReference reference = new ConstantReference(this, node, qName,
+                node.getJSDocInfo(), type);
+        constants.put(qName, reference);
     }
 
-    public void emit(BaseReference reference, StringBuilder sb)
-    {
-        reference.emit(sb);
-    }
-
-    public String emit(BaseReference reference)
+    public void addField(Node node, String className, String qualfiedName)
     {
-        StringBuilder sb = new StringBuilder();
-        reference.emit(sb);
-        return sb.toString();
+        ClassReference classReference = getClassReference(className);
+        if (classReference != null)
+            classReference.addField(node, qualfiedName, node.getJSDocInfo(),
+                    false);
     }
 
-    public void compile() throws IOException
+    public void addStaticField(Node node, String className, String qualfiedName)
     {
-        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<SourceFile>();
-        for (ExternalFile externalFile : externals)
+        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)
         {
-            String name = externalFile.getName();
-            String source = FileUtils.readFileToString(externalFile.getFile());
-            sources.add(SourceFile.fromCode("[" + name + "]", source));
+            classReference.addField(node, qualfiedName, comment, true);
         }
-
-        Result compile = compiler.compile(EMPTY_EXTERNS, sources, options);
-        if (!compile.success)
+        else
         {
-
+            System.err.println(">>>> {ReferenceModel} Class [" + className
+                    + "] not found in " + node.getSourceFileName());
         }
     }
 
+    //----------------------------------------------------
+
     public ExcludedMemeber isExcludedClass(ClassReference classReference)
     {
-        for (ExcludedMemeber memeber : excludesClass)
-        {
-            if (memeber.isExcluded(classReference, null))
-                return memeber;
-        }
-        return null;
+        return getConfiguration().isExcludedClass(classReference);
     }
 
     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());
-        }
+        return getConfiguration().isExcludedMember(classReference,
+                memberReference);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index a6aebdb..815d9ee 100644
--- 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
@@ -36,6 +36,7 @@ public class JSTypeUtils
 
         JSTypeExpression paramType = reference.getComment().getParameterType(
                 paramName);
+
         if (paramType != null)
         {
             JSType jsType = JSTypeUtils.toParamJsType(


[2/2] git commit: [flex-falcon] [refs/heads/develop] - Major refactor into ExternalClient. - Added config, started testing base types. - Rewrote the Memeber compiler pass to traverse Script children.

Posted by ms...@apache.org.
Major refactor into ExternalClient.
- Added config, started testing base types.
- Rewrote the Memeber compiler pass to traverse Script children.


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

Branch: refs/heads/develop
Commit: 21053509954bf97a7714536109cd0f99bebbcc85
Parents: 3870092
Author: Michael Schmalle <ms...@apache.org>
Authored: Thu Jun 11 13:48:50 2015 -0400
Committer: Michael Schmalle <ms...@apache.org>
Committed: Thu Jun 11 13:49:22 2015 -0400

----------------------------------------------------------------------
 .../codegen/externals/ExternalsTestBase.java    |  69 ++++
 .../codegen/externals/ExternalsTestUtils.java   | 137 +++----
 .../externals/TestExternalsJSCompile.java       |  38 +-
 .../codegen/externals/TestPackageNamespace.java |  39 ++
 .../codegen/externals/TestReferenceModel.java   |  41 +-
 .../codegen/externals/TestTypeExternals.java    | 132 ++++++
 .../externals_unit_tests/constructor_members.js |  57 +++
 .../externals_unit_tests/package_namespace.js   |  48 +++
 .../externals_unit_tests/types_param.js         |  82 ++++
 .../codegen/externals/ExternalsClient.java      |  67 +++
 .../externals/ExternalsClientConfig.java        | 185 +++++++++
 .../externals/emit/ReferenceEmitter.java        | 141 +++++++
 .../externals/pass/AbstractCompilerPass.java    |  57 +++
 .../codegen/externals/pass/AddMemberPass.java   |  16 +-
 .../externals/pass/CollectTypesPass.java        | 190 ++++-----
 .../externals/pass/ReferenceCompiler.java       | 121 ++++++
 .../externals/reference/BaseReference.java      |  26 +-
 .../externals/reference/ClassReference.java     |   5 +
 .../externals/reference/ConstantReference.java  |  17 +-
 .../externals/reference/FieldReference.java     |   2 +-
 .../externals/reference/FunctionReference.java  |   2 +-
 .../externals/reference/MemberReference.java    |   3 +-
 .../externals/reference/MethodReference.java    |   2 +-
 .../externals/reference/ReferenceModel.java     | 411 +++++--------------
 .../codegen/externals/utils/JSTypeUtils.java    |   1 +
 25 files changed, 1346 insertions(+), 543 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java
new file mode 100644
index 0000000..44166ed
--- /dev/null
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestBase.java
@@ -0,0 +1,69 @@
+/*
+ *
+ *  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;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+import org.apache.flex.utils.FilenameNormalization;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+
+import com.google.javascript.jscomp.Result;
+
+public abstract class ExternalsTestBase
+{
+    private static File unitTestBaseDir = new File(
+            FilenameNormalization.normalize("test-files/externals_unit_tests"));
+
+    protected ExternalsClientConfig config;
+    protected ExternalsClient client;
+    protected ReferenceModel model;
+
+    @Before
+    public void setUp()
+    {
+        config = new ExternalsClientConfig();
+        client = new ExternalsClient(config);
+        model = client.getModel();
+    }
+
+    @After
+    public void tearDown()
+    {
+        model = null;
+    }
+
+    protected Result compile(String fileName) throws IOException
+    {
+        return compile(new File(unitTestBaseDir, fileName));
+    }
+
+    protected Result compile(File file) throws IOException
+    {
+        config.addExternal(file);
+        Result result = client.compile();
+        Assert.assertTrue(result.success);
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
index bd111b8..cd61e1f 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
@@ -22,7 +22,6 @@ package org.apache.flex.compiler.internal.codegen.externals;
 import java.io.File;
 import java.io.IOException;
 
-import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
 import org.apache.flex.utils.FilenameNormalization;
 
 public class ExternalsTestUtils
@@ -39,91 +38,91 @@ public class ExternalsTestUtils
 
     public static File AS_ROOT_DIR = new File(TEMP_DIR, "externals/as");
 
-    public static void addTestExcludesFull(ReferenceModel model)
+    public static void addTestExcludesFull(ExternalsClientConfig config)
     {
-        model.addFieldExclude("Window", "focus");
-        model.addClassExclude("controlRange");
-
-        model.addExclude("Array", "toSource");
-        model.addExclude("Date", "valueOf");
-        model.addExclude("String", "valueOf");
-
-        model.addExclude("FontFaceSet", "delete");
-
-        model.addExclude("CSSStyleDeclaration", "cssText");
-        model.addExclude("CSSStyleRule", "style");
-        model.addExclude("CSSFontFaceRule", "style");
-        model.addExclude("CSSPageRule", "style");
-
-        model.addExclude("Generator", "throw");
-        model.addExclude("Generator", "return");
-        model.addExclude("HTMLMenuItemElement", "default");
-        model.addExclude("MessageEvent", "data"); // TODO returns T
-        model.addExclude("MessageEvent", "initMessageEventNS"); // TODO param T
-        model.addExclude("MessageEvent", "initMessageEvent"); // TODO param T
-        model.addExclude("MessageEvent", "default");
-        model.addExclude("Object", "is");
-        model.addExclude("Promise", "catch");
-
-        model.addExclude("IDBCursor", "continue");
-        model.addExclude("IDBCursor", "delete");
-        model.addExclude("IDBObjectStore", "delete");
+        config.addFieldExclude("Window", "focus");
+        config.addClassExclude("controlRange");
+
+        config.addExclude("Array", "toSource");
+        config.addExclude("Date", "valueOf");
+        config.addExclude("String", "valueOf");
+
+        config.addExclude("FontFaceSet", "delete");
+
+        config.addExclude("CSSStyleDeclaration", "cssText");
+        config.addExclude("CSSStyleRule", "style");
+        config.addExclude("CSSFontFaceRule", "style");
+        config.addExclude("CSSPageRule", "style");
+
+        config.addExclude("Generator", "throw");
+        config.addExclude("Generator", "return");
+        config.addExclude("HTMLMenuItemElement", "default");
+        config.addExclude("MessageEvent", "data"); // TODO returns T
+        config.addExclude("MessageEvent", "initMessageEventNS"); // TODO param T
+        config.addExclude("MessageEvent", "initMessageEvent"); // TODO param T
+        config.addExclude("MessageEvent", "default");
+        config.addExclude("Object", "is");
+        config.addExclude("Promise", "catch");
+
+        config.addExclude("IDBCursor", "continue");
+        config.addExclude("IDBCursor", "delete");
+        config.addExclude("IDBObjectStore", "delete");
     }
 
-    public static void addTestExternalsFull(ReferenceModel model)
+    public static void addTestExternalsFull(ExternalsClientConfig config)
             throws IOException
     {
         String coreRoot = ExternalsTestUtils.EXTERNAL_JS_DIR.getAbsolutePath();
 
-        model.addExternal(ExternalsTestUtils.MISSING_JS_FILE);
-        model.addExternal(coreRoot + "/es3.js");
-        model.addExternal(coreRoot + "/es5.js");
-        model.addExternal(coreRoot + "/es6.js");
-
-        model.addExternal(coreRoot + "/w3c_anim_timing.js");
-        model.addExternal(coreRoot + "/w3c_audio.js");
-        model.addExternal(coreRoot + "/w3c_batterystatus.js");
-        model.addExternal(coreRoot + "/w3c_css.js");
-        model.addExternal(coreRoot + "/w3c_css3d.js");
-        model.addExternal(coreRoot + "/w3c_device_sensor_event.js");
-        model.addExternal(coreRoot + "/w3c_dom1.js");
-        model.addExternal(coreRoot + "/w3c_dom2.js");
-        model.addExternal(coreRoot + "/w3c_dom3.js");
-        model.addExternal(coreRoot + "/w3c_elementtraversal.js");
-        model.addExternal(coreRoot + "/w3c_encoding.js");
-        model.addExternal(coreRoot + "/w3c_event.js");
-        model.addExternal(coreRoot + "/w3c_event3.js");
-        model.addExternal(coreRoot + "/w3c_geolocation.js");
-        model.addExternal(coreRoot + "/w3c_indexeddb.js");
-        model.addExternal(coreRoot + "/w3c_navigation_timing.js");
-        model.addExternal(coreRoot + "/w3c_range.js");
-        model.addExternal(coreRoot + "/w3c_rtc.js");
-        model.addExternal(coreRoot + "/w3c_selectors.js");
+        config.addExternal(ExternalsTestUtils.MISSING_JS_FILE);
+        config.addExternal(coreRoot + "/es3.js");
+        config.addExternal(coreRoot + "/es5.js");
+        config.addExternal(coreRoot + "/es6.js");
+
+        config.addExternal(coreRoot + "/w3c_anim_timing.js");
+        config.addExternal(coreRoot + "/w3c_audio.js");
+        config.addExternal(coreRoot + "/w3c_batterystatus.js");
+        config.addExternal(coreRoot + "/w3c_css.js");
+        config.addExternal(coreRoot + "/w3c_css3d.js");
+        config.addExternal(coreRoot + "/w3c_device_sensor_event.js");
+        config.addExternal(coreRoot + "/w3c_dom1.js");
+        config.addExternal(coreRoot + "/w3c_dom2.js");
+        config.addExternal(coreRoot + "/w3c_dom3.js");
+        config.addExternal(coreRoot + "/w3c_elementtraversal.js");
+        config.addExternal(coreRoot + "/w3c_encoding.js");
+        config.addExternal(coreRoot + "/w3c_event.js");
+        config.addExternal(coreRoot + "/w3c_event3.js");
+        config.addExternal(coreRoot + "/w3c_geolocation.js");
+        config.addExternal(coreRoot + "/w3c_indexeddb.js");
+        config.addExternal(coreRoot + "/w3c_navigation_timing.js");
+        config.addExternal(coreRoot + "/w3c_range.js");
+        config.addExternal(coreRoot + "/w3c_rtc.js");
+        config.addExternal(coreRoot + "/w3c_selectors.js");
         //model.addExternal(coreRoot + "/w3c_serviceworker.js");
         //model.addExternal(coreRoot + "/w3c_webcrypto.js");
-        model.addExternal(coreRoot + "/w3c_xml.js");
+        config.addExternal(coreRoot + "/w3c_xml.js");
 
         //model.addExternal(coreRoot + "/fetchapi");
 
-        model.addExternal(coreRoot + "/window.js");
+        config.addExternal(coreRoot + "/window.js");
 
-        model.addExternal(coreRoot + "/ie_dom.js");
-        model.addExternal(coreRoot + "/gecko_dom.js");
+        config.addExternal(coreRoot + "/ie_dom.js");
+        config.addExternal(coreRoot + "/gecko_dom.js");
 
-        model.addExternal(coreRoot + "/webkit_css.js");
-        model.addExternal(coreRoot + "/webkit_dom.js");
-        model.addExternal(coreRoot + "/webkit_event.js");
+        config.addExternal(coreRoot + "/webkit_css.js");
+        config.addExternal(coreRoot + "/webkit_dom.js");
+        config.addExternal(coreRoot + "/webkit_event.js");
         //model.addExternal(coreRoot + "/webkit_notifications.js");
 
-        model.addExternal(coreRoot + "/iphone.js");
-        model.addExternal(coreRoot + "/chrome.js");
-        model.addExternal(coreRoot + "/flash.js");
+        config.addExternal(coreRoot + "/iphone.js");
+        config.addExternal(coreRoot + "/chrome.js");
+        config.addExternal(coreRoot + "/flash.js");
 
-        model.addExternal(coreRoot + "/page_visibility.js");
-        model.addExternal(coreRoot + "/fileapi.js");
-        model.addExternal(coreRoot + "/html5.js");
+        config.addExternal(coreRoot + "/page_visibility.js");
+        config.addExternal(coreRoot + "/fileapi.js");
+        config.addExternal(coreRoot + "/html5.js");
 
-        model.addExternal(coreRoot + "/webgl.js");
-        model.addExternal(coreRoot + "/webstorage.js");
+        config.addExternal(coreRoot + "/webgl.js");
+        config.addExternal(coreRoot + "/webstorage.js");
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java
index a868ab8..6c46a07 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternalsJSCompile.java
@@ -33,7 +33,6 @@ import org.apache.flex.compiler.clients.COMPC;
 import org.apache.flex.compiler.codegen.as.IASEmitter;
 import org.apache.flex.compiler.config.Configurator;
 import org.apache.flex.compiler.internal.codegen.as.ASFilterWriter;
-import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
 import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
 import org.apache.flex.compiler.internal.projects.FlexJSProject;
 import org.apache.flex.compiler.internal.projects.FlexProjectConfigurator;
@@ -64,8 +63,6 @@ public class TestExternalsJSCompile
     private static File jsSWCFile = new File(
             FilenameNormalization.normalize("temp/externals/bin/JS.swc"));
 
-    private ReferenceModel model;
-
     protected static Workspace workspace = new Workspace();
     protected FlexJSProject project;
     private ArrayList<ICompilerProblem> errors;
@@ -78,11 +75,16 @@ public class TestExternalsJSCompile
     private ArrayList<File> sourcePaths;
     private ArrayList<File> libraries;
 
+    private ExternalsClient client;
+
+    private ExternalsClientConfig config;
+
     @Before
     public void setUp()
     {
         backend = new FlexJSBackend();
-        model = new ReferenceModel();
+        config = new ExternalsClientConfig();
+        client = new ExternalsClient(config);
 
         if (project == null)
             project = new FlexJSProject(workspace);
@@ -103,20 +105,20 @@ public class TestExternalsJSCompile
     @After
     public void tearDown()
     {
-        model = null;
+        client = null;
     }
 
     @Test
     public void test_full_compile() throws IOException
     {
-        model.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+        config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
 
-        ExternalsTestUtils.addTestExcludesFull(model);
-        ExternalsTestUtils.addTestExternalsFull(model);
+        ExternalsTestUtils.addTestExcludesFull(config);
+        ExternalsTestUtils.addTestExternalsFull(config);
 
-        model.cleanOutput();
-        model.compile();
-        model.emit();
+        client.cleanOutput();
+        client.compile();
+        client.emit();
 
         compileSWC();
         assertTrue(jsSWCFile.exists());
@@ -223,18 +225,24 @@ public class TestExternalsJSCompile
     {
         arguments.setOutput(jsSWCFile.getAbsolutePath());
 
-        File root = ExternalsTestUtils.AS_ROOT_DIR.getParentFile();
-        File classes = new File(root, "as");
-        File constants = new File(root, "as_constants");
-        File functions = new File(root, "as_functions");
+        File root = ExternalsTestUtils.AS_ROOT_DIR;
+        File classes = new File(root, "classes");
+        File interfaces = new File(root, "interfaces");
+        File constants = new File(root, "constants");
+        File functions = new File(root, "functions");
+        File typedefs = new File(root, "typedefs");
 
         arguments.addSourcepath(classes.getAbsolutePath());
+        arguments.addSourcepath(interfaces.getAbsolutePath());
         arguments.addSourcepath(constants.getAbsolutePath());
         arguments.addSourcepath(functions.getAbsolutePath());
+        arguments.addSourcepath(typedefs.getAbsolutePath());
 
         arguments.addIncludedSources(classes.getAbsolutePath());
+        arguments.addIncludedSources(interfaces.getAbsolutePath());
         arguments.addIncludedSources(constants.getAbsolutePath());
         arguments.addIncludedSources(functions.getAbsolutePath());
+        arguments.addIncludedSources(typedefs.getAbsolutePath());
     }
 
     protected File getOutputClassFile(String qname, File outputFolder)

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java
new file mode 100644
index 0000000..2977ece
--- /dev/null
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestPackageNamespace.java
@@ -0,0 +1,39 @@
+package org.apache.flex.compiler.internal.codegen.externals;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+public class TestPackageNamespace extends ExternalsTestBase
+{
+    @Test
+    public void test_pacakge1() throws IOException
+    {
+        compile("package_namespace.js");
+
+        ClassReference reference1 = model.getClassReference("Foo");
+        ClassReference reference2 = model.getClassReference("foo.bar.Baz");
+        ClassReference reference3 = model.getClassReference("Goo");
+
+        assertFalse(reference1.isQualifiedName());
+        assertEquals("Foo", reference1.getBaseName());
+        assertEquals("", reference1.getPackageName());
+        assertEquals("Foo", reference1.getQualifiedName());
+
+        assertTrue(reference2.isQualifiedName());
+        assertEquals("Baz", reference2.getBaseName());
+        assertEquals("foo.bar", reference2.getPackageName());
+        assertEquals("foo.bar.Baz", reference2.getQualifiedName());
+
+        assertFalse(reference3.isQualifiedName());
+        assertEquals("Goo", reference3.getBaseName());
+        assertEquals("", reference3.getPackageName());
+        assertEquals("Goo", reference3.getQualifiedName());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestReferenceModel.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestReferenceModel.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestReferenceModel.java
index e83979e..107b18c 100644
--- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestReferenceModel.java
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestReferenceModel.java
@@ -25,49 +25,34 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.io.IOException;
 
-import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 
-public class TestReferenceModel
+public class TestReferenceModel extends ExternalsTestBase
 {
-    private ReferenceModel model;
-
-    @Before
-    public void setUp()
-    {
-        model = new ReferenceModel();
-    }
-
-    @After
-    public void tearDown()
-    {
-        model = null;
-    }
-
     @Test
     public void test_full_compile() throws IOException
     {
-        model.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
+        config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR);
 
-        ExternalsTestUtils.addTestExcludesFull(model);
-        ExternalsTestUtils.addTestExternalsFull(model);
+        ExternalsTestUtils.addTestExcludesFull(config);
+        ExternalsTestUtils.addTestExternalsFull(config);
 
-        model.cleanOutput();
+        client.cleanOutput();
 
         // TODO (mschmalle) this root needs to create 'classes' in the root and move 
         // constants and functions up into it aside classes
         assertFalse(ExternalsTestUtils.AS_ROOT_DIR.exists());
 
         // TODO (mschmalle) get warnings and errors from the closure compiler
-        model.compile();
+        client.compile();
 
-        model.emit();
+        client.emit();
 
-        File root = ExternalsTestUtils.AS_ROOT_DIR.getParentFile();
-        assertTrue(new File(root, "as").exists());
-        assertTrue(new File(root, "as_constants").exists());
-        assertTrue(new File(root, "as_functions").exists());
+        File root = ExternalsTestUtils.AS_ROOT_DIR;
+        assertTrue(new File(root, "classes").exists());
+        assertTrue(new File(root, "interfaces").exists());
+        assertTrue(new File(root, "constants").exists());
+        assertTrue(new File(root, "functions").exists());
+        assertTrue(new File(root, "typedefs").exists());
     }
 }

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestTypeExternals.java
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestTypeExternals.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestTypeExternals.java
new file mode 100644
index 0000000..c4a56fc
--- /dev/null
+++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestTypeExternals.java
@@ -0,0 +1,132 @@
+/*
+ *
+ *  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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.junit.Test;
+
+import com.google.javascript.rhino.JSDocInfo;
+import com.google.javascript.rhino.JSTypeExpression;
+import com.google.javascript.rhino.jstype.JSType;
+import com.google.javascript.rhino.jstype.NamedType;
+
+public class TestTypeExternals extends ExternalsTestBase
+{
+    @Test
+    public void test_constructor() throws IOException
+    {
+        compile("constructor_members.js");
+
+        ClassReference reference = model.getClassReference("Foo");
+        assertTrue(reference.hasField("bar"));
+        assertFalse(reference.hasField("foo"));
+        assertTrue(reference.hasMethod("method1"));
+        assertTrue(reference.hasMethod("method2"));
+        assertTrue(model.hasConstant("bar"));
+    }
+
+    @SuppressWarnings("unused")
+    @Test
+    public void test_types() throws IOException
+    {
+        compile("types_param.js");
+
+        ClassReference reference = model.getClassReference("Foo");
+
+        JSType jsType1 = getJSType("test1", "arg1");
+        JSType jsType2 = getJSType("test2", "arg1");
+        JSType jsType3 = getJSType("test3", "arg1");
+        JSType jsType4 = getJSType("test4", "arg1");
+        JSType jsType5 = getJSType("test5", "arg1");
+        JSType jsType6 = getJSType("test6", "arg1");
+
+        assertTrue(jsType1.isString());
+        assertTrue(jsType2.isUnionType());
+        assertTrue(jsType3.isRecordType());
+        assertTrue(jsType4.isUnionType());
+        assertTrue(jsType5.isInstanceType());
+        assertTrue(jsType6.isFunctionType());
+
+        assertEquals("String", toParamTypeString(jsType1));
+        assertEquals("foo.bar.Baz", toParamTypeString(jsType2));
+        assertEquals("Object /* {myNum: number, myObject: ?} */",
+                toParamTypeString(jsType3));
+        assertEquals("Number", toParamTypeString(jsType4));
+        assertEquals("Object", toParamTypeString(jsType5));
+        assertEquals("Function /* function (string, boolean): ? */",
+                toParamTypeString(jsType6));
+    }
+
+    public String toParamTypeString(JSType jsType)
+    {
+        String result = "";
+        if (jsType instanceof NamedType)
+        {
+            NamedType nt = (NamedType) jsType;
+            return nt.toAnnotationString();
+        }
+        else if (jsType.isString())
+        {
+            return "String";
+        }
+        else if (jsType.isBooleanObjectType())
+        {
+            return "Boolean";
+        }
+        else if (jsType.isNumber())
+        {
+            return "Number";
+        }
+        else if (jsType.isUnionType())
+        {
+            JSType collapseUnion = jsType.restrictByNotNullOrUndefined();
+            return toParamTypeString(collapseUnion);
+        }
+        else if (jsType.isRecordType())
+        {
+            return "Object /* " + jsType.toAnnotationString() + " */";
+        }
+        else if (jsType.isInstanceType())
+        {
+            return jsType.toAnnotationString();
+        }
+        else if (jsType.isFunctionType())
+        {
+            return "Function /* " + jsType.toAnnotationString() + " */";
+        }
+
+        return result;
+    }
+
+    private JSType getJSType(String methodName, String paramName)
+    {
+        JSDocInfo comment = model.getClassReference("Foo").getMethod(methodName).getComment();
+        JSTypeExpression parameterType = comment.getParameterType("arg1");
+        JSType jsType = parameterType.evaluate(null,
+                model.getCompiler().getTypeRegistry());
+        return jsType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/test-files/externals_unit_tests/constructor_members.js
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/test-files/externals_unit_tests/constructor_members.js b/compiler.jx.tests/test-files/externals_unit_tests/constructor_members.js
new file mode 100644
index 0000000..fef6730
--- /dev/null
+++ b/compiler.jx.tests/test-files/externals_unit_tests/constructor_members.js
@@ -0,0 +1,57 @@
+/*
+ *
+ *  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.
+ *
+ */
+
+// define class
+/**
+ * @constructor
+ * @param {number} y
+ * @param {*=} opt_separator
+ * @param {...*} var_args
+ */
+function Foo(arg1, opt_arg2, var_args) {}
+
+// property
+/**
+ * @type {Function}
+ */
+Foo.prototype.bar;
+
+// global variable instance
+/**
+ * @type {!Foo}
+ */
+var foo;
+
+// method with arg and no return
+/**
+ * @param {string} arg1
+ */
+Foo.prototype.method1 = function(arg1) {};
+
+// method with arg and return
+/**
+ * @param {string} arg1
+ * @return {boolean}
+ */
+Foo.prototype.method2 = function(arg1) {};
+
+/**
+ * @const
+ */
+var bar;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/test-files/externals_unit_tests/package_namespace.js
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/test-files/externals_unit_tests/package_namespace.js b/compiler.jx.tests/test-files/externals_unit_tests/package_namespace.js
new file mode 100644
index 0000000..e4048e9
--- /dev/null
+++ b/compiler.jx.tests/test-files/externals_unit_tests/package_namespace.js
@@ -0,0 +1,48 @@
+/*
+ *
+ *  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.
+ *
+ */
+
+/**
+ * @constructor
+ */
+Foo = function () {};
+
+/**
+ * @const
+ */
+var foo = {};
+
+/**
+ * @const
+ */
+foo.bar = {};
+
+ /**
+  * @constructor
+  */
+foo.bar.Baz = function () {};
+
+/**
+ * @constructor
+ */
+function Goo () {}
+
+/**
+ * @typedef {Foo}
+ */
+var ATypeDef;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx.tests/test-files/externals_unit_tests/types_param.js
----------------------------------------------------------------------
diff --git a/compiler.jx.tests/test-files/externals_unit_tests/types_param.js b/compiler.jx.tests/test-files/externals_unit_tests/types_param.js
new file mode 100644
index 0000000..76cfe03
--- /dev/null
+++ b/compiler.jx.tests/test-files/externals_unit_tests/types_param.js
@@ -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.
+ *
+ */
+
+ 
+/**
+ * @const
+ */
+var foo = {};
+
+/**
+ * @const
+ */
+foo.bar = {};
+
+ /**
+  * @constructor
+  */
+foo.bar.Baz = function () {};
+ 
+ /**
+  * @constructor
+  */
+function Foo () {}
+
+/**
+ * @param {string} arg1
+ */
+Foo.test1 = function (arg1) {};
+
+/**
+ * @param {foo.bar.Baz} arg1
+ */
+Foo.test2 = function (arg1) {};
+
+/**
+ * @param {{myNum: number, myObject}} arg1
+ */
+Foo.test3 = function (arg1) {};
+
+/**
+ * @param {?number} arg1
+ */
+Foo.test4 = function (arg1) {};
+
+/**
+ * @param {!Object} arg1
+ */
+Foo.test5 = function (arg1) {};
+
+/**
+ * @param {function(string, boolean)} arg1
+ */
+Foo.test6 = function (arg1) {};
+
+
+
+
+
+
+
+
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClient.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClient.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClient.java
new file mode 100644
index 0000000..9fa5348
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClient.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.externals;
+
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.flex.compiler.internal.codegen.externals.emit.ReferenceEmitter;
+import org.apache.flex.compiler.internal.codegen.externals.pass.ReferenceCompiler;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.javascript.jscomp.Result;
+
+public class ExternalsClient
+{
+    private ExternalsClientConfig configuration;
+    private ReferenceModel model;
+    private ReferenceCompiler compiler;
+    private ReferenceEmitter emitter;
+
+    public ReferenceModel getModel()
+    {
+        return model;
+    }
+
+    public ExternalsClient(ExternalsClientConfig config)
+    {
+        this.configuration = config;
+
+        model = new ReferenceModel(config);
+        compiler = new ReferenceCompiler(model);
+        emitter = new ReferenceEmitter(model);
+    }
+
+    public void cleanOutput() throws IOException
+    {
+        FileUtils.deleteDirectory(configuration.getAsRoot());
+    }
+
+    public void emit() throws IOException
+    {
+        emitter.emit();
+    }
+
+    public Result compile() throws IOException
+    {
+        return compiler.compile();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClientConfig.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClientConfig.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClientConfig.java
new file mode 100644
index 0000000..1d64449
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/ExternalsClientConfig.java
@@ -0,0 +1,185 @@
+/*
+ *
+ *  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;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.flex.compiler.internal.codegen.externals.pass.ReferenceCompiler.ExternalFile;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.FieldReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.MemberReference;
+import org.apache.flex.utils.FilenameNormalization;
+
+public class ExternalsClientConfig
+{
+    private File asRoot;
+
+    private File asClassRoot;
+    private File asInterfaceRoot;
+    private File asFunctionRoot;
+    private File asConstantRoot;
+    private File asTypeDefRoot;
+
+    private List<ExternalFile> externals = new ArrayList<ExternalFile>();
+
+    private List<ExcludedMemeber> excludesClass = new ArrayList<ExcludedMemeber>();
+    private List<ExcludedMemeber> excludesField = new ArrayList<ExcludedMemeber>();
+    private List<ExcludedMemeber> excludes = new ArrayList<ExcludedMemeber>();
+
+    public Collection<ExternalFile> getExternals()
+    {
+        return externals;
+    }
+
+    public File getAsRoot()
+    {
+        return asRoot;
+    }
+
+    public void setASRoot(File file)
+    {
+        this.asRoot = file;
+
+        asClassRoot = new File(asRoot.getParent(), "as_functions");
+        asInterfaceRoot = new File(asRoot.getParent(), "as_interfaces");
+        asFunctionRoot = new File(asRoot.getParent(), "as_functions");
+        asConstantRoot = new File(asRoot.getParent(), "as_constants");
+        asTypeDefRoot = new File(asRoot.getParent(), "as_typedefs");
+    }
+
+    public void addExternal(File file) throws IOException
+    {
+        if (!file.exists())
+            throw new IOException(file.getAbsolutePath() + " does not exist.");
+        externals.add(new ExternalFile(file));
+    }
+
+    public void addExternal(String externalFile) throws IOException
+    {
+        addExternal(new File(FilenameNormalization.normalize(externalFile)));
+    }
+
+    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 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 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("//");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java
new file mode 100644
index 0000000..308c0d4
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/emit/ReferenceEmitter.java
@@ -0,0 +1,141 @@
+/*
+ *
+ *  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.emit;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+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.FunctionReference;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+public class ReferenceEmitter
+{
+    private ReferenceModel model;
+
+    public ReferenceEmitter(ReferenceModel model)
+    {
+        this.model = model;
+    }
+
+    public void emit() throws IOException
+    {
+        final File asRoot = model.getConfiguration().getAsRoot();
+        asRoot.mkdirs();
+
+        File asClassRoot = new File(asRoot, "classes");
+        File asInterfacesRoot = new File(asRoot, "interfaces");
+        File asFunctionRoot = new File(asRoot, "functions");
+        File asConstantRoot = new File(asRoot, "constants");
+        File asTypeDefRoot = new File(asRoot, "typedefs");
+
+        for (ClassReference reference : model.getClasses())
+        {
+            if (model.isExcludedClass(reference) != null)
+                continue;
+
+            if (reference.isInterface())
+                continue;
+
+            StringBuilder sb = new StringBuilder();
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asClassRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        for (ClassReference reference : model.getClasses())
+        {
+            StringBuilder sb = new StringBuilder();
+
+            if (model.isExcludedClass(reference) != null)
+                continue;
+
+            if (!reference.isInterface())
+                continue;
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asInterfacesRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        // TODO figure out how to resolve/emit @typedef
+        for (ClassReference reference : model.getTypedefs())
+        {
+            if (model.isExcludedClass(reference) != null)
+                continue;
+
+            StringBuilder sb = new StringBuilder();
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asTypeDefRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        for (FunctionReference reference : model.getFunctions())
+        {
+            StringBuilder sb = new StringBuilder();
+
+            emit(reference, sb);
+
+            File sourceFile = reference.getFile(asFunctionRoot);
+            FileUtils.write(sourceFile, sb.toString());
+        }
+
+        for (ConstantReference reference : model.getConstants())
+        {
+            StringBuilder sb = new StringBuilder();
+
+            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();
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java
new file mode 100644
index 0000000..9253f29
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AbstractCompilerPass.java
@@ -0,0 +1,57 @@
+/*
+ *
+ *  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.Node;
+
+public abstract class AbstractCompilerPass implements CompilerPass, Callback
+{
+    protected ReferenceModel model;
+    protected AbstractCompiler compiler;
+
+    public AbstractCompilerPass(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);
+    }
+
+    protected void log(String message)
+    {
+        System.out.println(message);
+    }
+
+    protected void err(String message)
+    {
+        System.err.println(message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 9df1fb3..18b65be 100644
--- 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
@@ -23,30 +23,18 @@ import org.apache.flex.compiler.internal.codegen.externals.reference.ClassRefere
 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
+public class AddMemberPass extends AbstractCompilerPass
 {
-    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);
+        super(model, compiler);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 9a20c54..d29d9dd 100644
--- 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
@@ -22,165 +22,145 @@ 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
+public class CollectTypesPass extends AbstractCompilerPass
 {
-    protected AbstractCompiler compiler;
-    private ReferenceModel model;
-
     public CollectTypesPass(ReferenceModel model, AbstractCompiler compiler)
     {
-        this.model = model;
-        this.compiler = compiler;
+        super(model, compiler);
     }
 
     @Override
     public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n,
             Node parent)
     {
-        return true;
+        return n.isBlock() || n.isScript();
     }
 
     @Override
     public void visit(NodeTraversal t, Node n, Node parent)
     {
-        JSDocInfo jsDoc = n.getJSDocInfo();
-        if (jsDoc != null)
+
+        for (Node child : n.children())
         {
-            if (n.isVar())
+            //System.out.println("==================================");
+            //System.out.println(child.toStringTree());
+
+            if (child.isVar())
             {
-                visitVar(t, n, jsDoc);
+                visitVar(child);
             }
-            else if (n.isFunction())
+            else if (child.isFunction())
             {
-                visitFunction(t, n, jsDoc);
+                visitFunction(child);
             }
-            else if (n.isAssign())
+            else if (child.isExprResult())
             {
-                if (n.getFirstChild().isGetProp()
-                        && n.getChildAtIndex(1).isFunction())
-                {
-                    // instance or static method
-                    visitMethod(t, n, jsDoc);
-                }
+                visitExprResult(child);
             }
-
         }
-
     }
 
-    private void visitVar(NodeTraversal t, Node n, JSDocInfo jsDoc)
+    private void visitExprResult(Node child)
     {
+        JSDocInfo comment = null;
 
-        Node first = n.getFirstChild();
-        if (first.isName())
+        Node container = child.getFirstChild();
+        if (container.isAssign())
         {
-            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())
+            comment = container.getJSDocInfo();
+
+            Node left = container.getFirstChild();
+            Node right = container.getLastChild();
+
+            if (left.isName() && right.isFunction())
             {
-                /*
-                 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())
+                if (comment.isConstructor() || comment.isInterface())
                 {
-                    model.addClass(n, name.getString());
+                    // Foo = function () {};
+                    model.addClass(container, left.getString());
                 }
-                //System.err.println(n.toStringTree());
+
             }
-            else
+            else if (left.isGetProp() && right.isFunction())
             {
-                if (jsDoc.isConstant())
+                boolean isConstructor = comment != null
+                        && (comment.isConstructor() || comment.isInterface());
+                // foo.bar.Baz = function () {};
+                if (isConstructor)
                 {
-                    // * @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);
+                    model.addClass(container, left.getQualifiedName());
                 }
+                //    System.out.println(child.toStringTree());
             }
         }
-
     }
 
-    private void visitFunction(NodeTraversal t, Node n, JSDocInfo jsDoc)
+    private void visitFunction(Node child)
     {
-        if (jsDoc.isConstructor())
-        {
-            Node name = n.getChildAtIndex(0);
-            //System.out.println("Class " + name.getString());
-            //System.out.println(n.toStringTree());
+        JSDocInfo comment = child.getJSDocInfo();
 
-            model.addClass(n, name.getQualifiedName());
-        }
-        else if (jsDoc.isInterface())
-        {
-            Node name = n.getChildAtIndex(0);
-            //System.out.println("Interface " + name.getString());
+        boolean isConstructor = comment != null
+                && (comment.isConstructor() || comment.isInterface());
 
-            model.addInterface(n, name.getQualifiedName());
+        if (isConstructor)
+        {
+            // function Goo () {};
+            model.addClass(child, child.getFirstChild().getString());
         }
         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());
+            model.addFunction(child, child.getFirstChild().getString());
         }
     }
 
-    private void visitMethod(NodeTraversal t, Node n, JSDocInfo jsDoc)
+    private void visitVar(Node child)
     {
+        JSDocInfo comment = child.getJSDocInfo();
 
-    }
+        Node first = child.getFirstChild();
+        if (first.isName())
+        {
+            Node subFirst = first.getFirstChild();
+            if (subFirst != null && subFirst.isObjectLit())
+            {
+                //System.out.println(first.getFirstChild().toStringTree());
+                //log("Encountered namespace [" + first.getQualifiedName() + "]");
+                model.addNamespace(child, first.getQualifiedName());
+            }
+            else if (subFirst != null && subFirst.isFunction())
+            {
+                boolean isConstructor = comment != null
+                        && (comment.isConstructor() || comment.isInterface());
+                // foo.bar.Baz = function () {};
+                if (isConstructor)
+                {
+                    model.addClass(child, first.getString());
+                }
+            }
+            else
+            {
+                boolean isConstructor = comment != null
+                        && (comment.getTypedefType() != null);
+                // * @typedef
+                // var foo;
+                if (isConstructor)
+                {
+                    // model.addClass(child, first.getString());
+                    model.addTypeDef(child, first.getString());
+                }
+                else if (comment != null && comment.isConstant())
+                {
+                    System.out.println(child.toStringTree());
+                    model.addConstant(child, first.getString());
+                }
+                //log(child.toStringTree());
+            }
+        }
 
-    @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/21053509/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/ReferenceCompiler.java
----------------------------------------------------------------------
diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/ReferenceCompiler.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/ReferenceCompiler.java
new file mode 100644
index 0000000..769d429
--- /dev/null
+++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/ReferenceCompiler.java
@@ -0,0 +1,121 @@
+/*
+ *
+ *  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 java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel;
+
+import com.google.common.collect.ImmutableList;
+import com.google.javascript.jscomp.Compiler;
+import com.google.javascript.jscomp.CustomPassExecutionTime;
+import com.google.javascript.jscomp.JXCompilerOptions;
+import com.google.javascript.jscomp.Result;
+import com.google.javascript.jscomp.SourceFile;
+
+public class ReferenceCompiler
+{
+    private static final List<SourceFile> EMPTY_EXTERNS = ImmutableList.of(SourceFile.fromCode(
+            "externs", ""));
+
+    private ReferenceModel model;
+
+    private Compiler compiler;
+    private JXCompilerOptions options;
+
+    public ReferenceCompiler(ReferenceModel model)
+    {
+        this.model = model;
+
+        initializeCompiler();
+    }
+
+    private void initializeCompiler()
+    {
+        compiler = new Compiler();
+
+        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);
+
+        options.addCustomPass(CustomPassExecutionTime.BEFORE_OPTIMIZATIONS,
+                new CollectTypesPass(model, compiler));
+        options.addCustomPass(CustomPassExecutionTime.BEFORE_OPTIMIZATIONS,
+                new AddMemberPass(model, compiler));
+
+        //compiler.setErrorManager(testErrorManager);
+        compiler.initOptions(options);
+
+        model.setCompiler(compiler);
+    }
+
+    public Result compile() throws IOException
+    {
+        //Node script = compiler.parse(SourceFile.fromCode("[test]", source));
+
+        List<SourceFile> sources = new ArrayList<SourceFile>();
+        for (ExternalFile externalFile : model.getConfiguration().getExternals())
+        {
+            String name = externalFile.getName();
+            String source = FileUtils.readFileToString(externalFile.getFile());
+            sources.add(SourceFile.fromCode("[" + name + "]", source));
+        }
+
+        Result result = compiler.compile(EMPTY_EXTERNS, sources, options);
+        if (!result.success)
+        {
+
+        }
+
+        return result;
+    }
+
+    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/21053509/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
index 2b235ef..36b7a06 100644
--- 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
@@ -21,8 +21,9 @@ 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.ExternalsClientConfig.ExcludedMemeber;
 
+import com.google.javascript.jscomp.Compiler;
 import com.google.javascript.rhino.JSDocInfo;
 import com.google.javascript.rhino.JSDocInfo.Marker;
 import com.google.javascript.rhino.JSDocInfo.StringPosition;
@@ -57,11 +58,29 @@ public abstract class BaseReference
         // return FilenameUtils.getBaseName(currentFile.getAbsolutePath());
     }
 
+    public String getBaseName()
+    {
+        return qualfiedName.substring(qualfiedName.lastIndexOf('.') + 1);
+    }
+
+    public String getPackageName()
+    {
+        int end = qualfiedName.lastIndexOf('.');
+        if (end == -1)
+            return "";
+        return qualfiedName.substring(0, end);
+    }
+
     public String getQualifiedName()
     {
         return qualfiedName;
     }
 
+    public final boolean isQualifiedName()
+    {
+        return qualfiedName.indexOf('.') != -1;
+    }
+
     public Node getNode()
     {
         return node;
@@ -82,6 +101,11 @@ public abstract class BaseReference
         return comment;
     }
 
+    public Compiler getCompiler()
+    {
+        return model.getCompiler();
+    }
+
     public ReferenceModel getModel()
     {
         return model;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 6965f6e..631202b 100644
--- 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
@@ -51,6 +51,11 @@ public class ClassReference extends BaseReference
         return methods;
     }
 
+    public MethodReference getMethod(String name)
+    {
+        return methods.get(name);
+    }
+
     public boolean isFinal()
     {
         return isFinal;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 20c09cd..62a3fab 100644
--- 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
@@ -25,14 +25,25 @@ import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils;
 
 import com.google.javascript.rhino.JSDocInfo;
 import com.google.javascript.rhino.Node;
+import com.google.javascript.rhino.jstype.JSType;
 
 public class ConstantReference extends ClassReference
 {
 
-    public ConstantReference(ReferenceModel model, Node node, String name,
-            JSDocInfo comment)
+    @SuppressWarnings("unused")
+    private JSType type;
+
+    public ConstantReference(ReferenceModel model, Node node,
+            String qualifiedName, JSDocInfo comment)
+    {
+        super(model, node, qualifiedName, comment);
+    }
+
+    public ConstantReference(ReferenceModel model, Node node,
+            String qualifiedName, JSDocInfo comment, JSType type)
     {
-        super(model, node, name, comment);
+        super(model, node, qualifiedName, comment);
+        this.type = type;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 5d8e849..fcae414 100644
--- 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
@@ -19,7 +19,7 @@
 
 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.ExternalsClientConfig.ExcludedMemeber;
 import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils;
 import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils;
 

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 3cda1c1..3fcb730 100644
--- 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
@@ -21,7 +21,7 @@ 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.ExternalsClientConfig.ExcludedMemeber;
 import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils;
 
 import com.google.javascript.rhino.JSDocInfo;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 2cb78e5..5c3f92b 100644
--- 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
@@ -19,7 +19,7 @@
 
 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.ExternalsClientConfig.ExcludedMemeber;
 
 import com.google.javascript.rhino.JSDocInfo;
 import com.google.javascript.rhino.Node;
@@ -41,6 +41,7 @@ public abstract class MemberReference extends BaseReference
         this.classReference = classReference;
     }
 
+    @Override
     public ExcludedMemeber isExcluded()
     {
         return getClassReference().getModel().isExcludedMember(

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/21053509/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
index 2a0db9c..2f239ee 100644
--- 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
@@ -19,7 +19,7 @@
 
 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.ExternalsClientConfig.ExcludedMemeber;
 import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils;
 
 import com.google.javascript.rhino.JSDocInfo;