diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt index 5194de23804..e557003142f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt @@ -30,7 +30,7 @@ open class SuspendFunctionGenerationStrategy( state: GenerationState, protected val originalSuspendDescriptor: FunctionDescriptor, protected val declaration: KtFunction, - private val containingClassInternalName: String, + protected val containingClassInternalName: String, private val constructorCallNormalizationMode: JVMConstructorCallNormalizationMode, protected val functionCodegen: FunctionCodegen ) : FunctionGenerationStrategy.CodegenBased(state) { @@ -53,16 +53,7 @@ open class SuspendFunctionGenerationStrategy( override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor { if (access and Opcodes.ACC_ABSTRACT != 0) return mv - val stateMachineBuilder = CoroutineTransformerMethodVisitor( - mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState, - isForNamedFunction = true, - element = declaration, - diagnostics = state.diagnostics, - shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization, - needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null, - internalNameForDispatchReceiver = containingClassInternalNameOrNull(), - languageVersionSettings = languageVersionSettings - ) + val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc) val forInline = state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true // Both capturing and inline functions share the same suffix, however, inline functions can also be capturing @@ -95,6 +86,24 @@ open class SuspendFunctionGenerationStrategy( ) else stateMachineBuilder } + protected fun createStateMachineBuilder( + mv: MethodVisitor, + access: Int, + name: String, + desc: String + ): CoroutineTransformerMethodVisitor { + return CoroutineTransformerMethodVisitor( + mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState, + isForNamedFunction = true, + element = declaration, + diagnostics = state.diagnostics, + shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization, + needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null, + internalNameForDispatchReceiver = containingClassInternalNameOrNull(), + languageVersionSettings = languageVersionSettings + ) + } + private fun containingClassInternalNameOrNull() = originalSuspendDescriptor.containingDeclaration.safeAs()?.let(state.typeMapper::mapClass)?.internalName diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendInlineFunctionGenerationStrategy.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendInlineFunctionGenerationStrategy.kt index 749e55c1119..601f98fff31 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendInlineFunctionGenerationStrategy.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendInlineFunctionGenerationStrategy.kt @@ -5,20 +5,30 @@ package org.jetbrains.kotlin.codegen.coroutines +import org.jetbrains.kotlin.builtins.isSuspendFunctionType import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.FunctionCodegen import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy import org.jetbrains.kotlin.codegen.TransformationMethodVisitor import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX +import org.jetbrains.kotlin.codegen.inline.coroutines.findReceiverOfInvoke +import org.jetbrains.kotlin.codegen.inline.coroutines.surroundInvokesWithSuspendMarkers +import org.jetbrains.kotlin.codegen.inline.isInvokeOnLambda +import org.jetbrains.kotlin.codegen.optimization.common.asSequence +import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer +import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes -import org.jetbrains.org.objectweb.asm.tree.MethodNode +import org.jetbrains.org.objectweb.asm.tree.* +import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter // For named suspend function we generate two methods: // 1) to use as noinline function, which have state machine @@ -44,7 +54,10 @@ class SuspendInlineFunctionGenerationStrategy( if (access and Opcodes.ACC_ABSTRACT != 0) return mv return MethodNodeCopyingMethodVisitor( - super.wrapMethodVisitor(mv, access, name, desc), access, name, desc, + SurroundSuspendParameterCallsWithSuspendMarkersMethodVisitor( + createStateMachineBuilder(mv, access, name, desc), + access, name, desc, containingClassInternalName, originalSuspendDescriptor.valueParameters + ), access, name, desc, newMethod = { origin, newAccess, newName, newDesc -> functionCodegen.newMethod(origin, newAccess, newName, newDesc, null, null) }, keepAccess = false @@ -78,3 +91,39 @@ class MethodNodeCopyingMethodVisitor( else access or Opcodes.ACC_PRIVATE and Opcodes.ACC_PUBLIC.inv() and Opcodes.ACC_PROTECTED.inv() } } + +private class SurroundSuspendParameterCallsWithSuspendMarkersMethodVisitor( + delegate: MethodVisitor, + access: Int, + name: String, + desc: String, + private val thisName: String, + private val valueParameters: List +): TransformationMethodVisitor(delegate, access, name, desc, null, null) { + override fun performTransformations(methodNode: MethodNode) { + fun AbstractInsnNode.index() = methodNode.instructions.indexOf(this) + fun AbstractInsnNode.isInlineSuspendParameter(): Boolean { + if (this !is VarInsnNode) return false + val index = `var` - (if (methodNode.access and Opcodes.ACC_STATIC != 0) 0 else 1) + return opcode == Opcodes.ALOAD && index < valueParameters.size && InlineUtil.isInlineParameter(valueParameters[index]) && + valueParameters[index].type.isSuspendFunctionType + } + + FixStackMethodTransformer().transform(thisName, methodNode) + + val sourceFrames = MethodTransformer.analyze(thisName, methodNode, SourceInterpreter()) + + val noinlineInvokes = arrayListOf>() + + for (insn in methodNode.instructions.asSequence()) { + if (insn.opcode != Opcodes.INVOKEINTERFACE) continue + insn as MethodInsnNode + if (!isInvokeOnLambda(insn.owner, insn.name)) continue + val frame = sourceFrames[insn.index()] ?: continue + val aload = findReceiverOfInvoke(frame, insn).takeIf { it?.isInlineSuspendParameter() == true } as? VarInsnNode ?: continue + noinlineInvokes.add(insn to aload) + } + + surroundInvokesWithSuspendMarkers(methodNode, noinlineInvokes) + } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/inlineOnly.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/inlineOnly.kt index f3a48f1518d..e8b941b96c1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/inlineOnly.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/inlineOnly.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -18,8 +18,7 @@ fun MemberDescriptor.isInlineOnlyOrReifiable(): Boolean = this is CallableMemberDescriptor && (isReifiable() || DescriptorUtils.getDirectMember(this).isReifiable() || isInlineOnly()) fun MemberDescriptor.isEffectivelyInlineOnly(): Boolean = - isInlineOnlyOrReifiable() || (this is FunctionDescriptor && isSuspend && isInline && - (valueParameters.any { it.isCrossinline } || visibility == Visibilities.PRIVATE)) + isInlineOnlyOrReifiable() || (this is FunctionDescriptor && isSuspend && isInline && visibility == Visibilities.PRIVATE) fun MemberDescriptor.isInlineOnly(): Boolean = this is FunctionDescriptor && isInline && diff --git a/compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt b/compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt new file mode 100644 index 00000000000..4ead14b567d --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt @@ -0,0 +1,78 @@ +// IGNORE_BACKEND: JVM_IR +// TARGET_BACKEND: JVM +// COMMON_COROUTINES_TEST +// WITH_RUNTIME +// WITH_COROUTINES +// NO_CHECK_LAMBDA_INLINING +// CHECK_STATE_MACHINE + +// FILE: inlineMe.kt + +package test + +inline suspend fun inlineMe(crossinline c: suspend () -> Unit) { c(); c() } + +inline suspend fun inlineMe2(c: suspend () -> Unit) { c(); c() } + +// FILE: A.java + +import test.InlineMeKt; +import helpers.CoroutineUtilKt; +import helpers.EmptyContinuation; +import kotlin.jvm.functions.Function1; +import COROUTINES_PACKAGE.Continuation; +import kotlin.Unit; + +public class A { + static Function1, Object> callback = new Function1, Object>() { + @Override + public Object invoke(Continuation continuation) { + return CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation); + } + }; + public static void call(Continuation cont) { + InlineMeKt.inlineMe(callback, cont); + } + public static void call2(Continuation cont) { + InlineMeKt.inlineMe2(callback, cont); + } +} + +// FILE: box.kt + +import test.* +import helpers.* +import COROUTINES_PACKAGE.* +import COROUTINES_PACKAGE.intrinsics.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(CheckStateMachineContinuation) +} + +fun box(): String { + A.call(CheckStateMachineContinuation) + StateMachineChecker.check(2) + StateMachineChecker.reset() + + builder { + inlineMe { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + } + StateMachineChecker.check(4) + StateMachineChecker.reset() + + A.call2(CheckStateMachineContinuation) + StateMachineChecker.check(2) + + StateMachineChecker.reset() + builder { + inlineMe2 { + StateMachineChecker.suspendHere() + StateMachineChecker.suspendHere() + } + } + StateMachineChecker.check(4) + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt index 5f29a1e1af7..e8cb1d1f635 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.txt @@ -272,6 +272,50 @@ public final class CrossinlineKt$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.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +public final class CrossinlineKt$fold$$inlined$consumeEach$2$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 label: int + synthetic field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$2 + inner class CrossinlineKt$fold$$inlined$consumeEach$2 + inner class CrossinlineKt$fold$$inlined$consumeEach$2$1 + public method (p0: CrossinlineKt$fold$$inlined$consumeEach$2, 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$fold$$inlined$consumeEach$2 { + synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef + synthetic final field $operation$inlined: kotlin.jvm.functions.Function3 + inner class CrossinlineKt$fold$$inlined$consumeEach$2 + inner class CrossinlineKt$fold$$inlined$consumeEach$2$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +public final class CrossinlineKt$fold$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 label: int + synthetic field result: java.lang.Object + inner class CrossinlineKt$fold$1 + public method (p0: 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 @kotlin.coroutines.jvm.internal.DebugMetadata public final class CrossinlineKt$range$$inlined$source$1$1 { @@ -330,12 +374,15 @@ public final class CrossinlineKt$source$1 { public final class CrossinlineKt { inner class CrossinlineKt$box$1 inner class CrossinlineKt$consumeEach$2 + inner class CrossinlineKt$fold$1 inner class CrossinlineKt$source$1 public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void - private final static method consumeEach(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method consumeEach$$forInline(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method consumeEach(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method filter(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function1): SourceCrossinline - private final static method fold(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, p2: kotlin.jvm.functions.Function3, p3: kotlin.coroutines.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method fold$$forInline(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function3, @org.jetbrains.annotations.NotNull p3: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method fold(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function3, @org.jetbrains.annotations.NotNull p3: kotlin.coroutines.Continuation): java.lang.Object public final static method isGood(p0: int): boolean public final static @org.jetbrains.annotations.NotNull method range(@org.jetbrains.annotations.NotNull p0: SourceCrossinline$Factory, p1: int, p2: int): SourceCrossinline public final static @org.jetbrains.annotations.NotNull method source(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2): SourceCrossinline 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 a6578175370..9a3c8b6af5d 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_1_2.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_1_2.txt @@ -280,6 +280,52 @@ public final class CrossinlineKt$fold$$inlined$consumeEach$1 { public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object } +@kotlin.Metadata +public final class CrossinlineKt$fold$$inlined$consumeEach$2$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 + synthetic field data: java.lang.Object + synthetic field exception: java.lang.Throwable + synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$2 + inner class CrossinlineKt$fold$$inlined$consumeEach$2 + inner class CrossinlineKt$fold$$inlined$consumeEach$2$1 + public method (p0: CrossinlineKt$fold$$inlined$consumeEach$2, 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$fold$$inlined$consumeEach$2 { + synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef + synthetic final field $operation$inlined: kotlin.jvm.functions.Function3 + inner class CrossinlineKt$fold$$inlined$consumeEach$2 + inner class CrossinlineKt$fold$$inlined$consumeEach$2$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object +} + +@kotlin.Metadata +public final class CrossinlineKt$fold$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 + synthetic field data: java.lang.Object + synthetic field exception: java.lang.Throwable + inner class CrossinlineKt$fold$1 + public method (p0: 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$range$$inlined$source$1$1 { field I$0: int @@ -340,12 +386,15 @@ public final class CrossinlineKt$source$1 { public final class CrossinlineKt { inner class CrossinlineKt$box$1 inner class CrossinlineKt$consumeEach$2 + inner class CrossinlineKt$fold$1 inner class CrossinlineKt$source$1 public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void - private final static method consumeEach(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.experimental.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method consumeEach$$forInline(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.experimental.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method consumeEach(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.experimental.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method filter(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function1): SourceCrossinline - private final static method fold(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, p2: kotlin.jvm.functions.Function3, p3: kotlin.coroutines.experimental.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method fold$$forInline(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function3, @org.jetbrains.annotations.NotNull p3: kotlin.coroutines.experimental.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method fold(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function3, @org.jetbrains.annotations.NotNull p3: kotlin.coroutines.experimental.Continuation): java.lang.Object public final static method isGood(p0: int): boolean public final static @org.jetbrains.annotations.NotNull method range(@org.jetbrains.annotations.NotNull p0: SourceCrossinline$Factory, p1: int, p2: int): SourceCrossinline public final static @org.jetbrains.annotations.NotNull method source(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2): SourceCrossinline diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt index 0fc94600efa..9c7f2197e52 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation.txt @@ -174,7 +174,8 @@ public final class flow/InnerObjectRetransformationKt { public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void public final static @org.jetbrains.annotations.Nullable method check(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object - private final static method collect(@org.jetbrains.annotations.NotNull p0: flow.Flow, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method flow(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2): flow.Flow public final static @org.jetbrains.annotations.NotNull method flowWith(@org.jetbrains.annotations.NotNull p0: flow.Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2): flow.Flow } 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 fdaa97d17a4..d5da1039d9e 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_1_2.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_1_2.txt @@ -180,7 +180,8 @@ public final class flow/InnerObjectRetransformationKt { public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void public final static @org.jetbrains.annotations.Nullable method check(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object - private final static method collect(@org.jetbrains.annotations.NotNull p0: flow.Flow, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.experimental.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.experimental.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.experimental.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method flow(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2): flow.Flow public final static @org.jetbrains.annotations.NotNull method flowWith(@org.jetbrains.annotations.NotNull p0: flow.Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2): flow.Flow } diff --git a/compiler/testData/codegen/bytecodeListing/inline/simpleNamed.txt b/compiler/testData/codegen/bytecodeListing/inline/simpleNamed.txt index 8be4b63ffe6..4e5a791ff5a 100644 --- a/compiler/testData/codegen/bytecodeListing/inline/simpleNamed.txt +++ b/compiler/testData/codegen/bytecodeListing/inline/simpleNamed.txt @@ -1,7 +1,8 @@ @kotlin.Metadata public final class Foo { public method (): void - private final method acceptsCrossinline(p0: kotlin.jvm.functions.Function0, p1: kotlin.coroutines.Continuation): java.lang.Object + private final @org.jetbrains.annotations.Nullable method acceptsCrossinline$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public final @org.jetbrains.annotations.Nullable method acceptsCrossinline(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object private final @org.jetbrains.annotations.Nullable method generic$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object private final @org.jetbrains.annotations.Nullable method generic$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public final @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object @@ -18,7 +19,8 @@ public final class Foo { @kotlin.Metadata public final class SimpleNamedKt { - private final static method acceptsCrossinline(p0: kotlin.jvm.functions.Function0, p1: kotlin.coroutines.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method acceptsCrossinline$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method acceptsCrossinline(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object private final static @org.jetbrains.annotations.Nullable method generic$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object private final static @org.jetbrains.annotations.Nullable method generic$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public final static @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object diff --git a/compiler/testData/codegen/bytecodeListing/tcoContinuation.txt b/compiler/testData/codegen/bytecodeListing/tcoContinuation.txt index 9eff51e4b3a..ee8f5375bca 100644 --- a/compiler/testData/codegen/bytecodeListing/tcoContinuation.txt +++ b/compiler/testData/codegen/bytecodeListing/tcoContinuation.txt @@ -347,7 +347,8 @@ public final class TcoContinuationKt$transform$$inlined$flow$3 { public final class TcoContinuationKt { inner class TcoContinuationKt$collect$2 inner class TcoContinuationKt$flow$1 - private final static method collect(@org.jetbrains.annotations.NotNull p0: Flow, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.experimental.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.experimental.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.experimental.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method flow(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2): Flow public final static @org.jetbrains.annotations.Nullable method foo(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method map(@org.jetbrains.annotations.NotNull p0: Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2): Flow diff --git a/compiler/testData/codegen/bytecodeListing/tcoContinuation_1_3.txt b/compiler/testData/codegen/bytecodeListing/tcoContinuation_1_3.txt index 2f37543ae51..90de9a89fa2 100644 --- a/compiler/testData/codegen/bytecodeListing/tcoContinuation_1_3.txt +++ b/compiler/testData/codegen/bytecodeListing/tcoContinuation_1_3.txt @@ -322,7 +322,8 @@ public final class TcoContinuationKt$transform$$inlined$flow$3 { public final class TcoContinuationKt { inner class TcoContinuationKt$collect$2 inner class TcoContinuationKt$flow$1 - private final static method collect(@org.jetbrains.annotations.NotNull p0: Flow, p1: kotlin.jvm.functions.Function2, p2: kotlin.coroutines.Continuation): java.lang.Object + private final static @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method flow(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2): Flow public final static @org.jetbrains.annotations.Nullable method foo(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object public final static @org.jetbrains.annotations.NotNull method map(@org.jetbrains.annotations.NotNull p0: Flow, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2): Flow diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index f6da264818e..749c9ecb9c4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -7441,6 +7441,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testSeveralCaptures_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines"); } + + @TestMetadata("suspendInlineWithCrossinline.kt") + public void testSuspendInlineWithCrossinline_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendInlineWithCrossinline.kt") + public void testSuspendInlineWithCrossinline_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt", "kotlin.coroutines"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 92092b90dab..12825b2c909 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7441,6 +7441,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testSeveralCaptures_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines"); } + + @TestMetadata("suspendInlineWithCrossinline.kt") + public void testSuspendInlineWithCrossinline_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendInlineWithCrossinline.kt") + public void testSuspendInlineWithCrossinline_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt", "kotlin.coroutines"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index f15c9ad7864..65abff12dff 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -7441,6 +7441,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testSeveralCaptures_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines"); } + + @TestMetadata("suspendInlineWithCrossinline.kt") + public void testSuspendInlineWithCrossinline_1_2() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt", "kotlin.coroutines.experimental"); + } + + @TestMetadata("suspendInlineWithCrossinline.kt") + public void testSuspendInlineWithCrossinline_1_3() throws Exception { + runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt", "kotlin.coroutines"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")