diff --git a/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/bound/emptyLHS.kt b/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/bound/emptyLHS.kt index f125a65a40c..5b68ae0d4d2 100644 --- a/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/bound/emptyLHS.kt +++ b/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/bound/emptyLHS.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND: NATIVE -// IGNORE_BACKEND: JS // IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt b/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt index 12531114a8e..99bc3d3a2b8 100644 --- a/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt +++ b/compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND: NATIVE -// IGNORE_BACKEND: JS // IGNORE_BACKEND: JVM_IR // WITH_COROUTINES // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt b/compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt new file mode 100644 index 00000000000..764ef25af13 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt @@ -0,0 +1,53 @@ +// !LANGUAGE: +ReleaseCoroutines +// IGNORE_BACKEND: JVM_IR +// WITH_RUNTIME +// WITH_COROUTINES +import helpers.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +suspend fun id(s: String) = s + +suspend fun String.idExt() = this + +class A { + suspend fun id(s: String) = s +} + +suspend fun run(block: suspend () -> String) = block() + +inline suspend fun runInline(block: suspend () -> String) = block() + +suspend fun O(block: suspend (String) -> String) = block("O") + +inline suspend fun K(block: suspend (String) -> String) = block("K") + +suspend fun ok(o: String): String { + return o + run { + if (o != "K") { + (::ok)("K") + } else "" + } +} + +fun box(): String { + var result = "" + + builder { + result = O(::id) + K(::id) + result += run("O"::idExt) + runInline("K"::idExt) + + val a = A() + result += O(a::id) + K(a::id) + + result += ok("O") + } + + if (result != "OKOKOKOK") return "fail: $result" + + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt b/compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt index c756e24583a..22d5b5496e8 100644 --- a/compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt +++ b/compiler/testData/codegen/boxInline/suspend/callableReference/simple.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +ReleaseCoroutines // IGNORE_BACKEND: NATIVE -// IGNORE_BACKEND: JS // IGNORE_BACKEND: JVM_IR // NO_CHECK_LAMBDA_INLINING // FILE: test.kt diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index c9b41bc99a9..eee4317ed14 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -6267,6 +6267,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleException.kt", "kotlin.coroutines"); } + @TestMetadata("simpleSuspendCallableReference.kt") + public void testSimpleSuspendCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 1b241a67d64..e480ea3fd1e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -6267,6 +6267,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleException.kt", "kotlin.coroutines"); } + @TestMetadata("simpleSuspendCallableReference.kt") + public void testSimpleSuspendCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ad00a4fe857..466ed95966f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -6267,6 +6267,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleException.kt", "kotlin.coroutines"); } + @TestMetadata("simpleSuspendCallableReference.kt") + public void testSimpleSuspendCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt", "kotlin.coroutines.experimental"); diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineTransformer.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineTransformer.kt index ea5c2b999dd..f97cd0f4d19 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineTransformer.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineTransformer.kt @@ -44,17 +44,14 @@ class CoroutineTransformer : JsVisitorWithContextImpl() { return super.visit(x, ctx) } - override fun visit(x: JsFunction, ctx: JsContext<*>): Boolean { + override fun endVisit(x: JsFunction, ctx: JsContext<*>) { if (x.isInlineableCoroutineBody) { x.body = transformCoroutineMetadataToSpecialFunctions(x.body) - return false } if (x.coroutineMetadata != null) { lastStatementLevelContext.addPrevious(CoroutineFunctionTransformer(x, functionName[x]).transform()) x.coroutineMetadata = null - return false } - return super.visit(x, ctx) } override fun visit(x: JsVars.JsVar, ctx: JsContext<*>): Boolean { diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 04511686b48..1f6090925aa 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -5072,6 +5072,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleException.kt", "kotlin.coroutines"); } + @TestMetadata("simpleSuspendCallableReference.kt") + public void testSimpleSuspendCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt", "kotlin.coroutines"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index e395984be12..641b144d6b0 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -5397,6 +5397,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleException.kt", "kotlin.coroutines"); } + @TestMetadata("simpleSuspendCallableReference.kt") + public void testSimpleSuspendCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/simpleSuspendCallableReference.kt"); + } + @TestMetadata("simpleWithHandleResult.kt") public void testSimpleWithHandleResult_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/simpleWithHandleResult.kt", "kotlin.coroutines.experimental"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java index 2fd7a71695f..95671d93d5a 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java @@ -540,9 +540,11 @@ public class TranslationContext { @Nullable public JsExpression getAliasForDescriptor(@NotNull DeclarationDescriptor descriptor) { - JsExpression nameRef = captureIfNeedAndGetCapturedName(descriptor); - if (nameRef != null) { - return nameRef; + if (continuationParameterDescriptor != descriptor) { + JsExpression nameRef = captureIfNeedAndGetCapturedName(descriptor); + if (nameRef != null) { + return nameRef; + } } JsExpression alias = aliasingContext.getAliasForDescriptor(descriptor); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt index e310de44b88..7b92373c02a 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt @@ -24,9 +24,7 @@ import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.general.Translation -import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils -import org.jetbrains.kotlin.js.translate.utils.TranslationUtils -import org.jetbrains.kotlin.js.translate.utils.finalElement +import org.jetbrains.kotlin.js.translate.utils.* import org.jetbrains.kotlin.psi.KtCallableReferenceExpression import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getFunctionResolvedCallWithAssert @@ -127,7 +125,18 @@ object CallableReferenceTranslator { val type = functionDescriptor.valueParameters[index].type aliases[valueArg.getArgumentExpression()!!] = TranslationUtils.coerce(context, paramRef, type) } - val functionContext = context.innerBlock(function.body).innerContextWithAliasesForExpressions(aliases) + + var functionContext = context.innerBlock(function.body).innerContextWithAliasesForExpressions(aliases).inner(functionDescriptor) + + functionContext.continuationParameterDescriptor?.let { continuationDescriptor -> + function.parameters += JsParameter(context.getNameForDescriptor(continuationDescriptor)) + functionContext = functionContext.innerContextWithDescriptorsAliased(mapOf(continuationDescriptor to JsAstUtils.stateMachineReceiver())) + } + + if (functionDescriptor.isSuspend) { + function.fillCoroutineMetadata(functionContext, descriptor, hasController = false) + } + val invocation = CallTranslator.translate(functionContext, fakeResolvedCall, receiverParam) function.body.statements += JsReturn(TranslationUtils.coerce(context, invocation, context.currentModule.builtIns.anyType))