Fix continuaion retrieval on generated coroutineContext intrinsic code

Use fake continuation instead on real one in JVM BE.
Pass continuation parameter to closure generator in JS BE.

 #KT-22577: Fixed
This commit is contained in:
Ilmir Usmanov
2018-02-02 20:48:17 +03:00
parent e8cd8b566e
commit ad385f42a9
11 changed files with 111 additions and 22 deletions
@@ -6285,6 +6285,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("coroutineContextInInlinedLambda.kt")
public void testCoroutineContextInInlinedLambda() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/coroutineContextInInlinedLambda.kt");
doTest(fileName);
}
@TestMetadata("createCoroutineSafe.kt")
public void testCreateCoroutineSafe() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt");
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.inline.InlineStrategy
@@ -39,13 +40,13 @@ object CoroutineContextFIF : FunctionIntrinsicFactory {
object Intrinsic : FunctionIntrinsic() {
override fun apply(callInfo: CallInfo, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
val continuation = context.continuationParameterDescriptor ?: error("coroutineContext called from outside of coroutine")
val continuation = TranslationUtils.getEnclosingContinuationParameter(context)
val continuationDescriptor = continuation.type.constructor.declarationDescriptor as? ClassDescriptor ?: error("Continuation is not a class")
val contContext = DescriptorUtils.getPropertyByName(continuationDescriptor.unsubstitutedMemberScope, Name.identifier("context"))
val res = JsNameRef(
context.getNameForDescriptor(contContext),
if (context.declarationDescriptor?.isCoroutineLambda == true) JsAstUtils.stateMachineReceiver()
else context.getNameForDescriptor(continuation).makeRef()
context.getNameForDescriptor(contContext),
if (context.declarationDescriptor?.isCoroutineLambda == true) JsAstUtils.stateMachineReceiver()
else TranslationUtils.translateContinuationArgument(context)
)
res.inlineStrategy = InlineStrategy.NOT_INLINE
return res
@@ -354,7 +354,7 @@ public final class TranslationUtils {
}
@NotNull
private static VariableDescriptor getEnclosingContinuationParameter(@NotNull TranslationContext context) {
public static VariableDescriptor getEnclosingContinuationParameter(@NotNull TranslationContext context) {
VariableDescriptor result = context.getContinuationParameterDescriptor();
if (result == null) {
assert context.getParent() != null;