JsInterop namespace: assign constructor to last node.

Bug-Link: https://github.com/gwtproject/gwt/issues/9201
Change-Id: I8ffc492bff0a200ac6ad15ac11a4a70096ed10f6
diff --git a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
index 185ac08..687225f 100644
--- a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
+++ b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
@@ -146,11 +146,8 @@
 
     // Parentheses added to eliminate strict JS warning in Firefox.
     for (var part; parts.length && (part = parts.shift());) {
-        if (cur[part]) {
-            cur = cur[part];
-        } else {
-            cur = cur[part] = optCtor || {};
-        }
+        // assign the constructor to the last node (when parts is empty)
+        cur = cur[part] = cur[part] || !parts.length && optCtor || {};
     }
     return cur;
   }-*/;
diff --git a/user/test/com/google/gwt/core/client/interop/JsExportTest.java b/user/test/com/google/gwt/core/client/interop/JsExportTest.java
index fa5215e..1c044d8 100644
--- a/user/test/com/google/gwt/core/client/interop/JsExportTest.java
+++ b/user/test/com/google/gwt/core/client/interop/JsExportTest.java
@@ -18,6 +18,8 @@
 import static com.google.gwt.core.client.ScriptInjector.TOP_WINDOW;
 
 import com.google.gwt.core.client.ScriptInjector;
+import com.google.gwt.core.client.js.JsExport;
+import com.google.gwt.core.client.js.JsNamespace;
 import com.google.gwt.junit.client.GWTTestCase;
 
 /**
@@ -144,8 +146,42 @@
     return obj.getInstance();
   }-*/;
 
+  @JsExport
+  @JsNamespace("bar.foo.baz")
+  static class MyExportedClassCorrectNamespace {
+    public MyExportedClassCorrectNamespace() { }
+  }
+
+  public void testExportClass_correctNamespace() {
+    assertNull(getGlobalByQualifiedName("bar.MyExportedClassCorrectNamespace"));
+    assertNull(getGlobalByQualifiedName("bar.foo.MyExportedClassCorrectNamespace"));
+    assertTrue(isFunction(getGlobalByQualifiedName("bar.foo.baz.MyExportedClassCorrectNamespace")));
+    Object o = newInstance(getGlobalByQualifiedName("bar.foo.baz.MyExportedClassCorrectNamespace"));
+    assertNotNull(o);
+    assertTrue(o instanceof MyExportedClassCorrectNamespace);
+  }
+
+  private native Object getGlobalByQualifiedName(String qualifiedName) /*-{
+    var components = qualifiedName.split('\.');
+    var scope = $global;
+    for (var i = 0; i < components.length; i++) {
+      scope = scope[components[i]];
+    }
+    return scope;
+  }-*/;
+
+  private native boolean isFunction(Object object) /*-{
+    return typeof object == "function";
+  }-*/;
+
+  private native Object newInstance(Object jsConstructor) /*-{
+    return new jsConstructor;
+  }-*/;
+
   public void testExportClass_implicitConstructor() {
-    assertNotNull(createMyExportedClassWithImplicitConstructor());
+    Object o = createMyExportedClassWithImplicitConstructor();
+    assertNotNull(o);
+    assertTrue(o instanceof MyExportedClassWithImplicitConstructor);
   }
 
   private native Object createMyExportedClassWithImplicitConstructor() /*-{
diff --git a/user/test/com/google/gwt/core/client/interop/MyExportedClassWithImplicitConstructor.java b/user/test/com/google/gwt/core/client/interop/MyExportedClassWithImplicitConstructor.java
index f4d62a5..f74c39f 100644
--- a/user/test/com/google/gwt/core/client/interop/MyExportedClassWithImplicitConstructor.java
+++ b/user/test/com/google/gwt/core/client/interop/MyExportedClassWithImplicitConstructor.java
@@ -23,5 +23,4 @@
  */
 @JsExport
 public class MyExportedClassWithImplicitConstructor {
-
 }