Disallow instanceof JsFunction implementations.
JsFunction implemetnations are meant to be lightweight enough
to make it possible to generate them as plain JsFunctions.
Change-Id: I1f6bb0b9d013653cb1ffe26b6f23e6684ef856bb
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java
index 063e6d7..3f8dc71 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java
@@ -609,7 +609,7 @@
}.accept(jprogram);
}
- private void checkInstanceOfNativeJsTypes() {
+ private void checkInstanceOfNativeJsTypesOrJsFunctionImplementations() {
new JVisitor() {
@Override
public boolean visit(JInstanceOf x, Context ctx) {
@@ -617,6 +617,9 @@
if (type.isJsNative() && type instanceof JInterfaceType) {
logError(x, "Cannot do instanceof against native JsType interface '%s'.",
JjsUtils.getReadableDescription(type));
+ } else if (type.isJsFunctionImplementation()) {
+ logError(x, "Cannot do instanceof against JsFunction implementation '%s'.",
+ JjsUtils.getReadableDescription(type));
}
return true;
}
@@ -721,7 +724,7 @@
checkType(type);
}
checkStaticJsPropertyCalls();
- checkInstanceOfNativeJsTypes();
+ checkInstanceOfNativeJsTypesOrJsFunctionImplementations();
if (wasUnusableByJsWarningReported) {
logSuggestion(
"Suppress \"[unusable-by-js]\" warnings by adding a "
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java
index f76803b..1e37df0 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java
@@ -1257,6 +1257,19 @@
"Line 6: JsFunction 'EntryPoint.Buggy' cannot have static initializer.");
}
+ public void testJsFunctionImplementationInInstanceofFails() throws Exception {
+ addSnippetImport("jsinterop.annotations.JsFunction");
+ addSnippetClassDecl(
+ "@JsFunction interface Function { void m(); }",
+ "final static class FunctionImplementation implements Function { public void m() {} ; }",
+ "public static class Buggy {",
+ " public Buggy() { if (new Object() instanceof FunctionImplementation) {} }",
+ "}");
+
+ assertBuggyFails("Line 7: Cannot do instanceof against JsFunction implementation "
+ + "'EntryPoint.FunctionImplementation'.");
+ }
+
public void testNativeJsTypeStaticInitializerFails() {
addSnippetImport("jsinterop.annotations.JsType");
addSnippetClassDecl(
diff --git a/user/test/com/google/gwt/core/interop/JsFunctionTest.java b/user/test/com/google/gwt/core/interop/JsFunctionTest.java
index 8423f77..4f74b93 100644
--- a/user/test/com/google/gwt/core/interop/JsFunctionTest.java
+++ b/user/test/com/google/gwt/core/interop/JsFunctionTest.java
@@ -213,7 +213,6 @@
assertTrue(object instanceof MyJsFunctionInterface);
assertTrue(object instanceof MyJsFunctionIdentityInterface);
assertTrue(object instanceof MyJsFunctionWithOnlyInstanceofReference);
- assertFalse(object instanceof MyJsFunctionInterfaceImpl);
}
public void testInstanceOf_jsObject() {
@@ -221,13 +220,11 @@
assertFalse(object instanceof MyJsFunctionInterface);
assertFalse(object instanceof MyJsFunctionIdentityInterface);
assertFalse(object instanceof MyJsFunctionWithOnlyInstanceofReference);
- assertFalse(object instanceof MyJsFunctionInterfaceImpl);
}
public void testInstanceOf_javaInstance() {
Object object = new MyJsFunctionInterfaceImpl();
assertTrue(object instanceof MyJsFunctionInterface);
- assertTrue(object instanceof MyJsFunctionInterfaceImpl);
assertTrue(object instanceof MyJsFunctionIdentityInterface);
assertTrue(object instanceof MyJsFunctionWithOnlyInstanceofReference);
assertFalse(object instanceof HTMLElementConcreteNativeJsType);