[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) {
|
private fun StringBuilder.appendExternalClassReference(klass: IrClass) {
|
||||||
val parent = klass.parent
|
val parent = klass.parent
|
||||||
if (parent is IrClass) {
|
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)
|
appendExternalClassReference(parent)
|
||||||
if (klass.isCompanion) {
|
if (klass.isCompanion) {
|
||||||
// Reference to external companion object is reference to its parent class
|
// 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");
|
runTest("compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt59082.kt")
|
||||||
|
public void testKt59082() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxWasmJsInterop/kt59082.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lambdaAdapterNameClash.kt")
|
@TestMetadata("lambdaAdapterNameClash.kt")
|
||||||
public void testLambdaAdapterNameClash() throws Exception {
|
public void testLambdaAdapterNameClash() throws Exception {
|
||||||
|
|||||||
+6
@@ -115,6 +115,12 @@ public class K1WasmCodegenWasmJsInteropTestGenerated extends AbstractK1WasmCodeg
|
|||||||
runTest("compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt");
|
runTest("compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt59082.kt")
|
||||||
|
public void testKt59082() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxWasmJsInterop/kt59082.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lambdaAdapterNameClash.kt")
|
@TestMetadata("lambdaAdapterNameClash.kt")
|
||||||
public void testLambdaAdapterNameClash() throws Exception {
|
public void testLambdaAdapterNameClash() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user