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);