From 659e0bde0abf605a9e89dc41a2ebafc75bdaebac Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 17 Jan 2024 10:48:21 -0800 Subject: [PATCH] Allow for empty JS namespaces to represent top-level symbols We currently don't have a way to overlay a native type that has form: ``` js goog.module('TopLevelClass'); exports = class {}; ``` With this change you'd now represent this as: ``` java @JsType(isNative = true, namespace = "", name = "TopLevelClass") class TopLevelClass {} ``` This all works since we currently treat the first component of the `name` attribute as the last component of the `goog.require` statement for `@JsType`. PiperOrigin-RevId: 599223849 --- .../passes/JsInteropRestrictionsChecker.java | 11 +- .../readable/java/nativejstypes/Main.java | 10 + .../readable/java/nativejstypes/TopLevel.java | 35 ++ .../nativejstypes/native_sources/toplevel.js | 24 ++ .../output_closure/Main.impl.java.js.txt | 13 + .../output_closure/Main.java.js.txt | 1 + .../output_closure/Main.js.mappings.txt | 12 + .../TopLevel$$Overlay.impl.java.js.txt | 25 ++ .../TopLevel$$Overlay.java.js.txt | 8 + .../TopLevel$$Overlay.js.mappings.txt | 4 + .../TopLevel$Nested$$Overlay.impl.java.js.txt | 25 ++ .../TopLevel$Nested$$Overlay.java.js.txt | 8 + .../TopLevel$Nested$$Overlay.js.mappings.txt | 4 + ...lNestedReference$$Overlay.impl.java.js.txt | 25 ++ ...pLevelNestedReference$$Overlay.java.js.txt | 8 + ...elNestedReference$$Overlay.js.mappings.txt | 4 + .../native_sources/toplevel.js.txt | 24 ++ .../output_kt/Main+J2ObjCCompat.h.txt | 4 + .../java/nativejstypes/output_kt/Main.kt.txt | 12 + .../nativejstypes/output_kt/TopLevel.kt.txt | 46 +++ .../nativejstypes/output_wasm/module.wat.txt | 347 ++++++++++++++++++ .../output_wasm_imports/module.imports.js.txt | 7 + .../JsInteropRestrictionsCheckerTest.java | 13 +- 23 files changed, 668 insertions(+), 2 deletions(-) create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/TopLevel.java create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.impl.java.js.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.java.js.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.js.mappings.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.impl.java.js.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.java.js.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.js.mappings.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.impl.java.js.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.java.js.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.js.mappings.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js.txt create mode 100644 transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/TopLevel.kt.txt diff --git a/transpiler/java/com/google/j2cl/transpiler/passes/JsInteropRestrictionsChecker.java b/transpiler/java/com/google/j2cl/transpiler/passes/JsInteropRestrictionsChecker.java index 40e808aee6..a495e9b34b 100644 --- a/transpiler/java/com/google/j2cl/transpiler/passes/JsInteropRestrictionsChecker.java +++ b/transpiler/java/com/google/j2cl/transpiler/passes/JsInteropRestrictionsChecker.java @@ -1102,7 +1102,16 @@ private void checkQualifiedJsName(Type type) { } checkJsName(type); - checkJsNamespace(type); + + String namespace = type.getJsNamespace(); + // Permit empty namespaces on native JsTypes to represent a top-level non-extern type. This + // works since the first component of the name is always used as the last component of the + // import statement. + boolean isValidEmptyNamespace = namespace.isEmpty() && type.getDeclaration().isNative(); + + if (!isValidEmptyNamespace) { + checkJsNamespace(type); + } } private boolean checkQualifiedJsName(Member member) { diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/Main.java b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/Main.java index b4961cedff..28eb2cdb34 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/Main.java +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/Main.java @@ -69,4 +69,14 @@ public static void testNativeTypeObjectMethods() { int unusedHash = bar.hashCode(); boolean unusedEq = bar.equals(new Object()); } + + public static void testTopLevel() { + TopLevel.x = 2; + + TopLevel.Nested nested = new TopLevel.Nested(); + nested.x = 3; + + TopLevelNestedReference topLevelNestedReference = new TopLevelNestedReference(); + topLevelNestedReference.x = 4; + } } diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/TopLevel.java b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/TopLevel.java new file mode 100644 index 0000000000..69cc96ca5f --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/TopLevel.java @@ -0,0 +1,35 @@ +/* + * Copyright 2024 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 nativejstypes; + +import jsinterop.annotations.JsType; + +@JsType(isNative = true, namespace = "", name = "toplevel") +class TopLevel { + private TopLevel() {} + + public static int x; + + @JsType(isNative = true) + static class Nested { + public int x; + } +} + +@JsType(isNative = true, namespace = "", name = "toplevel.Nested") +class TopLevelNestedReference { + public int x; +} diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js new file mode 100644 index 0000000000..c5e5fe8a37 --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js @@ -0,0 +1,24 @@ +// Copyright 2024 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 +// +// https://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. +goog.module('toplevel'); + +exports.Nested = class Nested { + constructor() { + /** @type {number} */ + this.x = 1; + } +}; + +/** @type {number} */ +exports.x = 1; diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.impl.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.impl.java.js.txt index 56843b20a2..c794bcdd9e 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.impl.java.js.txt +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.impl.java.js.txt @@ -7,6 +7,8 @@ let Foo = goog.forwardDeclare('com.acme.MyFoo'); let Class = goog.forwardDeclare('java.lang.Class$impl'); let Bar = goog.forwardDeclare('nativejstypes.Bar'); let $synthetic_nativejstypes_Bar = goog.forwardDeclare('nativejstypes.Bar'); +let TopLevel = goog.forwardDeclare('toplevel'); +let toplevel = goog.forwardDeclare('toplevel'); let $JavaScriptObject = goog.forwardDeclare('vmbootstrap.JavaScriptObject$impl'); let $Objects = goog.forwardDeclare('vmbootstrap.Objects$impl'); @@ -85,6 +87,15 @@ class Main extends j_l_Object { let unusedEq = $Objects.m_equals__java_lang_Object__java_lang_Object__boolean(bar, j_l_Object.$create__()); } /** @nodts */ + static m_testTopLevel__void() { + Main.$clinit(); + TopLevel.x = 2; + let nested = new TopLevel.Nested(); + nested.x = 3; + let topLevelNestedReference = new toplevel.Nested(); + topLevelNestedReference.x = 4; + } + /** @nodts */ static $clinit() { Main.$clinit = () =>{}; Main.$loadModules(); @@ -101,6 +112,8 @@ class Main extends j_l_Object { Class = goog.module.get('java.lang.Class$impl'); Bar = goog.module.get('nativejstypes.Bar'); $synthetic_nativejstypes_Bar = goog.module.get('nativejstypes.Bar'); + TopLevel = goog.module.get('toplevel'); + toplevel = goog.module.get('toplevel'); $JavaScriptObject = goog.module.get('vmbootstrap.JavaScriptObject$impl'); $Objects = goog.module.get('vmbootstrap.Objects$impl'); } diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.java.js.txt index 6a7bc1b49e..7c4b4ebcfa 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.java.js.txt +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.java.js.txt @@ -5,6 +5,7 @@ goog.require('java.lang.Class'); goog.require('java.lang.Object'); goog.require('nativebootstrap.Util'); goog.require('nativejstypes.Bar'); +goog.require('toplevel'); goog.require('vmbootstrap.JavaScriptObject'); goog.require('vmbootstrap.Objects'); diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.js.mappings.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.js.mappings.txt index d7e2ac0c33..64b24448f5 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.js.mappings.txt +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/Main.js.mappings.txt @@ -87,6 +87,18 @@ [unusedHash] => [unusedHash] "unusedHash" [boolean unusedEq = bar.equals(new Object());] => [let unusedEq = $Objects.m_equals__java_lang_Object__java_lang_Object__boolean(bar, j_l_Object.$create__());] "nativejstypes.Main.testNativeTypeObjectMethods" [unusedEq] => [unusedEq] "unusedEq" +[testTopLevel] => [m_testTopLevel__void] +[{ + TopLevel.x = 2; +... topLevelNestedReference.x = 4; + }] => [Main.$clinit();] "nativejstypes.Main.testTopLevel" +[TopLevel.x = 2;] => [TopLevel.x = 2;] "nativejstypes.Main.testTopLevel" +[TopLevel.Nested nested = new TopLevel.Nested();] => [let nested = new TopLevel.Nested();] "nativejstypes.Main.testTopLevel" +[nested] => [nested] "nested" +[nested.x = 3;] => [nested.x = 3;] "nativejstypes.Main.testTopLevel" +[TopLevelNestedReference topLevelNestedReference = new TopLevelNestedReference();] => [let topLevelNestedReference = new toplevel.Nested();] "nativejstypes.Main.testTopLevel" +[topLevelNestedReference] => [topLevelNestedReference] "topLevelNestedReference" +[topLevelNestedReference.x = 4;] => [topLevelNestedReference.x = 4;] "nativejstypes.Main.testTopLevel" [Main] => [$clinit] [Main] => [Main.$clinit = () =>{};] "nativejstypes.Main." [Main] => [Main.$loadModules();] "nativejstypes.Main." diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.impl.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.impl.java.js.txt new file mode 100644 index 0000000000..da5d564c15 --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.impl.java.js.txt @@ -0,0 +1,25 @@ +goog.module('nativejstypes.TopLevel.$Overlay$impl'); + +const $Util = goog.require('nativebootstrap.Util$impl'); +const TopLevel = goog.require('toplevel'); + +/** @nodts */ +class $Overlay { + /** @nodts */ + static $clinit() { + $Overlay.$clinit = () =>{}; + $Overlay.$loadModules(); + } + /** @nodts @return {boolean} */ + static $isInstance(/** ? */ instance) { + return instance instanceof TopLevel; + } + + /** @nodts */ + static $loadModules() {} +} +$Util.$setClassMetadata($Overlay, 'toplevel'); + +exports = $Overlay; + +//# sourceMappingURL=TopLevel$$Overlay.js.map diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.java.js.txt new file mode 100644 index 0000000000..30c470be8f --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.java.js.txt @@ -0,0 +1,8 @@ +goog.module('nativejstypes.TopLevel.$Overlay'); + +goog.require('nativebootstrap.Util'); +goog.require('toplevel'); + +const $Overlay = goog.require('nativejstypes.TopLevel.$Overlay$impl'); +/** @nodts */ +exports = $Overlay; diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.js.mappings.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.js.mappings.txt new file mode 100644 index 0000000000..b83058d278 --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$$Overlay.js.mappings.txt @@ -0,0 +1,4 @@ +[TopLevel] => [$Overlay] +[TopLevel] => [$clinit] +[TopLevel] => [$Overlay.$clinit = () =>{};] "nativejstypes.TopLevel$$Overlay." +[TopLevel] => [$Overlay.$loadModules();] "nativejstypes.TopLevel$$Overlay." diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.impl.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.impl.java.js.txt new file mode 100644 index 0000000000..48970e3098 --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.impl.java.js.txt @@ -0,0 +1,25 @@ +goog.module('nativejstypes.TopLevel.Nested.$Overlay$impl'); + +const $Util = goog.require('nativebootstrap.Util$impl'); +const TopLevel = goog.require('toplevel'); + +/** @nodts */ +class $Overlay { + /** @nodts */ + static $clinit() { + $Overlay.$clinit = () =>{}; + $Overlay.$loadModules(); + } + /** @nodts @return {boolean} */ + static $isInstance(/** ? */ instance) { + return instance instanceof TopLevel.Nested; + } + + /** @nodts */ + static $loadModules() {} +} +$Util.$setClassMetadata($Overlay, 'toplevel.Nested'); + +exports = $Overlay; + +//# sourceMappingURL=TopLevel$Nested$$Overlay.js.map diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.java.js.txt new file mode 100644 index 0000000000..900ca9df3e --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.java.js.txt @@ -0,0 +1,8 @@ +goog.module('nativejstypes.TopLevel.Nested.$Overlay'); + +goog.require('nativebootstrap.Util'); +goog.require('toplevel'); + +const $Overlay = goog.require('nativejstypes.TopLevel.Nested.$Overlay$impl'); +/** @nodts */ +exports = $Overlay; diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.js.mappings.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.js.mappings.txt new file mode 100644 index 0000000000..a1596abe3a --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevel$Nested$$Overlay.js.mappings.txt @@ -0,0 +1,4 @@ +[Nested] => [$Overlay] +[Nested] => [$clinit] +[Nested] => [$Overlay.$clinit = () =>{};] "nativejstypes.TopLevel$Nested$$Overlay." +[Nested] => [$Overlay.$loadModules();] "nativejstypes.TopLevel$Nested$$Overlay." diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.impl.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.impl.java.js.txt new file mode 100644 index 0000000000..1cec7b9afe --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.impl.java.js.txt @@ -0,0 +1,25 @@ +goog.module('nativejstypes.TopLevelNestedReference.$Overlay$impl'); + +const $Util = goog.require('nativebootstrap.Util$impl'); +const toplevel = goog.require('toplevel'); + +/** @nodts */ +class $Overlay { + /** @nodts */ + static $clinit() { + $Overlay.$clinit = () =>{}; + $Overlay.$loadModules(); + } + /** @nodts @return {boolean} */ + static $isInstance(/** ? */ instance) { + return instance instanceof toplevel.Nested; + } + + /** @nodts */ + static $loadModules() {} +} +$Util.$setClassMetadata($Overlay, 'toplevel.Nested'); + +exports = $Overlay; + +//# sourceMappingURL=TopLevelNestedReference$$Overlay.js.map diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.java.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.java.js.txt new file mode 100644 index 0000000000..85f3aa6340 --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.java.js.txt @@ -0,0 +1,8 @@ +goog.module('nativejstypes.TopLevelNestedReference.$Overlay'); + +goog.require('nativebootstrap.Util'); +goog.require('toplevel'); + +const $Overlay = goog.require('nativejstypes.TopLevelNestedReference.$Overlay$impl'); +/** @nodts */ +exports = $Overlay; diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.js.mappings.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.js.mappings.txt new file mode 100644 index 0000000000..34bdb0ff54 --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/TopLevelNestedReference$$Overlay.js.mappings.txt @@ -0,0 +1,4 @@ +[TopLevelNestedReference] => [$Overlay] +[TopLevelNestedReference] => [$clinit] +[TopLevelNestedReference] => [$Overlay.$clinit = () =>{};] "nativejstypes.TopLevelNestedReference$$Overlay." +[TopLevelNestedReference] => [$Overlay.$loadModules();] "nativejstypes.TopLevelNestedReference$$Overlay." diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js.txt new file mode 100644 index 0000000000..b2e2da93af --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_closure/com/google/j2cl/readable/java/nativejstypes/native_sources/toplevel.js.txt @@ -0,0 +1,24 @@ +// Copyright 2024 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 +// +// https://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. +goog.module('toplevel'); + +exports.Nested = class Nested { + constructor() { + /** @type {number} */ + this.x = 1; + } +} + +/** @type {number} */ +exports.x = 1; diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main+J2ObjCCompat.h.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main+J2ObjCCompat.h.txt index b23967d1ab..e54d57905a 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main+J2ObjCCompat.h.txt +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main+J2ObjCCompat.h.txt @@ -45,4 +45,8 @@ NS_INLINE void NativejstypesMain_testNativeTypeObjectMethods(void) { [J2ktNativejstypesMainCompanion.shared testNativeTypeObjectMethods]; } +NS_INLINE void NativejstypesMain_testTopLevel(void) { + [J2ktNativejstypesMainCompanion.shared testTopLevel]; +} + NS_ASSUME_NONNULL_END diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main.kt.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main.kt.txt index 0580e1590a..4a29b6a37c 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main.kt.txt +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/Main.kt.txt @@ -34,6 +34,8 @@ import nativejstypes.Bar import nativejstypes.BarInnerWithDotInName import nativejstypes.Foo import nativejstypes.Headers +import nativejstypes.TopLevel +import nativejstypes.TopLevelNestedReference @ObjCName("J2ktNativejstypesMain", exact = true) open class Main { @@ -104,5 +106,15 @@ open class Main { val unusedHash: Int = bar!!.hashCode() val unusedEq: Boolean = bar!!.equals(Any()) } + + @JvmStatic + @ObjCName("testTopLevel") + fun testTopLevel() { + TopLevel.x = 2 + val nested: TopLevel.Nested? = TopLevel.Nested() + nested!!.x = 3 + val topLevelNestedReference: TopLevelNestedReference? = TopLevelNestedReference() + topLevelNestedReference!!.x = 4 + } } } diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/TopLevel.kt.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/TopLevel.kt.txt new file mode 100644 index 0000000000..7ac163f205 --- /dev/null +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_kt/TopLevel.kt.txt @@ -0,0 +1,46 @@ +// Generated from "nativejstypes/TopLevel.java" +@file:Suppress( + "ALWAYS_NULL", + "PARAMETER_NAME_CHANGED_ON_OVERRIDE", + "REPEATED_BOUND", + "SENSELESS_COMPARISON", + "UNCHECKED_CAST", + "UNNECESSARY_LATEINIT", + "UNNECESSARY_NOT_NULL_ASSERTION", + "UNREACHABLE_CODE", + "UNUSED_ANONYMOUS_PARAMETER", + "UNUSED_PARAMETER", + "UNUSED_VARIABLE", + "USELESS_CAST", + "VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL", + "VARIABLE_WITH_REDUNDANT_INITIALIZER") + +package nativejstypes + +import javaemul.lang.* +import jsinterop.annotations.JsType +import kotlin.Int +import kotlin.Suppress +import kotlin.jvm.JvmField + +@JsType(name = "toplevel", namespace = "", isNative = true) +open class TopLevel { + internal constructor() + + companion object { + @JvmField + var x: Int = 0 + } + + @JsType(isNative = true) + open class Nested internal constructor() { + @JvmField + var x: Int = 0 + } +} + +@JsType(name = "toplevel.Nested", namespace = "", isNative = true) +open class TopLevelNestedReference internal constructor() { + @JvmField + var x: Int = 0 +} diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm/module.wat.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm/module.wat.txt index bba4f2bf53..96a2caf8b6 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm/module.wat.txt +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm/module.wat.txt @@ -86,6 +86,39 @@ )) ) + ;;; Code for nativejstypes.TopLevel.$Overlay [type definition] + (type $nativejstypes.TopLevel.$Overlay (sub (struct + (field $vtable (ref $nativejstypes.TopLevel.$Overlay.vtable)) + (field $itable (ref $itable)) + )) + ) + (type $nativejstypes.TopLevel.$Overlay.vtable (sub (struct + (field $$getClassImpl__java_lang_Class (ref $function.$getClassImpl__java_lang_Class)) + )) + ) + + ;;; Code for nativejstypes.TopLevelNestedReference.$Overlay [type definition] + (type $nativejstypes.TopLevelNestedReference.$Overlay (sub (struct + (field $vtable (ref $nativejstypes.TopLevelNestedReference.$Overlay.vtable)) + (field $itable (ref $itable)) + )) + ) + (type $nativejstypes.TopLevelNestedReference.$Overlay.vtable (sub (struct + (field $$getClassImpl__java_lang_Class (ref $function.$getClassImpl__java_lang_Class)) + )) + ) + + ;;; Code for nativejstypes.TopLevel.Nested.$Overlay [type definition] + (type $nativejstypes.TopLevel.Nested.$Overlay (sub (struct + (field $vtable (ref $nativejstypes.TopLevel.Nested.$Overlay.vtable)) + (field $itable (ref $itable)) + )) + ) + (type $nativejstypes.TopLevel.Nested.$Overlay.vtable (sub (struct + (field $$getClassImpl__java_lang_Class (ref $function.$getClassImpl__java_lang_Class)) + )) + ) + ;;; Code for nativejstypes.Bar [type definition] ;;; Code for nativejstypes.BarInnerWithDotInName [type definition] @@ -118,6 +151,12 @@ ;;; Code for nativejstypes.NullabilityNullMarked [type definition] + ;;; Code for nativejstypes.TopLevel [type definition] + + ;;; Code for nativejstypes.TopLevelNestedReference [type definition] + + ;;; Code for nativejstypes.TopLevel.Nested [type definition] + ;;; Code for nativejstypes.Bar.$Overlay [vtable.init] (global $nativejstypes.Bar.$Overlay.vtable (ref $nativejstypes.Bar.$Overlay.vtable) (struct.new $nativejstypes.Bar.$Overlay.vtable @@ -185,6 +224,27 @@ ) ) +;;; Code for nativejstypes.TopLevel.$Overlay [vtable.init] +(global $nativejstypes.TopLevel.$Overlay.vtable (ref $nativejstypes.TopLevel.$Overlay.vtable) + (struct.new $nativejstypes.TopLevel.$Overlay.vtable + (ref.func $$getClassImpl__java_lang_Class@nativejstypes.TopLevel.$Overlay) + ) +) + +;;; Code for nativejstypes.TopLevelNestedReference.$Overlay [vtable.init] +(global $nativejstypes.TopLevelNestedReference.$Overlay.vtable (ref $nativejstypes.TopLevelNestedReference.$Overlay.vtable) + (struct.new $nativejstypes.TopLevelNestedReference.$Overlay.vtable + (ref.func $$getClassImpl__java_lang_Class@nativejstypes.TopLevelNestedReference.$Overlay) + ) +) + +;;; Code for nativejstypes.TopLevel.Nested.$Overlay [vtable.init] +(global $nativejstypes.TopLevel.Nested.$Overlay.vtable (ref $nativejstypes.TopLevel.Nested.$Overlay.vtable) + (struct.new $nativejstypes.TopLevel.Nested.$Overlay.vtable + (ref.func $$getClassImpl__java_lang_Class@nativejstypes.TopLevel.Nested.$Overlay) + ) +) + ;;; Code for nativejstypes.Bar [static fields] ;;; Code for nativejstypes.BarInnerWithDotInName [static fields] @@ -306,6 +366,45 @@ (ref.null $java.lang.String) ) +;;; Code for nativejstypes.TopLevel [static fields] + +;;; Code for nativejstypes.TopLevelNestedReference [static fields] + +;;; Code for nativejstypes.TopLevel.Nested [static fields] + +;;; Code for nativejstypes.TopLevel.$Overlay [static fields] +(global $$class-initialized@nativejstypes.TopLevel.$Overlay (mut i32) + (i32.const 0) +) +(global $$class@nativejstypes.TopLevel.$Overlay (mut (ref null $java.lang.Class)) + (ref.null $java.lang.Class) +) +(global $$string_|nativejstype...|@nativejstypes.TopLevel.$Overlay (mut (ref null $java.lang.String)) + (ref.null $java.lang.String) +) + +;;; Code for nativejstypes.TopLevelNestedReference.$Overlay [static fields] +(global $$class-initialized@nativejstypes.TopLevelNestedReference.$Overlay (mut i32) + (i32.const 0) +) +(global $$class@nativejstypes.TopLevelNestedReference.$Overlay (mut (ref null $java.lang.Class)) + (ref.null $java.lang.Class) +) +(global $$string_|nativejstype...|@nativejstypes.TopLevelNestedReference.$Overlay (mut (ref null $java.lang.String)) + (ref.null $java.lang.String) +) + +;;; Code for nativejstypes.TopLevel.Nested.$Overlay [static fields] +(global $$class-initialized@nativejstypes.TopLevel.Nested.$Overlay (mut i32) + (i32.const 0) +) +(global $$class@nativejstypes.TopLevel.Nested.$Overlay (mut (ref null $java.lang.Class)) + (ref.null $java.lang.Class) +) +(global $$string_|nativejstype...|@nativejstypes.TopLevel.Nested.$Overlay (mut (ref null $java.lang.String)) + (ref.null $java.lang.String) +) + ;;; Code for nativejstypes.Bar.$Overlay [methods] ;;; void $Overlay.$clinit() @@ -778,6 +877,183 @@ ) ) +;;; Code for nativejstypes.TopLevel.$Overlay [methods] + +;;; void $Overlay.$clinit() +(func $$clinit__void__@nativejstypes.TopLevel.$Overlay + ;;@ nativejstypes/TopLevel.java:21:6 + (block + ;;@ nativejstypes/TopLevel.java:21:6 + (if (global.get $$class-initialized@nativejstypes.TopLevel.$Overlay) + (then + ;;@ nativejstypes/TopLevel.java:21:6 + (return ) + ) + ) + ;;@ nativejstypes/TopLevel.java:21:6 + (global.set $$class-initialized@nativejstypes.TopLevel.$Overlay (i32.const 1)) + ) +) + +;;; Class $Overlay.$getClassMetadata() +(func $$getClassMetadata__java_lang_Class__@nativejstypes.TopLevel.$Overlay + (result (ref null $java.lang.Class)) + (block + (if (i32.eqz (ref.is_null (global.get $$class@nativejstypes.TopLevel.$Overlay))) + (then + (return (global.get $$class@nativejstypes.TopLevel.$Overlay)) + ) + ) + (global.set $$class@nativejstypes.TopLevel.$Overlay (call $m_createForClass__java_lang_String__java_lang_Class__java_lang_Class@java.lang.Class (call $$getString_|nativejstype...|__java_lang_String__@nativejstypes.TopLevel.$Overlay )(ref.null $java.lang.Class))) + (return (global.get $$class@nativejstypes.TopLevel.$Overlay)) + ) +) + +;;; Class $Overlay.$getClassImpl() +(func $$getClassImpl__java_lang_Class@nativejstypes.TopLevel.$Overlay + (type $function.$getClassImpl__java_lang_Class) + (param $this.untyped (ref $java.lang.Object)) + (result (ref null $java.lang.Class)) + (local $this (ref null $nativejstypes.TopLevel.$Overlay)) + (local.set $this (ref.cast (ref $nativejstypes.TopLevel.$Overlay) (local.get $this.untyped))) + (block + (return (call $$getClassMetadata__java_lang_Class__@nativejstypes.TopLevel.$Overlay )) + ) +) +(elem declare func $$getClassImpl__java_lang_Class@nativejstypes.TopLevel.$Overlay) + +;;; String $Overlay.$getString_|nativejstype...|() +(func $$getString_|nativejstype...|__java_lang_String__@nativejstypes.TopLevel.$Overlay + (result (ref null $java.lang.String)) + (block + (if (i32.eqz (ref.is_null (global.get $$string_|nativejstype...|@nativejstypes.TopLevel.$Overlay))) + (then + (return (global.get $$string_|nativejstype...|@nativejstypes.TopLevel.$Overlay)) + ) + ) + (global.set $$string_|nativejstype...|@nativejstypes.TopLevel.$Overlay (call $m_fromJsString__java_lang_String_NativeString__java_lang_String@java.lang.String (string.const "nativejstypes.TopLevel$$Overlay"))) + (return (global.get $$string_|nativejstype...|@nativejstypes.TopLevel.$Overlay)) + ) +) + +;;; Code for nativejstypes.TopLevelNestedReference.$Overlay [methods] + +;;; void $Overlay.$clinit() +(func $$clinit__void__@nativejstypes.TopLevelNestedReference.$Overlay + ;;@ nativejstypes/TopLevel.java:33:6 + (block + ;;@ nativejstypes/TopLevel.java:33:6 + (if (global.get $$class-initialized@nativejstypes.TopLevelNestedReference.$Overlay) + (then + ;;@ nativejstypes/TopLevel.java:33:6 + (return ) + ) + ) + ;;@ nativejstypes/TopLevel.java:33:6 + (global.set $$class-initialized@nativejstypes.TopLevelNestedReference.$Overlay (i32.const 1)) + ) +) + +;;; Class $Overlay.$getClassMetadata() +(func $$getClassMetadata__java_lang_Class__@nativejstypes.TopLevelNestedReference.$Overlay + (result (ref null $java.lang.Class)) + (block + (if (i32.eqz (ref.is_null (global.get $$class@nativejstypes.TopLevelNestedReference.$Overlay))) + (then + (return (global.get $$class@nativejstypes.TopLevelNestedReference.$Overlay)) + ) + ) + (global.set $$class@nativejstypes.TopLevelNestedReference.$Overlay (call $m_createForClass__java_lang_String__java_lang_Class__java_lang_Class@java.lang.Class (call $$getString_|nativejstype...|__java_lang_String__@nativejstypes.TopLevelNestedReference.$Overlay )(ref.null $java.lang.Class))) + (return (global.get $$class@nativejstypes.TopLevelNestedReference.$Overlay)) + ) +) + +;;; Class $Overlay.$getClassImpl() +(func $$getClassImpl__java_lang_Class@nativejstypes.TopLevelNestedReference.$Overlay + (type $function.$getClassImpl__java_lang_Class) + (param $this.untyped (ref $java.lang.Object)) + (result (ref null $java.lang.Class)) + (local $this (ref null $nativejstypes.TopLevelNestedReference.$Overlay)) + (local.set $this (ref.cast (ref $nativejstypes.TopLevelNestedReference.$Overlay) (local.get $this.untyped))) + (block + (return (call $$getClassMetadata__java_lang_Class__@nativejstypes.TopLevelNestedReference.$Overlay )) + ) +) +(elem declare func $$getClassImpl__java_lang_Class@nativejstypes.TopLevelNestedReference.$Overlay) + +;;; String $Overlay.$getString_|nativejstype...|() +(func $$getString_|nativejstype...|__java_lang_String__@nativejstypes.TopLevelNestedReference.$Overlay + (result (ref null $java.lang.String)) + (block + (if (i32.eqz (ref.is_null (global.get $$string_|nativejstype...|@nativejstypes.TopLevelNestedReference.$Overlay))) + (then + (return (global.get $$string_|nativejstype...|@nativejstypes.TopLevelNestedReference.$Overlay)) + ) + ) + (global.set $$string_|nativejstype...|@nativejstypes.TopLevelNestedReference.$Overlay (call $m_fromJsString__java_lang_String_NativeString__java_lang_String@java.lang.String (string.const "nativejstypes.TopLevelNestedReference$$Overlay"))) + (return (global.get $$string_|nativejstype...|@nativejstypes.TopLevelNestedReference.$Overlay)) + ) +) + +;;; Code for nativejstypes.TopLevel.Nested.$Overlay [methods] + +;;; void $Overlay.$clinit() +(func $$clinit__void__@nativejstypes.TopLevel.Nested.$Overlay + ;;@ nativejstypes/TopLevel.java:27:15 + (block + ;;@ nativejstypes/TopLevel.java:27:15 + (if (global.get $$class-initialized@nativejstypes.TopLevel.Nested.$Overlay) + (then + ;;@ nativejstypes/TopLevel.java:27:15 + (return ) + ) + ) + ;;@ nativejstypes/TopLevel.java:27:15 + (global.set $$class-initialized@nativejstypes.TopLevel.Nested.$Overlay (i32.const 1)) + ) +) + +;;; Class $Overlay.$getClassMetadata() +(func $$getClassMetadata__java_lang_Class__@nativejstypes.TopLevel.Nested.$Overlay + (result (ref null $java.lang.Class)) + (block + (if (i32.eqz (ref.is_null (global.get $$class@nativejstypes.TopLevel.Nested.$Overlay))) + (then + (return (global.get $$class@nativejstypes.TopLevel.Nested.$Overlay)) + ) + ) + (global.set $$class@nativejstypes.TopLevel.Nested.$Overlay (call $m_createForClass__java_lang_String__java_lang_Class__java_lang_Class@java.lang.Class (call $$getString_|nativejstype...|__java_lang_String__@nativejstypes.TopLevel.Nested.$Overlay )(ref.null $java.lang.Class))) + (return (global.get $$class@nativejstypes.TopLevel.Nested.$Overlay)) + ) +) + +;;; Class $Overlay.$getClassImpl() +(func $$getClassImpl__java_lang_Class@nativejstypes.TopLevel.Nested.$Overlay + (type $function.$getClassImpl__java_lang_Class) + (param $this.untyped (ref $java.lang.Object)) + (result (ref null $java.lang.Class)) + (local $this (ref null $nativejstypes.TopLevel.Nested.$Overlay)) + (local.set $this (ref.cast (ref $nativejstypes.TopLevel.Nested.$Overlay) (local.get $this.untyped))) + (block + (return (call $$getClassMetadata__java_lang_Class__@nativejstypes.TopLevel.Nested.$Overlay )) + ) +) +(elem declare func $$getClassImpl__java_lang_Class@nativejstypes.TopLevel.Nested.$Overlay) + +;;; String $Overlay.$getString_|nativejstype...|() +(func $$getString_|nativejstype...|__java_lang_String__@nativejstypes.TopLevel.Nested.$Overlay + (result (ref null $java.lang.String)) + (block + (if (i32.eqz (ref.is_null (global.get $$string_|nativejstype...|@nativejstypes.TopLevel.Nested.$Overlay))) + (then + (return (global.get $$string_|nativejstype...|@nativejstypes.TopLevel.Nested.$Overlay)) + ) + ) + (global.set $$string_|nativejstype...|@nativejstypes.TopLevel.Nested.$Overlay (call $m_fromJsString__java_lang_String_NativeString__java_lang_String@java.lang.String (string.const "nativejstypes.TopLevel$Nested$$Overlay"))) + (return (global.get $$string_|nativejstype...|@nativejstypes.TopLevel.Nested.$Overlay)) + ) +) + ;;; Code for nativejstypes.Bar [methods] ;;; Bar(int x, int y) @@ -1094,6 +1370,27 @@ ) ) +;;; void Main.testTopLevel() +(func $m_testTopLevel__void@nativejstypes.Main + ;;@ nativejstypes/Main.java:73:21 + (local $nested (ref null extern)) + (local $topLevelNestedReference (ref null extern)) + (block + ;;@ nativejstypes/Main.java:73:36 + (call $$clinit__void__@nativejstypes.Main ) + ;;@ nativejstypes/Main.java:74:4 + (call $f_x__int__void@nativejstypes.TopLevel (i32.const 2)) + ;;@ nativejstypes/Main.java:76:4 + (local.set $nested (call $m___@nativejstypes.TopLevel.Nested )) + ;;@ nativejstypes/Main.java:77:4 + (call $f_x__int__void@nativejstypes.TopLevel.Nested (ref.as_non_null (local.get $nested))(i32.const 3)) + ;;@ nativejstypes/Main.java:79:4 + (local.set $topLevelNestedReference (call $m___@nativejstypes.TopLevelNestedReference )) + ;;@ nativejstypes/Main.java:80:4 + (call $f_x__int__void@nativejstypes.TopLevelNestedReference (ref.as_non_null (local.get $topLevelNestedReference))(i32.const 4)) + ) +) + ;;; void Main.$clinit() (func $$clinit__void__@nativejstypes.Main ;;@ nativejstypes/Main.java:20:13 @@ -1218,3 +1515,53 @@ (param $this (ref null extern)) (param $arg (ref null string)) ) + +;;; Code for nativejstypes.TopLevel [methods] + +;;; int TopLevel.x() +(func $f_x__int@nativejstypes.TopLevel (import "imports" "get toplevel.x") + (result i32) +) + +;;; void TopLevel.x(int value) +(func $f_x__int__void@nativejstypes.TopLevel (import "imports" "set toplevel.x") + (param $value i32) +) + +;;; Code for nativejstypes.TopLevelNestedReference [methods] + +;;; TopLevelNestedReference() +(func $m___@nativejstypes.TopLevelNestedReference (import "imports" "toplevel.Nested.constructor") + (result (ref null extern)) +) + +;;; int TopLevelNestedReference.x() +(func $f_x__int@nativejstypes.TopLevelNestedReference (import "imports" "get toplevel.Nested.x") + (param $this (ref null extern)) + (result i32) +) + +;;; void TopLevelNestedReference.x(int value) +(func $f_x__int__void@nativejstypes.TopLevelNestedReference (import "imports" "set toplevel.Nested.x") + (param $this (ref null extern)) + (param $value i32) +) + +;;; Code for nativejstypes.TopLevel.Nested [methods] + +;;; Nested() +(func $m___@nativejstypes.TopLevel.Nested (import "imports" "toplevel.Nested.constructor") + (result (ref null extern)) +) + +;;; int Nested.x() +(func $f_x__int@nativejstypes.TopLevel.Nested (import "imports" "get toplevel.Nested.x") + (param $this (ref null extern)) + (result i32) +) + +;;; void Nested.x(int value) +(func $f_x__int__void@nativejstypes.TopLevel.Nested (import "imports" "set toplevel.Nested.x") + (param $this (ref null extern)) + (param $value i32) +) diff --git a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm_imports/module.imports.js.txt b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm_imports/module.imports.js.txt index fcbc0c87af..54fef61b6e 100644 --- a/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm_imports/module.imports.js.txt +++ b/transpiler/javatests/com/google/j2cl/readable/java/nativejstypes/output_wasm_imports/module.imports.js.txt @@ -7,6 +7,8 @@ const j2wasm_StringUtils = goog.require('j2wasm.StringUtils'); const nativejstypes_Bar = goog.require('nativejstypes.Bar'); const nativejstypes_Bar_Inner = goog.require('nativejstypes.Bar.Inner'); const nativejstypes_Nullability = goog.require('nativejstypes.Nullability'); +const toplevel = goog.require('toplevel'); +const toplevel_Nested = goog.require('toplevel.Nested'); /** @return {!Object>} Wasm import object */ function getImports() { @@ -86,6 +88,8 @@ function getImports() { 'get nativejstypes.Bar.f': () => nativejstypes_Bar.f, 'get nativejstypes.Bar.x': (/** !nativejstypes_Bar */ $instance, ) => $instance.x, 'get nativejstypes.Bar.y': (/** !nativejstypes_Bar */ $instance, ) => $instance.y, + 'get toplevel.Nested.x': (/** !toplevel.Nested */ $instance, ) => $instance.x, + 'get toplevel.x': () => toplevel.x, 'j2wasm.CharUtils.charToLowerCase': j2wasm_CharUtils.charToLowerCase, 'j2wasm.CharUtils.charToUpperCase': j2wasm_CharUtils.charToUpperCase, 'j2wasm.CharUtils.codePointToLowerCase': j2wasm_CharUtils.codePointToLowerCase, @@ -115,6 +119,8 @@ function getImports() { 'set nativejstypes.Bar.f': (/** number */ value, ) => nativejstypes_Bar.f = value, 'set nativejstypes.Bar.x': (/** !nativejstypes_Bar */ $instance, /** number */ value, ) => $instance.x = value, 'set nativejstypes.Bar.y': (/** !nativejstypes_Bar */ $instance, /** number */ value, ) => $instance.y = value, + 'set toplevel.Nested.x': (/** !toplevel.Nested */ $instance, /** number */ value, ) => $instance.x = value, + 'set toplevel.x': (/** number */ value, ) => toplevel.x = value, 'string.indexOf$1': (/** string */ $instance, /** string */ str, ) => $instance.indexOf(str, ), 'string.indexOf$2': (/** string */ $instance, /** string */ str, /** number */ startIndex, ) => $instance.indexOf(str, startIndex, ), 'string.lastIndexOf$1': (/** string */ $instance, /** string */ str, ) => $instance.lastIndexOf(str, ), @@ -125,6 +131,7 @@ function getImports() { 'string.toLocaleUpperCase': (/** string */ $instance, ) => $instance.toLocaleUpperCase(), 'string.toLowerCase': (/** string */ $instance, ) => $instance.toLowerCase(), 'string.toUpperCase': (/** string */ $instance, ) => $instance.toUpperCase(), + 'toplevel.Nested.constructor': () => new toplevel.Nested(), } }; } diff --git a/transpiler/javatests/com/google/j2cl/transpiler/JsInteropRestrictionsCheckerTest.java b/transpiler/javatests/com/google/j2cl/transpiler/JsInteropRestrictionsCheckerTest.java index 4d4c5e662c..d6659cdf6a 100644 --- a/transpiler/javatests/com/google/j2cl/transpiler/JsInteropRestrictionsCheckerTest.java +++ b/transpiler/javatests/com/google/j2cl/transpiler/JsInteropRestrictionsCheckerTest.java @@ -1406,6 +1406,7 @@ public void testJsNameInvalidNamespacesFails() { " @JsMethod(namespace = JsPackage.GLOBAL) public static void m() {}", " @JsProperty(namespace = JsPackage.GLOBAL) public static int n;", "}", + "@JsType(namespace = \"\") class NonNativeClass {}", "@JsEnum(isNative = true, namespace = \"=\") enum NativeEnum { }", "@JsEnum(namespace = \"^\") enum MyJsEnum { }") .assertErrorsWithoutSourcePosition( @@ -1421,7 +1422,8 @@ public void testJsNameInvalidNamespacesFails() { "Non-native member 'JsTypeOnWindow.r' cannot declare a namespace.", "Non-native member 'void JsTypeOnWindow.s()' cannot declare a namespace.", "Non-native member 'void InvalidGlobal.m()' cannot declare a namespace.", - "Non-native member 'InvalidGlobal.n' cannot declare a namespace."); + "Non-native member 'InvalidGlobal.n' cannot declare a namespace.", + "'NonNativeClass' cannot have an empty namespace."); } public void testJsNameGlobalNamespacesSucceeds() { @@ -1455,6 +1457,15 @@ public void testJsNameGlobalNamespacesSucceeds() { .assertNoWarnings(); } + public void testNativeJsTypeEmptyNamespaceSucceeds() { + assertTranspileSucceeds( + "test.Buggy", + "import jsinterop.annotations.*;", + "@JsType(isNative = true, namespace = \"\", name = \"a.c\")", + "class NativeOnTopLevelNamespace {}") + .assertNoWarnings(); + } + public void testSingleJsTypeSucceeds() { assertTranspileSucceeds( "test.Buggy",