Avoid tighthening @JsType/@JsFunction types.
Change-Id: I25314dc26df90ee34e82ee6b611c733c61f0a7f8
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
index d702194..48dd9f8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
@@ -85,6 +85,11 @@
}
@Override
+ public boolean isJsType() {
+ return getLeafType().isJsType() || getLeafType().isJsFunction();
+ }
+
+ @Override
public boolean isJsoType() {
return false;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
index dd51b0e..3e683a3 100755
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
@@ -349,10 +349,12 @@
return methods;
}
+ @Override
public boolean isJsType() {
return isJsType;
}
+ @Override
public boolean isOrExtendsJsType() {
if (isJsType()) {
return true;
@@ -365,10 +367,12 @@
return false;
}
+ @Override
public boolean isJsFunction() {
return isJsFunction;
}
+ @Override
public boolean isOrExtendsJsFunction() {
if (isJsFunction()) {
return true;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
index 0a66231..0b03ddb 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
@@ -69,6 +69,22 @@
return false;
}
+ public boolean isJsType() {
+ return false;
+ }
+
+ public boolean isOrExtendsJsType() {
+ return isJsType();
+ }
+
+ public boolean isJsFunction() {
+ return false;
+ }
+
+ public boolean isOrExtendsJsFunction() {
+ return isJsFunction();
+ }
+
/**
* Returns {@code true} if this is a JavaScriptObject type.
*/
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 641fa7c..526f561 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
@@ -555,6 +555,7 @@
assert !x.isStaticDispatchOnly();
JMethodCall newCall = new JMethodCall(x.getSourceInfo(), x.getInstance(), concreteMethod);
newCall.addArgs(x.getArgs());
+ newCall.setCannotBePolymorphic();
ctx.replaceMe(newCall);
}
}
@@ -625,7 +626,7 @@
* type.
*/
private JReferenceType getSingleConcreteType(JType type) {
- if (!(type instanceof JReferenceType)) {
+ if (!(type instanceof JReferenceType) || type.isJsType() || type.isJsFunction()) {
return null;
}
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 0ffd3b0..e76de02 100644
--- a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
+++ b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
@@ -19,6 +19,8 @@
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.ScriptInjector;
+import com.google.gwt.core.client.js.JsFunction;
+import com.google.gwt.core.client.js.JsType;
import com.google.gwt.junit.client.GWTTestCase;
import java.util.Iterator;
@@ -360,4 +362,74 @@
assertFalse("Field '" + field + "' should not be exported", hasField(obj, field));
}
}
+
+ @JsType
+ interface SimpleJsTypeFieldInterface {
+ }
+
+ static class SimpleJsTypeFieldClass implements SimpleJsTypeFieldInterface {
+ }
+
+ @JsType
+ static class SimpleJsTypeWithField {
+ public SimpleJsTypeFieldInterface someField;
+ }
+
+ public void testJsTypeField() {
+ new SimpleJsTypeFieldClass();
+ SimpleJsTypeWithField holder = new SimpleJsTypeWithField();
+ fillJsTypeField(holder);
+ SimpleJsTypeFieldInterface someField = holder.someField;
+ assertNotNull(someField);
+ }
+
+ private native void fillJsTypeField(SimpleJsTypeWithField jstype) /*-{
+ jstype.someField = {};
+ }-*/;
+
+ @JsType
+ interface InterfaceWithSingleJavaConcrete {
+ int m();
+ }
+
+ static class JavaConcrete implements InterfaceWithSingleJavaConcrete {
+ public int m() {
+ return 5;
+ }
+ }
+
+ private native Object nativeObjectImplementingM() /*-{
+ return {m: function() { return 3;} }
+ }-*/;
+
+ public void testSingleJavaConcreteInterface() {
+ // Create a couple of instances and use the objects in some way to avoid complete pruning
+ // of JavaConcrete
+ assertTrue(new JavaConcrete() != new JavaConcrete());
+ assertSame(5, new JavaConcrete().m());
+ assertSame(3, ((InterfaceWithSingleJavaConcrete) nativeObjectImplementingM()).m());
+ }
+
+ @JsFunction
+ interface JsFunctionInterface {
+ int m();
+ }
+
+ static class JavaConcreteJsFunction implements JsFunctionInterface {
+ public int m() {
+ return 5;
+ }
+ }
+
+ private native Object nativeJsFunction() /*-{
+ return function() { return 3;};
+ }-*/;
+
+ public void testSingleJavaConcreteJsFunction() {
+ // Create a couple of instances and use the objects in some way to avoid complete pruning
+ // of JavaConcrete
+ assertTrue(new JavaConcreteJsFunction() != new JavaConcreteJsFunction());
+ assertSame(5, new JavaConcreteJsFunction().m());
+ assertSame(3, ((JsFunctionInterface) nativeJsFunction()).m());
+ }
}