http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java
 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java
new file mode 100644
index 0000000..e6ab1e4
--- /dev/null
+++ 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java
@@ -0,0 +1,1177 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js.flexjs;
+
+import java.util.ArrayList;
+
+import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.internal.codegen.js.goog.TestGoogPackage;
+import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.tree.as.IFileNode;
+import org.junit.Test;
+
+/**
+ * @author Erik de Bruin
+ */
+public class TestFlexJSPackage extends TestGoogPackage
+{
+    @Override
+    public void setUp()
+    {
+       project = new FlexJSProject(workspace);
+       JSGoogConfiguration config = new JSGoogConfiguration();
+       ArrayList<String> values = new ArrayList<String>();
+       values.add("Event");
+       config.setCompilerKeepAs3Metadata(null, values);
+       ((FlexJSProject)project).config = config;
+        super.setUp();
+    }
+    
+    @Override
+    @Test
+    public void testPackageSimple_Class()
+    {
+        // does JS need a implicit constructor function? ... always?
+        // All class nodes in AST get either an implicit or explicit 
constructor
+        // this is an implicit and the way I have the before/after handler 
working
+        // with block disallows implicit blocks from getting { }
+
+        // (erikdebruin) the constuctor IS the class definition, in 'goog' JS,
+        //               therefor we need to write out implicit constructors 
+        //               (if I understand the term correctly)
+
+        IFileNode node = compileAS("package {public class A{}}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                       " * A\n" +
+                       " *\n" +
+                       " * @fileoverview\n" +
+                       " *\n" +
+                       " * @suppress {checkTypes|accessControls}\n" +
+                       " */\n" +
+                       "\n" +
+                       "goog.provide('A');\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * @constructor\n" +
+                       " */\n" +
+                       "A = function() {\n" +
+                       "};\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Metadata\n" +
+                       " *\n" +
+                       " * @type {Object.<string, Array.<Object>>}\n" +
+                       " */\n" +
+                       "A.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'A', 
qName: 'A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('A', A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    }\n" + 
+                       "  };\n" +
+                       "};\n");
+    }
+
+    @Override
+    @Test
+    public void testPackageQualified_Class()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {public class A{}}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                       " * foo.bar.baz.A\n" +
+                       " *\n" +
+                       " * @fileoverview\n" +
+                       " *\n" +
+                       " * @suppress {checkTypes|accessControls}\n" +
+                       " */\n" +
+                       "\n" +
+                       "goog.provide('foo.bar.baz.A');\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * @constructor\n" +
+                       " */\n" +
+                       "foo.bar.baz.A = function() {\n" +
+                       "};\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Metadata\n" +
+                       " *\n" +
+                       " * @type {Object.<string, Array.<Object>>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    }\n" + 
+                       "  };\n" +
+                       "};\n");
+    }
+
+    @Override
+    @Test
+    public void testPackageQualified_ClassBody()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {public class A{public 
function A(){}}}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                       " * foo.bar.baz.A\n" +
+                       " *\n" +
+                       " * @fileoverview\n" +
+                       " *\n" +
+                       " * @suppress {checkTypes|accessControls}\n" +
+                       " */\n" +
+                       "\n" +
+                       "goog.provide('foo.bar.baz.A');\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * @constructor\n" +
+                       " */\n" +
+                       "foo.bar.baz.A = function() {\n" +
+                       "};\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Metadata\n" +
+                       " *\n" +
+                       " * @type {Object.<string, Array.<Object>>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" + 
+                       "  };\n" +
+                       "};\n");
+    }
+
+    @Override
+    @Test
+    public void testPackageQualified_ClassBodyMethodContents()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {public class A{public 
function A(){if (a){for (var i:Object in obj){doit();}}}}}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                       " * foo.bar.baz.A\n" +
+                       " *\n" +
+                       " * @fileoverview\n" +
+                       " *\n" +
+                       " * @suppress {checkTypes|accessControls}\n" +
+                       " */\n" +
+                       "\n" +
+                       "goog.provide('foo.bar.baz.A');\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * @constructor\n" +
+                       " */\n" +
+                       "foo.bar.baz.A = function() {\n" +
+                       "  if (a) {\n" +
+                       "    for (var /** @type {Object} */ i in obj) {\n" +
+                       "      doit();\n" +
+                       "    }\n" +
+                       "  }\n" +
+                       "};\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Metadata\n" +
+                       " *\n" +
+                       " * @type {Object.<string, Array.<Object>>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" + 
+                       "  };\n" +
+                       "};\n");
+    }
+
+    @Test
+    public void testPackageQualified_ClassBodyMetaData()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {[Event(name='add', 
type='mx.events.FlexEvent')]\npublic class A{public function A(){}}}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                       " * foo.bar.baz.A\n" +
+                       " *\n" +
+                       " * @fileoverview\n" +
+                       " *\n" +
+                       " * @suppress {checkTypes|accessControls}\n" +
+                       " */\n" +
+                       "\n" +
+                       "goog.provide('foo.bar.baz.A');\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * @constructor\n" +
+                       " */\n" +
+                       "foo.bar.baz.A = function() {\n" +
+                       "};\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Metadata\n" +
+                       " *\n" +
+                       " * @type {Object.<string, Array.<Object>>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    metadata: function () { return [ { name: 'Event', 
args: [ { key: 'name', value: 'add'}, { key: 'type', value: 
'mx.events.FlexEvent'}]}]; }\n" +
+                       "  };\n" +
+                       "};\n");
+    }
+
+    @Test
+    public void testPackageQualified_ClassAndInternalClass()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {\n" + 
+                                                                 "public class 
A {\n" +
+                                                                 "public 
function A(){\n" +
+                                                                     "var 
internalClass:InternalClass = new InternalClass();\n" +
+                                                                 "}}}\n" +
+                                                                 "class 
InternalClass {\n" +
+                                                                     "public 
function InternalClass(){}\n" +
+                                                                 "}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                         " * foo.bar.baz.A\n" +
+                         " *\n" +
+                         " * @fileoverview\n" +
+                         " *\n" +
+                         " * @suppress {checkTypes|accessControls}\n" +
+                         " */\n" +
+                         "\n" +
+                         "goog.provide('foo.bar.baz.A');\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " */\n" +
+                         "foo.bar.baz.A = function() {\n" +
+                         "  var /** @type {foo.bar.baz.A.InternalClass} */ 
internalClass = new foo.bar.baz.A.InternalClass();\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n/" +
+                         "**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass = function() {\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 
'InternalClass', qName: 'foo.bar.baz.A.InternalClass'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A.InternalClass', 
foo.bar.baz.A.InternalClass);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_REFLECTION_INFO = function () 
{\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'InternalClass': { type: '', declaredBy: 
'foo.bar.baz.A.InternalClass'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n");
+    }
+
+       @Test
+       public void testPackageQualified_ClassAndInternalFunction()
+       {
+               IFileNode node = compileAS("package foo.bar.baz {\n" +
+                               "public class A {\n" +
+                               "public function A(){\n" +
+                               "internalFunction();\n" +
+                               "}}}\n" +
+                               "function internalFunction(){}");
+               asBlockWalker.visitFile(node);
+               assertOutWithMetadata("/**\n" +
+                               " * foo.bar.baz.A\n" +
+                               " *\n" +
+                               " * @fileoverview\n" +
+                               " *\n" +
+                               " * @suppress {checkTypes|accessControls}\n" +
+                               " */\n" +
+                               "\n" +
+                               "goog.provide('foo.bar.baz.A');\n" +
+                               "\n" +
+                               "\n" +
+                               "\n" +
+                               "/**\n" +
+                               " * @constructor\n" +
+                               " */\n" +
+                               "foo.bar.baz.A = function() {\n" +
+                               "  foo.bar.baz.A.internalFunction();\n" +
+                               "};\n" +
+                               "\n" +
+                               "\n/" +
+                               "**\n" +
+                               " * Metadata\n" +
+                               " *\n" +
+                               " * @type {Object.<string, Array.<Object>>}\n" +
+                               " */\n" +
+                               "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { 
names: [{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n" +
+                               "\n" +
+                               "\n" +
+                               "\n" +
+                               "foo.bar.baz.A.internalFunction = function() 
{\n" +
+                               "}");
+       }
+
+       @Test
+       public void testPackageQualified_ClassAndInternalVariable()
+       {
+               IFileNode node = compileAS("package foo.bar.baz {\n" +
+                               "public class A {\n" +
+                               "public function A(){\n" +
+                               "internalVar = 3;\n" +
+                               "}}}\n" +
+                               "var internalVar:Number = 2;");
+               asBlockWalker.visitFile(node);
+               assertOutWithMetadata("/**\n" +
+                               " * foo.bar.baz.A\n" +
+                               " *\n" +
+                               " * @fileoverview\n" +
+                               " *\n" +
+                               " * @suppress {checkTypes|accessControls}\n" +
+                               " */\n" +
+                               "\n" +
+                               "goog.provide('foo.bar.baz.A');\n" +
+                               "\n" +
+                               "\n" +
+                               "\n" +
+                               "/**\n" +
+                               " * @constructor\n" +
+                               " */\n" +
+                               "foo.bar.baz.A = function() {\n" +
+                               "  foo.bar.baz.A.internalVar = 3;\n" +
+                               "};\n" +
+                               "\n" +
+                               "\n/" +
+                               "**\n" +
+                               " * Metadata\n" +
+                               " *\n" +
+                               " * @type {Object.<string, Array.<Object>>}\n" +
+                               " */\n" +
+                               "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { 
names: [{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n" +
+                               "\n" +
+                               "\n" +
+                               "\n" +
+                               "/**\n" +
+                               " * @export\n" +
+                               " * @type {number}\n" +
+                               " */\n" +
+                               "foo.bar.baz.A.internalVar = 2");
+       }
+
+    @Test
+    public void testPackageQualified_ClassAndInternalClassMethods()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {\n" + 
+                                                                 "public class 
A {\n" +
+                                                                 "public 
function A(){\n" +
+                                                                     "var 
internalClass:InternalClass = new InternalClass();\n" +
+                                                                     "var 
myString:String = InternalClass.someString;\n" +
+                                                                     "myString 
= InternalClass.someStaticFunction();\n" +
+                                                                     "myString 
= internalClass.someMethod();\n" +
+                                                                 "}}}\n" +
+                                                                 "class 
InternalClass {\n" +
+                                                                     "public 
function InternalClass(){\n" +
+                                                                     "}\n" +
+                                                                         
"public static var someString:String = \"foo\";\n" +
+                                                                 "public 
static function someStaticFunction():String { return \"bar\";}\n" +
+                                                                 "public 
function someMethod():String { return \"baz\";}\n" +
+                                                                 "}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                         " * foo.bar.baz.A\n" +
+                         " *\n" +
+                         " * @fileoverview\n" +
+                         " *\n" +
+                         " * @suppress {checkTypes|accessControls}\n" +
+                         " */\n" +
+                         "\n" +
+                         "goog.provide('foo.bar.baz.A');\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " */\n" +
+                         "foo.bar.baz.A = function() {\n" +
+                         "  var /** @type {foo.bar.baz.A.InternalClass} */ 
internalClass = new foo.bar.baz.A.InternalClass();\n" +
+                         "  var /** @type {string} */ myString = 
foo.bar.baz.A.InternalClass.someString;\n" +
+                         "  myString = 
foo.bar.baz.A.InternalClass.someStaticFunction();\n" +
+                         "  myString = internalClass.someMethod();\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass = function() {\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @export\n" +
+                         " * @type {string}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass.someString = \"foo\";\n" 
+
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @export\n" +
+                         " * @return {string}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass.someStaticFunction = 
function() {\n" +
+                         "  return \"bar\";\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @export\n" +
+                         " * @return {string}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass.prototype.someMethod = 
function() {\n" +
+                         "  return \"baz\";\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 
'InternalClass', qName: 'foo.bar.baz.A.InternalClass'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A.InternalClass', 
foo.bar.baz.A.InternalClass);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_REFLECTION_INFO = function () 
{\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'InternalClass': { type: '', declaredBy: 
'foo.bar.baz.A.InternalClass'},\n" +
+                       "        'someMethod': { type: 'String', declaredBy: 
'foo.bar.baz.A.InternalClass'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n");
+    }
+    
+    @Test
+    public void testPackageQualified_ClassAndInternalGettersAndSetters()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {\n" + 
+                                                                 "public class 
A {\n" +
+                                                                 "public 
function A(){\n" +
+                                                                     "var 
internalClass:InternalClass = new InternalClass();\n" +
+                                                                     "myString 
= internalClass.someString;\n" +
+                                                                     
"internalClass.someString = myString;\n" +
+                                                                 "}\n" +
+                                                                 "public 
function get myString():String {\n" +
+                                                                 "    return 
null;\n" +
+                                                                 "}\n" +
+                                                                 "public 
function set myString(value:String):void {}\n" +
+                                                                 "}}\n" +
+                                                                 "class 
InternalClass {\n" +
+                                                                     "public 
function InternalClass(){\n" +
+                                                                     "}\n" +
+                                                                         
"public function get someString():String {\n" +
+                                                                         "    
return null;\n" +
+                                                                         "}\n" 
+
+                                                                 "public 
function set someString(value:String):void {}\n" +
+                                                                 "}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                         " * foo.bar.baz.A\n" +
+                         " *\n" +
+                         " * @fileoverview\n" +
+                         " *\n" +
+                         " * @suppress {checkTypes|accessControls}\n" +
+                         " */\n" +
+                         "\n" +
+                         "goog.provide('foo.bar.baz.A');\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " */\n" +
+                         "foo.bar.baz.A = function() {\n" +
+                         "  var /** @type {foo.bar.baz.A.InternalClass} */ 
internalClass = new foo.bar.baz.A.InternalClass();\n" +
+                         "  this.myString = internalClass.someString;\n" +
+                         "  internalClass.someString = this.myString;\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "Object.defineProperties(foo.bar.baz.A.prototype, /** 
@lends {foo.bar.baz.A.prototype} */ {\n" +
+                  "/** @export */\n" +
+                  "myString: {\n" +
+                  "get: /** @this {foo.bar.baz.A} */ function() {\n" +
+                  "  return null;\n" +
+                  "},\n" +
+                  "set: /** @this {foo.bar.baz.A} */ function(value) {\n" +
+                  "}}}\n" +
+                  ");\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "        'myString': { type: 'String', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass = function() {\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         
"Object.defineProperties(foo.bar.baz.A.InternalClass.prototype, /** @lends 
{foo.bar.baz.A.InternalClass.prototype} */ {\n" +
+                  "/** @export */\n" +
+                  "someString: {\n" +
+                  "get: /** @this {foo.bar.baz.A.InternalClass} */ function() 
{\n" +
+                  "  return null;\n" +
+                  "},\n" +
+                  "set: /** @this {foo.bar.baz.A.InternalClass} */ 
function(value) {\n" +
+                  "}}}\n" +
+                  ");\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 
'InternalClass', qName: 'foo.bar.baz.A.InternalClass'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A.InternalClass', 
foo.bar.baz.A.InternalClass);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_REFLECTION_INFO = function () 
{\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "        'someString': { type: 'String', declaredBy: 
'foo.bar.baz.A.InternalClass'}\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'InternalClass': { type: '', declaredBy: 
'foo.bar.baz.A.InternalClass'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n");
+    }
+    
+    @Test
+    public void testPackageQualified_ClassAndInternalFLEXJS_CLASS_INFO()
+    {
+        IFileNode node = compileAS("package foo.bar.baz {\n" + 
+                                                                 "public class 
A {\n" +
+                                                                 "public 
function A(){\n" +
+                                                                     "var 
internalClass:ITestInterface = new InternalClass() as ITestInterface;\n" +
+                                                                     
"internalClass.test();\n" +
+                                                                 "}\n" +
+                                                                 "}}\n" +
+                                                                 "interface 
ITestInterface {\n" +
+                                                                 "function 
test():void;\n" +
+                                                                 "}\n" +
+                                                                 "class 
InternalClass implements ITestInterface {\n" +
+                                                                     "public 
function InternalClass(){\n" +
+                                                                     "}\n" +
+                                                                         
"public function test():void {}\n" +
+                                                                 "}");
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                         " * foo.bar.baz.A\n" +
+                         " *\n" +
+                         " * @fileoverview\n" +
+                         " *\n" +
+                         " * @suppress {checkTypes|accessControls}\n" +
+                         " */\n" +
+                         "\n" +
+                         "goog.provide('foo.bar.baz.A');\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " */\n" +
+                         "foo.bar.baz.A = function() {\n" +
+                         "  var /** @type {foo.bar.baz.A.ITestInterface} */ 
internalClass = org.apache.flex.utils.Language.as(new 
foo.bar.baz.A.InternalClass(), foo.bar.baz.A.ITestInterface);\n" +
+                         "  internalClass.test();\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.prototype.FLEXJS_CLASS_INFO = { names: 
[{ name: 'A', qName: 'foo.bar.baz.A'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       "foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = 
function () {\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'A': { type: '', declaredBy: 
'foo.bar.baz.A'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @interface\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.ITestInterface = function() {\n" +
+                         "};\n" +
+                         "foo.bar.baz.A.ITestInterface.prototype.test = 
function() {\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         
"foo.bar.baz.A.ITestInterface.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 
'ITestInterface', qName: 'foo.bar.baz.A.ITestInterface'}] };\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       
"foo.bar.baz.A.ITestInterface.prototype.FLEXJS_REFLECTION_INFO = function () 
{\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'test': { type: 'void', declaredBy: 
'foo.bar.baz.A.ITestInterface'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n" +
+                         "\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @constructor\n" +
+                         " * @implements {foo.bar.baz.A.ITestInterface}\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass = function() {\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * @export\n" +
+                         " */\n" +
+                         "foo.bar.baz.A.InternalClass.prototype.test = 
function() {\n" +
+                         "};\n" +
+                         "\n" +
+                         "\n" +
+                         "/**\n" +
+                         " * Metadata\n" +
+                         " *\n" +
+                         " * @type {Object.<string, Array.<Object>>}\n" +
+                         " */\n" +
+                         
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 
'InternalClass', qName: 'foo.bar.baz.A.InternalClass'}], interfaces: 
[foo.bar.baz.A.ITestInterface] };\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Prevent renaming of class. Needed for 
reflection.\n" +
+                       " */\n" +
+                       "goog.exportSymbol('foo.bar.baz.A.InternalClass', 
foo.bar.baz.A.InternalClass);\n" +
+                       "\n" +
+                       "\n" +
+                       "\n" +
+                       "/**\n" +
+                       " * Reflection\n" +
+                       " *\n" +
+                       " * @return {Object.<string, Function>}\n" +
+                       " */\n" +
+                       
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_REFLECTION_INFO = function () 
{\n" +
+                       "  return {\n" +
+                       "    variables: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" + 
+                       "    },\n" +
+                       "    accessors: function () {\n" +
+                       "      return {\n" +
+                       "      };\n" +
+                       "    },\n" +
+                       "    methods: function () {\n" +
+                       "      return {\n" +
+                       "        'InternalClass': { type: '', declaredBy: 
'foo.bar.baz.A.InternalClass'},\n" +
+                       "        'test': { type: 'void', declaredBy: 
'foo.bar.baz.A.InternalClass'}\n" +
+                       "      };\n" +
+                       "    }\n" +
+                       "  };\n" +
+                       "};\n"
+                         );
+    }
+
+       @Test
+       public void testPackageSimple_Function()
+       {
+               IFileNode node = compileAS("package {public function A(){}}");
+               asBlockWalker.visitFile(node);
+               assertOutWithMetadata("/**\n * A\n *\n * @fileoverview\n *\n * 
@suppress {checkTypes|accessControls}\n */\n\ngoog.provide('A');\n\n\n\n/**\n * 
@export\n */\nA = function() {\n}");
+       }
+
+       @Test
+       public void testPackageQualified_Function()
+       {
+               IFileNode node = compileAS("package foo.bar.baz {public 
function A(){}}");
+               asBlockWalker.visitFile(node);
+               assertOutWithMetadata("/**\n * foo.bar.baz.A\n *\n * 
@fileoverview\n *\n * @suppress {checkTypes|accessControls}\n 
*/\n\ngoog.provide('foo.bar.baz.A');\n\n\n\n/**\n * @export\n */\nfoo.bar.baz.A 
= function() {\n}");
+       }
+
+       @Test
+       public void testPackageSimple_Variable()
+       {
+               IFileNode node = compileAS("package {public var A:String = 
\"Hello\";");
+               asBlockWalker.visitFile(node);
+               assertOutWithMetadata("/**\n * A\n *\n * @fileoverview\n *\n * 
@suppress {checkTypes|accessControls}\n */\n\ngoog.provide('A');\n\n\n\n/**\n * 
@export\n * @type {string}\n */\nA = \"Hello\"");
+       }
+
+       @Test
+       public void testPackageQualified_Variable()
+       {
+               IFileNode node = compileAS("package foo.bar.baz {public var 
A:String = \"Hello\";");
+               asBlockWalker.visitFile(node);
+               assertOutWithMetadata("/**\n * foo.bar.baz.A\n *\n * 
@fileoverview\n *\n * @suppress {checkTypes|accessControls}\n 
*/\n\ngoog.provide('foo.bar.baz.A');\n\n\n\n/**\n * @export\n * @type 
{string}\n */\nfoo.bar.baz.A = \"Hello\"");
+       }
+    
+    @Override
+    protected IBackend createBackend()
+    {
+        return new FlexJSBackend();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java
 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java
new file mode 100644
index 0000000..c057f92
--- /dev/null
+++ 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java
@@ -0,0 +1,339 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js.flexjs;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.Assert;
+import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.exceptions.ConfigurationException;
+import org.apache.flex.compiler.internal.codegen.js.goog.TestGoogProject;
+import org.apache.flex.compiler.internal.config.TargetSettings;
+import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.utils.FilenameNormalization;
+import org.apache.flex.utils.ITestAdapter;
+import org.apache.flex.utils.TestAdapterFactory;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This class tests the production of valid 'flexjs' JS code from an external
+ * project.
+ * 
+ * @author Erik de Bruin
+ */
+public class TestFlexJSProject extends TestGoogProject
+{
+    private static ITestAdapter testAdapter = 
TestAdapterFactory.getTestAdapter();
+
+    private static String projectDirPath = "flexjs/projects";
+    private String sourcePath;
+    private Collection<String> externs = new ArrayList<String>();
+
+    @Override
+    public void setUp()
+    {
+        project = new FlexJSProject(workspace);
+        ((FlexJSProject)project).config = new JSGoogConfiguration();
+        super.setUp();
+    }
+    
+    @Ignore
+    @Test
+    public void test_imports()
+    {
+        // crude bypass to allow for successful inheritance
+    }
+
+    @Test
+    public void test_Test()
+    {
+        String testDirPath = projectDirPath + "/interfaces";
+
+        String fileName = "Test";
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/interfaces").getPath();
+        
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_Super()
+    {
+        String testDirPath = projectDirPath + "/super";
+
+        String fileName = "Base";
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/super").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_InternalAndSamePackageRequires()
+    {
+        String testDirPath = projectDirPath + "/internal";
+
+        String fileName = "MainClass";
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/internal").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_IsItCircular()
+    {
+        String testDirPath = projectDirPath + "/circular";
+
+        String fileName = "Base";
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/circular").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_XMLRequires()
+    {
+        String testDirPath = projectDirPath + "/xml_requires";
+
+        String fileName = "XMLRequire";
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/xml_requires").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_Overrides()
+    {
+        String testDirPath = projectDirPath + "/overrides";
+
+        String fileName = "Test";
+
+        try {
+                       
((FlexJSProject)project).config.setCompilerAllowSubclassOverrides(null, true);
+               } catch (ConfigurationException e) {
+            Assert.fail(e.getMessage());
+               }
+        project.setTargetSettings(new 
TargetSettings(((FlexJSProject)project).config));
+        
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/overrides").getPath();
+
+        StringBuilder sb = new StringBuilder();
+        List<String> compiledFileNames = compileProject(fileName, testDirPath, 
sb, false);
+
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+    
+    @Test
+    public void test_Bad_Overrides()
+    {
+        String testDirPath = projectDirPath + "/bad_overrides";
+
+        String fileName = "Test";
+
+        try {
+                       
((FlexJSProject)project).config.setCompilerAllowSubclassOverrides(null, true);
+               } catch (ConfigurationException e) {
+            Assert.fail(e.getMessage());
+               }
+        project.setTargetSettings(new 
TargetSettings(((FlexJSProject)project).config));
+        
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/bad_overrides").getPath();
+
+        StringBuilder sb = new StringBuilder();
+        compileProject(fileName, testDirPath, sb, false);
+
+        String out = sb.toString();
+        out = out.replace("\\", "/");
+
+        String expected = testAdapter.getUnitTestBaseDir().getPath() + 
"/flexjs/projects/bad_overrides/Test.as(31:29)\n" +
+                "interface method someFunction in interface IA is implemented 
with an incompatible signature in class Test\n" +
+                testAdapter.getUnitTestBaseDir().getPath() + 
"/flexjs/projects/bad_overrides/Test.as(36:26)\n" +
+                "interface method someOtherFunction in interface IA is 
implemented with an incompatible signature in class Test\n" +
+                testAdapter.getUnitTestBaseDir().getPath() + 
"/flexjs/projects/bad_overrides/Test.as(31:29)\n" +
+                "Incompatible override.\n" +
+                testAdapter.getUnitTestBaseDir().getPath() + 
"/flexjs/projects/bad_overrides/Test.as(36:26)\n" +
+                "Incompatible override.\n";
+        assertThat(out, is(expected));
+    }
+    
+    @Test
+    public void test_PackageConflict_AmbiguousDefinition()
+    {
+        String testDirPath = projectDirPath + 
"/package_conflicts_ambiguous_definition";
+
+        String fileName = "AmbiguousDefinition";
+
+        externs.add("Event");
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + 
"/package_conflicts_ambiguous_definition").getPath();
+
+        StringBuilder sb = new StringBuilder();
+        compileProject(fileName, testDirPath, sb, false);
+
+        externs.clear();
+
+        String out = sb.toString();
+        out = out.replace("\\", "/");
+
+        assertThat(out, is(testAdapter.getUnitTestBaseDir().getPath() +
+                
"/flexjs/projects/package_conflicts_ambiguous_definition/mypackage/TestClass.as(29:20)\nAmbiguous
 reference to Event\n" +
+                testAdapter.getUnitTestBaseDir().getPath() +
+                
"/flexjs/projects/package_conflicts_ambiguous_definition/mypackage/TestClass.as(30:41)\nAmbiguous
 reference to Event\n"));
+    }
+
+    @Test
+    public void test_PackageConflict_SamePackageAsConflict()
+    {
+        String testDirPath = projectDirPath + 
"/package_conflicts_same_package_as_conflict";
+
+        String fileName = "SamePackageAsConflict";
+
+        externs.add("Event");
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + 
"/package_conflicts_same_package_as_conflict").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        externs.clear();
+        
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_PackageConflict_DifferentPackageAsConflict()
+    {
+        String testDirPath = projectDirPath + 
"/package_conflicts_different_package_as_conflict";
+
+        String fileName = "DifferentPackageAsConflict";
+
+        externs.add("Event");
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + 
"/package_conflicts_different_package_as_conflict").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        externs.clear();
+        
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_PackageConflict_UseWindow()
+    {
+        String testDirPath = projectDirPath + "/package_conflicts_use_window";
+
+        String fileName = "UseWindow";
+
+        externs.add("Event");
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + "/package_conflicts_use_window").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        externs.clear();
+        
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_PackageConflict_NoConflictNoWindow()
+    {
+        String testDirPath = projectDirPath + 
"/package_conflicts_no_conflict_no_window";
+
+        String fileName = "NoConflictNoWindow";
+
+        externs.add("Event");
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + 
"/package_conflicts_no_conflict_no_window").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        externs.clear();
+        
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Test
+    public void test_PackageConflict_NoConflictUseWindow()
+    {
+        String testDirPath = projectDirPath + 
"/package_conflicts_no_conflict_use_window";
+
+        String fileName = "NoConflictUseWindow";
+
+        externs.add("Event");
+
+        sourcePath = new 
File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
+                projectDirPath + 
"/package_conflicts_no_conflict_use_window").getPath();
+
+        List<String> compiledFileNames = compileProject(fileName, testDirPath);
+
+        externs.clear();
+        
+        assertProjectOut(compiledFileNames, testDirPath);
+    }
+
+    @Override
+    protected void addSourcePaths(List<File> sourcePaths)
+    {
+        sourcePaths.add(new File(FilenameNormalization.normalize(sourcePath)));
+        ((FlexJSProject)project).unitTestExterns = externs;
+    }
+
+    @Override
+    protected IBackend createBackend()
+    {
+        return new FlexJSBackend();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSStatements.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSStatements.java
 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSStatements.java
new file mode 100644
index 0000000..f2022b3
--- /dev/null
+++ 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSStatements.java
@@ -0,0 +1,600 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.codegen.js.flexjs;
+
+import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.internal.codegen.js.goog.TestGoogStatements;
+import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.tree.as.LabeledStatementNode;
+import org.apache.flex.compiler.tree.as.IFileNode;
+import org.apache.flex.compiler.tree.as.IForLoopNode;
+import org.apache.flex.compiler.tree.as.IIfNode;
+import org.apache.flex.compiler.tree.as.ILiteralNode;
+import org.apache.flex.compiler.tree.as.ISwitchNode;
+import org.apache.flex.compiler.tree.as.ITryNode;
+import org.apache.flex.compiler.tree.as.IVariableNode;
+import org.apache.flex.compiler.tree.as.IWhileLoopNode;
+import org.apache.flex.compiler.tree.as.IWithNode;
+import org.junit.Test;
+
+/**
+ * @author Erik de Bruin
+ */
+public class TestFlexJSStatements extends TestGoogStatements
+{
+    @Override
+    public void setUp()
+    {
+       project = new FlexJSProject(workspace);
+        super.setUp();
+    }
+    
+    @Test
+    public void testObjectListeral_withPropertyNameMatchingConst()
+    {
+        ILiteralNode node = (ILiteralNode) getNode("static const myConst:int; 
function falconTest_a():Object { return { myConst : myConst } }",
+                       ILiteralNode.class, WRAP_LEVEL_CLASS);
+        asBlockWalker.visitLiteral(node);
+        assertOut("{myConst:FalconTest_A.myConst}");
+    }
+    
+    @Test
+    public void testVarDeclaration_withTypeAssignedStringWithNewLine()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:String = \"\\n\"",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {string} */ a = \"\\n\"");
+    }
+
+    //----------------------------------
+    // const declaration
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testConstDeclaration()
+    {
+        IVariableNode node = (IVariableNode) getNode("const a = 42;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("\n/**\n * @const\n * @type {*}\n */\nvar a = 42");
+    }
+
+    @Override
+    @Test
+    public void testConstDeclaration_withType()
+    {
+        IVariableNode node = (IVariableNode) getNode("const a:int = 42;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("\n/**\n * @const\n * @type {number}\n */\nvar a = 42");
+    }
+
+    @Override
+    @Test
+    public void testConstDeclaration_withList()
+    {
+        IVariableNode node = (IVariableNode) getNode(
+                "const a:int = 4, b:int = 11, c:int = 42;", 
IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("\n/**\n * @const\n * @type {number}\n */\nvar a = 4, 
\n/**\n * @const\n * @type {number}\n */\nb = 11, \n/**\n * @const\n * @type 
{number}\n */\nc = 42");
+    }
+
+    //----------------------------------
+    // for () { }
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitFor_1a()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int = 0; i < len; i++) { break; }",
+                IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var /** @type {number} */ i = 0; i < len; i++) {\n  
break;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitFor_1b()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int = 0; i < len; i++) break;", 
IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var /** @type {number} */ i = 0; i < len; i++)\n  
break;");
+    }
+
+    @Override
+    @Test
+    public void testVisitForIn_1()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int in obj) { break; }", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var /** @type {number} */ i in obj) {\n  break;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitForIn_1a()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for (var i:int in obj)  break; ", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (var /** @type {number} */ i in obj)\n  break;");
+    }
+
+    @Override
+    @Test
+    public void testVisitForEach_1()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for each(var i:int in obj) { break; }", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("var foreachiter0_target = obj;\nfor (var foreachiter0 in 
foreachiter0_target) \n{\nvar i = foreachiter0_target[foreachiter0];\n{\n  
break;\n}}\n");
+    }
+
+    @Override
+    @Test
+    public void testVisitForEach_1a()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for each(var i:int in obj)  break; ", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("var foreachiter0_target = obj;\nfor (var foreachiter0 in 
foreachiter0_target) \n{\nvar i = foreachiter0_target[foreachiter0];\n\n  
break;}\n");
+    }
+
+    @Test
+    public void testVisitForEach_2()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "for each(var i:int in obj.foo()) { break; }", 
IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("var foreachiter0_target = obj.foo();\nfor (var foreachiter0 
in foreachiter0_target) \n{\nvar i = foreachiter0_target[foreachiter0];\n{\n  
break;\n}}\n");
+    }
+
+    @Test
+    public void testVisitForEach_HoistedVar()
+    {
+        IForLoopNode node = (IForLoopNode) getNode(
+                "var i:int; for each(i in obj)  break; ", IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("var foreachiter0_target = obj;\nfor (var foreachiter0 in 
foreachiter0_target) \n{\ni = foreachiter0_target[foreachiter0];\n\n  
break;}\n");
+    }
+
+    //----------------------------------
+    // try {} catch () {} finally {}
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitTry_Catch()
+    {
+        ITryNode node = (ITryNode) getNode("try { a; } catch (e:Error) { b; }",
+                ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n  a;\n} catch (e) {\n  b;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitTry_Catch_Finally()
+    {
+        ITryNode node = (ITryNode) getNode(
+                "try { a; } catch (e:Error) { b; } finally { c; }",
+                ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n  a;\n} catch (e) {\n  b;\n} finally {\n  c;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitTry_Catch_Catch_Finally()
+    {
+        // TODO (erikdebruin) handle multiple 'catch' statements (FW in Wiki)
+        ITryNode node = (ITryNode) getNode(
+                "try { a; } catch (e:Error) { b; } catch (f:Error) { c; } 
finally { d; }",
+                ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n  a;\n} catch (e) {\n  b;\n} catch (f) {\n  c;\n} 
finally {\n  d;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitTry_CatchEmpty_FinallyEmpty_()
+    {
+        ITryNode node = (ITryNode) getNode(
+                "try { a; } catch (e:Error) {  } finally {  }", 
ITryNode.class);
+        asBlockWalker.visitTry(node);
+        assertOut("try {\n  a;\n} catch (e) {\n} finally {\n}");
+    }
+
+    //----------------------------------
+    // switch {}
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitSwitch_1()
+    {
+        ISwitchNode node = (ISwitchNode) getNode("switch(i){case 1: break;}",
+                ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        assertOut("switch (i) {\n  case 1:\n    break;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitSwitch_1a()
+    {
+        ISwitchNode node = (ISwitchNode) getNode(
+                "switch(i){case 1: { break; }}", ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        // (erikdebruin) the code is valid without the extra braces, 
+        //               i.e. we're good, we "don't care"
+        assertOut("switch (i) {\n  case 1:\n    break;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitSwitch_2()
+    {
+        ISwitchNode node = (ISwitchNode) getNode(
+                "switch(i){case 1: break; default: return;}", 
ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        assertOut("switch (i) {\n  case 1:\n    break;\n  default:\n    
return;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitSwitch_3()
+    {
+        ISwitchNode node = (ISwitchNode) getNode(
+                "switch(i){case 1: { var x:int = 42; break; }; case 2: { var 
y:int = 66; break; }}", ISwitchNode.class);
+        asBlockWalker.visitSwitch(node);
+        assertOut("switch (i) {\n  case 1:\n    var /** @type {number} */ x = 
42;\n    break;\n  case 2:\n    var /** @type {number} */ y = 66;\n    
break;\n}");
+    }
+
+    //----------------------------------
+    // if ()
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitIf_1()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) b++;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n  b++;");
+    }
+
+    @Override
+    @Test
+    public void testVisitIf_2()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) b++; else c++;", 
IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n  b++;\nelse\n  c++;");
+    }
+
+    @Override
+    @Test
+    public void testVisitIf_4()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) b++; else if (c) d++; else if(e) --f;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n  b++;\nelse if (c)\n  d++;\nelse if (e)\n  --f;");
+    }
+
+    //----------------------------------
+    // if () { }
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitIf_1a()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) { b++; }", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a) {\n  b++;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitIf_1b()
+    {
+        IIfNode node = (IIfNode) getNode("if (a) { b++; } else { c++; }",
+                IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a) {\n  b++;\n} else {\n  c++;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitIf_1c()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) { b++; } else if (b) { c++; } else { d++; }",
+                IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a) {\n  b++;\n} else if (b) {\n  c++;\n} else {\n  
d++;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitIf_3()
+    {
+        IIfNode node = (IIfNode) getNode(
+                "if (a) b++; else if (c) d++; else --e;", IIfNode.class);
+        asBlockWalker.visitIf(node);
+        assertOut("if (a)\n  b++;\nelse if (c)\n  d++;\nelse\n  --e;");
+    }
+
+    //----------------------------------
+    // label : for () {}
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitFor_2()
+    {
+        IForLoopNode node = (IForLoopNode) getNode("for (;;) { break; }",
+                IForLoopNode.class);
+        asBlockWalker.visitForLoop(node);
+        assertOut("for (;;) {\n  break;\n}");
+    }
+    
+    //----------------------------------
+    // while () { }
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitWhileLoop_1()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode(
+                "while(a > b){a++;--b;}", IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("while (a > b) {\n  a++;\n  --b;\n}");
+    }
+
+    @Override
+    @Test
+    public void testVisitWhileLoop_1a()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode("while(a > b) a++;",
+                IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("while (a > b)\n  a++;");
+    }
+
+    //----------------------------------
+    // do {} while ()
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitWhileLoop_Do_1()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode(
+                "do {a++;--b;} while(a > b);", IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("do {\n  a++;\n  --b;\n} while (a > b);");
+    }
+
+    @Override
+    @Test
+    public void testVisitWhileLoop_Do_1a()
+    {
+        IWhileLoopNode node = (IWhileLoopNode) getNode("do a++; while(a > b);",
+                IWhileLoopNode.class);
+        asBlockWalker.visitWhileLoop(node);
+        assertOut("do\n  a++;\nwhile (a > b);");
+    }
+
+    //----------------------------------
+    // label : for () {}
+    //----------------------------------
+
+    @Override
+    @Test
+    public void testVisitLabel_1()
+    {
+        LabeledStatementNode node = (LabeledStatementNode) getNode(
+                "foo: for each(var i:int in obj) { break foo; }",
+                LabeledStatementNode.class);
+        asBlockWalker.visitLabeledStatement(node);
+        assertOut("var foreachiter0_target = obj;\nfoo : for (var foreachiter0 
in foreachiter0_target) \n{\nvar i = foreachiter0_target[foreachiter0];\n{\n  
break foo;\n}}\n");
+    }
+
+    @Override
+    @Test
+    public void testVisitLabel_1a()
+    {
+        // TODO (mschmalle) LabelStatement messes up in finally{} block, 
something is wrong there
+        LabeledStatementNode node = (LabeledStatementNode) getNode(
+                "foo: for each(var i:int in obj) break foo;",
+                LabeledStatementNode.class);
+        asBlockWalker.visitLabeledStatement(node);
+        assertOut("var foreachiter0_target = obj;\nfoo : for (var foreachiter0 
in foreachiter0_target) \n{\nvar i = foreachiter0_target[foreachiter0];\n\n  
break foo;}\n");
+    }
+
+    //----------------------------------
+    // with () {}
+    //----------------------------------
+
+    @Test
+    public void testVisitWith()
+    {
+        IWithNode node = (IWithNode) getNode("with (a) { b; }", 
IWithNode.class);
+        asBlockWalker.visitWith(node);
+        assertOut("with (a) {\n  b;\n}");
+    }
+
+    @Test
+    public void testVisitWith_1a()
+    {
+        IWithNode node = (IWithNode) getNode("with (a) b;", IWithNode.class);
+        asBlockWalker.visitWith(node);
+        assertOut("with (a)\n  b;");
+    }
+
+    @Override
+    @Test
+    public void testVisit()
+    {
+        IFileNode node = (IFileNode) getNode(
+                "try { a; } catch (e:Error) { if (a) { if (b) { if (c) b; else 
if (f) a; else e; }} } finally {  }"
+                        + "if (d) for (var i:int = 0; i < len; i++) break;"
+                        + "if (a) { with (ab) { c(); } "
+                        + "do {a++;do a++; while(a > b);} while(c > d); }"
+                        + "if (b) { try { a; throw new Error('foo'); } catch 
(e:Error) { "
+                        + " switch(i){case 1: break; default: return;}"
+                        + " } finally { "
+                        + "  d;  var a:Object = function(foo:int, bar:String = 
'goo'):int{return -1;};"
+                        + "  eee.dd; eee.dd; eee.dd; eee.dd;} }"
+                        + "foo: for each(var i:int in obj) break foo;",
+                IFileNode.class);
+        asBlockWalker.visitFile(node);
+        assertOutWithMetadata("/**\n" +
+                                     " * FalconTest_A\n" +
+                                     " *\n" +
+                                     " * @fileoverview\n" +
+                                     " *\n" +
+                                     " * @suppress 
{checkTypes|accessControls}\n" +
+                                     " */\n" +
+                                     "\n" +
+                                     "goog.provide('FalconTest_A');\n" +
+                                     "\n\n\n" +
+                                     "/**\n" +
+                                     " * @constructor\n" +
+                                     " */\n" +
+                                     "FalconTest_A = function() {\n" +
+                                     "};\n\n\n" +
+                                     "FalconTest_A.prototype.falconTest_a = 
function() {\n" +
+                                     "  var self = this;\n" +
+                                     "  var /** @type {Function} */ 
__localFn0__ = function(foo, bar) {\n" +
+                                 "    bar = typeof bar !== 'undefined' ? bar : 
'goo';\n" +
+                                 "    return -1;\n" +
+                                 "  }\n" +
+                                 "  try {\n" +
+                                     "    a;\n" +
+                                     "  } catch (e) {\n" +
+                                     "    if (a) {\n" +
+                                     "      if (b) {\n" +
+                                     "        if (c)\n" +
+                                     "          b;\n" +
+                                     "        else if (f)\n" +
+                                     "          a;\n" +
+                                     "        else\n" +
+                                     "          e;\n" +
+                                     "      }\n" +
+                                     "    }\n" +
+                                     "  } finally {\n" +
+                                     "  }\n" +
+                                     "  if (d)\n" +
+                                     "    for (var /** @type {number} */ i = 
0; i < len; i++)\n" +
+                                     "      break;\n" +
+                                     "  if (a) {\n" +
+                                     "    with (ab) {\n" +
+                                     "      c();\n" +
+                                     "    }\n" +
+                                     "    do {\n" +
+                                     "      a++;\n" +
+                                     "      do\n" +
+                                     "        a++;\n" +
+                                     "      while (a > b);\n" +
+                                     "    } while (c > d);\n" +
+                                     "  }\n" +
+                                     "  if (b) {\n" +
+                                     "    try {\n" +
+                                     "      a;\n" +
+                                     "      throw new Error('foo');\n" +
+                                     "    } catch (e) {\n" +
+                                     "      switch (i) {\n" +
+                                     "        case 1:\n" +
+                                     "          break;\n" +
+                                     "        default:\n" +
+                                     "          return;\n" +
+                                     "      }\n" +
+                                     "    } finally {\n" +
+                                     "      d;\n" +
+                                     "      var /** @type {Object} */ a = 
__localFn0__;\n" +
+                                     "      eee.dd;\n" +
+                                     "      eee.dd;\n" +
+                                     "      eee.dd;\n" +
+                                     "      eee.dd;\n" +
+                                     "    }\n" +
+                                     "  }\n" +
+                                     "  var foreachiter0_target = obj;\n" +
+                                     "  foo : for (var foreachiter0 in 
foreachiter0_target) \n" +
+                                     "  {\n" +
+                                     "  var i = 
foreachiter0_target[foreachiter0];\n" +
+                                     "  \n" +
+                                     "    break foo;}\n" +
+                                     "  ;\n};\n\n\n" +
+                                     "/**\n * Metadata\n" +
+                                     " *\n" +
+                                     " * @type {Object.<string, 
Array.<Object>>}\n" +
+                                     " */\n" +
+                                     "FalconTest_A.prototype.FLEXJS_CLASS_INFO 
= { names: [{ name: 'FalconTest_A', qName: 'FalconTest_A'}] };\n" +
+                                               "\n" +
+                                               "\n" +
+                                               "/**\n" +
+                                               " * Prevent renaming of class. 
Needed for reflection.\n" +
+                                               " */\n" +
+                                               
"goog.exportSymbol('FalconTest_A', FalconTest_A);\n" +
+                                               "\n" +
+                                               "\n" +
+                                               "\n" +
+                                               "/**\n" +
+                                               " * Reflection\n" +
+                                               " *\n" +
+                                               " * @return {Object.<string, 
Function>}\n" +
+                                               " */\n" +
+                                               
"FalconTest_A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
+                                               "return {\n" +
+                                               "  variables: function () {\n" +
+                                               "    return {\n" +
+                                               "    };\n" + 
+                                               "  },\n" +
+                                               "  accessors: function () {\n" +
+                                               "    return {\n" +
+                                               "    };\n" +
+                                               "  },\n" +
+                                               "  methods: function () {\n" +
+                                               "    return {\n" +
+                                               "    };\n" +
+                                               "  }\n" +
+                                               "};\n" +
+                                               "};\n");
+    }
+
+    @Override
+    protected IBackend createBackend()
+    {
+        return new FlexJSBackend();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.java
----------------------------------------------------------------------
diff --git 
a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.java
 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.java
new file mode 100644
index 0000000..02965c0
--- /dev/null
+++ 
b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/goog/TestGoogAccessorMembers.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.js.goog;
+
+import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.internal.codegen.as.TestAccessorMembers;
+import org.apache.flex.compiler.internal.driver.js.goog.GoogBackend;
+import org.apache.flex.compiler.tree.as.IGetterNode;
+import org.apache.flex.compiler.tree.as.ISetterNode;
+import org.junit.Test;
+
+/**
+ * This class tests the production of valid 'goog' JS code for Class Accessor
+ * members.
+ * 
+ * @author Michael Schmalle
+ * @author Erik de Bruin
+ */
+public class TestGoogAccessorMembers extends TestAccessorMembers
+{
+    @Override
+    @Test
+    public void testGetAccessor()
+    {
+        IGetterNode node = (IGetterNode) getAccessor("function get 
foo():int{}");
+        asBlockWalker.visitGetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', "
+                + "\n\t{get:function() {\n\t}, configurable:true}\n)");
+    }
+
+    @Test
+    public void testGetAccessor_withBody()
+    {
+        IGetterNode node = (IGetterNode) getAccessor("function get 
foo():int{return -1;}");
+        asBlockWalker.visitGetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', "
+                + "\n\t{get:function() {\n\t\tvar self = this;\n\t\treturn 
-1;\n\t}, configurable:true}\n)");
+    }
+
+    @Override
+    @Test
+    public void testGetAccessor_withNamespace()
+    {
+        IGetterNode node = (IGetterNode) getAccessor("public function get 
foo():int{return -1;}");
+        asBlockWalker.visitGetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', "
+                + "\n\t{get:function() {\n\t\tvar self = this;\n\t\treturn 
-1;\n\t}, configurable:true}\n)");
+    }
+
+    @Override
+    @Test
+    public void testGetAccessor_withNamespaceOverride()
+    {
+        // TODO (erikdebruin) need to figure out how to handle calls to 
+        //                    'super' since the JS getter is actually an 
+        //                    anonymous function... goog.bind or goog.partial?
+        IGetterNode node = (IGetterNode) getAccessor("public override function 
get foo():int{super.foo(); return -1;}");
+        asBlockWalker.visitGetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', \n\t{get:function() {\n\t\tvar self = 
this;\n\t\tFalconTest_A.base(this, 'foo');\n\t\treturn -1;\n\t}, 
configurable:true}\n)");
+    }
+
+    @Override
+    @Test
+    public void testGetAccessor_withStatic()
+    {
+        IGetterNode node = (IGetterNode) getAccessor("public static function 
get foo():int{return -1;}");
+        asBlockWalker.visitGetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A, \n\t'foo', 
\n\t{get:function() {\n\t\treturn -1;\n\t}, configurable:true}\n)");
+    }
+
+    @Override
+    @Test
+    public void testSetAccessor()
+    {
+        ISetterNode node = (ISetterNode) getAccessor("function set 
foo(value:int):void{}");
+        asBlockWalker.visitSetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', \n\t{set:function(value)"
+                + " {\n\t}, configurable:true}\n)");
+    }
+
+    @Test
+    public void testSetAccessor_withBody()
+    {
+        ISetterNode node = (ISetterNode) getAccessor("function set 
foo(value:int):void{trace('haai');}");
+        asBlockWalker.visitSetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', "
+                + "\n\t{set:function(value) {\n\t\tvar self = 
this;\n\t\ttrace('haai');\n\t}, configurable:true}\n)");
+    }
+
+    @Override
+    @Test
+    public void testSetAccessor_withNamespace()
+    {
+        ISetterNode node = (ISetterNode) getAccessor("public function set 
foo(value:int):void{}");
+        asBlockWalker.visitSetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', \n\t{set:function(value)"
+                + " {\n\t}, configurable:true}\n)");
+    }
+
+    @Override
+    @Test
+    public void testSetAccessor_withNamespaceOverride()
+    {
+        // TODO (erikdebruin) see: testGetAccessor_withNamespaceOverride
+        ISetterNode node = (ISetterNode) getAccessor("public override function 
set foo(value:int):void{super.foo();}");
+        asBlockWalker.visitSetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A.prototype, 
\n\t'foo', \n\t{set:function(value) {\n\t\tvar self = 
this;\n\t\tFalconTest_A.base(this, 'foo');\n\t}, configurable:true}\n)");
+    }
+
+    @Override
+    @Test
+    public void testSetAccessor_withStatic()
+    {
+        ISetterNode node = (ISetterNode) getAccessor("public static function 
set foo(value:int):void{}");
+        asBlockWalker.visitSetter(node);
+        assertOut("Object.defineProperty(\n\tFalconTest_A, \n\t'foo', 
\n\t{set:function(value) {\n\t}, configurable:true}\n)");
+    }
+
+    @Override
+    protected IBackend createBackend()
+    {
+        return new GoogBackend();
+    }
+}

Reply via email to