Generate state-machine even if the object is going to be transformed
This fixes Java interop of inline functions, which use coroutines. However, we cannot transform the state-machine. Thus, we generate a $$forInline counterpart for suspend functions (similar to inline suspend functions) and invokeSuspend$$forInline for lambdas if these coroutines are going to transformed (i.e. are declared inside inline functions). During transformation we just skip method with state-machine and transform the $$forInline counterpart. Of course, if inline site is inline itself, we generate both state-machine version (which will be dropped during the next transformation) and $$forInline version. Consequently, the final version of the coroutines will not have $$forInline counterpart. Unfortunately, since CompileKotlinAgainstInlineKotlin tests do not allow java sources, the tests for the interop are usual box tests. #KT-30707 Fixed
This commit is contained in:
@@ -125,7 +125,8 @@ public class FunctionCodegen {
|
|||||||
CoroutineCodegenUtilKt.<FunctionDescriptor>unwrapInitialDescriptorForSuspendFunction(functionDescriptor),
|
CoroutineCodegenUtilKt.<FunctionDescriptor>unwrapInitialDescriptorForSuspendFunction(functionDescriptor),
|
||||||
function,
|
function,
|
||||||
v.getThisName(),
|
v.getThisName(),
|
||||||
state.getConstructorCallNormalizationMode()
|
state.getConstructorCallNormalizationMode(),
|
||||||
|
this
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
strategy = new SuspendInlineFunctionGenerationStrategy(
|
strategy = new SuspendInlineFunctionGenerationStrategy(
|
||||||
@@ -1642,4 +1643,9 @@ public class FunctionCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables() {
|
||||||
|
return owner.closure == null ? null : owner.closure.getCaptureVariables();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,14 @@
|
|||||||
package org.jetbrains.kotlin.codegen.coroutines
|
package org.jetbrains.kotlin.codegen.coroutines
|
||||||
|
|
||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
|
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA
|
||||||
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
||||||
|
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.coroutines.SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
@@ -462,10 +465,8 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) {
|
object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) {
|
||||||
|
|
||||||
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
||||||
val addEndLabelMethodVisitor = AddEndLabelMethodVisitor(mv, access, name, desc, endLabel)
|
val stateMachineBuilder = CoroutineTransformerMethodVisitor(
|
||||||
if (forInline) return super.wrapMethodVisitor(addEndLabelMethodVisitor, access, name, desc)
|
mv, access, name, desc, null, null,
|
||||||
return CoroutineTransformerMethodVisitor(
|
|
||||||
addEndLabelMethodVisitor, access, name, desc, null, null,
|
|
||||||
obtainClassBuilderForCoroutineState = { v },
|
obtainClassBuilderForCoroutineState = { v },
|
||||||
element = element,
|
element = element,
|
||||||
diagnostics = state.diagnostics,
|
diagnostics = state.diagnostics,
|
||||||
@@ -474,6 +475,17 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
isForNamedFunction = false,
|
isForNamedFunction = false,
|
||||||
languageVersionSettings = languageVersionSettings
|
languageVersionSettings = languageVersionSettings
|
||||||
)
|
)
|
||||||
|
return if (forInline) AddEndLabelMethodVisitor(
|
||||||
|
MethodNodeCopyingMethodVisitor(
|
||||||
|
SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||||
|
stateMachineBuilder, access, name, desc, v.thisName,
|
||||||
|
isCapturedSuspendLambda = { isCapturedSuspendLambda(closure.captureVariables, it.name) }
|
||||||
|
), access, name, desc,
|
||||||
|
newMethod = { origin, newAccess, newName, newDesc ->
|
||||||
|
functionCodegen.newMethod(origin, newAccess, newName, newDesc, null, null)
|
||||||
|
}
|
||||||
|
), access, name, desc, endLabel
|
||||||
|
) else AddEndLabelMethodVisitor(stateMachineBuilder, access, name, desc, endLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
@@ -516,13 +528,22 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isCapturedSuspendLambda(captureVariables: Map<DeclarationDescriptor, EnclosedValueDescriptor>, name: String): Boolean {
|
||||||
|
for ((param, value) in captureVariables) {
|
||||||
|
if (param !is ValueParameterDescriptor) continue
|
||||||
|
if (value.fieldName != name) continue
|
||||||
|
return param.type.isSuspendFunctionTypeOrSubtype
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private class AddEndLabelMethodVisitor(
|
private class AddEndLabelMethodVisitor(
|
||||||
delegate: MethodVisitor,
|
delegate: MethodVisitor,
|
||||||
access: Int,
|
access: Int,
|
||||||
name: String,
|
name: String,
|
||||||
desc: String,
|
desc: String,
|
||||||
private val endLabel: Label
|
private val endLabel: Label
|
||||||
): TransformationMethodVisitor(delegate, access, name, desc, null, null) {
|
) : TransformationMethodVisitor(delegate, access, name, desc, null, null) {
|
||||||
override fun performTransformations(methodNode: MethodNode) {
|
override fun performTransformations(methodNode: MethodNode) {
|
||||||
methodNode.instructions.add(
|
methodNode.instructions.add(
|
||||||
withInstructionAdapter {
|
withInstructionAdapter {
|
||||||
|
|||||||
+2
-1
@@ -48,6 +48,7 @@ private const val COROUTINES_METADATA_VERSION_JVM_NAME = "v"
|
|||||||
|
|
||||||
const val SUSPEND_FUNCTION_CONTINUATION_PARAMETER = "\$completion"
|
const val SUSPEND_FUNCTION_CONTINUATION_PARAMETER = "\$completion"
|
||||||
const val SUSPEND_CALL_RESULT_NAME = "\$result"
|
const val SUSPEND_CALL_RESULT_NAME = "\$result"
|
||||||
|
const val ILLEGAL_STATE_ERROR_MESSAGE = "call to 'resume' before 'invoke' with coroutine"
|
||||||
|
|
||||||
class CoroutineTransformerMethodVisitor(
|
class CoroutineTransformerMethodVisitor(
|
||||||
delegate: MethodVisitor,
|
delegate: MethodVisitor,
|
||||||
@@ -176,7 +177,7 @@ class CoroutineTransformerMethodVisitor(
|
|||||||
insert(last, defaultLabel)
|
insert(last, defaultLabel)
|
||||||
|
|
||||||
insert(last, withInstructionAdapter {
|
insert(last, withInstructionAdapter {
|
||||||
AsmUtil.genThrow(this, "java/lang/IllegalStateException", "call to 'resume' before 'invoke' with coroutine")
|
AsmUtil.genThrow(this, "java/lang/IllegalStateException", ILLEGAL_STATE_ERROR_MESSAGE)
|
||||||
areturn(Type.VOID_TYPE)
|
areturn(Type.VOID_TYPE)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-21
@@ -5,12 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.coroutines
|
package org.jetbrains.kotlin.codegen.coroutines
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy
|
|
||||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.inline.addFakeContinuationConstructorCallMarker
|
import org.jetbrains.kotlin.codegen.inline.addFakeContinuationConstructorCallMarker
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.coroutines.SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
@@ -22,17 +20,19 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
import org.jetbrains.kotlin.utils.sure
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
|
||||||
open class SuspendFunctionGenerationStrategy(
|
open class SuspendFunctionGenerationStrategy(
|
||||||
state: GenerationState,
|
state: GenerationState,
|
||||||
protected val originalSuspendDescriptor: FunctionDescriptor,
|
protected val originalSuspendDescriptor: FunctionDescriptor,
|
||||||
protected val declaration: KtFunction,
|
protected val declaration: KtFunction,
|
||||||
private val containingClassInternalName: String,
|
private val containingClassInternalName: String,
|
||||||
private val constructorCallNormalizationMode: JVMConstructorCallNormalizationMode
|
private val constructorCallNormalizationMode: JVMConstructorCallNormalizationMode,
|
||||||
|
protected val functionCodegen: FunctionCodegen
|
||||||
) : FunctionGenerationStrategy.CodegenBased(state) {
|
) : FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
|
|
||||||
private lateinit var codegen: ExpressionCodegen
|
private lateinit var codegen: ExpressionCodegen
|
||||||
@@ -45,7 +45,7 @@ open class SuspendFunctionGenerationStrategy(
|
|||||||
declaration.containingFile
|
declaration.containingFile
|
||||||
).also {
|
).also {
|
||||||
val coroutineCodegen =
|
val coroutineCodegen =
|
||||||
CoroutineCodegenForNamedFunction.create(it, codegen, originalSuspendDescriptor, declaration)
|
CoroutineCodegenForNamedFunction.create(it, codegen, originalSuspendDescriptor, declaration)
|
||||||
coroutineCodegen.generate()
|
coroutineCodegen.generate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,16 +53,7 @@ open class SuspendFunctionGenerationStrategy(
|
|||||||
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
||||||
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
|
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
|
||||||
|
|
||||||
if (state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true) {
|
val stateMachineBuilder = CoroutineTransformerMethodVisitor(
|
||||||
return AddConstructorCallForCoroutineRegeneration(
|
|
||||||
mv, access, name, desc, null, null, this::classBuilderForCoroutineState,
|
|
||||||
containingClassInternalName,
|
|
||||||
originalSuspendDescriptor.dispatchReceiverParameter != null,
|
|
||||||
containingClassInternalNameOrNull(),
|
|
||||||
languageVersionSettings
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return CoroutineTransformerMethodVisitor(
|
|
||||||
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
|
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
|
||||||
isForNamedFunction = true,
|
isForNamedFunction = true,
|
||||||
element = declaration,
|
element = declaration,
|
||||||
@@ -72,10 +63,37 @@ open class SuspendFunctionGenerationStrategy(
|
|||||||
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
||||||
languageVersionSettings = languageVersionSettings
|
languageVersionSettings = languageVersionSettings
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val forInline = state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true
|
||||||
|
// Yegor Bugayenko style
|
||||||
|
return if (forInline)
|
||||||
|
AddConstructorCallForCoroutineRegeneration(
|
||||||
|
MethodNodeCopyingMethodVisitor(
|
||||||
|
SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||||
|
stateMachineBuilder,
|
||||||
|
access, name, desc, containingClassInternalName,
|
||||||
|
isCapturedSuspendLambda = {
|
||||||
|
isCapturedSuspendLambda(
|
||||||
|
functionCodegen.captureVariables.sure {
|
||||||
|
"Anonymous object should have closure"
|
||||||
|
},
|
||||||
|
it.name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
), access, name, desc,
|
||||||
|
newMethod = { origin, newAccess, newName, newDesc ->
|
||||||
|
functionCodegen.newMethod(origin, newAccess, newName, newDesc, null, null)
|
||||||
|
}
|
||||||
|
), access, name, desc, null, null, this::classBuilderForCoroutineState,
|
||||||
|
containingClassInternalName,
|
||||||
|
originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||||
|
containingClassInternalNameOrNull(),
|
||||||
|
languageVersionSettings
|
||||||
|
) else stateMachineBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun containingClassInternalNameOrNull() =
|
private fun containingClassInternalNameOrNull() =
|
||||||
originalSuspendDescriptor.containingDeclaration.safeAs<ClassDescriptor>()?.let(state.typeMapper::mapClass)?.internalName
|
originalSuspendDescriptor.containingDeclaration.safeAs<ClassDescriptor>()?.let(state.typeMapper::mapClass)?.internalName
|
||||||
|
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
this.codegen = codegen
|
this.codegen = codegen
|
||||||
@@ -115,6 +133,7 @@ open class SuspendFunctionGenerationStrategy(
|
|||||||
languageVersionSettings
|
languageVersionSettings
|
||||||
)
|
)
|
||||||
addFakeContinuationConstructorCallMarker(this, false)
|
addFakeContinuationConstructorCallMarker(this, false)
|
||||||
|
pop() // Otherwise stack-transformation breaks
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-53
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -9,12 +9,12 @@ import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|||||||
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy
|
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy
|
||||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
@@ -29,13 +29,14 @@ class SuspendInlineFunctionGenerationStrategy(
|
|||||||
declaration: KtFunction,
|
declaration: KtFunction,
|
||||||
containingClassInternalName: String,
|
containingClassInternalName: String,
|
||||||
constructorCallNormalizationMode: JVMConstructorCallNormalizationMode,
|
constructorCallNormalizationMode: JVMConstructorCallNormalizationMode,
|
||||||
private val codegen: FunctionCodegen
|
codegen: FunctionCodegen
|
||||||
) : SuspendFunctionGenerationStrategy(
|
) : SuspendFunctionGenerationStrategy(
|
||||||
state,
|
state,
|
||||||
originalSuspendDescriptor,
|
originalSuspendDescriptor,
|
||||||
declaration,
|
declaration,
|
||||||
containingClassInternalName,
|
containingClassInternalName,
|
||||||
constructorCallNormalizationMode
|
constructorCallNormalizationMode,
|
||||||
|
codegen
|
||||||
) {
|
) {
|
||||||
private val defaultStrategy = FunctionGenerationStrategy.FunctionDefault(state, declaration)
|
private val defaultStrategy = FunctionGenerationStrategy.FunctionDefault(state, declaration)
|
||||||
|
|
||||||
@@ -43,16 +44,10 @@ class SuspendInlineFunctionGenerationStrategy(
|
|||||||
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
|
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
|
||||||
|
|
||||||
return MethodNodeCopyingMethodVisitor(
|
return MethodNodeCopyingMethodVisitor(
|
||||||
super.wrapMethodVisitor(mv, access, name, desc),
|
super.wrapMethodVisitor(mv, access, name, desc), access, name, desc,
|
||||||
access,
|
newMethod = { origin, newAccess, newName, newDesc ->
|
||||||
name,
|
functionCodegen.newMethod(origin, newAccess, newName, newDesc, null, null)
|
||||||
desc = desc,
|
}, keepAccess = false
|
||||||
signature = null,
|
|
||||||
exceptions = null,
|
|
||||||
codegen = codegen,
|
|
||||||
declaration = declaration,
|
|
||||||
originalSuspendDescriptor = originalSuspendDescriptor,
|
|
||||||
isReleaseCoroutines = state.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,46 +55,26 @@ class SuspendInlineFunctionGenerationStrategy(
|
|||||||
super.doGenerateBody(codegen, signature)
|
super.doGenerateBody(codegen, signature)
|
||||||
defaultStrategy.doGenerateBody(codegen, signature)
|
defaultStrategy.doGenerateBody(codegen, signature)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class MethodNodeCopyingMethodVisitor(
|
class MethodNodeCopyingMethodVisitor(
|
||||||
delegate: MethodVisitor,
|
delegate: MethodVisitor, private val access: Int, private val name: String, private val desc: String,
|
||||||
private val access: Int,
|
private val newMethod: (JvmDeclarationOrigin, Int, String, String) -> MethodVisitor,
|
||||||
private val name: String,
|
private val keepAccess: Boolean = true
|
||||||
private val desc: String,
|
) : TransformationMethodVisitor(
|
||||||
private val signature: String?,
|
delegate, calculateAccessForInline(access, keepAccess), "$name$FOR_INLINE_SUFFIX", desc, null, null
|
||||||
private val exceptions: Array<out String>?,
|
) {
|
||||||
private val codegen: FunctionCodegen,
|
override fun performTransformations(methodNode: MethodNode) {
|
||||||
private val declaration: KtFunction,
|
val newMethodNode = newMethod(
|
||||||
private val originalSuspendDescriptor: FunctionDescriptor,
|
JvmDeclarationOrigin.NO_ORIGIN, calculateAccessForInline(access, keepAccess), "$name$FOR_INLINE_SUFFIX", desc
|
||||||
private val isReleaseCoroutines: Boolean
|
)
|
||||||
) : TransformationMethodVisitor(
|
methodNode.instructions.resetLabels()
|
||||||
delegate,
|
methodNode.accept(newMethodNode)
|
||||||
calculateAccessForInline(access),
|
|
||||||
"$name\$\$forInline",
|
|
||||||
desc,
|
|
||||||
signature,
|
|
||||||
exceptions
|
|
||||||
) {
|
|
||||||
override fun performTransformations(methodNode: MethodNode) {
|
|
||||||
val newMethodNode = codegen.newMethod(
|
|
||||||
OtherOrigin(declaration, getOrCreateJvmSuspendFunctionView(originalSuspendDescriptor, isReleaseCoroutines)),
|
|
||||||
calculateAccessForInline(access), "$name\$\$forInline", desc, signature, exceptions
|
|
||||||
)
|
|
||||||
methodNode.instructions.resetLabels()
|
|
||||||
methodNode.accept(newMethodNode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun calculateAccessForInline(access: Int): Int {
|
private fun calculateAccessForInline(access: Int, keepAccess: Boolean): Int =
|
||||||
var accessForInline = access
|
if (keepAccess) access
|
||||||
if (accessForInline and Opcodes.ACC_PUBLIC != 0) {
|
else access or Opcodes.ACC_PRIVATE and Opcodes.ACC_PUBLIC.inv() and Opcodes.ACC_PROTECTED.inv()
|
||||||
accessForInline = accessForInline xor Opcodes.ACC_PUBLIC
|
|
||||||
}
|
|
||||||
if (accessForInline and Opcodes.ACC_PROTECTED != 0) {
|
|
||||||
accessForInline = accessForInline xor Opcodes.ACC_PROTECTED
|
|
||||||
}
|
|
||||||
return accessForInline or Opcodes.ACC_PRIVATE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-3
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.codegen.inline
|
|||||||
|
|
||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
|
import org.jetbrains.kotlin.codegen.coroutines.DEBUG_METADATA_ANNOTATION_ASM_TYPE
|
||||||
|
import org.jetbrains.kotlin.codegen.coroutines.isCapturedSuspendLambda
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass
|
import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
|
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable
|
import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable
|
||||||
@@ -67,6 +69,8 @@ class AnonymousObjectTransformer(
|
|||||||
// Empty inner class info because no inner classes are used in kotlin.Metadata and its arguments
|
// Empty inner class info because no inner classes are used in kotlin.Metadata and its arguments
|
||||||
val innerClassesInfo = FileBasedKotlinClass.InnerClassesInfo()
|
val innerClassesInfo = FileBasedKotlinClass.InnerClassesInfo()
|
||||||
return FileBasedKotlinClass.convertAnnotationVisitor(metadataReader, desc, innerClassesInfo)
|
return FileBasedKotlinClass.convertAnnotationVisitor(metadataReader, desc, innerClassesInfo)
|
||||||
|
} else if (desc == DEBUG_METADATA_ANNOTATION_ASM_TYPE.descriptor) {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
return super.visitAnnotation(desc, visible)
|
return super.visitAnnotation(desc, visible)
|
||||||
}
|
}
|
||||||
@@ -135,12 +139,13 @@ class AnonymousObjectTransformer(
|
|||||||
classBuilder,
|
classBuilder,
|
||||||
methodsToTransform,
|
methodsToTransform,
|
||||||
superClassName,
|
superClassName,
|
||||||
additionalFakeParams
|
allCapturedParamBuilder.listCaptured()
|
||||||
)
|
)
|
||||||
for (next in methodsToTransform) {
|
loop@for (next in methodsToTransform) {
|
||||||
val deferringVisitor =
|
val deferringVisitor =
|
||||||
when {
|
when {
|
||||||
coroutineTransformer.shouldTransform(next) -> coroutineTransformer.newMethod(next)
|
coroutineTransformer.shouldSkip(next) -> continue@loop
|
||||||
|
coroutineTransformer.shouldGenerateStateMachine(next) -> coroutineTransformer.newMethod(next)
|
||||||
else -> newMethod(classBuilder, next)
|
else -> newMethod(classBuilder, next)
|
||||||
}
|
}
|
||||||
val funResult = inlineMethodAndUpdateGlobalResult(parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false)
|
val funResult = inlineMethodAndUpdateGlobalResult(parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false)
|
||||||
@@ -479,6 +484,11 @@ class AnonymousObjectTransformer(
|
|||||||
alreadyAddedParam?.newFieldName ?: getNewFieldName(desc.fieldName, false),
|
alreadyAddedParam?.newFieldName ?: getNewFieldName(desc.fieldName, false),
|
||||||
alreadyAddedParam != null
|
alreadyAddedParam != null
|
||||||
)
|
)
|
||||||
|
if (info is PsiExpressionLambda && info.captureVariables.any { it.value.fieldName == desc.fieldName }) {
|
||||||
|
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend(
|
||||||
|
isCapturedSuspendLambda(info.captureVariables, desc.fieldName)
|
||||||
|
)
|
||||||
|
}
|
||||||
val composed = StackValue.field(
|
val composed = StackValue.field(
|
||||||
desc.type,
|
desc.type,
|
||||||
oldObjectType, /*TODO owner type*/
|
oldObjectType, /*TODO owner type*/
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags
|
|||||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructors
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructors
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
@@ -575,7 +576,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
// 2) for inliner: with mangled name and without state machine
|
// 2) for inliner: with mangled name and without state machine
|
||||||
private fun mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor: FunctionDescriptor, asmMethod: Method): Method {
|
private fun mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor: FunctionDescriptor, asmMethod: Method): Method {
|
||||||
if (!functionDescriptor.isSuspend) return asmMethod
|
if (!functionDescriptor.isSuspend) return asmMethod
|
||||||
return Method("${asmMethod.name}\$\$forInline", asmMethod.descriptor)
|
return Method("${asmMethod.name}$FOR_INLINE_SUFFIX", asmMethod.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDirectMemberAndCallableFromObject(functionDescriptor: FunctionDescriptor): CallableMemberDescriptor {
|
private fun getDirectMemberAndCallableFromObject(functionDescriptor: FunctionDescriptor): CallableMemberDescriptor {
|
||||||
|
|||||||
@@ -307,4 +307,6 @@ class PsiExpressionLambda(
|
|||||||
|
|
||||||
val isPropertyReference: Boolean
|
val isPropertyReference: Boolean
|
||||||
get() = propertyReferenceInfo != null
|
get() = propertyReferenceInfo != null
|
||||||
|
|
||||||
|
val captureVariables = closure.captureVariables
|
||||||
}
|
}
|
||||||
+38
-15
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.inline;
|
package org.jetbrains.kotlin.codegen.inline;
|
||||||
@@ -29,9 +18,13 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|||||||
import org.jetbrains.org.objectweb.asm.commons.*;
|
import org.jetbrains.org.objectweb.asm.commons.*;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.FieldRemapper;
|
import org.jetbrains.org.objectweb.asm.commons.FieldRemapper;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class RemappingClassBuilder extends DelegatingClassBuilder {
|
public class RemappingClassBuilder extends DelegatingClassBuilder {
|
||||||
private final ClassBuilder builder;
|
private final ClassBuilder builder;
|
||||||
private final Remapper remapper;
|
private final Remapper remapper;
|
||||||
|
private final Map<String, FieldVisitor> spilledCoroutineVariables = new HashMap<>();
|
||||||
|
|
||||||
public RemappingClassBuilder(@NotNull ClassBuilder builder, @NotNull Remapper remapper) {
|
public RemappingClassBuilder(@NotNull ClassBuilder builder, @NotNull Remapper remapper) {
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
@@ -68,9 +61,39 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
|
|||||||
@Nullable String signature,
|
@Nullable String signature,
|
||||||
@Nullable Object value
|
@Nullable Object value
|
||||||
) {
|
) {
|
||||||
return new FieldRemapper(
|
if (spilledCoroutineVariables.containsKey(name)) return spilledCoroutineVariables.get(name);
|
||||||
builder.newField(origin, access, name, remapper.mapDesc(desc), remapper.mapSignature(signature, true), value), remapper
|
|
||||||
|
FieldRemapper field = new FieldRemapper(
|
||||||
|
builder.newField(origin, access, name, this.remapper.mapDesc(desc), this.remapper.mapSignature(signature, true), value),
|
||||||
|
this.remapper
|
||||||
);
|
);
|
||||||
|
if (isSpilledCoroutineVariableName(name)) {
|
||||||
|
spilledCoroutineVariables.put(name, field);
|
||||||
|
}
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSpilledCoroutineVariableName(String name) {
|
||||||
|
if (name.length() < 3) return false;
|
||||||
|
switch (name.charAt(0)) {
|
||||||
|
case 'L':
|
||||||
|
case 'Z':
|
||||||
|
case 'C':
|
||||||
|
case 'B':
|
||||||
|
case 'S':
|
||||||
|
case 'I':
|
||||||
|
case 'F':
|
||||||
|
case 'J':
|
||||||
|
case 'D':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name.charAt(1) != '$') return false;
|
||||||
|
for (int i = 2; i < name.length(); ++i) {
|
||||||
|
if (!Character.isDigit(name.charAt(i))) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+80
-53
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen.inline.coroutines
|
package org.jetbrains.kotlin.codegen.inline.coroutines
|
||||||
|
|
||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||||
@@ -16,7 +17,6 @@ import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
|||||||
import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull
|
import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull
|
||||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
@@ -29,6 +29,8 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
|
|||||||
|
|
||||||
const val NOINLINE_CALL_MARKER = "NOINLINE_CALL_MARKER"
|
const val NOINLINE_CALL_MARKER = "NOINLINE_CALL_MARKER"
|
||||||
|
|
||||||
|
const val FOR_INLINE_SUFFIX = "\$\$forInline"
|
||||||
|
|
||||||
class CoroutineTransformer(
|
class CoroutineTransformer(
|
||||||
private val inliningContext: InliningContext,
|
private val inliningContext: InliningContext,
|
||||||
private val classBuilder: ClassBuilder,
|
private val classBuilder: ClassBuilder,
|
||||||
@@ -37,24 +39,20 @@ class CoroutineTransformer(
|
|||||||
private val capturedParams: List<CapturedParamInfo>
|
private val capturedParams: List<CapturedParamInfo>
|
||||||
) {
|
) {
|
||||||
private val state = inliningContext.state
|
private val state = inliningContext.state
|
||||||
|
// If we inline into inline function, we should generate both method with state-machine for Java interop and method without
|
||||||
|
// state-machine for further transformation/inlining.
|
||||||
|
private val generateForInline = inliningContext.callSiteInfo.isInlineOrInsideInline
|
||||||
|
|
||||||
fun shouldTransform(node: MethodNode): Boolean {
|
fun shouldSkip(node: MethodNode): Boolean = methods.any { it.name == node.name + FOR_INLINE_SUFFIX && it.desc == node.desc }
|
||||||
// Never generate state-machine for objects, which are going to be retransformed
|
|
||||||
// See innerObjectRetransformation.kt
|
fun shouldGenerateStateMachine(node: MethodNode): Boolean {
|
||||||
if (inliningContext.callSiteInfo.isInlineOrInsideInline) return false
|
// Continuations are similar to lambdas from bird's view, but we should never generate state machine for them
|
||||||
if (isContinuationNotLambda()) return false
|
if (isContinuationNotLambda()) return false
|
||||||
val crossinlineParam = crossinlineLambda()
|
// The method does not have state-machine, but should. Generate it
|
||||||
if (inliningContext.isInliningLambda && !inliningContext.isContinuation) return false
|
if (node.name.endsWith(FOR_INLINE_SUFFIX)) return true
|
||||||
return when {
|
// there can be suspend lambdas inside inline functions, which do not
|
||||||
isSuspendFunction(node) -> true
|
// capture crossinline lambdas, thus, there is no need to transform them
|
||||||
isSuspendLambda(node) -> {
|
return isSuspendFunctionWithFakeConstructorCall(node) || (isSuspendLambda(node) && !isStateMachine(node))
|
||||||
if (isStateMachine(node)) return false
|
|
||||||
val functionDescriptor =
|
|
||||||
crossinlineParam?.invokeMethodDescriptor?.containingDeclaration as? FunctionDescriptor ?: return true
|
|
||||||
!functionDescriptor.isInline
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isContinuationNotLambda(): Boolean = inliningContext.isContinuation &&
|
private fun isContinuationNotLambda(): Boolean = inliningContext.isContinuation &&
|
||||||
@@ -66,7 +64,7 @@ class CoroutineTransformer(
|
|||||||
}?.cast()
|
}?.cast()
|
||||||
|
|
||||||
private fun isStateMachine(node: MethodNode): Boolean =
|
private fun isStateMachine(node: MethodNode): Boolean =
|
||||||
node.instructions.asSequence().any { it.opcode == Opcodes.INVOKESTATIC && (it as MethodInsnNode).name == "getCOROUTINE_SUSPENDED" }
|
node.instructions.asSequence().any { insn -> insn is LdcInsnNode && insn.cst == ILLEGAL_STATE_ERROR_MESSAGE }
|
||||||
|
|
||||||
private fun isSuspendLambda(node: MethodNode) = isResumeImpl(node)
|
private fun isSuspendLambda(node: MethodNode) = isResumeImpl(node)
|
||||||
|
|
||||||
@@ -83,28 +81,29 @@ class CoroutineTransformer(
|
|||||||
}
|
}
|
||||||
newStateMachineForLambda(node, element)
|
newStateMachineForLambda(node, element)
|
||||||
}
|
}
|
||||||
isSuspendFunction(node) -> newStateMachineForNamedFunction(node, element)
|
isSuspendFunctionWithFakeConstructorCall(node) -> newStateMachineForNamedFunction(node, element)
|
||||||
else -> error("no need to generate state maching for ${node.name}")
|
else -> error("no need to generate state maching for ${node.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isResumeImpl(node: MethodNode): Boolean =
|
private fun isResumeImpl(node: MethodNode): Boolean =
|
||||||
state.languageVersionSettings.isResumeImplMethodName(node.name) &&
|
state.languageVersionSettings.isResumeImplMethodName(node.name.removeSuffix(FOR_INLINE_SUFFIX)) &&
|
||||||
inliningContext.isContinuation
|
inliningContext.isContinuation
|
||||||
|
|
||||||
private fun isSuspendFunction(node: MethodNode): Boolean = findFakeContinuationConstructorClassName(node) != null
|
private fun isSuspendFunctionWithFakeConstructorCall(node: MethodNode): Boolean = findFakeContinuationConstructorClassName(node) != null
|
||||||
|
|
||||||
private fun newStateMachineForLambda(node: MethodNode, element: KtElement): DeferredMethodVisitor {
|
private fun newStateMachineForLambda(node: MethodNode, element: KtElement): DeferredMethodVisitor {
|
||||||
|
val name = node.name.removeSuffix(FOR_INLINE_SUFFIX)
|
||||||
return DeferredMethodVisitor(
|
return DeferredMethodVisitor(
|
||||||
MethodNode(
|
MethodNode(
|
||||||
node.access, node.name, node.desc, node.signature,
|
node.access, name, node.desc, node.signature,
|
||||||
ArrayUtil.toStringArray(node.exceptions)
|
ArrayUtil.toStringArray(node.exceptions)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
surroundNoinlineCallsWithMarkersIfNeeded(
|
val stateMachineBuilder = surroundNoinlineCallsWithMarkersIfNeeded(
|
||||||
node,
|
node,
|
||||||
CoroutineTransformerMethodVisitor(
|
CoroutineTransformerMethodVisitor(
|
||||||
createNewMethodFrom(node), node.access, node.name, node.desc, null, null,
|
createNewMethodFrom(node, name), node.access, name, node.desc, null, null,
|
||||||
obtainClassBuilderForCoroutineState = { classBuilder },
|
obtainClassBuilderForCoroutineState = { classBuilder },
|
||||||
element = element,
|
element = element,
|
||||||
diagnostics = state.diagnostics,
|
diagnostics = state.diagnostics,
|
||||||
@@ -114,22 +113,36 @@ class CoroutineTransformer(
|
|||||||
isForNamedFunction = false
|
isForNamedFunction = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (generateForInline)
|
||||||
|
MethodNodeCopyingMethodVisitor(
|
||||||
|
delegate = stateMachineBuilder,
|
||||||
|
access = node.access,
|
||||||
|
name = name,
|
||||||
|
desc = node.desc,
|
||||||
|
newMethod = { origin, newAccess, newName, newDesc ->
|
||||||
|
classBuilder.newMethod(origin, newAccess, newName, newDesc, null, null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else
|
||||||
|
stateMachineBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun newStateMachineForNamedFunction(node: MethodNode, element: KtElement): DeferredMethodVisitor {
|
private fun newStateMachineForNamedFunction(node: MethodNode, element: KtElement): DeferredMethodVisitor {
|
||||||
|
val name = node.name.removeSuffix(FOR_INLINE_SUFFIX)
|
||||||
val continuationClassName = findFakeContinuationConstructorClassName(node)
|
val continuationClassName = findFakeContinuationConstructorClassName(node)
|
||||||
assert(inliningContext is RegeneratedClassContext)
|
assert(inliningContext is RegeneratedClassContext)
|
||||||
return DeferredMethodVisitor(
|
return DeferredMethodVisitor(
|
||||||
MethodNode(
|
MethodNode(
|
||||||
node.access, node.name, node.desc, node.signature,
|
node.access, name, node.desc, node.signature,
|
||||||
ArrayUtil.toStringArray(node.exceptions)
|
ArrayUtil.toStringArray(node.exceptions)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
surroundNoinlineCallsWithMarkersIfNeeded(
|
val stateMachineBuilder = surroundNoinlineCallsWithMarkersIfNeeded(
|
||||||
node,
|
node,
|
||||||
CoroutineTransformerMethodVisitor(
|
CoroutineTransformerMethodVisitor(
|
||||||
createNewMethodFrom(node), node.access, node.name, node.desc, null, null,
|
createNewMethodFrom(node, name), node.access, name, node.desc, null, null,
|
||||||
obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! },
|
obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! },
|
||||||
element = element,
|
element = element,
|
||||||
diagnostics = state.diagnostics,
|
diagnostics = state.diagnostics,
|
||||||
@@ -141,30 +154,33 @@ class CoroutineTransformer(
|
|||||||
internalNameForDispatchReceiver = classBuilder.thisName
|
internalNameForDispatchReceiver = classBuilder.thisName
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (generateForInline)
|
||||||
|
MethodNodeCopyingMethodVisitor(
|
||||||
|
stateMachineBuilder, node.access, name, node.desc,
|
||||||
|
newMethod = { origin, newAccess, newName, newDesc ->
|
||||||
|
classBuilder.newMethod(origin, newAccess, newName, newDesc, null, null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else
|
||||||
|
stateMachineBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun surroundNoinlineCallsWithMarkersIfNeeded(node: MethodNode, delegate: MethodVisitor): MethodVisitor =
|
private fun surroundNoinlineCallsWithMarkersIfNeeded(node: MethodNode, delegate: MethodVisitor): MethodVisitor =
|
||||||
if (capturedParams.any { (it.functionalArgument as? NonInlineableArgumentForInlineableParameterCalledInSuspend)?.isSuspend == true })
|
if (capturedParams.any { it.functionalArgument?.isSuspendLambda() == true })
|
||||||
SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||||
delegate,
|
delegate, node.access, node.name, node.desc, classBuilder.thisName, this::isCapturedSuspendLambda
|
||||||
node.access,
|
|
||||||
node.name,
|
|
||||||
node.desc,
|
|
||||||
classBuilder.thisName,
|
|
||||||
capturedParams
|
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
delegate
|
delegate
|
||||||
|
|
||||||
private fun createNewMethodFrom(node: MethodNode): MethodVisitor {
|
private fun isCapturedSuspendLambda(field: FieldInsnNode): Boolean =
|
||||||
|
capturedParams.find { it.newFieldName == field.name }?.functionalArgument?.isSuspendLambda() == true
|
||||||
|
|
||||||
|
private fun createNewMethodFrom(node: MethodNode, name: String): MethodVisitor {
|
||||||
return classBuilder.newMethod(
|
return classBuilder.newMethod(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN,
|
JvmDeclarationOrigin.NO_ORIGIN, node.access, name, node.desc, node.signature, ArrayUtil.toStringArray(node.exceptions)
|
||||||
node.access,
|
|
||||||
node.name,
|
|
||||||
node.desc,
|
|
||||||
node.signature,
|
|
||||||
ArrayUtil.toStringArray(node.exceptions)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,13 +209,10 @@ class CoroutineTransformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
class SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||||
delegate: MethodVisitor,
|
delegate: MethodVisitor, access: Int, name: String, desc: String,
|
||||||
access: Int,
|
private val thisName: String,
|
||||||
name: String,
|
private val isCapturedSuspendLambda: (FieldInsnNode) -> Boolean
|
||||||
desc: String,
|
|
||||||
val thisName: String,
|
|
||||||
val capturedParams: List<CapturedParamInfo>
|
|
||||||
) : TransformationMethodVisitor(delegate, access, name, desc, null, null) {
|
) : TransformationMethodVisitor(delegate, access, name, desc, null, null) {
|
||||||
override fun performTransformations(methodNode: MethodNode) {
|
override fun performTransformations(methodNode: MethodNode) {
|
||||||
fun AbstractInsnNode.index() = methodNode.instructions.indexOf(this)
|
fun AbstractInsnNode.index() = methodNode.instructions.indexOf(this)
|
||||||
@@ -213,7 +226,7 @@ private class SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
|||||||
insn as MethodInsnNode
|
insn as MethodInsnNode
|
||||||
if (!isInvokeOnLambda(insn.owner, insn.name)) continue
|
if (!isInvokeOnLambda(insn.owner, insn.name)) continue
|
||||||
val frame = sourceFrames[insn.index()]
|
val frame = sourceFrames[insn.index()]
|
||||||
val receiver = findReceiverOfInvoke(frame, insn).takeIf { it?.isNoinlineSuspendLambda(insn) == true } as? FieldInsnNode ?: continue
|
val receiver = findReceiverOfInvoke(frame, insn).takeIf { it?.isSuspendLambda(insn) == true } as? FieldInsnNode ?: continue
|
||||||
val aload = receiver.findPreviousOrNull { it.opcode != Opcodes.GETFIELD } ?: error("GETFIELD cannot be the first instruction")
|
val aload = receiver.findPreviousOrNull { it.opcode != Opcodes.GETFIELD } ?: error("GETFIELD cannot be the first instruction")
|
||||||
assert(aload.opcode == Opcodes.ALOAD) { "Before GETFIELD there shall be ALOAD" }
|
assert(aload.opcode == Opcodes.ALOAD) { "Before GETFIELD there shall be ALOAD" }
|
||||||
noinlineInvokes.add(insn to aload)
|
noinlineInvokes.add(insn to aload)
|
||||||
@@ -222,15 +235,29 @@ private class SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
|||||||
surroundInvokesWithSuspendMarkers(methodNode, noinlineInvokes)
|
surroundInvokesWithSuspendMarkers(methodNode, noinlineInvokes)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun AbstractInsnNode.isNoinlineSuspendLambda(invoke: MethodInsnNode): Boolean {
|
private fun AbstractInsnNode.isSuspendLambda(invoke: MethodInsnNode): Boolean {
|
||||||
if (opcode != Opcodes.GETFIELD) return false
|
if (opcode != Opcodes.GETFIELD) return false
|
||||||
this as FieldInsnNode
|
this as FieldInsnNode
|
||||||
if (owner != thisName || desc != "L${invoke.owner};") return false
|
if (desc != "L${invoke.owner};") return false
|
||||||
val functionalArgument = capturedParams.find { it.newFieldName == name }?.functionalArgument ?: return false
|
var current: FieldInsnNode? = this
|
||||||
return functionalArgument is NonInlineableArgumentForInlineableParameterCalledInSuspend && functionalArgument.isSuspend
|
// Unroll the battery of
|
||||||
|
// GETFIELD <outer1>.this$0 L<outer2>;
|
||||||
|
// GETFIELD <outer2>.this$0 L<outer3>;
|
||||||
|
// ...
|
||||||
|
// GETFIELD <outerN>.$action Lkotlin/jvm/functions/FunctionM;
|
||||||
|
while (current != null) {
|
||||||
|
if (current.owner == thisName) break
|
||||||
|
if (current.previous?.opcode != Opcodes.GETFIELD || current.previous.cast<FieldInsnNode>().name != CAPTURED_THIS_FIELD) return false
|
||||||
|
current = current.previous as FieldInsnNode
|
||||||
|
}
|
||||||
|
return isCapturedSuspendLambda(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FunctionalArgument.isSuspendLambda(): Boolean =
|
||||||
|
(this is NonInlineableArgumentForInlineableParameterCalledInSuspend && isSuspend) ||
|
||||||
|
(this is PsiExpressionLambda && invokeMethodDescriptor.isSuspend)
|
||||||
|
|
||||||
fun surroundInvokesWithSuspendMarkers(
|
fun surroundInvokesWithSuspendMarkers(
|
||||||
methodNode: MethodNode,
|
methodNode: MethodNode,
|
||||||
noinlineInvokes: List<Pair<AbstractInsnNode, AbstractInsnNode>>
|
noinlineInvokes: List<Pair<AbstractInsnNode, AbstractInsnNode>>
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// COMMON_COROUTINES_TEST
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
|
// CHECK_STATE_MACHINE
|
||||||
|
|
||||||
|
// FILE: inlineMe.kt
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
inline fun inlineMe(crossinline c: suspend () -> Unit) = suspend { c(); c() }
|
||||||
|
|
||||||
|
inline fun inlineMe2(crossinline c: suspend () -> Unit) = inlineMe { c(); c() }
|
||||||
|
|
||||||
|
inline fun inlineMe3(crossinline c: suspend () -> Unit) = suspend {
|
||||||
|
var sr = inlineMe {
|
||||||
|
c()
|
||||||
|
c()
|
||||||
|
}
|
||||||
|
sr()
|
||||||
|
sr = inlineMe {
|
||||||
|
c()
|
||||||
|
c()
|
||||||
|
}
|
||||||
|
sr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import test.InlineMeKt;
|
||||||
|
import helpers.CoroutineUtilKt;
|
||||||
|
import helpers.EmptyContinuation;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
|
public class A {
|
||||||
|
public static Object call() {
|
||||||
|
return InlineMeKt.inlineMe((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||||
|
}
|
||||||
|
public static Object call2() {
|
||||||
|
return InlineMeKt.inlineMe2((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||||
|
}
|
||||||
|
public static Object call3() {
|
||||||
|
return InlineMeKt.inlineMe3((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: box.kt
|
||||||
|
|
||||||
|
import test.*
|
||||||
|
import helpers.*
|
||||||
|
import COROUTINES_PACKAGE.*
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(CheckStateMachineContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
builder {
|
||||||
|
(A.call() as (suspend () -> Unit))()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(2)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
(A.call2() as (suspend () -> Unit))()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(4)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
(A.call3() as (suspend () -> Unit))()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(8)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
inlineMe {
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(4)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
inlineMe2 {
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(8)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
inlineMe3 {
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(16)
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// COMMON_COROUTINES_TEST
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
|
// CHECK_STATE_MACHINE
|
||||||
|
|
||||||
|
// FILE: inlineMe.kt
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
interface SuspendRunnable {
|
||||||
|
suspend fun run()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun inlineMe(crossinline c: suspend () -> Unit) = object : SuspendRunnable {
|
||||||
|
override suspend fun run() {
|
||||||
|
c(); c()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun inlineMe2(crossinline c: suspend () -> Unit) = inlineMe { c(); c() }
|
||||||
|
|
||||||
|
inline fun inlineMe3(crossinline c: suspend () -> Unit) = object: SuspendRunnable {
|
||||||
|
override suspend fun run() {
|
||||||
|
var sr = inlineMe {
|
||||||
|
c()
|
||||||
|
c()
|
||||||
|
}
|
||||||
|
sr.run()
|
||||||
|
sr = inlineMe {
|
||||||
|
c()
|
||||||
|
c()
|
||||||
|
}
|
||||||
|
sr.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import test.InlineMeKt;
|
||||||
|
import helpers.CoroutineUtilKt;
|
||||||
|
import helpers.EmptyContinuation;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
|
public class A {
|
||||||
|
public static Object call() {
|
||||||
|
return InlineMeKt.inlineMe((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||||
|
}
|
||||||
|
public static Object call2() {
|
||||||
|
return InlineMeKt.inlineMe2((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||||
|
}
|
||||||
|
public static Object call3() {
|
||||||
|
return InlineMeKt.inlineMe3((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: box.kt
|
||||||
|
|
||||||
|
import test.*
|
||||||
|
import helpers.*
|
||||||
|
import COROUTINES_PACKAGE.*
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(CheckStateMachineContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
builder {
|
||||||
|
(A.call() as SuspendRunnable).run()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(2)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
(A.call2() as SuspendRunnable).run()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(4)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
(A.call3() as SuspendRunnable).run()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(8)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
inlineMe {
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(4)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
inlineMe2 {
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(8)
|
||||||
|
StateMachineChecker.reset()
|
||||||
|
|
||||||
|
builder {
|
||||||
|
inlineMe3 {
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
StateMachineChecker.suspendHere()
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
StateMachineChecker.check(16)
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+47
@@ -1,5 +1,12 @@
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
|
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 {
|
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
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
@@ -10,7 +17,12 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
|
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1 {
|
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
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
||||||
@@ -28,6 +40,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
|||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
||||||
public method <init>(p0: Sink, p1: CrossinlineKt$box$1$filter$$inlined$source$1): void
|
public method <init>(p0: Sink, p1: CrossinlineKt$box$1$filter$$inlined$source$1): void
|
||||||
public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,11 +51,18 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1 {
|
|||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
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
|
@kotlin.Metadata
|
||||||
|
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||||
public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1 {
|
public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$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 label: int
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$fold$$inlined$consumeEach$1
|
synthetic final field this$0: CrossinlineKt$box$1$fold$$inlined$consumeEach$1
|
||||||
@@ -60,6 +80,7 @@ public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$1 {
|
|||||||
inner class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1
|
inner class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1
|
||||||
public method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void
|
public method <init>(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 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +140,11 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1$1 {
|
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$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 label: int
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1
|
synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1
|
||||||
@@ -173,11 +199,19 @@ public final class CrossinlineKt$consumeEach$2 {
|
|||||||
inner class CrossinlineKt$consumeEach$2$send$1
|
inner class CrossinlineKt$consumeEach$2$send$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): 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
|
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.Metadata
|
||||||
|
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1$1 {
|
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
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
||||||
@@ -188,7 +222,12 @@ public final class CrossinlineKt$filter$$inlined$source$1$1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
|
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1$lambda$1$1 {
|
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
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1$lambda$1
|
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1$lambda$1
|
||||||
@@ -206,6 +245,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
|||||||
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
||||||
public method <init>(p0: Sink, p1: CrossinlineKt$filter$$inlined$source$1): void
|
public method <init>(p0: Sink, p1: CrossinlineKt$filter$$inlined$source$1): void
|
||||||
public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +256,7 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
|
|||||||
inner class CrossinlineKt$filter$$inlined$source$1
|
inner class CrossinlineKt$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,6 +279,7 @@ public final class CrossinlineKt$fold$$inlined$consumeEach$1 {
|
|||||||
inner class CrossinlineKt$fold$$inlined$consumeEach$1$1
|
inner class CrossinlineKt$fold$$inlined$consumeEach$1$1
|
||||||
public method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void
|
public method <init>(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 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +313,11 @@ public final class CrossinlineKt$range$$inlined$source$1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
|
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||||
public final class CrossinlineKt$source$1$consume$1 {
|
public final class CrossinlineKt$source$1$consume$1 {
|
||||||
|
field L$0: java.lang.Object
|
||||||
|
field L$1: java.lang.Object
|
||||||
|
field L$2: java.lang.Object
|
||||||
field label: int
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: CrossinlineKt$source$1
|
synthetic final field this$0: CrossinlineKt$source$1
|
||||||
@@ -287,6 +333,7 @@ public final class CrossinlineKt$source$1 {
|
|||||||
inner class CrossinlineKt$source$1
|
inner class CrossinlineKt$source$1
|
||||||
inner class CrossinlineKt$source$1$consume$1
|
inner class CrossinlineKt$source$1$consume$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+41
@@ -56,6 +56,11 @@ public final class CrossinlineKt$box$1$doResume$$inlined$filter$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$doResume$$inlined$fold$1$1 {
|
public final class CrossinlineKt$box$1$doResume$$inlined$fold$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
|
||||||
synthetic field data: java.lang.Object
|
synthetic field data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$doResume$$inlined$fold$1
|
synthetic final field this$0: CrossinlineKt$box$1$doResume$$inlined$fold$1
|
||||||
@@ -79,6 +84,12 @@ public final class CrossinlineKt$box$1$doResume$$inlined$fold$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 {
|
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 data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
@@ -92,6 +103,10 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1 {
|
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 data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
||||||
@@ -111,6 +126,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
|||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
||||||
public method <init>(p0: Sink, p1: CrossinlineKt$box$1$filter$$inlined$source$1): void
|
public method <init>(p0: Sink, p1: CrossinlineKt$box$1$filter$$inlined$source$1): void
|
||||||
public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,11 +137,17 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1 {
|
|||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
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
|
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
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1 {
|
public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$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
|
||||||
synthetic field data: java.lang.Object
|
synthetic field data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$fold$$inlined$consumeEach$1
|
synthetic final field this$0: CrossinlineKt$box$1$fold$$inlined$consumeEach$1
|
||||||
@@ -145,6 +167,7 @@ public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$1 {
|
|||||||
inner class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1
|
inner class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1
|
||||||
public method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void
|
public method <init>(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 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,11 +206,18 @@ public final class CrossinlineKt$consumeEach$2 {
|
|||||||
inner class CrossinlineKt$consumeEach$2$send$1
|
inner class CrossinlineKt$consumeEach$2$send$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): 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
|
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
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1$1 {
|
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 data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
||||||
@@ -201,6 +231,10 @@ public final class CrossinlineKt$filter$$inlined$source$1$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1$lambda$1$1 {
|
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 data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1$lambda$1
|
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1$lambda$1
|
||||||
@@ -220,6 +254,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
|||||||
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
||||||
public method <init>(p0: Sink, p1: CrossinlineKt$filter$$inlined$source$1): void
|
public method <init>(p0: Sink, p1: CrossinlineKt$filter$$inlined$source$1): void
|
||||||
public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +265,7 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
|
|||||||
inner class CrossinlineKt$filter$$inlined$source$1
|
inner class CrossinlineKt$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,6 +290,7 @@ public final class CrossinlineKt$fold$$inlined$consumeEach$1 {
|
|||||||
inner class CrossinlineKt$fold$$inlined$consumeEach$1$1
|
inner class CrossinlineKt$fold$$inlined$consumeEach$1$1
|
||||||
public method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void
|
public method <init>(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 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
|
public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,6 +326,9 @@ public final class CrossinlineKt$range$$inlined$source$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$source$1$consume$1 {
|
public final class CrossinlineKt$source$1$consume$1 {
|
||||||
|
field L$0: java.lang.Object
|
||||||
|
field L$1: java.lang.Object
|
||||||
|
field L$2: java.lang.Object
|
||||||
synthetic field data: java.lang.Object
|
synthetic field data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: CrossinlineKt$source$1
|
synthetic final field this$0: CrossinlineKt$source$1
|
||||||
@@ -306,6 +346,7 @@ public final class CrossinlineKt$source$1 {
|
|||||||
inner class CrossinlineKt$source$1
|
inner class CrossinlineKt$source$1
|
||||||
inner class CrossinlineKt$source$1$consume$1
|
inner class CrossinlineKt$source$1$consume$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+13
@@ -64,6 +64,10 @@ public final class flow/InnerObjectRetransformationKt$check$$inlined$flow$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 {
|
public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$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
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1
|
synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1
|
||||||
@@ -110,6 +114,7 @@ public final class flow/InnerObjectRetransformationKt$collect$2 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$collect$2
|
inner class flow/InnerObjectRetransformationKt$collect$2
|
||||||
inner class flow/InnerObjectRetransformationKt$collect$2$emit$1
|
inner class flow/InnerObjectRetransformationKt$collect$2$emit$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method emit$$forInline(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
public @org.jetbrains.annotations.Nullable method emit(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
public @org.jetbrains.annotations.Nullable method emit(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +135,7 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$flow$1
|
inner class flow/InnerObjectRetransformationKt$flow$1
|
||||||
inner class flow/InnerObjectRetransformationKt$flow$1$collect$1
|
inner class flow/InnerObjectRetransformationKt$flow$1$collect$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,11 +157,17 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1
|
||||||
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
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
|
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
|
@kotlin.Metadata
|
||||||
|
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||||
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 {
|
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$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 label: int
|
field label: int
|
||||||
synthetic field result: java.lang.Object
|
synthetic field result: java.lang.Object
|
||||||
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
||||||
@@ -172,6 +184,7 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1
|
||||||
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+12
@@ -65,6 +65,10 @@ public final class flow/InnerObjectRetransformationKt$check$$inlined$flow$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1$1 {
|
public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$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 data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1
|
synthetic final field this$0: flow.InnerObjectRetransformationKt$check$$inlined$flowWith$1
|
||||||
@@ -116,6 +120,7 @@ public final class flow/InnerObjectRetransformationKt$collect$2 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$collect$2
|
inner class flow/InnerObjectRetransformationKt$collect$2
|
||||||
inner class flow/InnerObjectRetransformationKt$collect$2$emit$1
|
inner class flow/InnerObjectRetransformationKt$collect$2$emit$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method emit$$forInline(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
public @org.jetbrains.annotations.Nullable method emit(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
public @org.jetbrains.annotations.Nullable method emit(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +143,7 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$flow$1
|
inner class flow/InnerObjectRetransformationKt$flow$1
|
||||||
inner class flow/InnerObjectRetransformationKt$flow$1$collect$1
|
inner class flow/InnerObjectRetransformationKt$flow$1$collect$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,11 +167,16 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1
|
||||||
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
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
|
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
|
@kotlin.Metadata
|
||||||
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 {
|
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$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
|
||||||
synthetic field data: java.lang.Object
|
synthetic field data: java.lang.Object
|
||||||
synthetic field exception: java.lang.Throwable
|
synthetic field exception: java.lang.Throwable
|
||||||
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
||||||
@@ -184,6 +195,7 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2 {
|
|||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2
|
||||||
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1
|
inner class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1
|
||||||
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
public method <init>(p0: flow.Flow, p1: kotlin.jvm.functions.Function2): void
|
||||||
|
public @org.jetbrains.annotations.Nullable method collect$$forInline(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ final class CoroutineFieldsKt$box$1 {
|
|||||||
field J$0: long
|
field J$0: long
|
||||||
field L$0: java.lang.Object
|
field L$0: java.lang.Object
|
||||||
field L$1: java.lang.Object
|
field L$1: java.lang.Object
|
||||||
|
field L$2: java.lang.Object
|
||||||
private field p$: Controller
|
private field p$: Controller
|
||||||
inner class CoroutineFieldsKt$box$1
|
inner class CoroutineFieldsKt$box$1
|
||||||
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: COROUTINES_PACKAGE.Continuation): void
|
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: COROUTINES_PACKAGE.Continuation): void
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ final class CoroutineFieldsKt$box$1 {
|
|||||||
field J$0: long
|
field J$0: long
|
||||||
field L$0: java.lang.Object
|
field L$0: java.lang.Object
|
||||||
field L$1: java.lang.Object
|
field L$1: java.lang.Object
|
||||||
|
field L$2: java.lang.Object
|
||||||
field label: int
|
field label: int
|
||||||
private field p$: Controller
|
private field p$: Controller
|
||||||
inner class CoroutineFieldsKt$box$1
|
inner class CoroutineFieldsKt$box$1
|
||||||
|
|||||||
@@ -6,5 +6,8 @@ inline fun inlineMe(crossinline c: suspend () -> Int): suspend () -> Int {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// invokeSuspend$$forInline : valueOf
|
||||||
|
// invokeSuspend : boxInt
|
||||||
|
|
||||||
// 1 valueOf
|
// 1 valueOf
|
||||||
// 0 boxInt
|
// 1 boxInt
|
||||||
|
|||||||
+2
-2
@@ -14,8 +14,8 @@ fun main(args: Array<String>) {
|
|||||||
@BuilderInference
|
@BuilderInference
|
||||||
suspend fun SequenceScope<Int>.awaitSeq(): Int = 42
|
suspend fun SequenceScope<Int>.awaitSeq(): Int = 42
|
||||||
|
|
||||||
// 1 LOCALVARIABLE a I L16 L.* 3
|
// 1 LOCALVARIABLE a I L17 L.* 3
|
||||||
// 1 LINENUMBER 8 L16
|
// 1 LINENUMBER 8 L17
|
||||||
// Adding ignore flags below the test since the test relies on line numbers.
|
// Adding ignore flags below the test since the test relies on line numbers.
|
||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -21,4 +21,6 @@ class Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4 TABLESWITCH
|
// suspend lambdas: 4
|
||||||
|
// suspend lambdas $$forInline: 1
|
||||||
|
// 5 TABLESWITCH
|
||||||
+37
@@ -7381,6 +7381,43 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/javaInterop")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JavaInterop extends AbstractBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJavaInterop() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/javaInterop"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+37
@@ -7381,6 +7381,43 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/javaInterop")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JavaInterop extends AbstractLightAnalysisModeTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJavaInterop() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/javaInterop"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+37
@@ -7381,6 +7381,43 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/javaInterop")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JavaInterop extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.JVM_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJavaInterop() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/javaInterop"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Generated
+27
@@ -5701,6 +5701,33 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/javaInterop")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JavaInterop extends AbstractIrJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJavaInterop() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/javaInterop"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+37
@@ -6441,6 +6441,43 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/coroutines/javaInterop")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JavaInterop extends AbstractJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestWithPackageReplacement(String testDataFilePath, String packageName) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(filePath -> doTestWithCoroutinesPackageReplacement(filePath, packageName), TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJavaInterop() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/coroutines/javaInterop"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnLambda.kt")
|
||||||
|
public void testReturnLambda_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnLambda.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_2() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnObject.kt")
|
||||||
|
public void testReturnObject_1_3() throws Exception {
|
||||||
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user