From 9f52326d14b925494d0c079a3e4115b241f0dd6c Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 25 Oct 2021 13:36:28 +0300 Subject: [PATCH] [JS IR] Fix default arguments in suspend functions Don't forget to remap parameter references in default arg expressions The issue originally discovered in kotlinx.coroutines tests. - add test --- .../FirBlackBoxCodegenTestGenerated.java | 6 +++ .../AddContinuationToFunctionsLowering.kt | 23 +++++++--- .../box/coroutines/simpleWithDefaultValue.kt | 44 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 +++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++ .../IrJsCodegenBoxTestGenerated.java | 5 +++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++ .../js/testNew/JsCodegenBoxTestGenerated.java | 6 +++ 10 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 7b71c7ff4c2..343eb3aba8e 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -9894,6 +9894,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @Test + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @Test @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AddContinuationToFunctionsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AddContinuationToFunctionsLowering.kt index dd68a7319bf..447977e2d96 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AddContinuationToFunctionsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/AddContinuationToFunctionsLowering.kt @@ -5,19 +5,25 @@ package org.jetbrains.kotlin.ir.backend.js.lower.coroutines -import org.jetbrains.kotlin.backend.common.* +import org.jetbrains.kotlin.backend.common.BodyLoweringPass +import org.jetbrains.kotlin.backend.common.DeclarationTransformer +import org.jetbrains.kotlin.backend.common.getOrPut import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext -import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.builders.declarations.* +import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter +import org.jetbrains.kotlin.ir.builders.declarations.buildFun +import org.jetbrains.kotlin.ir.builders.irReturnUnit import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.ir.expressions.IrBody +import org.jetbrains.kotlin.ir.expressions.IrReturn +import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.isNullable import org.jetbrains.kotlin.ir.types.typeWith -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.util.explicitParameters +import org.jetbrains.kotlin.ir.util.substitute import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -109,6 +115,11 @@ private fun IrSimpleFunction.createSuspendFunctionStub(context: JsCommonBackendC } function.valueParameters = valueParameters.map { it.copyTo(function) } + val mapping = mutableMapOf() + valueParameters.forEach { mapping[it.symbol] = function.valueParameters[it.index].symbol } + val remapper = ValueRemapper(mapping) + function.valueParameters.forEach { it.defaultValue = it.defaultValue?.transform(remapper, null) } + function.addValueParameter( "\$cont", continuationType(context).substitute(substitutionMap), diff --git a/compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt b/compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt new file mode 100644 index 00000000000..5495c67fadf --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt @@ -0,0 +1,44 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import helpers.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +suspend fun suspendHere(a: String, b: String = a, c: String = a + b): String = suspendCoroutineUninterceptedOrReturn { x -> + x.resume("$a:$b:$c") + COROUTINE_SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = suspendHere("AAA") + } + + if (result != "AAA:AAA:AAAAAA") return "FAIL 1: $result" + + builder { + result = suspendHere("AAA", c = "CCC") + } + + if (result != "AAA:AAA:CCC") return "FAIL 2: $result" + + builder { + result = suspendHere("AAA", "BBB") + } + + if (result != "AAA:BBB:AAABBB") return "FAIL 3: $result" + + builder { + result = suspendHere("AAA", "BBB", "CCC") + } + + if (result != "AAA:BBB:CCC") return "FAIL 4: $result" + + return "OK" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 1a384d826ae..f39ffbd49ff 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -9816,6 +9816,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @Test + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @Test @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 3a741203d3d..40c5e5ddb60 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -9894,6 +9894,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @Test + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @Test @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 05b679fdbe1..33c9ab873e9 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7698,6 +7698,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception { runTest("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index b31916d78dd..e1b6b6bbfe7 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -6857,6 +6857,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception { runTest("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 79d7f4d0f45..5c1cdd2e3b9 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -6263,6 +6263,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception { runTest("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index b25cb51c2e7..78c3794c1b4 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -6086,6 +6086,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception { runTest("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testNew/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testNew/JsCodegenBoxTestGenerated.java index ff9f9432fdf..d4be04d4656 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testNew/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testNew/JsCodegenBoxTestGenerated.java @@ -7082,6 +7082,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); } + @Test + @TestMetadata("simpleWithDefaultValue.kt") + public void testSimpleWithDefaultValue() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleWithDefaultValue.kt"); + } + @Test @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult() throws Exception {