Relax name checking native items on the JsPackage.GLOBAL namespace.
Allow qualifed names as the name component in native JsType, JsMethod,
JsProperty definitions.
Change-Id: I617b8ac0eb8bf935143c4c57667b9790399cc2d9
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/CanBeJsNative.java b/dev/core/src/com/google/gwt/dev/jjs/ast/CanBeJsNative.java
new file mode 100644
index 0000000..973604e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/CanBeJsNative.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.jjs.ast;
+
+/**
+ * Interface implemented by Java entities that can be declared native in JsInterop.
+ */
+public interface CanBeJsNative {
+ boolean isJsNative();
+}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java b/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java
index f0b70ab..23e0196 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java
@@ -22,7 +22,7 @@
/**
* Abstracts JsInterop information for the AST nodes.
*/
-public interface HasJsInfo extends HasJsName {
+public interface HasJsInfo extends HasJsName, CanBeJsNative {
/**
* Indicates type of JsMember.
*/
@@ -127,8 +127,6 @@
JsMemberType getJsMemberType();
- boolean isJsNative();
-
boolean isJsMethodVarargs();
boolean isJsOverlay();
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsName.java b/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsName.java
index bab517b..e3f66f1 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsName.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsName.java
@@ -18,7 +18,7 @@
/**
* Abstracts JsInterop name related information for the AST nodes.
*/
-public interface HasJsName {
+public interface HasJsName {
String getJsName();
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
index 86012c5..06b972e 100755
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
@@ -52,7 +52,7 @@
* initializer in the superclass chain needs to be called.
*/
public abstract class JDeclaredType extends JReferenceType
- implements CanHaveSuppressedWarnings, HasJsName {
+ implements CanHaveSuppressedWarnings, HasJsName, CanBeJsNative {
private boolean isJsFunction;
private boolean isJsType;
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 bd6885a..0b07d85 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
@@ -18,6 +18,7 @@
import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.javac.JsInteropUtil;
import com.google.gwt.dev.jjs.HasSourceInfo;
+import com.google.gwt.dev.jjs.ast.CanBeJsNative;
import com.google.gwt.dev.jjs.ast.CanHaveSuppressedWarnings;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.HasJsInfo.JsMemberType;
@@ -563,9 +564,15 @@
checkJsNamespace(member);
}
- private <T extends HasJsName & HasSourceInfo> void checkJsName(T item) {
+ private <T extends HasJsName & HasSourceInfo & CanBeJsNative> void checkJsName(T item) {
if (item.getJsName().isEmpty()) {
logError(item, "%s cannot have an empty name.", getDescription(item));
+ } else if (JsInteropUtil.isGlobal(item.getJsNamespace()) && item.isJsNative()) {
+ // Allow qualified names in the name field for JsPackage.GLOBAL native items for future
+ // compatibility
+ if (!JsUtils.isValidJsQualifiedName(item.getJsName())) {
+ logError(item, "%s has invalid name '%s'.", getDescription(item), item.getJsName());
+ }
} else if (!JsUtils.isValidJsIdentifier(item.getJsName())) {
logError(item, "%s has invalid name '%s'.", getDescription(item), item.getJsName());
}
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 bf7fcce..7c53281 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
@@ -1174,19 +1174,28 @@
public void testJsNameInvalidNamesFails() {
addSnippetImport("jsinterop.annotations.JsType");
addSnippetImport("jsinterop.annotations.JsMethod");
+ addSnippetImport("jsinterop.annotations.JsPackage");
addSnippetImport("jsinterop.annotations.JsProperty");
addSnippetClassDecl(
"@JsType(name = \"a.b.c\") public static class Buggy {",
" @JsMethod(name = \"34s\") public void m() {}",
" @JsProperty(name = \"s^\") public int m;",
" @JsProperty(name = \"\") public int n;",
- "}");
+ " @JsMethod(namespace = JsPackage.GLOBAL, name = \"a.b\") static void o() {}",
+ " @JsProperty(namespace = JsPackage.GLOBAL, name = \"a.c\") static int q;",
+ "}",
+ "@JsType(namespace=JsPackage.GLOBAL, name = \"a.b.d\") public static class OtherBuggy {",
+ "}"
+ );
assertBuggyFails(
- "Line 6: 'EntryPoint.Buggy' has invalid name 'a.b.c'.",
- "Line 7: 'void EntryPoint.Buggy.m()' has invalid name '34s'.",
- "Line 8: 'int EntryPoint.Buggy.m' has invalid name 's^'.",
- "Line 9: 'int EntryPoint.Buggy.n' cannot have an empty name.");
+ "Line 7: 'EntryPoint.Buggy' has invalid name 'a.b.c'.",
+ "Line 8: 'void EntryPoint.Buggy.m()' has invalid name '34s'.",
+ "Line 9: 'int EntryPoint.Buggy.m' has invalid name 's^'.",
+ "Line 10: 'int EntryPoint.Buggy.n' cannot have an empty name.",
+ "Line 11: 'void EntryPoint.Buggy.o()' has invalid name 'a.b'.",
+ "Line 12: 'int EntryPoint.Buggy.q' has invalid name 'a.c'.",
+ "Line 14: 'EntryPoint.OtherBuggy' has invalid name 'a.b.d'.");
}
public void testJsNameInvalidNamespacesFails() {
@@ -1219,7 +1228,14 @@
addSnippetClassDecl(
"@JsType(namespace = JsPackage.GLOBAL) public static class Buggy {",
" @JsMethod(namespace = JsPackage.GLOBAL) public static void m() {}",
- " @JsProperty(namespace = JsPackage.GLOBAL) public static int n;",
+ " @JsProperty(namespace = JsPackage.GLOBAL) public static int n;",
+ " @JsMethod(namespace = JsPackage.GLOBAL, name = \"a.b\") public static native void o();",
+ "}",
+ "@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = \"a.c\")",
+ "public static class OtherBuggy {",
+ " @JsMethod(namespace = JsPackage.GLOBAL, name = \"a.d\") static native void o();",
+ " @JsMethod(namespace = JsPackage.GLOBAL, name = \"a.e\") static native void getP();",
+ " @JsProperty(namespace = JsPackage.GLOBAL, name = \"a.f\") public static int n;",
"}");
assertBuggySucceeds();