Fail on instanceof native JsType interface. This is considered a programming error as native JsType interfaces are castable to any type. Change-Id: Ia5b081a370957504de7186a00f331f8286eef80c
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 87d8612..e332910 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
@@ -26,6 +26,8 @@ import com.google.gwt.dev.jjs.ast.JExpression; import com.google.gwt.dev.jjs.ast.JExpressionStatement; import com.google.gwt.dev.jjs.ast.JField; +import com.google.gwt.dev.jjs.ast.JInstanceOf; +import com.google.gwt.dev.jjs.ast.JInterfaceType; import com.google.gwt.dev.jjs.ast.JMember; import com.google.gwt.dev.jjs.ast.JMethod; import com.google.gwt.dev.jjs.ast.JMethod.JsPropertyAccessorType; @@ -34,6 +36,7 @@ import com.google.gwt.dev.jjs.ast.JParameter; import com.google.gwt.dev.jjs.ast.JPrimitiveType; import com.google.gwt.dev.jjs.ast.JProgram; +import com.google.gwt.dev.jjs.ast.JReferenceType; import com.google.gwt.dev.jjs.ast.JStatement; import com.google.gwt.dev.jjs.ast.JType; import com.google.gwt.dev.jjs.ast.JVisitor; @@ -50,10 +53,6 @@ /** * Checks and throws errors for invalid JsInterop constructs. */ -// TODO: handle custom JsType field/method names when that feature exists. -// TODO: move JsInterop checks from JSORestrictionsChecker to here. -// TODO: provide more information in global name collisions as it could be difficult to pinpoint in -// big projects. public class JsInteropRestrictionChecker { public static void exec(TreeLogger logger, JProgram jprogram, @@ -61,7 +60,7 @@ JsInteropRestrictionChecker jsInteropRestrictionChecker = new JsInteropRestrictionChecker(logger, jprogram, minimalRebuildCache); - jsInteropRestrictionChecker.checkProgram(jprogram); + jsInteropRestrictionChecker.checkProgram(); if (jsInteropRestrictionChecker.hasErrors) { throw new UnableToCompleteException(); } @@ -93,7 +92,7 @@ */ private static boolean isConstructorEmpty(final JConstructor constructor) { List<JStatement> statements = FluentIterable - .from(((JMethodBody) constructor.getBody()).getStatements()) + .from(constructor.getBody().getStatements()) .filter(new Predicate<JStatement>() { @Override public boolean apply(JStatement statement) { @@ -378,7 +377,7 @@ } } - private void checkNoStaticJsPropertyCalls() { + private void checkStaticJsPropertyCalls() { new JVisitor() { @Override public boolean visit(JMethod x, Context ctx) { @@ -399,6 +398,22 @@ }.accept(jprogram); } + private void checkInstanceOfNativeJsTypes() { + new JVisitor() { + @Override + public boolean visit(JInstanceOf x, Context ctx) { + JReferenceType type = x.getTestType(); + if (type.isJsNative() && type instanceof JInterfaceType) { + logError("Cannot do instanceof against native JsType interface %s (%s:%d).", + type.getName(), + x.getSourceInfo().getFileName(), + x.getSourceInfo().getStartLine()); + } + return true; + } + }.accept(jprogram); + } + private void checkNativeJsType(JDeclaredType type) { // TODO(rluble): add inheritance restrictions. if (type.isEnumOrSubclass() != null) { @@ -457,11 +472,12 @@ } } - private void checkProgram(JProgram jprogram) { + private void checkProgram() { for (JDeclaredType type : jprogram.getModuleDeclaredTypes()) { checkType(type); } - checkNoStaticJsPropertyCalls(); + checkStaticJsPropertyCalls(); + checkInstanceOfNativeJsTypes(); } private void checkType(JDeclaredType 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 3886569..f652546 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
@@ -992,6 +992,18 @@ assertBuggySucceeds(); } + public void testJsTypeInterfaceInInstanceofFails() throws Exception { + addSnippetImport("jsinterop.annotations.JsType"); + addSnippetClassDecl( + "@JsType(isNative=true) public interface IBuggy {}", + "@JsType public static class Buggy {", + " public Buggy() { if (new Object() instanceof IBuggy) {} }", + "}"); + + assertBuggyFails("Cannot do instanceof against native JsType interface test.EntryPoint$IBuggy " + + "(test/EntryPoint.java:6)."); + } + public void testNativeJsTypeEnumFails() { addSnippetImport("jsinterop.annotations.JsType"); addSnippetClassDecl(
diff --git a/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java b/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java index 5e55044..b775f46 100644 --- a/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java +++ b/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java
@@ -209,7 +209,6 @@ assertTrue(object instanceof MyJsFunctionIdentityInterface); assertTrue(object instanceof MyJsFunctionWithOnlyInstanceofReference); assertFalse(object instanceof MyJsFunctionInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); } public void testInstanceOf_jsObject() { @@ -218,7 +217,6 @@ assertFalse(object instanceof MyJsFunctionIdentityInterface); assertFalse(object instanceof MyJsFunctionWithOnlyInstanceofReference); assertFalse(object instanceof MyJsFunctionInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); } public void testInstanceOf_javaInstance() { @@ -227,7 +225,6 @@ assertTrue(object instanceof MyJsFunctionInterfaceImpl); assertTrue(object instanceof MyJsFunctionIdentityInterface); assertTrue(object instanceof MyJsFunctionWithOnlyInstanceofReference); - assertTrue(object instanceof ElementLikeNativeInterface); assertFalse(object instanceof HTMLElementConcreteNativeJsType); }
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 f84b0f0..7e24cf9 100644 --- a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java +++ b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
@@ -15,8 +15,6 @@ */ package com.google.gwt.core.client.interop; -import static com.google.gwt.core.client.ScriptInjector.TOP_WINDOW; - import static jsinterop.annotations.JsPackage.GLOBAL; import com.google.gwt.core.client.JavaScriptObject; @@ -46,7 +44,8 @@ ScriptInjector.fromString("function JsTypeTest_MyNativeJsType() {}\n" + "JsTypeTest_MyNativeJsType.prototype.sum = " + " function sum(bias) { return this.y + bias; };") - .setWindow(TOP_WINDOW).inject(); + .setWindow(ScriptInjector.TOP_WINDOW) + .inject(); } public void testVirtualUpRefs() { @@ -213,12 +212,9 @@ assertFalse(object instanceof HTMLButtonElement); assertFalse(object instanceof HTMLElementConcreteNativeJsType); assertFalse(object instanceof Iterator); - assertTrue(object instanceof MyNativeJsTypeInterface); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); assertFalse(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference); - assertTrue(object instanceof MyNativeJsTypeInterfaceAndOnlyInstanceofReference); assertTrue(object instanceof AliasToMyNativeJsTypeWithOnlyInstanceofReference); assertFalse(object instanceof ConcreteJsType); } @@ -231,12 +227,9 @@ assertFalse(object instanceof HTMLButtonElement); assertFalse(object instanceof HTMLElementConcreteNativeJsType); assertFalse(object instanceof Iterator); - assertTrue(object instanceof MyNativeJsTypeInterface); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); assertFalse(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference); - assertTrue(object instanceof MyNativeJsTypeInterfaceAndOnlyInstanceofReference); assertFalse(object instanceof AliasToMyNativeJsTypeWithOnlyInstanceofReference); assertFalse(object instanceof ConcreteJsType); } @@ -249,12 +242,9 @@ assertTrue(object instanceof HTMLButtonElement); assertTrue(object instanceof HTMLElementConcreteNativeJsType); assertFalse(object instanceof Iterator); - assertTrue(object instanceof MyNativeJsTypeInterface); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); assertFalse(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference); - assertTrue(object instanceof MyNativeJsTypeInterfaceAndOnlyInstanceofReference); assertFalse(object instanceof AliasToMyNativeJsTypeWithOnlyInstanceofReference); assertFalse(object instanceof ConcreteJsType); } @@ -268,12 +258,9 @@ assertFalse(object instanceof HTMLButtonElement); assertFalse(object instanceof HTMLElementConcreteNativeJsType); assertFalse(object instanceof Iterator); - assertTrue(object instanceof MyNativeJsTypeInterface); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); assertTrue(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference); - assertTrue(object instanceof MyNativeJsTypeInterfaceAndOnlyInstanceofReference); assertFalse(object instanceof AliasToMyNativeJsTypeWithOnlyInstanceofReference); assertFalse(object instanceof ConcreteJsType); } @@ -287,12 +274,9 @@ assertFalse(object instanceof HTMLButtonElement); assertFalse(object instanceof HTMLElementConcreteNativeJsType); assertFalse(object instanceof Iterator); - assertTrue(object instanceof MyNativeJsTypeInterface); assertTrue(object instanceof MyNativeJsTypeInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); assertFalse(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference); - assertTrue(object instanceof MyNativeJsTypeInterfaceAndOnlyInstanceofReference); assertFalse(object instanceof AliasToMyNativeJsTypeWithOnlyInstanceofReference); assertFalse(object instanceof ConcreteJsType); } @@ -306,12 +290,9 @@ assertFalse(object instanceof HTMLButtonElement); assertFalse(object instanceof HTMLElementConcreteNativeJsType); assertFalse(object instanceof Iterator); - assertTrue(object instanceof MyNativeJsTypeInterface); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); assertFalse(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference); - assertTrue(object instanceof MyNativeJsTypeInterfaceAndOnlyInstanceofReference); assertFalse(object instanceof AliasToMyNativeJsTypeWithOnlyInstanceofReference); assertTrue(object instanceof ConcreteJsType); } @@ -325,12 +306,9 @@ assertTrue(object instanceof HTMLButtonElement); assertTrue(object instanceof HTMLElementConcreteNativeJsType); assertTrue(object instanceof Iterable); - assertTrue(object instanceof MyNativeJsTypeInterface); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl); - assertTrue(object instanceof ElementLikeNativeInterface); assertFalse(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference); - assertTrue(object instanceof MyNativeJsTypeInterfaceAndOnlyInstanceofReference); assertFalse(object instanceof AliasToMyNativeJsTypeWithOnlyInstanceofReference); assertFalse(object instanceof ConcreteJsType); }