Disallow concrete @JsProperty on static methods.
Only allow native @JsProperty on static methods for now.
Change-Id: I218fa5fe4aec99c86da5a5bba20ed16dee911331
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 899aaf6..583431e 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
@@ -400,8 +400,10 @@
}
private boolean checkJsPropertyAccessor(JMember member) {
+ JsMemberType memberType = member.getJsMemberType();
+
if (member.getJsName().equals(JsInteropUtil.INVALID_JSNAME)) {
- assert member.getJsMemberType().isPropertyAccessor();
+ assert memberType.isPropertyAccessor();
logError(
member,
"JsProperty %s should either follow Java Bean naming conventions or provide a name.",
@@ -409,24 +411,30 @@
return false;
}
- if (member.getJsMemberType() == JsMemberType.UNDEFINED_ACCESSOR) {
- logError(member, "JsProperty %s should have a correct setter or getter signature.",
- getMemberDescription(member));
+ switch (memberType) {
+ case UNDEFINED_ACCESSOR:
+ logError(member, "JsProperty %s should have a correct setter or getter signature.",
+ getMemberDescription(member));
+ break;
+ case GETTER:
+ if (member.getType() != JPrimitiveType.BOOLEAN && member.getName().startsWith("is")) {
+ logError(member, "JsProperty %s cannot have a non-boolean return.",
+ getMemberDescription(member));
+ }
+ break;
+ case SETTER:
+ if (((JMethod) member).getParams().get(0).isVarargs()) {
+ logError(member, "JsProperty %s cannot have a vararg parameter.",
+ getMemberDescription(member));
+ }
+ break;
}
- if (member.getJsMemberType() == JsMemberType.GETTER) {
- if (member.getType() != JPrimitiveType.BOOLEAN && member.getName().startsWith("is")) {
- logError(member, "JsProperty %s cannot have a non-boolean return.",
- getMemberDescription(member));
- }
+ if (memberType.isPropertyAccessor() && member.isStatic() && !member.isJsNative()) {
+ logError(member, "Static property accessor '%s' can only be native.",
+ JjsUtils.getReadableDescription(member));
}
- if (member.getJsMemberType() == JsMemberType.SETTER) {
- if (((JMethod) member).getParams().get(0).isVarargs()) {
- logError(member, "JsProperty %s cannot have a vararg parameter.",
- getMemberDescription(member));
- }
- }
return true;
}
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 abbff0b..7bd4b60 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
@@ -143,13 +143,13 @@
addSnippetImport("jsinterop.annotations.JsProperty");
addSnippetClassDecl(
"@JsType",
- "public interface Buggy {",
- " @JsProperty static int getStaticX(){ return 0;}",
- " @JsProperty static void setStaticX(int x){}",
- " @JsProperty int getX();",
- " @JsProperty void setX(int x);",
- " @JsProperty boolean isY();",
- " @JsProperty void setY(boolean y);",
+ "public abstract static class Buggy {",
+ " @JsProperty static native int getStaticX();",
+ " @JsProperty static native void setStaticX(int x);",
+ " @JsProperty abstract int getX();",
+ " @JsProperty abstract void setX(int x);",
+ " @JsProperty abstract boolean isY();",
+ " @JsProperty abstract void setY(boolean y);",
"}");
assertBuggySucceeds();
@@ -159,7 +159,6 @@
addSnippetImport("jsinterop.annotations.JsType");
addSnippetImport("jsinterop.annotations.JsProperty");
addSnippetClassDecl(
- "@JsType",
"public interface Buggy {",
" @JsProperty int isX();",
" @JsProperty int getY(int x);",
@@ -172,20 +171,20 @@
"}");
assertBuggyFails(
- "Line 7: JsProperty 'int EntryPoint.Buggy.isX()' cannot have a non-boolean return.",
- "Line 8: JsProperty 'int EntryPoint.Buggy.getY(int)' should have a correct setter "
+ "Line 6: JsProperty 'int EntryPoint.Buggy.isX()' cannot have a non-boolean return.",
+ "Line 7: JsProperty 'int EntryPoint.Buggy.getY(int)' should have a correct setter "
+ "or getter signature.",
- "Line 9: JsProperty 'void EntryPoint.Buggy.getZ()' should have a correct setter "
+ "Line 8: JsProperty 'void EntryPoint.Buggy.getZ()' should have a correct setter "
+ "or getter signature.",
- "Line 10: JsProperty 'void EntryPoint.Buggy.setX(int, int)' should have a correct setter "
+ "Line 9: JsProperty 'void EntryPoint.Buggy.setX(int, int)' should have a correct setter "
+ "or getter signature.",
- "Line 11: JsProperty 'void EntryPoint.Buggy.setY()' should have a correct setter "
+ "Line 10: JsProperty 'void EntryPoint.Buggy.setY()' should have a correct setter "
+ "or getter signature.",
- "Line 12: JsProperty 'int EntryPoint.Buggy.setZ(int)' should have a correct setter "
+ "Line 11: JsProperty 'int EntryPoint.Buggy.setZ(int)' should have a correct setter "
+ "or getter signature.",
- "Line 13: JsProperty 'void EntryPoint.Buggy.setStatic()' should have a correct setter "
+ "Line 12: JsProperty 'void EntryPoint.Buggy.setStatic()' should have a correct setter "
+ "or getter signature.",
- "Line 14: JsProperty 'void EntryPoint.Buggy.setW(int[])' cannot have a vararg parameter.");
+ "Line 13: JsProperty 'void EntryPoint.Buggy.setW(int[])' cannot have a vararg parameter.");
}
public void testJsPropertyNonGetterStyleFails() throws Exception {
@@ -286,7 +285,8 @@
+ "cannot both use the same JavaScript name 'x'.");
}
- public void testCollidingPropertyAccessorExportsFails() throws Exception {
+ // TODO(rluble): enable when static property definitions are implemented.
+ public void __disabled__testCollidingPropertyAccessorExportsFails() throws Exception {
addSnippetImport("jsinterop.annotations.JsProperty");
addSnippetClassDecl(
"public static class Buggy {",
@@ -318,7 +318,8 @@
+ "by 'void EntryPoint.Buggy.show()'.");
}
- public void testCollidingMethodToPropertyAccessorExportsFails() throws Exception {
+ // TODO(rluble): enable when static property definitions are implemented.
+ public void __disabled__testCollidingMethodToPropertyAccessorExportsFails() throws Exception {
addSnippetImport("jsinterop.annotations.JsMethod");
addSnippetImport("jsinterop.annotations.JsProperty");
addSnippetClassDecl(
@@ -824,6 +825,18 @@
"Line 9: Cannot call property accessor 'int EntryPoint.Super.getX()' via super.");
}
+ public void testJsPropertyOnStaticMethodFails() {
+ addSnippetImport("jsinterop.annotations.JsType");
+ addSnippetImport("jsinterop.annotations.JsProperty");
+ addSnippetClassDecl(
+ "@JsType public static class Buggy {",
+ " @JsProperty public static int getX() { return 0; }",
+ "}");
+
+ assertBuggyFails(
+ "Line 6: Static property accessor 'int EntryPoint.Buggy.getX()' can only be native.");
+ }
+
public void testJsPropertyCallSucceeds() throws Exception {
addSnippetImport("jsinterop.annotations.JsType");
addSnippetImport("jsinterop.annotations.JsProperty");