Fixes type-tightening for JsType fields.

Change-Id: Iac41a0612aeb0e6a71112199409ec2744244dc4e
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
index dd5a834..641fa7c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
@@ -457,10 +457,9 @@
 
     @Override
     public void exit(JField x, Context ctx) {
-      // TODO: we should also skip @JsType fields when we implement them.
       if (program.codeGenTypes.contains(x.getEnclosingType())
-          || x.isExported()) {
-        // We cannot tighten this field as we don't know all callers.
+          || x.isExported() || x.isJsTypeMember()) {
+        // We cannot tighten this field as we don't see all references.
         return;
       }
       if (!x.isVolatile()) {
diff --git a/user/test/com/google/gwt/core/client/interop/ConcreteJsType.java b/user/test/com/google/gwt/core/client/interop/ConcreteJsType.java
index 1088001..ba5c362 100644
--- a/user/test/com/google/gwt/core/client/interop/ConcreteJsType.java
+++ b/user/test/com/google/gwt/core/client/interop/ConcreteJsType.java
@@ -47,4 +47,20 @@
   protected int protectedField = 10;
 
   int packageField = 10;
+
+  interface A {
+    int x();
+  }
+
+  public static class AImpl1 implements A {
+    @Override
+    public int x() { return 42; }
+  }
+
+  public static class AImpl2 implements A {
+    @Override
+    public int x() { return 101; }
+  }
+
+  public A notTypeTightenedField = new AImpl1();
 }
diff --git a/user/test/com/google/gwt/core/client/interop/JsTypeArrayTest.java b/user/test/com/google/gwt/core/client/interop/JsTypeArrayTest.java
index fecc5c5..eb64663 100644
--- a/user/test/com/google/gwt/core/client/interop/JsTypeArrayTest.java
+++ b/user/test/com/google/gwt/core/client/interop/JsTypeArrayTest.java
@@ -67,7 +67,7 @@
   }
 
   // TODO(rluble): Needs fixes in ImlementCastsAndTypeChecks, ArrayNormalizer and maybe type oracle.
-  public void __disabled__testJsTypeArray_asAField() {
+  public void testJsTypeArray_asAField() {
     SimpleJsTypeAsAFieldHolder holder = new SimpleJsTypeAsAFieldHolder();
     fillArrayField(holder);
     SimpleJsTypeAsAField[] array = holder.arrayField;
diff --git a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
index 26d81cc..0ffd3b0 100644
--- a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
+++ b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
@@ -100,6 +100,17 @@
         == callIntFunction(concreteJsTypeSubclass, "publicMethod"));
   }
 
+  public void testConcreteJsTypeNoTypeTightenField() {
+    // If we type-tighten, java side will see no calls and think that field could only AImpl1.
+    ConcreteJsType concreteJsType = new ConcreteJsType();
+    setTheField(concreteJsType, new ConcreteJsType.AImpl2());
+    assertEquals(101, concreteJsType.notTypeTightenedField.x());
+  }
+
+  private native void setTheField(ConcreteJsType obj, ConcreteJsType.A value)/*-{
+    obj.notTypeTightenedField = value;
+  }-*/;
+
   public void testRevealedOverrideJsType() {
     PlainParentType plainParentType = new PlainParentType();
     RevealedOverrideSubType revealedOverrideSubType = new RevealedOverrideSubType();