diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index 4d25c797464..0bc1f1ac628 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -276,7 +276,8 @@ class AnonymousObjectTransformer( InlineCallSiteInfo( transformationInfo.oldClassName, sourceNode.name, - if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc + if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc, + inliningContext.callSiteInfo.isInlineOrInsideInline ), null ) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCallSiteInfo.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCallSiteInfo.kt index 0e62df11b39..63fbc9f2b96 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCallSiteInfo.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCallSiteInfo.kt @@ -16,4 +16,4 @@ package org.jetbrains.kotlin.codegen.inline -class InlineCallSiteInfo(val ownerClassName: String, val functionName: String?, val functionDesc: String?) \ No newline at end of file +class InlineCallSiteInfo(val ownerClassName: String, val functionName: String?, val functionDesc: String?, val isInlineOrInsideInline: Boolean) \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt index 997d853cca2..0df5ad422a6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt @@ -121,7 +121,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid val signature = codegen.state.typeMapper.mapSignatureSkipGeneric(context.functionDescriptor, context.contextKind) return InlineCallSiteInfo( - parentCodegen.className, signature.asmMethod.name, signature.asmMethod.descriptor + parentCodegen.className, signature.asmMethod.name, signature.asmMethod.descriptor, compilationContextFunctionDescriptor.isInlineOrInsideInline() ) } @@ -472,4 +472,8 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid } } -} \ No newline at end of file +} + +private fun DeclarationDescriptor.isInlineOrInsideInline(): Boolean = + if (this is FunctionDescriptor && isInline) true + else containingDeclaration?.isInlineOrInsideInline() == true 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 98bd25aa32c..af3381918d4 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 @@ -34,6 +34,9 @@ class CoroutineTransformer( private val state = inliningContext.state fun shouldTransform(node: MethodNode): Boolean { + // Never generate state-machine for objects, which are going to be retransformed + // See innerObjectRetransformation.kt + if (inliningContext.callSiteInfo.isInlineOrInsideInline) return false if (isContinuationNotLambda()) return false val crossinlineParam = crossinlineLambda() ?: return false if (inliningContext.isInliningLambda && !inliningContext.isContinuation) return false diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index fcecebf418d..f0805d040f3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -63,7 +63,7 @@ class IrSourceCompilerForInline( get() = OwnerKind.getMemberOwnerKind(callElement.descriptor.containingDeclaration) override val inlineCallSiteInfo: InlineCallSiteInfo - get() = InlineCallSiteInfo("TODO", null, null) + get() = InlineCallSiteInfo("TODO", null, null, false) override val lazySourceMapper: DefaultSourceMapper get() = codegen.classCodegen.getOrCreateSourceMapper() diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt index 1ad00f7a5ba..41e099a75b5 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt @@ -1,12 +1,5 @@ @kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field L$4: java.lang.Object - field L$5: java.lang.Object field label: int synthetic field result: java.lang.Object synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1 @@ -16,13 +9,8 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } -@kotlin.coroutines.jvm.internal.DebugMetadata @kotlin.Metadata public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object field label: int synthetic field result: java.lang.Object synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 @@ -75,8 +63,8 @@ public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$1 { public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } -@kotlin.coroutines.jvm.internal.DebugMetadata @kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1 { field L$0: java.lang.Object field L$1: java.lang.Object @@ -93,8 +81,8 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } -@kotlin.coroutines.jvm.internal.DebugMetadata @kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1 { field L$0: java.lang.Object field L$1: java.lang.Object @@ -129,11 +117,22 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 { public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } +@kotlin.Metadata +public final class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1$1 { + field label: int + synthetic field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 + inner class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 + inner class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1$1 + public method (p0: CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1, p1: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + @kotlin.Metadata public final class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 { synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef - inner class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1 inner class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 + inner class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1$1 public method (p0: kotlin.jvm.internal.Ref$ObjectRef): void public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object @@ -178,14 +177,7 @@ public final class CrossinlineKt$consumeEach$2 { } @kotlin.Metadata -@kotlin.coroutines.jvm.internal.DebugMetadata public final class CrossinlineKt$filter$$inlined$source$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field L$4: java.lang.Object - field L$5: java.lang.Object field label: int synthetic field result: java.lang.Object synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1 @@ -195,13 +187,8 @@ public final class CrossinlineKt$filter$$inlined$source$1$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } -@kotlin.coroutines.jvm.internal.DebugMetadata @kotlin.Metadata public final class CrossinlineKt$filter$$inlined$source$1$lambda$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object field label: int synthetic field result: java.lang.Object synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1$lambda$1 diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_1_2.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_1_2.txt index 90225f11ccb..797b1d7e560 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_1_2.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_1_2.txt @@ -54,11 +54,24 @@ public final class CrossinlineKt$box$1$doResume$$inlined$filter$1 { public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object } +@kotlin.Metadata +public final class CrossinlineKt$box$1$doResume$$inlined$fold$1$1 { + synthetic field data: java.lang.Object + synthetic field exception: java.lang.Throwable + synthetic final field this$0: CrossinlineKt$box$1$doResume$$inlined$fold$1 + inner class CrossinlineKt$box$1$doResume$$inlined$fold$1 + inner class CrossinlineKt$box$1$doResume$$inlined$fold$1$1 + public method (p0: CrossinlineKt$box$1$doResume$$inlined$fold$1, p1: kotlin.coroutines.experimental.Continuation): void + public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object + synthetic final method getLabel(): int + synthetic final method setLabel(p0: int): void +} + @kotlin.Metadata public final class CrossinlineKt$box$1$doResume$$inlined$fold$1 { synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef inner class CrossinlineKt$box$1$doResume$$inlined$fold$1 - inner class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1 + inner class CrossinlineKt$box$1$doResume$$inlined$fold$1$1 public method (p0: kotlin.jvm.internal.Ref$ObjectRef): void public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object @@ -66,12 +79,6 @@ public final class CrossinlineKt$box$1$doResume$$inlined$fold$1 { @kotlin.Metadata public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field L$4: java.lang.Object - field L$5: java.lang.Object synthetic field data: java.lang.Object synthetic field exception: java.lang.Throwable synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1 @@ -85,10 +92,6 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 { @kotlin.Metadata public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object synthetic field data: java.lang.Object synthetic field exception: java.lang.Throwable synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 @@ -185,12 +188,6 @@ public final class CrossinlineKt$consumeEach$2 { @kotlin.Metadata public final class CrossinlineKt$filter$$inlined$source$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object - field L$4: java.lang.Object - field L$5: java.lang.Object synthetic field data: java.lang.Object synthetic field exception: java.lang.Throwable synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1 @@ -204,10 +201,6 @@ public final class CrossinlineKt$filter$$inlined$source$1$1 { @kotlin.Metadata public final class CrossinlineKt$filter$$inlined$source$1$lambda$1$1 { - field L$0: java.lang.Object - field L$1: java.lang.Object - field L$2: java.lang.Object - field L$3: java.lang.Object synthetic field data: java.lang.Object synthetic field exception: java.lang.Throwable synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1$lambda$1 diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt index c8cb5a60470..4efa4f7c703 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt @@ -62,11 +62,22 @@ public final class flow/InnerObjectRetransformationKt$check$$inlined$flow$1 { public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } +@kotlin.Metadata +public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 { + field label: int + synthetic field result: java.lang.Object + synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1 + inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 + inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 + public method (p0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1, p1: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + @kotlin.Metadata public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 { synthetic final field $this_flowWith$inlined: flow.Flow inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 - inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 + inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 public method (p0: flow.Flow): void public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_1_2.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_1_2.txt index 801ea53b2ac..f158e59d625 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_1_2.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_1_2.txt @@ -63,11 +63,24 @@ public final class flow/InnerObjectRetransformationKt$check$$inlined$flow$1 { public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object } +@kotlin.Metadata +public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 { + synthetic field data: java.lang.Object + synthetic field exception: java.lang.Throwable + synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1 + inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 + inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 + public method (p0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1, p1: kotlin.coroutines.experimental.Continuation): void + public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object + synthetic final method getLabel(): int + synthetic final method setLabel(p0: int): void +} + @kotlin.Metadata public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 { synthetic final field $this_flowWith$inlined: flow.Flow inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 - inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 + inner class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 public method (p0: flow.Flow): void public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object } diff --git a/compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt b/compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt new file mode 100644 index 00000000000..1744f20f2a2 --- /dev/null +++ b/compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt @@ -0,0 +1,79 @@ +// IGNORE_BACKEND: JVM_IR +// COMMON_COROUTINES_TEST +// WITH_RUNTIME +// WITH_COROUTINES +// CHECK_STATE_MACHINE + +// In this test the following transformation are occuring: +// flow$1 -> flowWith$$inlined$flow$1 +// flow$1 -> check$$inlined$flow$1 +// flow$1 -> flowWith$$inlined$flow$2 +// flowWith$$inlined$flow$2 -> check$$inlined$flowWith$1 + +// All thansformations, except the third, shall generate state-machine. +// The third shall not generate state-machine, since it is retransformed. + +// FILE: inline.kt +package flow + +interface FlowCollector { + suspend fun emit(value: T) +} + +interface Flow { + suspend fun collect(collector: FlowCollector) +} + +public inline fun flow(crossinline block: suspend FlowCollector.() -> Unit) = object : Flow { + override suspend fun collect(collector: FlowCollector) { + collector.block() + collector.block() + } +} + +suspend inline fun Flow.collect(crossinline action: suspend (T) -> Unit) { + collect(object : FlowCollector { + override suspend fun emit(value: T) { + action(value) + action(value) + } + }) +} + +inline fun Flow.flowWith(crossinline builderBlock: suspend Flow.() -> Flow): Flow = + flow { + builderBlock() + builderBlock() + } + +// FILE: box.kt +// COMMON_COROUTINES_TEST + +import flow.* + +import helpers.* +import COROUTINES_PACKAGE.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(CheckStateMachineContinuation) +} + +suspend fun check() { + val f: Unit = flow { + emit(1) + }.flowWith { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + this + }.collect { + // In this test collect is just terminating operation, which just runs the lazy computations + } +} + +fun box(): String { + builder { + check() + } + StateMachineChecker.check(numberOfSuspensions = 8) + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt b/compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt new file mode 100644 index 00000000000..d2cb0408004 --- /dev/null +++ b/compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt @@ -0,0 +1,48 @@ +// IGNORE_BACKEND: JVM_IR +// COMMON_COROUTINES_TEST +// WITH_RUNTIME +// WITH_COROUTINES +// CHECK_STATE_MACHINE + +// FILE: inline.kt + +import helpers.* + +interface SuspendRunnable { + suspend fun run() +} + +class R : SuspendRunnable { + override suspend fun run() { + val sr: SuspendRunnable = inlineMe2 { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + sr.run() + } + + inline fun inlineMe2(crossinline c: suspend () -> Unit) = object : SuspendRunnable { + override suspend fun run() { + c() + c() + } + } +} + +// FILE: box.kt +// COMMON_COROUTINES_TEST + +import helpers.* +import COROUTINES_PACKAGE.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(CheckStateMachineContinuation) +} + +fun box(): String { + builder { + R().run() + } + StateMachineChecker.check(numberOfSuspensions = 4) + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt b/compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt new file mode 100644 index 00000000000..c2ed9d8205e --- /dev/null +++ b/compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt @@ -0,0 +1,44 @@ +// IGNORE_BACKEND: JVM_IR +// COMMON_COROUTINES_TEST +// WITH_RUNTIME +// WITH_COROUTINES +// CHECK_STATE_MACHINE + +// FILE: inline.kt + +interface SuspendRunnable { + suspend fun run() +} + +inline fun inlineMe(crossinline c: suspend () -> Unit) = { + { + val sr: SuspendRunnable = object : SuspendRunnable { + override suspend fun run() { + c() + c() + } + } + sr + }() +}() + +// FILE: box.kt +// COMMON_COROUTINES_TEST + +import helpers.* +import COROUTINES_PACKAGE.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(CheckStateMachineContinuation) +} + +fun box(): String { + builder { + inlineMe { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + }.run() + } + StateMachineChecker.check(numberOfSuspensions = 4) + return "OK" +} diff --git a/compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt b/compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt new file mode 100644 index 00000000000..c5978b23e91 --- /dev/null +++ b/compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt @@ -0,0 +1,57 @@ +// IGNORE_BACKEND: JVM_IR +// COMMON_COROUTINES_TEST +// WITH_RUNTIME +// WITH_COROUTINES +// CHECK_STATE_MACHINE + +// FILE: inline.kt + +interface SuspendRunnable { + suspend fun run() + suspend fun run2() +} + +inline fun inlineMe(crossinline c: suspend () -> Unit, crossinline c2: suspend () -> Unit) = + object : SuspendRunnable { + override suspend fun run() { + c() + c() + } + + override suspend fun run2() { + c2() + c2() + } + } + +// FILE: box.kt +// COMMON_COROUTINES_TEST + +import helpers.* +import COROUTINES_PACKAGE.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(CheckStateMachineContinuation) +} + +fun box(): String { + val r = inlineMe( + { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + ) { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + builder { + r.run() + } + StateMachineChecker.check(numberOfSuspensions = 4) + StateMachineChecker.reset() + builder { + r.run2() + } + StateMachineChecker.check(numberOfSuspensions = 4) + return "OK" +} diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt index e1710dd329f..3371c25fb7c 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt @@ -83,6 +83,12 @@ fun createTextForHelpers(isReleaseCoroutines: Boolean, checkStateMachine: Boolea var proceed: () -> Unit = {} + fun reset() { + counter = 0 + finished = false + proceed = {} + } + suspend fun suspendHere() = suspendCoroutine { c -> counter++ proceed = { c.resume(Unit) } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index 6afd49fe595..020116e6e4e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -3821,6 +3821,16 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectInsideInnerObject.kt", "kotlin.coroutines"); } + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines"); + } + @TestMetadata("innerObjectSeveralFunctions.kt") public void testInnerObjectSeveralFunctions_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectSeveralFunctions.kt", "kotlin.coroutines.experimental"); @@ -3851,6 +3861,16 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObject.kt", "kotlin.coroutines"); } + @TestMetadata("insideObject.kt") + public void testInsideObject_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("insideObject.kt") + public void testInsideObject_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental"); @@ -3870,6 +3890,26 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo public void testNumberOfSuspentions_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/numberOfSuspentions.kt", "kotlin.coroutines"); } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); + } } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 61c37959612..04c49e7ca00 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -3821,6 +3821,16 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectInsideInnerObject.kt", "kotlin.coroutines"); } + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines"); + } + @TestMetadata("innerObjectSeveralFunctions.kt") public void testInnerObjectSeveralFunctions_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectSeveralFunctions.kt", "kotlin.coroutines.experimental"); @@ -3851,6 +3861,16 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObject.kt", "kotlin.coroutines"); } + @TestMetadata("insideObject.kt") + public void testInsideObject_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("insideObject.kt") + public void testInsideObject_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental"); @@ -3870,6 +3890,26 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi public void testNumberOfSuspentions_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/numberOfSuspentions.kt", "kotlin.coroutines"); } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); + } } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index 52fe86bd543..41c7c59578e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -3821,6 +3821,16 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectInsideInnerObject.kt", "kotlin.coroutines"); } + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines"); + } + @TestMetadata("innerObjectSeveralFunctions.kt") public void testInnerObjectSeveralFunctions_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectSeveralFunctions.kt", "kotlin.coroutines.experimental"); @@ -3851,6 +3861,16 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObject.kt", "kotlin.coroutines"); } + @TestMetadata("insideObject.kt") + public void testInsideObject_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("insideObject.kt") + public void testInsideObject_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental"); @@ -3870,6 +3890,26 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli public void testNumberOfSuspentions_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/numberOfSuspentions.kt", "kotlin.coroutines"); } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); + } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java index 18e20bbddaf..253019b9897 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrInlineSuspendTestsGenerated.java @@ -289,6 +289,11 @@ public class IrInlineSuspendTestsGenerated extends AbstractIrInlineSuspendTests runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectInsideInnerObject.kt", "kotlin.coroutines"); } + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines"); + } + @TestMetadata("innerObjectSeveralFunctions.kt") public void testInnerObjectSeveralFunctions_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectSeveralFunctions.kt", "kotlin.coroutines"); @@ -304,6 +309,11 @@ public class IrInlineSuspendTestsGenerated extends AbstractIrInlineSuspendTests runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObject.kt", "kotlin.coroutines"); } + @TestMetadata("insideObject.kt") + public void testInsideObject_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines"); @@ -313,5 +323,15 @@ public class IrInlineSuspendTestsGenerated extends AbstractIrInlineSuspendTests public void testNumberOfSuspentions_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/numberOfSuspentions.kt", "kotlin.coroutines"); } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); + } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java index df422c24c12..76fd53f1e3f 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineSuspendTestsGenerated.java @@ -439,6 +439,16 @@ public class InlineSuspendTestsGenerated extends AbstractInlineSuspendTests { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectInsideInnerObject.kt", "kotlin.coroutines"); } + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("innerObjectRetransformation.kt") + public void testInnerObjectRetransformation_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectRetransformation.kt", "kotlin.coroutines"); + } + @TestMetadata("innerObjectSeveralFunctions.kt") public void testInnerObjectSeveralFunctions_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObjectSeveralFunctions.kt", "kotlin.coroutines.experimental"); @@ -469,6 +479,16 @@ public class InlineSuspendTestsGenerated extends AbstractInlineSuspendTests { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/innerObject.kt", "kotlin.coroutines"); } + @TestMetadata("insideObject.kt") + public void testInsideObject_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("insideObject.kt") + public void testInsideObject_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines"); + } + @TestMetadata("normalInline.kt") public void testNormalInline_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental"); @@ -488,5 +508,25 @@ public class InlineSuspendTestsGenerated extends AbstractInlineSuspendTests { public void testNumberOfSuspentions_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/numberOfSuspentions.kt", "kotlin.coroutines"); } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("objectInsideLambdas.kt") + public void testObjectInsideLambdas_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/objectInsideLambdas.kt", "kotlin.coroutines"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("oneInlineTwoCaptures.kt") + public void testOneInlineTwoCaptures_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/oneInlineTwoCaptures.kt", "kotlin.coroutines"); + } } }