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();