diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt index 636c81c705b..c2371e9b14d 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt @@ -290,8 +290,8 @@ class WasmSymbols( val wasmAnyRefClass = getIrClass(FqName("kotlin.wasm.internal.reftypes.anyref")) - private val externalInterfaceClass = getIrClass(FqName("kotlin.wasm.internal.ExternalInterfaceType")) - val externalInterfaceType by lazy { externalInterfaceClass.defaultType } + private val jsAnyClass = getIrClass(FqName("kotlin.js.JsAny")) + val jsAnyType by lazy { jsAnyClass.defaultType } inner class JsInteropAdapters { val kotlinToJsStringAdapter = getInternalFunction("kotlinToJsStringAdapter") diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt index 8d1860a4d01..d11c58bf937 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/JsInteropFunctionsLowering.kt @@ -33,7 +33,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions -import kotlin.math.absoluteValue /** * Create wrappers for external and @JsExport functions when type adaptation is needed @@ -466,7 +465,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT private fun createKotlinToJsClosureConvertor(info: FunctionTypeInfo): IrSimpleFunction { val result = context.irFactory.buildFun { name = Name.identifier("__convertKotlinClosureToJsClosure_${info.hashString}") - returnType = context.wasmSymbols.externalInterfaceType + returnType = context.wasmSymbols.jsAnyType isExternal = true } result.parent = currentParent @@ -507,7 +506,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT result.parent = currentParent result.addValueParameter { name = Name.identifier("f") - type = context.wasmSymbols.externalInterfaceType + type = context.wasmSymbols.jsAnyType } val closureClass = context.irFactory.buildClass { @@ -520,7 +519,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT val closureClassField = closureClass.addField { name = Name.identifier("jsClosure") - type = context.wasmSymbols.externalInterfaceType + type = context.wasmSymbols.jsAnyType visibility = DescriptorVisibilities.PRIVATE isFinal = true } @@ -589,7 +588,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT result.parent = currentParent result.addValueParameter { name = Name.identifier("f") - type = symbols.externalInterfaceType + type = symbols.jsAnyType } val arity = info.adaptedParameterTypes.size repeat(arity) { paramIndex -> @@ -790,7 +789,7 @@ class JsInteropFunctionsLowering(val context: WasmBackendContext) : DeclarationT private val fromElementType: IrType, ) : InteropTypeAdapter { override val toType: IrType = - context.wasmSymbols.externalInterfaceType + context.wasmSymbols.jsAnyType private val elementAdapter = primitivesToExternRefAdapters[fromElementType] diff --git a/compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt b/compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt new file mode 100644 index 00000000000..6e75d30168a --- /dev/null +++ b/compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt @@ -0,0 +1,61 @@ +// TARGET_BACKEND: WASM +// WITH_STDLIB +import kotlin.test.* + +fun jsRepresentation(x: JsAny): String = js("(typeof x) + ':' + String(x)") + +fun box(): String { + // JsNumber + val jsNum10: JsNumber = 10.toJsNumber() + val anotherJsNum10: JsNumber = 10.toDouble().toJsNumber() + assertTrue(jsNum10 == anotherJsNum10) + assertTrue(jsNum10.toDouble() == 10.0) + assertTrue(anotherJsNum10.toInt() == 10) + val jsNumAsJsAny: JsAny = jsNum10 + assertTrue(jsNumAsJsAny == anotherJsNum10) + assertTrue(jsNumAsJsAny is JsNumber) + assertTrue(jsNumAsJsAny !is JsString) + assertTrue(jsNumAsJsAny !is JsBoolean) + assertTrue((jsNumAsJsAny as JsNumber).toInt() == 10) + val jsNumAsAny: Any = jsNum10 + assertTrue(jsNumAsAny == anotherJsNum10) + assertTrue(jsNumAsAny is JsNumber) + assertTrue(jsNumAsAny !is JsString) + assertTrue(jsNumAsAny !is JsBoolean) + assertTrue((jsNumAsAny as JsNumber).toInt() == 10) + assertTrue(jsRepresentation(jsNum10) == "number:10") + + // JsString + val jsStr1: JsString = "str1".toJsString() + assertTrue(jsStr1 == "str1".toJsString()) + assertTrue(jsStr1 != "str2".toJsString()) + assertTrue(jsStr1.toString() == "str1") + assertTrue((jsStr1 as Any) is JsString) + assertTrue((jsStr1 as Any) !is JsNumber) + assertTrue(jsRepresentation(jsStr1) == "string:str1") + + // JsString + val jsBoolTrue: JsBoolean = true.toJsBoolean() + assertTrue(jsBoolTrue == true.toJsBoolean()) + assertTrue(jsBoolTrue != false.toJsBoolean()) + assertTrue(jsRepresentation(jsBoolTrue) == "boolean:true") + + // JsArray + val jsArray: JsArray = JsArray() + repeat(3) { + jsArray[it] = "element$it".toJsString() + } + assertTrue(jsArray.length == 3) + assertTrue(jsArray[1] == "element1".toJsString()) + assertTrue(jsRepresentation(jsArray) == "object:element0,element1,element2") + + // JsHandle + val jsHandle: JsHandle = 10.toJsHandle() + assertTrue(jsHandle.get() == 10) + assertTrue(jsHandle.toJsHandle().get() == jsHandle) + val c = listOf(1) + assertTrue(c.toJsHandle().get() === c.toJsHandle().get()) + assertTrue(c.toJsHandle() === c.toJsHandle()) + + return "OK" +} \ No newline at end of file diff --git a/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/JasmineLikeAdapter.kt b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/JasmineLikeAdapter.kt index 378b88485dc..822dedc8115 100644 --- a/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/JasmineLikeAdapter.kt +++ b/libraries/kotlin.test/wasm/src/main/kotlin/kotlin/test/JasmineLikeAdapter.kt @@ -15,10 +15,10 @@ private fun describe(name: String, fn: () -> Unit): Unit = private fun xdescribe(name: String, fn: () -> Unit): Unit = js("xdescribe(name, fn)") -private fun it(name: String, fn: () -> Any?): Unit = +private fun it(name: String, fn: () -> JsAny?): Unit = js("it(name, fn)") -private fun xit(name: String, fn: () -> Any?): Unit = +private fun xit(name: String, fn: () -> JsAny?): Unit = js("xit(name, fn)") private fun jsThrow(jsException: Dynamic) { @@ -45,7 +45,7 @@ internal class JasmineLikeAdapter : FrameworkAdapter { } } - private fun callTest(testFn: () -> Any?): Any? = + private fun callTest(testFn: () -> Any?): JsAny? = try { (testFn() as? Promise<*>)?.catch { exception -> val jsException = exception diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt index fbf62f22fa3..6939d341929 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt @@ -11,7 +11,7 @@ import kotlin.wasm.internal.reftypes.anyref import kotlin.wasm.unsafe.withScopedMemoryAllocator import kotlin.wasm.unsafe.UnsafeWasmMemoryApi -internal external interface ExternalInterfaceType +internal typealias ExternalInterfaceType = JsAny internal class JsExternalBox @WasmPrimitiveConstructor constructor(val ref: ExternalInterfaceType) { override fun toString(): String = @@ -106,7 +106,7 @@ private fun externrefToFloat(ref: ExternalInterfaceType): Float = private fun externrefToDouble(ref: ExternalInterfaceType): Double = js("Number(ref)") -private fun intToExternref(x: Int): ExternalInterfaceType = +private fun intToExternref(x: Int): JsNumber = js("x") private fun longToExternref(x: Long): ExternalInterfaceType = @@ -118,13 +118,16 @@ private fun booleanToExternref(x: Boolean): ExternalInterfaceType = private fun floatToExternref(x: Float): ExternalInterfaceType = js("x") -private fun doubleToExternref(x: Double): ExternalInterfaceType = +private fun doubleToExternref(x: Double): JsNumber = js("x") private fun externrefEquals(lhs: ExternalInterfaceType, rhs: ExternalInterfaceType): Boolean = js("lhs === rhs") -private external fun tryGetOrSetExternrefBox(ref: ExternalInterfaceType, ifNotCached: JsExternalBox): JsExternalBox? +private external fun tryGetOrSetExternrefBox( + ref: ExternalInterfaceType, + ifNotCached: JsHandle +): JsHandle? @WasmNoOpCast @Suppress("unused") @@ -171,7 +174,7 @@ internal fun externRefToAny(ref: ExternalInterfaceType): Any? { // If we have Null in notNullRef -- return null // If we already have a box -- return it, // otherwise -- remember new box and return it. - return tryGetOrSetExternrefBox(ref, JsExternalBox(ref)) + return tryGetOrSetExternrefBox(ref, JsExternalBox(ref).toJsHandle()) } @@ -187,7 +190,7 @@ internal fun stringLength(x: ExternalInterfaceType): Int = // kotlin string to js string export // TODO Uint16Array may work with byte endian different with Wasm (i.e. little endian) -internal fun importStringFromWasm(address: Int, length: Int, prefix: ExternalInterfaceType?): ExternalInterfaceType { +internal fun importStringFromWasm(address: Int, length: Int, prefix: ExternalInterfaceType?): JsString { js(""" const mem16 = new Uint16Array(wasmExports.memory.buffer, address, length); const str = String.fromCharCode.apply(null, mem16); @@ -195,7 +198,7 @@ internal fun importStringFromWasm(address: Int, length: Int, prefix: ExternalInt """) } -internal fun kotlinToJsStringAdapter(x: String?): ExternalInterfaceType? { +internal fun kotlinToJsStringAdapter(x: String?): JsString? { // Using nullable String to represent default value // for parameters with default values if (x == null) return null @@ -269,13 +272,13 @@ internal fun jsToKotlinStringAdapter(x: ExternalInterfaceType): String { } -private fun getJsEmptyString(): ExternalInterfaceType = +private fun getJsEmptyString(): JsString = js("''") -private fun getJsTrue(): ExternalInterfaceType = +private fun getJsTrue(): JsBoolean = js("true") -private fun getJsFalse(): ExternalInterfaceType = +private fun getJsFalse(): JsBoolean = js("false") private val jsEmptyString by lazy(::getJsEmptyString) @@ -310,11 +313,10 @@ internal fun externRefToKotlinFloatAdapter(x: ExternalInterfaceType): Float = internal fun externRefToKotlinDoubleAdapter(x: ExternalInterfaceType): Double = externrefToDouble(x) - -internal fun kotlinIntToExternRefAdapter(x: Int): ExternalInterfaceType = +internal fun kotlinIntToExternRefAdapter(x: Int): JsNumber = intToExternref(x) -internal fun kotlinBooleanToExternRefAdapter(x: Boolean): ExternalInterfaceType = +internal fun kotlinBooleanToExternRefAdapter(x: Boolean): JsBoolean = if (x) jsTrue else jsFalse internal fun kotlinLongToExternRefAdapter(x: Long): ExternalInterfaceType = @@ -323,7 +325,7 @@ internal fun kotlinLongToExternRefAdapter(x: Long): ExternalInterfaceType = internal fun kotlinFloatToExternRefAdapter(x: Float): ExternalInterfaceType = floatToExternref(x) -internal fun kotlinDoubleToExternRefAdapter(x: Double): ExternalInterfaceType = +internal fun kotlinDoubleToExternRefAdapter(x: Double): JsNumber = doubleToExternref(x) internal fun kotlinByteToExternRefAdapter(x: Byte): ExternalInterfaceType = diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt index 06db2218dd3..a7d68896543 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/WasmInstructions.kt @@ -295,10 +295,12 @@ internal external fun wasm_f32_truncate(a: Float): Float internal external fun wasm_f32_abs(a: Float): Float @WasmOp(WasmOp.REF_IS_NULL) -internal external fun wasm_ref_is_null(a: Any?): Boolean +internal fun wasm_ref_is_null(a: Any?): Boolean = + implementedAsIntrinsic @WasmOp(WasmOp.REF_EQ) -internal external fun wasm_ref_eq(a: Any?, b: Any?): Boolean +internal fun wasm_ref_eq(a: Any?, b: Any?): Boolean = + implementedAsIntrinsic // --- diff --git a/libraries/stdlib/wasm/src/kotlin/Dynamic.kt b/libraries/stdlib/wasm/src/kotlin/Dynamic.kt index b19d02f93fb..1701737d547 100644 --- a/libraries/stdlib/wasm/src/kotlin/Dynamic.kt +++ b/libraries/stdlib/wasm/src/kotlin/Dynamic.kt @@ -152,7 +152,7 @@ internal fun Dynamic.getAny(index: Int): T? = dynamicGetAny(this, index.toSt /** * Represents unversal type for JS interoperability. */ -external interface Dynamic +external interface Dynamic : JsAny /** * Reinterprets this value as a value of the Dynamic type. diff --git a/libraries/stdlib/wasm/src/kotlin/js/JsAny.kt b/libraries/stdlib/wasm/src/kotlin/js/JsAny.kt new file mode 100644 index 00000000000..748c8d5f3f0 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/js/JsAny.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.js + +/** + * Any JavaScript value except null or undefined + */ +public external interface JsAny \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/js/JsArray.kt b/libraries/stdlib/wasm/src/kotlin/js/JsArray.kt new file mode 100644 index 00000000000..f1cfb0f9f0d --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/js/JsArray.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.js + +/** JavaScript Array */ +@JsName("Array") +public external class JsArray : JsAny { + val length: Int +} + +public operator fun JsArray.get(index: Int): T? = + jsArrayGet(this, index) + +public operator fun JsArray.set(index: Int, value: T) { + jsArraySet(this, index, value) +} + +@Suppress("RedundantNullableReturnType", "UNUSED_PARAMETER") +private fun jsArrayGet(array: JsArray, index: Int): T? = + js("array[index]") + +@Suppress("UNUSED_PARAMETER") +private fun jsArraySet(array: JsArray, index: Int, value: T) { + js("array[index] = value") +} \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/js/JsBoolean.kt b/libraries/stdlib/wasm/src/kotlin/js/JsBoolean.kt new file mode 100644 index 00000000000..b3b6e3642b1 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/js/JsBoolean.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.js + +import kotlin.wasm.internal.JsPrimitive +import kotlin.wasm.internal.externRefToKotlinBooleanAdapter +import kotlin.wasm.internal.kotlinBooleanToExternRefAdapter + +/** JavaScript primitive boolean */ +@JsPrimitive("boolean") +public external class JsBoolean internal constructor() : JsAny + +public fun JsBoolean.toBoolean(): Boolean = + externRefToKotlinBooleanAdapter(this) + +public fun Boolean.toJsBoolean(): JsBoolean = + kotlinBooleanToExternRefAdapter(this) \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/js/JsHandle.kt b/libraries/stdlib/wasm/src/kotlin/js/JsHandle.kt new file mode 100644 index 00000000000..62595c919f4 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/js/JsHandle.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.js + +import kotlin.wasm.internal.WasmOp +import kotlin.wasm.internal.implementedAsIntrinsic +import kotlin.wasm.internal.returnArgumentIfItIsKotlinAny + +/** + * JavaScript value that can serve as a handle for any Kotlin value. + * + * In JavaScript, it behaves like an immutable empty object with a null prototype. + * When passed back to Kotlin/Wasm, the original value can be retrieved using the [get] method. + */ +@Suppress("WRONG_JS_INTEROP_TYPE") // Exception to the rule +public sealed external interface JsHandle : JsAny + +@WasmOp(WasmOp.EXTERN_EXTERNALIZE) +public fun T.toJsHandle(): JsHandle = + implementedAsIntrinsic + +/** Retrieve original Kotlin value from JsHandle */ +public fun JsHandle.get(): T { + returnArgumentIfItIsKotlinAny(this) + throw ClassCastException("JsHandle doesn't contain a Kotlin type") +} \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/js/JsNumber.kt b/libraries/stdlib/wasm/src/kotlin/js/JsNumber.kt new file mode 100644 index 00000000000..98e9a2ad829 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/js/JsNumber.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.js + +import kotlin.wasm.internal.JsPrimitive +import kotlin.wasm.internal.externRefToKotlinDoubleAdapter +import kotlin.wasm.internal.externRefToKotlinIntAdapter +import kotlin.wasm.internal.kotlinDoubleToExternRefAdapter +import kotlin.wasm.internal.kotlinIntToExternRefAdapter + +/** JavaScript primitive number */ +@JsPrimitive("number") +public external class JsNumber internal constructor() : JsAny + +public fun JsNumber.toDouble(): Double = + externRefToKotlinDoubleAdapter(this) + +public fun Double.toJsNumber(): JsNumber = + kotlinDoubleToExternRefAdapter(this) + +public fun JsNumber.toInt(): Int = + externRefToKotlinIntAdapter(this) + +public fun Int.toJsNumber(): JsNumber = + kotlinIntToExternRefAdapter(this) \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/js/JsString.kt b/libraries/stdlib/wasm/src/kotlin/js/JsString.kt new file mode 100644 index 00000000000..103eea1b778 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/js/JsString.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.js + +import kotlin.wasm.internal.JsPrimitive +import kotlin.wasm.internal.kotlinToJsStringAdapter + +/** JavaScript primitive string */ +@JsPrimitive("string") +public external class JsString internal constructor() : JsAny + +public fun String.toJsString(): JsString = + kotlinToJsStringAdapter(this)!! \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/js/Promise.kt b/libraries/stdlib/wasm/src/kotlin/js/Promise.kt index a44b4907786..27a83e52e2a 100644 --- a/libraries/stdlib/wasm/src/kotlin/js/Promise.kt +++ b/libraries/stdlib/wasm/src/kotlin/js/Promise.kt @@ -8,7 +8,7 @@ package kotlin.js /** * Exposes the JavaScript [Promise object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise) to Kotlin. */ -public external class Promise(executor: (resolve: (Dynamic?) -> Unit, reject: (Dynamic) -> Unit) -> Unit) { +public external class Promise(executor: (resolve: (Dynamic?) -> Unit, reject: (Dynamic) -> Unit) -> Unit) : JsAny { public fun then(onFulfilled: (Dynamic?) -> Dynamic?): Promise public fun then(onFulfilled: (Dynamic?) -> Dynamic?, onRejected: (Dynamic) -> Dynamic?): Promise public fun catch(onRejected: (Dynamic) -> Dynamic?): Promise diff --git a/libraries/stdlib/wasm/src/kotlin/js/core.kt b/libraries/stdlib/wasm/src/kotlin/js/core.kt index 760185a7c8c..78a2a7d05af 100644 --- a/libraries/stdlib/wasm/src/kotlin/js/core.kt +++ b/libraries/stdlib/wasm/src/kotlin/js/core.kt @@ -34,6 +34,7 @@ import kotlin.wasm.internal.ExcludedFromCodegen * ``` */ @ExcludedFromCodegen +@Suppress("WRONG_JS_INTEROP_TYPE") public external val definedExternally: Nothing /** diff --git a/libraries/stdlib/wasm/src/kotlinx/dom/ItemArrayLike.kt b/libraries/stdlib/wasm/src/kotlinx/dom/ItemArrayLike.kt index 696a800f4a4..165dca7044b 100644 --- a/libraries/stdlib/wasm/src/kotlinx/dom/ItemArrayLike.kt +++ b/libraries/stdlib/wasm/src/kotlinx/dom/ItemArrayLike.kt @@ -5,12 +5,12 @@ package org.w3c.dom -public external interface ItemArrayLike { +public external interface ItemArrayLike : JsAny { val length: Int fun item(index: Int): T? } -public fun ItemArrayLike.asList(): List = object : AbstractList() { +public fun ItemArrayLike.asList(): List = object : AbstractList() { override val size: Int get() = this@asList.length @Suppress("UNCHECKED_CAST") diff --git a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenWasmJsInteropWasmTestGenerated.java b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenWasmJsInteropWasmTestGenerated.java index b4b770065ad..d7e6dd2502f 100644 --- a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenWasmJsInteropWasmTestGenerated.java +++ b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenWasmJsInteropWasmTestGenerated.java @@ -95,6 +95,11 @@ public class IrCodegenWasmJsInteropWasmTestGenerated extends AbstractIrCodegenWa runTest("compiler/testData/codegen/boxWasmJsInterop/jsToKotlinAdapters.kt"); } + @TestMetadata("jsTypes.kt") + public void testJsTypes() throws Exception { + runTest("compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt"); + } + @TestMetadata("kotlinToJsAdapters.kt") public void testKotlinToJsAdapters() throws Exception { runTest("compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt");