From 3c35328c09709c045ac8e4ff05caa37b670dd42b Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Mon, 27 Feb 2023 08:56:39 +0100 Subject: [PATCH] [Wasm] Fix overriding external fun with default parameters (Fix KT-56976) --- ...DeclarationsToTopLevelFunctionsLowering.kt | 12 ++++++++ .../codegen/boxWasmJsInterop/defaultValues.kt | 30 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt index 1df314bd59a..f320dab37a8 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/ComplexExternalDeclarationsToTopLevelFunctionsLowering.kt @@ -476,6 +476,18 @@ class ComplexExternalDeclarationsUsageLowering(val context: WasmBackendContext) } private fun numDefaultParametersForExternalFunction(function: IrFunction): Int { + if (function is IrSimpleFunction) { + // Default parameters can be in overridden external functions + val numDefaultParametersInOverrides = + function.overriddenSymbols.maxOfOrNull { + numDefaultParametersForExternalFunction(it.owner) + } ?: 0 + + if (numDefaultParametersInOverrides > 0) { + return numDefaultParametersInOverrides + } + } + val firstDefaultParameterIndex: Int? = function.valueParameters.firstOrNull { it.defaultValue != null }?.index diff --git a/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt b/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt index cc63f371c3c..8a20476e8e5 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt @@ -21,6 +21,16 @@ class C { } } +class Writable { + foo(x = 10, y = "default") { + return x + y; + } + end(cb = () => "default") { + return cb() + } +} + + // FILE: defaultValues.kt external fun foo( @@ -47,6 +57,21 @@ external class C { fun bar(x5: C = definedExternally, x6: Any = definedExternally) : String } +open external class Writable: WritableStream { + override fun foo(x: Int, y: String): String + override fun end(cb: () -> String): String +} + +external interface WritableStream { + fun foo( + x: Int = definedExternally, + y: String = definedExternally + ): String + + fun end(cb: () -> String = definedExternally): String +} + + fun box(): String { if (foo() != "d1 d2 d3 d4 d5") return "Fail 1" if (foo(x1 = "x1", x3 = "x3", x5 = "x5") != "x1 d2 x3 d4 x5") return "Fail 2" @@ -62,5 +87,10 @@ fun box(): String { if (C().bar(C(), C()) != "100 200 300 400 100 200 300 400") return "Fail 10" if (C().bar() != "10 20 300 400 1 2 300 400") return "Fail 11" + if (Writable().end({ "OK" }) != "OK") return "Fail 12" + if (Writable().end() != "default") return "Fail 13" + if (Writable().foo(x = 33) != "33default") return "Fail 14" + if (Writable().foo(y = "OK") != "10OK") return "Fail 15" + return "OK" } \ No newline at end of file