[Wasm] Fix access to WebIDL dictionary members
Evaluate external interface companion objects as an empty JS object instead of null due to null checks on interop boundary. ^KT-59082 Fixed
This commit is contained in:
committed by
Space Team
parent
92de137cd6
commit
384c700a85
+21
@@ -156,6 +156,27 @@ class ComplexExternalDeclarationsToTopLevelFunctionsLowering(val context: WasmBa
|
||||
private fun StringBuilder.appendExternalClassReference(klass: IrClass) {
|
||||
val parent = klass.parent
|
||||
if (parent is IrClass) {
|
||||
|
||||
// This is hack to support Kotlin/JS like implementation of IDL string enums bindings
|
||||
// with error suppression:
|
||||
//
|
||||
// @JsName("null")
|
||||
// @Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
|
||||
// public external interface CanvasFillRule {
|
||||
// companion object
|
||||
// }
|
||||
// public inline val CanvasFillRule.Companion.NONZERO: CanvasFillRule get() = "nonzero".asDynamic().unsafeCast<CanvasFillRule>()
|
||||
//
|
||||
// Kotlin/JS translates access to CanvasFillRule.Companion as `null` due to @JsName("null"),
|
||||
// but Kotlin/Wasm fails to do this due to stricter null checks on interop boundary.
|
||||
//
|
||||
// Instead, as a temporary solution, we evaluate such companion object to an empty JS object.
|
||||
// TODO: Optimize (KT-60661)
|
||||
if (parent.isInterface) {
|
||||
append("({})")
|
||||
return
|
||||
}
|
||||
|
||||
appendExternalClassReference(parent)
|
||||
if (klass.isCompanion) {
|
||||
// Reference to external companion object is reference to its parent class
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// TARGET_BACKEND: WASM
|
||||
|
||||
@JsName("null")
|
||||
@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
|
||||
public external interface CanvasFillRule : JsAny {
|
||||
companion object
|
||||
}
|
||||
|
||||
public inline val CanvasFillRule.Companion.EVENODD: CanvasFillRule get() =
|
||||
"evenodd".toJsString().unsafeCast<CanvasFillRule>()
|
||||
|
||||
fun box(): String {
|
||||
if (CanvasFillRule.EVENODD.toString() != "evenodd") return "Fail 1"
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -115,6 +115,12 @@ public class FirWasmCodegenWasmJsInteropTestGenerated extends AbstractFirWasmCod
|
||||
runTest("compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt59082.kt")
|
||||
public void testKt59082() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxWasmJsInterop/kt59082.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaAdapterNameClash.kt")
|
||||
public void testLambdaAdapterNameClash() throws Exception {
|
||||
|
||||
+6
@@ -115,6 +115,12 @@ public class K1WasmCodegenWasmJsInteropTestGenerated extends AbstractK1WasmCodeg
|
||||
runTest("compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt59082.kt")
|
||||
public void testKt59082() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxWasmJsInterop/kt59082.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaAdapterNameClash.kt")
|
||||
public void testLambdaAdapterNameClash() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user