From 3bfee39995e977887fc0f3aa52dccb0d182b5826 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Thu, 28 Mar 2019 22:16:01 +0300 Subject: [PATCH] Generate debug metadata for lambdas which capture crossinline lambdas After cold stream related fixes, we do not generate state machine until the very last transformation of the lambda. Thus, it is safe to generate debug metadata for that lambda. #KT-30694 Fixed --- .../coroutines/CoroutineTransformerMethodVisitor.kt | 6 ++---- .../inline/coroutines/CoroutineTransformer.kt | 3 +-- .../codegen/boxInline/suspend/fileNameInMetadata.kt | 12 ++++++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index fa0766df5ed..a8de636f806 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -66,9 +66,7 @@ class CoroutineTransformerMethodVisitor( // It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls private val needDispatchReceiver: Boolean = false, // May differ from containingClassInternalName in case of DefaultImpls - private val internalNameForDispatchReceiver: String? = null, - // For crossinline lambdas we do not generate DebugMetadata annotation, otherwise it will be generated twice - private val isCrossinlineLambda: Boolean = false + private val internalNameForDispatchReceiver: String? = null ) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) { private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState) @@ -193,7 +191,7 @@ class CoroutineTransformerMethodVisitor( fixLvtForParameters(methodNode, startLabel, endLabel) - if (languageVersionSettings.isReleaseCoroutines() && !isCrossinlineLambda) { + if (languageVersionSettings.isReleaseCoroutines()) { writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping) } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt index c83a547e461..ccb1f4503eb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt @@ -109,8 +109,7 @@ class CoroutineTransformer( languageVersionSettings = state.languageVersionSettings, shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, containingClassInternalName = classBuilder.thisName, - isForNamedFunction = false, - isCrossinlineLambda = inliningContext.isContinuation + isForNamedFunction = false ) } } diff --git a/compiler/testData/codegen/boxInline/suspend/fileNameInMetadata.kt b/compiler/testData/codegen/boxInline/suspend/fileNameInMetadata.kt index 20b227c8d3b..d33d13c568b 100644 --- a/compiler/testData/codegen/boxInline/suspend/fileNameInMetadata.kt +++ b/compiler/testData/codegen/boxInline/suspend/fileNameInMetadata.kt @@ -23,6 +23,10 @@ inline suspend fun Flow.collect(crossinline action: suspend (T) -> override suspend fun emit(value: T) = action(value) }) +inline suspend fun inlineMe(crossinline block: suspend () -> Unit) = suspend { + block() +} + // FILE: Test.kt import flow.* @@ -45,5 +49,13 @@ fun box(): String { } } if ("(Test.kt:" !in str) return str + builder { + inlineMe { + var continuation: Continuation? = null + suspendCoroutineUninterceptedOrReturn { continuation = it; Unit } + str = "$continuation" + }() + } + if ("(Test.kt:" !in str) return str return "OK" } \ No newline at end of file