Add native JsType checks to JsInteropRestriction checker.

Change-Id: I13a996af4353a5d02af9a311aefce5dd71f988fa
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 f6a7822..85f4c84 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
@@ -499,8 +499,6 @@
   }
 
   private boolean checkNativeJsType(JDeclaredType type) {
-    // TODO(rluble): add inheritance restrictions.
-
     if (type.isEnumOrSubclass() != null) {
       logError("Enum '%s' cannot be a native JsType.", type);
       return false;
@@ -511,6 +509,20 @@
       return false;
     }
 
+    JClassType superClass = type.getSuperClass();
+    if (superClass != null && superClass != jprogram.getTypeJavaLangObject() &&
+        !superClass.isJsNative()) {
+      logError("Native JsType '%s' can only extend native JsType classes.", type);
+    }
+
+    for (JInterfaceType interfaceType : type.getImplements()) {
+      if (!interfaceType.isJsNative()) {
+        logError(type, "Native JsType '%s' can only %s native JsType interfaces.",
+            getDescription(type),
+            type instanceof JInterfaceType ? "extend" : "implement");
+      }
+    }
+
     if (!isClinitEmpty(type)) {
       logError("Native JsType '%s' cannot have static initializer.", type);
     }
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 139f50a..5b17008 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
@@ -1280,6 +1280,66 @@
     assertBuggySucceeds();
   }
 
+  public void testNativeJsTypeExtendsJsTypeFails() {
+    addSnippetImport("jsinterop.annotations.JsType");
+    addSnippetClassDecl(
+        "@JsType public static class Super {",
+        "}",
+        "@JsType(isNative=true) public static class Buggy extends Super {",
+        "}");
+
+    assertBuggyFails(
+        "Line 6: Native JsType 'EntryPoint.Buggy' can only extend native JsType classes.");
+  }
+
+  public void testNativeJsTypeImplementsJsTypeInterfaceFails() {
+    addSnippetImport("jsinterop.annotations.JsType");
+    addSnippetClassDecl(
+        "@JsType public interface Interface {",
+        "}",
+        "@JsType(isNative=true) public static class Buggy implements Interface {",
+        "}");
+
+    assertBuggyFails(
+        "Line 6: Native JsType ''EntryPoint.Buggy'' can only implement native JsType interfaces.");
+  }
+
+  public void testNativeJsTypeInterfaceExtendsJsTypeInterfaceFails() {
+    addSnippetImport("jsinterop.annotations.JsType");
+    addSnippetClassDecl(
+        "@JsType public interface Interface {",
+        "}",
+        "@JsType(isNative=true) public interface Buggy extends Interface {",
+        "}");
+
+    assertBuggyFails(
+        "Line 6: Native JsType ''EntryPoint.Buggy'' can only extend native JsType interfaces.");
+  }
+
+  public void testNativeJsTypeImplementsNonJsTypeFails() {
+    addSnippetImport("jsinterop.annotations.JsType");
+    addSnippetClassDecl(
+        "public interface Super {",
+        "}",
+        "@JsType(isNative=true) public static class Buggy implements Super {",
+        "}");
+
+    assertBuggyFails(
+        "Line 6: Native JsType ''EntryPoint.Buggy'' can only implement native JsType interfaces.");
+  }
+
+  public void testNativeJsTypeInterfaceExtendsNonJsTypeFails() {
+    addSnippetImport("jsinterop.annotations.JsType");
+    addSnippetClassDecl(
+        "public interface Super {",
+        "}",
+        "@JsType(isNative=true) public interface Buggy extends Super {",
+        "}");
+
+    assertBuggyFails(
+        "Line 6: Native JsType ''EntryPoint.Buggy'' can only extend native JsType interfaces.");
+  }
+
   public void testJsOverlayOnNativeJsTypeMemberSucceeds() throws Exception {
     addSnippetImport("jsinterop.annotations.JsType");
     addSnippetImport("jsinterop.annotations.JsOverlay");