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
This commit is contained in:
Ilmir Usmanov
2019-03-28 22:16:01 +03:00
parent f09457c569
commit 3bfee39995
3 changed files with 15 additions and 6 deletions
@@ -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)
}
}
@@ -109,8 +109,7 @@ class CoroutineTransformer(
languageVersionSettings = state.languageVersionSettings,
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
containingClassInternalName = classBuilder.thisName,
isForNamedFunction = false,
isCrossinlineLambda = inliningContext.isContinuation
isForNamedFunction = false
)
}
}
@@ -23,6 +23,10 @@ inline suspend fun <T : Any> Flow<T>.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<Unit>? = null
suspendCoroutineUninterceptedOrReturn<Unit> { continuation = it; Unit }
str = "$continuation"
}()
}
if ("(Test.kt:" !in str) return str
return "OK"
}