diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt index 7036b7e2dba..ee185a8f32d 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/StateMachineBuilder.kt @@ -488,6 +488,24 @@ class StateMachineBuilder( transformLastExpression { expression.apply { receiver = it } } } + override fun visitDynamicMemberExpression(expression: IrDynamicMemberExpression, data: Nothing?) { + if (expression !in suspendableNodes) return addStatement(expression) + expression.acceptChildrenVoid(this) + transformLastExpression { expression.apply { receiver = it } } + } + + override fun visitDynamicOperatorExpression(expression: IrDynamicOperatorExpression) { + if (expression !in suspendableNodes) return addStatement(expression) + + val newArguments = transformArguments(expression.arguments.toTypedArray()) + + for (i in 0 until expression.arguments.size) { + expression.arguments[i] = newArguments[i]!! + } + + addStatement(expression) + } + override fun visitGetClass(expression: IrGetClass) { if (expression !in suspendableNodes) return addStatement(expression) expression.acceptChildrenVoid(this) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java index 3859bbe7139..bc270e16190 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java @@ -796,6 +796,24 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/coroutines/debugStatement.kt"); } + @Test + @TestMetadata("dynamicSuspendReturn.kt") + public void testDynamicSuspendReturn() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturn.kt"); + } + + @Test + @TestMetadata("dynamicSuspendReturnWithArrayAccess.kt") + public void testDynamicSuspendReturnWithArrayAccess() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithArrayAccess.kt"); + } + + @Test + @TestMetadata("dynamicSuspendReturnWithOperator.kt") + public void testDynamicSuspendReturnWithOperator() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithOperator.kt"); + } + @Test @TestMetadata("kt54382.kt") public void testKt54382() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java index 656caee647a..22430babb5e 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java @@ -860,6 +860,24 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest { runTest("js/js.translator/testData/box/coroutines/debugStatement.kt"); } + @Test + @TestMetadata("dynamicSuspendReturn.kt") + public void testDynamicSuspendReturn() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturn.kt"); + } + + @Test + @TestMetadata("dynamicSuspendReturnWithArrayAccess.kt") + public void testDynamicSuspendReturnWithArrayAccess() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithArrayAccess.kt"); + } + + @Test + @TestMetadata("dynamicSuspendReturnWithOperator.kt") + public void testDynamicSuspendReturnWithOperator() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithOperator.kt"); + } + @Test @TestMetadata("kt54382.kt") public void testKt54382() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java index 6e3f3d081c2..90b48cfbfc6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java @@ -860,6 +860,24 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/coroutines/debugStatement.kt"); } + @Test + @TestMetadata("dynamicSuspendReturn.kt") + public void testDynamicSuspendReturn() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturn.kt"); + } + + @Test + @TestMetadata("dynamicSuspendReturnWithArrayAccess.kt") + public void testDynamicSuspendReturnWithArrayAccess() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithArrayAccess.kt"); + } + + @Test + @TestMetadata("dynamicSuspendReturnWithOperator.kt") + public void testDynamicSuspendReturnWithOperator() throws Exception { + runTest("js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithOperator.kt"); + } + @Test @TestMetadata("kt54382.kt") public void testKt54382() throws Exception { diff --git a/js/js.translator/testData/box/coroutines/dynamicSuspendReturn.kt b/js/js.translator/testData/box/coroutines/dynamicSuspendReturn.kt new file mode 100644 index 00000000000..90616eb7309 --- /dev/null +++ b/js/js.translator/testData/box/coroutines/dynamicSuspendReturn.kt @@ -0,0 +1,26 @@ +// WITH_STDLIB +// EXPECTED_REACHABLE_NODES: 1292 + +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +suspend fun foo(): dynamic { + return js("{ test: 'OK' }") +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(object : Continuation { + override val context = EmptyCoroutineContext + override fun resumeWith(result: Result) {} + }) +} + +fun box(): String { + var result = "" + + builder { + result += foo().test + } + + return result +} diff --git a/js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithArrayAccess.kt b/js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithArrayAccess.kt new file mode 100644 index 00000000000..cd83e1ae765 --- /dev/null +++ b/js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithArrayAccess.kt @@ -0,0 +1,28 @@ +// IGNORE_BACKEND: JS +// WITH_STDLIB +// EXPECTED_REACHABLE_NODES: 1292 + +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +suspend fun foo(): dynamic { + return js("[1, 2, 3]") +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(object : Continuation { + override val context = EmptyCoroutineContext + override fun resumeWith(result: Result) {} + }) +} + +fun box(): String { + var result: dynamic = 0 + val count = 0; + + builder { + result += foo()[count + 0] + foo()[count + 1] * foo()[count + 2] + } + + return if (result == 7) "OK" else "fail: the wrong answer. Expect to have 7 but got $result" +} diff --git a/js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithOperator.kt b/js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithOperator.kt new file mode 100644 index 00000000000..e7b048bef3d --- /dev/null +++ b/js/js.translator/testData/box/coroutines/dynamicSuspendReturnWithOperator.kt @@ -0,0 +1,27 @@ +// IGNORE_BACKEND: JS +// WITH_STDLIB +// EXPECTED_REACHABLE_NODES: 1292 + +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +suspend fun foo(): dynamic { + return 2 +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(object : Continuation { + override val context = EmptyCoroutineContext + override fun resumeWith(result: Result) {} + }) +} + +fun box(): String { + var result: dynamic = 1 + + builder { + result += foo() + 2 + result + foo() + } + + return if (result == 8) "OK" else "fail: the wrong answer. Expect to have 8 but got $result" +}