Add JsPropertyChecks to JsInteropRestrictionChecker.
Change-Id: I9ba1da90676484915c99fdbb350e62c6444d46b6
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 ee338e1..fb3faf9 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
@@ -16,6 +16,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.MinimalRebuildCache;
+import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpressionStatement;
@@ -29,6 +30,7 @@
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JStatement;
import com.google.gwt.dev.jjs.ast.JType;
+import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.thirdparty.guava.common.base.Predicate;
import com.google.gwt.thirdparty.guava.common.collect.FluentIterable;
import com.google.gwt.thirdparty.guava.common.collect.Iterables;
@@ -275,6 +277,21 @@
}
}
+ private void checkNoStaticJsPropertyCalls() {
+ new JVisitor() {
+ @Override
+ public void endVisit(JMethodCall x, Context ctx) {
+ JMethod target = x.getTarget();
+ if (x.isStaticDispatchOnly() && target.isJsPropertyAccessor()) {
+ logError("Cannot call property accessor '%s' via super (%s:%d).",
+ target.getQualifiedName(),
+ x.getSourceInfo().getFileName(),
+ x.getSourceInfo().getStartLine());
+ }
+ }
+ }.accept(jprogram);
+ }
+
private void checkJsNative(JDeclaredType type) {
// TODO(rluble): add inheritance restrictions.
if (!JjsUtils.isClinitEmpty(type)) {
@@ -326,6 +343,7 @@
for (JDeclaredType type : jprogram.getModuleDeclaredTypes()) {
checkType(type);
}
+ checkNoStaticJsPropertyCalls();
}
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 b5a4bdd..a6e4b10 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
@@ -257,11 +257,11 @@
assertBuggyFails(
"The JsType member 'test.EntryPoint$IBuggy.x(Z)Z' and JsProperty "
- + "'test.EntryPoint$IBuggy.setX(I)V' can't both be named 'x' in "
- + "type 'test.EntryPoint$IBuggy'.",
+ + "'test.EntryPoint$IBuggy.setX(I)V' can't both be named 'x' in "
+ + "type 'test.EntryPoint$IBuggy'.",
"The JsType member 'test.EntryPoint$Buggy.x(Z)Z' and JsProperty "
- + "'test.EntryPoint$Buggy.setX(I)V' can't both be named 'x' in "
- + "type 'test.EntryPoint$Buggy'.");
+ + "'test.EntryPoint$Buggy.setX(I)V' can't both be named 'x' in "
+ + "type 'test.EntryPoint$Buggy'.");
}
public void testCollidingMethodExportsFails() throws Exception {
@@ -276,7 +276,7 @@
assertBuggyFails(
"Member 'test.EntryPoint$Buggy.display()V' can't be exported "
- + "because the global name 'test.EntryPoint.Buggy.show' is already taken.");
+ + "because the global name 'test.EntryPoint.Buggy.show' is already taken.");
}
public void testCollidingMethodToFieldExportsFails() throws Exception {
@@ -637,6 +637,59 @@
+ "'test.EntryPoint$Exported' is not a JsType.");
}
+ public void testJsPropertySuperCallFails()
+ throws UnableToCompleteException {
+ addSnippetImport("com.google.gwt.core.client.js.JsType");
+ addSnippetImport("com.google.gwt.core.client.js.JsProperty");
+ addSnippetClassDecl(
+ "@JsType public static class Super {",
+ " @JsProperty public int getX() { return 5; }",
+ "}",
+ "@JsType public static class Buggy extends Super {",
+ " public int m() { return super.getX(); }",
+ "}");
+
+ assertBuggyFails(
+ "Cannot call property accessor 'test.EntryPoint$Super.getX()I' via super "
+ + "(test/EntryPoint.java:9).");
+ }
+
+ public void testJsPropertyCallSucceeds()
+ throws UnableToCompleteException {
+ addSnippetImport("com.google.gwt.core.client.js.JsType");
+ addSnippetImport("com.google.gwt.core.client.js.JsProperty");
+ addSnippetClassDecl(
+ "@JsType public static class Super {",
+ " @JsProperty public int getX() { return 5; }",
+ "}",
+ "@JsType public static class Buggy extends Super {",
+ " public int m() { return getX(); }",
+ "}");
+
+ assertBuggySucceeds();
+ }
+
+ // TODO(rluble): this test should succeed, fix after eliminating the accidental overrides.
+ public void testJsPropertyAccidentalSuperCallFails()
+ throws UnableToCompleteException {
+ addSnippetImport("com.google.gwt.core.client.js.JsType");
+ addSnippetImport("com.google.gwt.core.client.js.JsProperty");
+ addSnippetClassDecl(
+ "@JsType public static class Super {",
+ " @JsProperty public int getX() { return 5; }",
+ "}",
+ "@JsType public interface Interface {",
+ " @JsProperty int getX();",
+ "}",
+
+ "@JsType public static class Buggy extends Super implements Interface {",
+ "}");
+
+ assertBuggyFails(
+ "Cannot call property accessor 'test.EntryPoint$Super.getX()I' via super "
+ + "(test/EntryPoint.java:6).");
+ }
+
public void testMultiplePrivateConstructorsExportSucceeds() throws Exception {
addSnippetImport("com.google.gwt.core.client.js.JsExport");
addSnippetClassDecl(