JVM_IR: Generate $$forInline companion for suspend inline functions
Set isInline flag for $$forInline functions. Otherwise, SMAP will not be generated for inner objects/lambdas, leading to error in inliner.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -105,6 +105,7 @@ class JvmBackendContext(
|
||||
val continuationClassBuilders = mutableMapOf<IrSimpleFunction, ClassBuilder>()
|
||||
val suspendFunctionOriginalToView = mutableMapOf<IrFunction, IrFunction>()
|
||||
val suspendFunctionViewToOriginal = mutableMapOf<IrFunction, IrFunction>()
|
||||
val originalToForInline = mutableMapOf<IrFunction, IrFunction>()
|
||||
val fakeContinuation: IrExpression = createFakeContinuation(this)
|
||||
|
||||
val staticDefaultStubs = mutableMapOf<IrFunctionSymbol, IrFunction>()
|
||||
|
||||
+28
-4
@@ -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
|
||||
|
||||
+8
-4
@@ -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) {
|
||||
|
||||
+17
-6
@@ -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!!)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-4
@@ -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)
|
||||
|
||||
+26
-17
@@ -47,16 +47,10 @@ internal val addContinuationPhase = makeIrFilePhase(
|
||||
)
|
||||
|
||||
private class AddContinuationLowering(private val context: JvmBackendContext) : FileLoweringPass {
|
||||
private val functionsToAdd = mutableMapOf<IrClass, MutableSet<IrFunction>>()
|
||||
|
||||
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<IrFunction>) {
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
private val functionsStack = arrayListOf<IrFunction>()
|
||||
private val suspendFunctionsCapturingCrossinline = mutableSetOf<IrFunction>()
|
||||
private val functionsToAdd = arrayListOf<MutableSet<IrFunction>>()
|
||||
|
||||
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<SuspendLambdaInfo>, List<IrFunction>> {
|
||||
val suspendLambdas = arrayListOf<SuspendLambdaInfo>()
|
||||
val capturesCrossinline = mutableSetOf<IrCallableReference>()
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// COMMON_COROUTINES_TEST
|
||||
// WITH_RUNTIME
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
// COMMON_COROUTINES_TEST
|
||||
|
||||
Vendored
+9
@@ -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 <init>(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
|
||||
}
|
||||
|
||||
Vendored
+10
-1
@@ -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 <init>(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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user