diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt index 01f6d5bd1ca..0df7300ddc2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2020 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. */ package org.jetbrains.kotlin.codegen.inline diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index dc3f661f72d..49331cb82e4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -105,6 +105,7 @@ class JvmBackendContext( val continuationClassBuilders = mutableMapOf() val suspendFunctionOriginalToView = mutableMapOf() val suspendFunctionViewToOriginal = mutableMapOf() + val originalToForInline = mutableMapOf() val fakeContinuation: IrExpression = createFakeContinuation(this) val staticDefaultStubs = mutableMapOf() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 092838eb97e..6434afede45 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -407,13 +407,13 @@ class ExpressionCodegen( expression.dispatchReceiver?.let { receiver -> val type = if ((expression as? IrCall)?.superQualifierSymbol != null) receiver.asmType else callable.owner - callGenerator.genValueAndPut(callee.dispatchReceiverParameter!!, receiver, type, this, data) + continuationAwareGenValueAndPut(receiver, type, callee.dispatchReceiverParameter!!, data, callGenerator) } expression.extensionReceiver?.let { receiver -> val type = callable.signature.valueParameters.singleOrNull { it.kind == JvmMethodParameterKind.RECEIVER }?.asmType ?: error("No single extension receiver parameter: ${callable.signature.valueParameters}") - callGenerator.genValueAndPut(callee.extensionReceiverParameter!!, receiver, type, this, data) + continuationAwareGenValueAndPut(receiver, type, callee.extensionReceiverParameter!!, data, callGenerator) } callGenerator.beforeValueParametersStart() @@ -421,7 +421,7 @@ class ExpressionCodegen( val arg = expression.getValueArgument(i) val parameterType = callable.valueParameterTypes[i] require(arg != null) { "Null argument in ExpressionCodegen for parameter ${irParameter.render()}" } - callGenerator.genValueAndPut(irParameter, arg, parameterType, this, data) + continuationAwareGenValueAndPut(arg, parameterType, irParameter, data, callGenerator) } expression.markLineNumber(true) @@ -431,7 +431,14 @@ class ExpressionCodegen( addSuspendMarker(mv, isStartNotEnd = true) } - callGenerator.genCall(callable, this, expression) + if (irFunction.isInvokeSuspendOfContinuation()) { + // Do not inline callee to continuation, instead, call it + with(callable) { + mv.visitMethodInsn(invokeOpcode, owner.internalName, asmMethod.name, asmMethod.descriptor, isInterfaceMethod) + } + } else { + callGenerator.genCall(callable, this, expression) + } if (callee.shouldGenerateSuspendMarkers()) { // Check return type of non-lowered suspend call, in order to replace the result of the call with Unit, @@ -465,6 +472,23 @@ class ExpressionCodegen( } } + // In order to support java interop of inline suspend functions, we generate continuations of inline suspend functions. + // They should behave as ordinary suspend functions, i.e. we should not inline the content of the inline function into continuation. + // Thus, we should put its arguments to stack. + private fun continuationAwareGenValueAndPut( + arg: IrExpression, + parameterType: Type, + irParameter: IrValueParameter, + data: BlockInfo, + callGenerator: IrCallGenerator + ) { + if (irFunction.isInvokeSuspendOfContinuation()) { + gen(arg, parameterType, irParameter.type, data) + } else { + callGenerator.genValueAndPut(irParameter, arg, parameterType, this, data) + } + } + private fun IrFunction.shouldGenerateSuspendMarkers(): Boolean { if (!isSuspend) return false if (irFunction.shouldNotContainSuspendMarkers()) return false diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index 2a0d63d3bb0..fcd454683cd 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -14,6 +14,9 @@ import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX import org.jetbrains.kotlin.codegen.mangleNameIfNeeded import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.codegen.ClassBuilderMode +import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX +import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.Modality @@ -31,6 +34,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.SYNCHRONIZED_ANNOTATION_FQ_N import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.sure import org.jetbrains.org.objectweb.asm.MethodVisitor @@ -125,17 +129,17 @@ open class FunctionCodegen( // We do not generate continuation and state-machine for synthetic accessors, bridges, and delegated members, // in a sense, they are tail-call !isKnownToBeTailCall() && - // TODO: We should generate two versions of inline suspend function: one with state-machine and one without - !isInline && // This is suspend lambda parameter of inline function origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA && // This is just a template for inliner origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE && // Continuations are generated for suspendImpls - parentAsClass.functions.none { it.name.asString() == name.asString() + SUSPEND_IMPL_NAME_SUFFIX } + parentAsClass.functions.none { it.name.asString() == name.asString() + SUSPEND_IMPL_NAME_SUFFIX } && + // $$forInline functions never have a continuation + origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE private fun continuationClass(): IrClass = - irFunction.body!!.statements[0] as IrClass + irFunction.body!!.statements.firstIsInstance() ?: error("No continuation class generated for ${irFunction.name}") private fun IrFunction.getVisibilityForDefaultArgumentStub(): Int = when (visibility) { 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 6dbfa9a84dd..f28e9c75180 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 @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME import org.jetbrains.kotlin.codegen.inline.* +import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -23,11 +24,9 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression -import org.jetbrains.kotlin.ir.util.isSuspend -import org.jetbrains.kotlin.ir.util.nameForIrSerialization -import org.jetbrains.kotlin.ir.util.parentAsClass -import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -35,6 +34,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.source.getPsi +import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.Method @@ -80,10 +80,21 @@ class IrSourceCompilerForInline( private fun makeInlineNode(function: IrFunction, classCodegen: ClassCodegen, isLambda: Boolean): SMAPAndMethodNode { var node: MethodNode? = null - val functionCodegen = object : FunctionCodegen(function, classCodegen, codegen.takeIf { isLambda }) { + val forInlineFunctionView = + if (function.isSuspend) + codegen.context.originalToForInline[codegen.context.suspendFunctionViewToOriginal[function]] ?: function + else function + val functionCodegen = object : FunctionCodegen(forInlineFunctionView, classCodegen, codegen.takeIf { isLambda }) { override fun createMethod(flags: Int, signature: JvmMethodGenericSignature): MethodVisitor { val asmMethod = signature.asmMethod - node = MethodNode(Opcodes.API_VERSION, flags, asmMethod.name, asmMethod.descriptor, signature.genericsSignature, null) + node = MethodNode( + Opcodes.API_VERSION, + flags, + asmMethod.name.removeSuffix(FOR_INLINE_SUFFIX), + asmMethod.descriptor, + signature.genericsSignature, + null + ) return wrapWithMaxLocalCalc(node!!) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index 6c42d22df8b..bf595b73515 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker -import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME +import org.jetbrains.kotlin.resolve.inline.* import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.utils.addIfNotNull @@ -279,9 +279,13 @@ fun IrDeclarationWithVisibility.isInlineOnlyOrReifiable(): Boolean = this is IrFunction && (isReifiable() || isInlineOnly()) fun IrDeclarationWithVisibility.isEffectivelyInlineOnly(): Boolean = - isInlineOnlyOrReifiable() || - (this is IrSimpleFunction && isSuspend && isInline && - (valueParameters.any { it.isCrossinline } || visibility === Visibilities.PRIVATE)) + isInlineOnlyOrReifiable() || isInlineOnlyPrivateInBytecode() + +fun IrDeclarationWithVisibility.isInlineOnlyPrivateInBytecode(): Boolean = + (this is IrFunction && isInlineOnly()) || isPrivateInlineSuspend() + +private fun IrDeclarationWithVisibility.isPrivateInlineSuspend(): Boolean = + this is IrFunction && isSuspend && isInline && visibility == Visibilities.PRIVATE fun IrFunction.isInlineOnly() = isInline && hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index 64401f35c08..56db31bc8cc 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -47,16 +47,10 @@ internal val addContinuationPhase = makeIrFilePhase( ) private class AddContinuationLowering(private val context: JvmBackendContext) : FileLoweringPass { - private val functionsToAdd = mutableMapOf>() override fun lower(irFile: IrFile) { val (suspendLambdas, inlineLambdas) = markSuspendLambdas(irFile) transformSuspendFunctions(irFile, (suspendLambdas.map { it.function } + inlineLambdas).toSet()) - for ((clazz, functions) in functionsToAdd) { - for (function in functions) { - clazz.declarations.add(function) - } - } transformReferencesToSuspendLambdas(irFile, suspendLambdas) } @@ -533,11 +527,19 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : return static } - // TODO: Generate two copies of inline suspend functions private fun transformSuspendFunctions(irFile: IrFile, suspendAndInlineLambdas: Set) { irFile.transformChildrenVoid(object : IrElementTransformerVoid() { private val functionsStack = arrayListOf() private val suspendFunctionsCapturingCrossinline = mutableSetOf() + private val functionsToAdd = arrayListOf>() + + override fun visitClass(declaration: IrClass): IrStatement { + functionsToAdd.push(mutableSetOf()) + val res = super.visitClass(declaration) + (res as IrClass).declarations.addAll(functionsToAdd.peek()!!) + functionsToAdd.pop() + return res + } override fun visitFunction(declaration: IrFunction): IrStatement { functionsStack.push(declaration) @@ -546,27 +548,34 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : if (skip(function)) return function function as IrSimpleFunction - if (function in suspendFunctionsCapturingCrossinline) { - val newFunction = buildFun { + if (function in suspendFunctionsCapturingCrossinline || function.isInline) { + val newFunction = buildFunWithDescriptorForInlining(function.descriptor) { name = Name.identifier(function.name.asString() + FOR_INLINE_SUFFIX) returnType = function.returnType modality = function.modality isSuspend = function.isSuspend - origin = JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE + isInline = function.isInline + origin = + if (function.isInline) JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE + else JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE }.apply { + copyTypeParameters(function.typeParameters) dispatchReceiverParameter = function.dispatchReceiverParameter?.copyTo(this) extensionReceiverParameter = function.extensionReceiverParameter?.copyTo(this) function.valueParameters.mapTo(valueParameters) { it.copyTo(this) } body = function.copyBodyTo(this) copyAttributes(function) } - registerNewFunction(function.parentAsClass, newFunction) + registerNewFunction(newFunction) + if (function.isInline) { + context.originalToForInline[function] = newFunction + } } val newFunction = if (function.isOverridable) { // Create static method for the suspend state machine method so that reentering the method // does not lead to virtual dispatch to the wrong method. - registerNewFunction(function.parentAsClass, function) + registerNewFunction(function) createStaticSuspendImpl(function) } else function @@ -584,11 +593,15 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : } private fun skip(function: IrFunction) = - !function.isSuspend || function in suspendAndInlineLambdas || function.isInline || function.body == null || + !function.isSuspend || function in suspendAndInlineLambdas || function.body == null || function.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE || function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER || function.parentAsClass.origin == JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL + private fun registerNewFunction(function: IrFunction) { + functionsToAdd.peek()!!.add(function) + } + override fun visitFieldAccess(expression: IrFieldAccessExpression): IrExpression { val result = super.visitFieldAccess(expression) val function = functionsStack.peek() ?: return result @@ -602,10 +615,6 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : }) } - private fun registerNewFunction(container: IrClass, function: IrFunction) { - functionsToAdd.getOrPut(container) { mutableSetOf() }.add(function) - } - private fun markSuspendLambdas(irElement: IrElement): Pair, List> { val suspendLambdas = arrayListOf() val capturesCrossinline = mutableSetOf() diff --git a/compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt b/compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt index d220f87d0b2..371337feff9 100644 --- a/compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt +++ b/compiler/testData/codegen/box/coroutines/javaInterop/suspendInlineWithCrossinline.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // COMMON_COROUTINES_TEST // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt b/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt index c33a5715b69..869a3263437 100644 --- a/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt +++ b/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleOverride.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // WITH_COROUTINES // WITH_RUNTIME // COMMON_COROUTINES_TEST diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt index d98e53f6086..d5dde4a8723 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/inlineWithoutStateMachine_ir.txt @@ -31,6 +31,14 @@ final class InlineWithoutStateMachineKt$suspendHere$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } +@kotlin.Metadata +final class InlineWithoutStateMachineKt$suspendThere$1 { + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + 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 public final class InlineWithoutStateMachineKt { inner class InlineWithoutStateMachineKt$box$1 @@ -38,5 +46,6 @@ public final class InlineWithoutStateMachineKt { public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void public final static @org.jetbrains.annotations.Nullable method complexSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method suspendThere$$forInline(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt index e9c90349033..ffe3d25608b 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/innerObjectRetransformation_ir.txt @@ -76,6 +76,14 @@ final class flow/InnerObjectRetransformationKt$check$1 { public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object } +@kotlin.Metadata +final class flow/InnerObjectRetransformationKt$collect$1 { + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + 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 final class flow/InnerObjectRetransformationKt$collect$2$emit$1 { field label: int @@ -164,7 +172,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 @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.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 }