From 6aacae30f24885f6e586a8729196f6e5d347d4d8 Mon Sep 17 00:00:00 2001 From: Molly Tian Date: Mon, 9 Sep 2024 12:51:17 -0700 Subject: [PATCH] Add tests around nullability PiperOrigin-RevId: 672641108 --- .../generator/externs/nullabletypes/BUILD | 17 ++ .../ClassWithNullableRefs.java.txt | 196 ++++++++++++++++++ .../NullableFunctionType.java.txt | 8 + .../NullableTypeDefOfRecord.java.txt | 28 +++ .../nullabletypes/SimpleClass.java.txt | 7 + .../externs/nullabletypes/SimpleEnum.java.txt | 10 + .../nullabletypes/SimpleInterface.java.txt | 7 + .../nullabletypes/SimpleRecord.java.txt | 7 + .../externs/nullabletypes/nullabletypes.js | 151 ++++++++++++++ 9 files changed, 431 insertions(+) create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/BUILD create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/ClassWithNullableRefs.java.txt create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/NullableFunctionType.java.txt create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/NullableTypeDefOfRecord.java.txt create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/SimpleClass.java.txt create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/SimpleEnum.java.txt create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/SimpleInterface.java.txt create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/SimpleRecord.java.txt create mode 100644 javatests/jsinterop/generator/externs/nullabletypes/nullabletypes.js diff --git a/javatests/jsinterop/generator/externs/nullabletypes/BUILD b/javatests/jsinterop/generator/externs/nullabletypes/BUILD new file mode 100644 index 0000000..749e028 --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/BUILD @@ -0,0 +1,17 @@ +load( + "//javatests/jsinterop/generator:jsinterop_generator_test.bzl", + "jsinterop_generator_test", +) + +package( + default_applicable_licenses = ["//:license"], + licenses = ["notice"], +) + +jsinterop_generator_test( + name = "nullabletypes", + srcs = ["nullabletypes.js"], + expected_output = glob([ + "*.java.txt", + ]), +) diff --git a/javatests/jsinterop/generator/externs/nullabletypes/ClassWithNullableRefs.java.txt b/javatests/jsinterop/generator/externs/nullabletypes/ClassWithNullableRefs.java.txt new file mode 100644 index 0000000..05c9fd8 --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/ClassWithNullableRefs.java.txt @@ -0,0 +1,196 @@ +package jsinterop.generator.externs.nullabletypes; + +import jsinterop.annotations.JsFunction; +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; +import jsinterop.base.Js; +import jsinterop.base.JsPropertyMap; + +@JsType(isNative = true, namespace = JsPackage.GLOBAL) +public class ClassWithNullableRefs { + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface AnonymousUnionTypeWithNullUnionType { + @JsOverlay + static ClassWithNullableRefs.AnonymousUnionTypeWithNullUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default double asDouble() { + return Js.asDouble(this); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default boolean isDouble() { + return (Object) this instanceof Double; + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + } + + @JsFunction + public interface NullableAnonymousFunctionTypeRefFn { + boolean onInvoke(String p0); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface NullableAnonymousRecordRefFieldType { + @JsOverlay + static ClassWithNullableRefs.NullableAnonymousRecordRefFieldType create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + String getBar(); + + @JsProperty + double getFoo(); + + @JsProperty + void setBar(String bar); + + @JsProperty + void setFoo(double foo); + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface NullableAnonymousUnionTypeRef2UnionType { + @JsOverlay + static ClassWithNullableRefs.NullableAnonymousUnionTypeRef2UnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default double asDouble() { + return Js.asDouble(this); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default boolean isDouble() { + return (Object) this instanceof Double; + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface NullableAnonymousUnionTypeRefUnionType { + @JsOverlay + static ClassWithNullableRefs.NullableAnonymousUnionTypeRefUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default double asDouble() { + return Js.asDouble(this); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default boolean isDouble() { + return (Object) this instanceof Double; + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface NullableUnionTypeRefUnionType { + @JsOverlay + static ClassWithNullableRefs.NullableUnionTypeRefUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default double asDouble() { + return Js.asDouble(this); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default boolean isDouble() { + return (Object) this instanceof Double; + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + } + + @JsType(isNative = true, name = "?", namespace = JsPackage.GLOBAL) + public interface UnionTypeWithNullRefUnionType { + @JsOverlay + static ClassWithNullableRefs.UnionTypeWithNullRefUnionType of(Object o) { + return Js.cast(o); + } + + @JsOverlay + default double asDouble() { + return Js.asDouble(this); + } + + @JsOverlay + default String asString() { + return Js.asString(this); + } + + @JsOverlay + default boolean isDouble() { + return (Object) this instanceof Double; + } + + @JsOverlay + default boolean isString() { + return (Object) this instanceof String; + } + } + + public ClassWithNullableRefs.AnonymousUnionTypeWithNullUnionType anonymousUnionTypeWithNull; + public ClassWithNullableRefs.NullableAnonymousFunctionTypeRefFn nullableAnonymousFunctionTypeRef; + public ClassWithNullableRefs.NullableAnonymousRecordRefFieldType nullableAnonymousRecordRef; + public ClassWithNullableRefs.NullableAnonymousUnionTypeRefUnionType nullableAnonymousUnionTypeRef; + public ClassWithNullableRefs.NullableAnonymousUnionTypeRef2UnionType + nullableAnonymousUnionTypeRef2; + public SimpleEnum nullableEnumRef; + public NullableFunctionType nullableFunctionTypeRef; + public SimpleInterface nullableInterfaceRef; + public double nullableNumber; + public SimpleRecord nullableRecordRef; + public String nullableString; + public NullableTypeDefOfRecord nullableTypeDefOfRecordRef; + public ClassWithNullableRefs.NullableUnionTypeRefUnionType nullableUnionTypeRef; + public SimpleClass simpleClassRef; + public ClassWithNullableRefs.UnionTypeWithNullRefUnionType unionTypeWithNullRef; + + public native SimpleRecord methodWithNullableParam(SimpleInterface foo); +} diff --git a/javatests/jsinterop/generator/externs/nullabletypes/NullableFunctionType.java.txt b/javatests/jsinterop/generator/externs/nullabletypes/NullableFunctionType.java.txt new file mode 100644 index 0000000..c133ac5 --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/NullableFunctionType.java.txt @@ -0,0 +1,8 @@ +package jsinterop.generator.externs.nullabletypes; + +import jsinterop.annotations.JsFunction; + +@JsFunction +public interface NullableFunctionType { + boolean onInvoke(String p0); +} diff --git a/javatests/jsinterop/generator/externs/nullabletypes/NullableTypeDefOfRecord.java.txt b/javatests/jsinterop/generator/externs/nullabletypes/NullableTypeDefOfRecord.java.txt new file mode 100644 index 0000000..fcd6c22 --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/NullableTypeDefOfRecord.java.txt @@ -0,0 +1,28 @@ +package jsinterop.generator.externs.nullabletypes; + +import jsinterop.annotations.JsOverlay; +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsProperty; +import jsinterop.annotations.JsType; +import jsinterop.base.Js; +import jsinterop.base.JsPropertyMap; + +@JsType(isNative = true, namespace = JsPackage.GLOBAL) +public interface NullableTypeDefOfRecord { + @JsOverlay + static NullableTypeDefOfRecord create() { + return Js.uncheckedCast(JsPropertyMap.of()); + } + + @JsProperty + String getBar(); + + @JsProperty + double getFoo(); + + @JsProperty + void setBar(String bar); + + @JsProperty + void setFoo(double foo); +} diff --git a/javatests/jsinterop/generator/externs/nullabletypes/SimpleClass.java.txt b/javatests/jsinterop/generator/externs/nullabletypes/SimpleClass.java.txt new file mode 100644 index 0000000..b6e2bce --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/SimpleClass.java.txt @@ -0,0 +1,7 @@ +package jsinterop.generator.externs.nullabletypes; + +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsType; + +@JsType(isNative = true, namespace = JsPackage.GLOBAL) +public class SimpleClass {} diff --git a/javatests/jsinterop/generator/externs/nullabletypes/SimpleEnum.java.txt b/javatests/jsinterop/generator/externs/nullabletypes/SimpleEnum.java.txt new file mode 100644 index 0000000..1bc5dbe --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/SimpleEnum.java.txt @@ -0,0 +1,10 @@ +package jsinterop.generator.externs.nullabletypes; + +import jsinterop.annotations.JsEnum; +import jsinterop.annotations.JsPackage; + +@JsEnum(isNative = true, namespace = JsPackage.GLOBAL) +public enum SimpleEnum { + A, + B; +} diff --git a/javatests/jsinterop/generator/externs/nullabletypes/SimpleInterface.java.txt b/javatests/jsinterop/generator/externs/nullabletypes/SimpleInterface.java.txt new file mode 100644 index 0000000..e71ba7f --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/SimpleInterface.java.txt @@ -0,0 +1,7 @@ +package jsinterop.generator.externs.nullabletypes; + +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsType; + +@JsType(isNative = true, namespace = JsPackage.GLOBAL) +public interface SimpleInterface {} diff --git a/javatests/jsinterop/generator/externs/nullabletypes/SimpleRecord.java.txt b/javatests/jsinterop/generator/externs/nullabletypes/SimpleRecord.java.txt new file mode 100644 index 0000000..666333b --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/SimpleRecord.java.txt @@ -0,0 +1,7 @@ +package jsinterop.generator.externs.nullabletypes; + +import jsinterop.annotations.JsPackage; +import jsinterop.annotations.JsType; + +@JsType(isNative = true, namespace = JsPackage.GLOBAL) +public interface SimpleRecord {} diff --git a/javatests/jsinterop/generator/externs/nullabletypes/nullabletypes.js b/javatests/jsinterop/generator/externs/nullabletypes/nullabletypes.js new file mode 100644 index 0000000..6d00bfd --- /dev/null +++ b/javatests/jsinterop/generator/externs/nullabletypes/nullabletypes.js @@ -0,0 +1,151 @@ + +// 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. + +/** + * @fileoverview Test nested classes conversion. + * @externs + */ + +/** + * @constructor + */ +function SimpleClass() {} + +/** + * @record + */ +function SimpleRecord() {}; + +/** + * @interface + */ +function SimpleInterface() {} + +/** + * @enum {string} + */ +var SimpleEnum = {A: 'A', B: 'B'}; + +/** + * @typedef {?function(string):boolean} + */ +var NullableFunctionType; + +/** + * @typedef {?string|number} + */ +var NullableUnionType; + +/** + * @typedef {null|string|number} + */ +var UnionTypeWithNull; + +/** + * @typedef {?{ + * foo: number, + * bar: string + * }} + */ +var NullableTypeDefOfRecord; + +/** + * @constructor + */ +function ClassWithNullableRefs() {} + +/** +@type {?SimpleClass} + */ +ClassWithNullableRefs.prototype.simpleClassRef; + +/** + * @type {?SimpleRecord} + */ +ClassWithNullableRefs.prototype.nullableRecordRef; + +/** + * @type {?SimpleInterface} + */ +ClassWithNullableRefs.prototype.nullableInterfaceRef; + +/** + * @type {?SimpleEnum} + */ +ClassWithNullableRefs.prototype.nullableEnumRef; + +/** + * @param {?SimpleInterface} foo + * @return {?SimpleRecord} + */ +ClassWithNullableRefs.prototype.methodWithNullableParam = function(foo) {}; + +/** + * @type {?string|number} + */ +ClassWithNullableRefs.prototype.nullableAnonymousUnionTypeRef; + +/** + * @type {?(string|number)} + */ +ClassWithNullableRefs.prototype.nullableAnonymousUnionTypeRef2; + +/** + * @type {?function(string):boolean} + */ +ClassWithNullableRefs.prototype.nullableAnonymousFunctionTypeRef; + +/** + * @type {?{ + * foo: number, + * bar: string + * }} + */ +ClassWithNullableRefs.prototype.nullableAnonymousRecordRef; + +/** + * @type {NullableUnionType} + */ +ClassWithNullableRefs.prototype.nullableUnionTypeRef; + +/** + * @type {NullableFunctionType} + */ +ClassWithNullableRefs.prototype.nullableFunctionTypeRef; + +/** + * @type {UnionTypeWithNull} + */ +ClassWithNullableRefs.prototype.unionTypeWithNullRef; + +/** + * @type {null|string|number} + */ +ClassWithNullableRefs.prototype.anonymousUnionTypeWithNull; + +/** + * @type {NullableTypeDefOfRecord} + */ +ClassWithNullableRefs.prototype.nullableTypeDefOfRecordRef; + +/** + * @type {?number} + */ +ClassWithNullableRefs.prototype.nullableNumber; + +/** + * @type {?string} + */ +ClassWithNullableRefs.prototype.nullableString;