Check variables, captured by outer object when searching for suspend crossinline parameters
This commit is contained in:
@@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.Bridge;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
@@ -1645,7 +1646,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables() {
|
||||
return owner.closure == null ? null : owner.closure.getCaptureVariables();
|
||||
public CalculatedClosure getClosure() {
|
||||
return owner.closure;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,11 @@ package org.jetbrains.kotlin.codegen.coroutines
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE
|
||||
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.inline.coroutines.SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
@@ -479,7 +481,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
MethodNodeCopyingMethodVisitor(
|
||||
SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||
stateMachineBuilder, access, name, desc, v.thisName,
|
||||
isCapturedSuspendLambda = { isCapturedSuspendLambda(closure.captureVariables, it.name) }
|
||||
isCapturedSuspendLambda = { isCapturedSuspendLambda(closure, it.name, state.bindingContext) }
|
||||
), access, name, desc,
|
||||
newMethod = { origin, newAccess, newName, newDesc ->
|
||||
functionCodegen.newMethod(origin, newAccess, newName, newDesc, null, null)
|
||||
@@ -528,13 +530,19 @@ class CoroutineCodegenForLambda private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun isCapturedSuspendLambda(captureVariables: Map<DeclarationDescriptor, EnclosedValueDescriptor>, name: String): Boolean {
|
||||
for ((param, value) in captureVariables) {
|
||||
fun isCapturedSuspendLambda(closure: CalculatedClosure, name: String, bindingContext: BindingContext): Boolean {
|
||||
for ((param, value) in closure.captureVariables) {
|
||||
if (param !is ValueParameterDescriptor) continue
|
||||
if (value.fieldName != name) continue
|
||||
return param.type.isSuspendFunctionTypeOrSubtype
|
||||
}
|
||||
return false
|
||||
val classDescriptor = closure.capturedOuterClassDescriptor ?: return false
|
||||
return isCapturedSuspendLambda(classDescriptor, name, bindingContext)
|
||||
}
|
||||
|
||||
fun isCapturedSuspendLambda(classDescriptor: ClassDescriptor, name: String, bindingContext: BindingContext): Boolean {
|
||||
val closure = bindingContext[CLOSURE, classDescriptor] ?: return false
|
||||
return isCapturedSuspendLambda(closure, name, bindingContext)
|
||||
}
|
||||
|
||||
private class AddEndLabelMethodVisitor(
|
||||
|
||||
+3
-2
@@ -76,10 +76,11 @@ open class SuspendFunctionGenerationStrategy(
|
||||
access, name, desc, containingClassInternalName,
|
||||
isCapturedSuspendLambda = {
|
||||
isCapturedSuspendLambda(
|
||||
functionCodegen.captureVariables.sure {
|
||||
functionCodegen.closure.sure {
|
||||
"Anonymous object should have closure"
|
||||
},
|
||||
it.name
|
||||
it.name,
|
||||
state.bindingContext
|
||||
)
|
||||
}
|
||||
), access, name, desc,
|
||||
|
||||
+2
-2
@@ -484,9 +484,9 @@ class AnonymousObjectTransformer(
|
||||
alreadyAddedParam?.newFieldName ?: getNewFieldName(desc.fieldName, false),
|
||||
alreadyAddedParam != null
|
||||
)
|
||||
if (info is PsiExpressionLambda && info.captureVariables.any { it.value.fieldName == desc.fieldName }) {
|
||||
if (info is PsiExpressionLambda && info.closure.captureVariables.any { it.value.fieldName == desc.fieldName }) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend(
|
||||
isCapturedSuspendLambda(info.captureVariables, desc.fieldName)
|
||||
isCapturedSuspendLambda(info.closure, desc.fieldName, inliningContext.state.bindingContext)
|
||||
)
|
||||
}
|
||||
val composed = StackValue.field(
|
||||
|
||||
@@ -230,7 +230,8 @@ class PsiExpressionLambda(
|
||||
|
||||
private val labels: Set<String>
|
||||
|
||||
private var closure: CalculatedClosure
|
||||
var closure: CalculatedClosure
|
||||
private set
|
||||
|
||||
init {
|
||||
val bindingContext = typeMapper.bindingContext
|
||||
@@ -307,6 +308,4 @@ class PsiExpressionLambda(
|
||||
|
||||
val isPropertyReference: Boolean
|
||||
get() = propertyReferenceInfo != null
|
||||
|
||||
val captureVariables = closure.captureVariables
|
||||
}
|
||||
+31
-13
@@ -10,13 +10,13 @@ import org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getLastParameterIndex
|
||||
import org.jetbrains.kotlin.codegen.coroutines.replaceFakeContinuationsWithRealOnes
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
@@ -98,7 +98,7 @@ class CoroutineTransformer(
|
||||
ArrayUtil.toStringArray(node.exceptions)
|
||||
)
|
||||
) {
|
||||
val stateMachineBuilder = surroundNoinlineCallsWithMarkersIfNeeded(
|
||||
val stateMachineBuilder = surroundNoinlineCallsWithMarkers(
|
||||
node,
|
||||
CoroutineTransformerMethodVisitor(
|
||||
createNewMethodFrom(node, name), node.access, name, node.desc, null, null,
|
||||
@@ -137,7 +137,7 @@ class CoroutineTransformer(
|
||||
ArrayUtil.toStringArray(node.exceptions)
|
||||
)
|
||||
) {
|
||||
val stateMachineBuilder = surroundNoinlineCallsWithMarkersIfNeeded(
|
||||
val stateMachineBuilder = surroundNoinlineCallsWithMarkers(
|
||||
node,
|
||||
CoroutineTransformerMethodVisitor(
|
||||
createNewMethodFrom(node, name), node.access, name, node.desc, null, null,
|
||||
@@ -165,16 +165,34 @@ class CoroutineTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun surroundNoinlineCallsWithMarkersIfNeeded(node: MethodNode, delegate: MethodVisitor): MethodVisitor =
|
||||
if (capturedParams.any { it.functionalArgument?.isSuspendLambda() == true })
|
||||
SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||
delegate, node.access, node.name, node.desc, classBuilder.thisName, this::isCapturedSuspendLambda
|
||||
)
|
||||
else
|
||||
delegate
|
||||
private fun surroundNoinlineCallsWithMarkers(node: MethodNode, delegate: MethodVisitor): MethodVisitor =
|
||||
SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||
delegate, node.access, node.name, node.desc, classBuilder.thisName, this::fieldIsCapturedSuspendLambda
|
||||
)
|
||||
|
||||
private fun isCapturedSuspendLambda(field: FieldInsnNode): Boolean =
|
||||
capturedParams.find { it.newFieldName == field.name }?.functionalArgument?.isSuspendLambda() == true
|
||||
private fun fieldIsCapturedSuspendLambda(field: FieldInsnNode): Boolean =
|
||||
capturedParams.find { it.newFieldName == field.name }?.let { it.functionalArgument?.isSuspendLambda() == true }
|
||||
?: isSuspendLambdaCapturedByOuterObjectOrLambda(field)
|
||||
|
||||
// We cannot find the lambda in captured parameters: it came from object outside of the our reach:
|
||||
// this can happen when the lambda capture by non-transformed closure:
|
||||
// inline fun inlineMe(crossinline c: suspend() -> Unit) = suspend { c() }
|
||||
// inline fun inlineMe2(crossinline c: suspend() -> Unit) = suspend { inlineMe { c() }() }
|
||||
// Suppose, we inline inlineMe into inlineMe2: the only knowledge we have about inlineMe$1 is captured receiver (this$0)
|
||||
// Thus, transformed lambda from inlineMe, inlineMe3$$inlined$inlineMe2$1 contains the following bytecode
|
||||
// ALOAD 0
|
||||
// GETFIELD inlineMe2$1$invokeSuspend$$inlined$inlineMe$1.this$0 : LScratchKt$inlineMe2$1;
|
||||
// GETFIELD inlineMe2$1.$c : Lkotlin/jvm/functions/Function1;
|
||||
// Since inlineMe2's lambda is outside of reach of the inliner, find crossinline parameter from compilation context:
|
||||
private fun isSuspendLambdaCapturedByOuterObjectOrLambda(field: FieldInsnNode): Boolean {
|
||||
val functionDescriptor = inliningContext.root.sourceCompilerForInline.compilationContextFunctionDescriptor
|
||||
val classDescriptor = functionDescriptor.findContainingClassOrLambda() ?: return false
|
||||
return isCapturedSuspendLambda(classDescriptor, field.name, inliningContext.state.bindingContext)
|
||||
}
|
||||
|
||||
private tailrec fun DeclarationDescriptor.findContainingClassOrLambda(): ClassDescriptor? =
|
||||
if (containingDeclaration is ClassDescriptor) containingDeclaration as ClassDescriptor
|
||||
else containingDeclaration?.findContainingClassOrLambda()
|
||||
|
||||
private fun createNewMethodFrom(node: MethodNode, name: String): MethodVisitor {
|
||||
return classBuilder.newMethod(
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// COMMON_COROUTINES_TEST
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// CHECK_STATE_MACHINE
|
||||
|
||||
// FILE: inlineMe.kt
|
||||
|
||||
package test
|
||||
|
||||
import helpers.*
|
||||
|
||||
interface SuspendRunnable {
|
||||
suspend fun run1()
|
||||
suspend fun run2()
|
||||
}
|
||||
|
||||
inline fun inlineMe(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = object : SuspendRunnable {
|
||||
override suspend fun run1() {
|
||||
c1(); c1()
|
||||
}
|
||||
override suspend fun run2() {
|
||||
c2(); c2()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun inlineMe2(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = inlineMe({ c1(); c1() }) { c2(); c2() }
|
||||
|
||||
inline fun inlineMe3(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = object : SuspendRunnable {
|
||||
override suspend fun run1() {
|
||||
val sr = inlineMe({ c1(); c1() }) { c2(); c2() }
|
||||
sr.run1()
|
||||
sr.run2()
|
||||
}
|
||||
override suspend fun run2() {
|
||||
val sr = inlineMe2({ c1(); c1() }) { c2(); c2() }
|
||||
sr.run1()
|
||||
sr.run2()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun inlineMe4(crossinline c1: suspend () -> Unit, crossinline c2: suspend () -> Unit) = object : SuspendRunnable {
|
||||
override suspend fun run1() {
|
||||
val sr = suspend {
|
||||
c1();
|
||||
c2()
|
||||
}
|
||||
sr()
|
||||
sr()
|
||||
}
|
||||
override suspend fun run2() {
|
||||
val sr = object : SuspendRunnable {
|
||||
override suspend fun run1() {
|
||||
c1(); c1()
|
||||
}
|
||||
override suspend fun run2() {
|
||||
c2(); c2()
|
||||
}
|
||||
}
|
||||
sr.run1()
|
||||
sr.run2()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun inlineMe5(crossinline c1: suspend () -> Unit) = inlineMe({ c1(); c1() }) {
|
||||
StateMachineChecker.suspendHere()
|
||||
}
|
||||
|
||||
// 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),
|
||||
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||
}
|
||||
public static Object call2() {
|
||||
return InlineMeKt.inlineMe2((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation),
|
||||
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||
}
|
||||
public static Object call3() {
|
||||
return InlineMeKt.inlineMe3((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation),
|
||||
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||
}
|
||||
public static Object call4() {
|
||||
return InlineMeKt.inlineMe4((continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation),
|
||||
(continuation) -> CoroutineUtilKt.getStateMachineChecker().suspendHere(continuation));
|
||||
}
|
||||
public static Object call5() {
|
||||
return InlineMeKt.inlineMe5((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).run1()
|
||||
}
|
||||
StateMachineChecker.check(2)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call() as SuspendRunnable).run2()
|
||||
}
|
||||
StateMachineChecker.check(2)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call2() as SuspendRunnable).run1()
|
||||
}
|
||||
StateMachineChecker.check(4)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call2() as SuspendRunnable).run2()
|
||||
}
|
||||
StateMachineChecker.check(4)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call3() as SuspendRunnable).run1()
|
||||
}
|
||||
StateMachineChecker.check(8)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call3() as SuspendRunnable).run2()
|
||||
}
|
||||
StateMachineChecker.check(16)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call4() as SuspendRunnable).run1()
|
||||
}
|
||||
StateMachineChecker.check(4)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call4() as SuspendRunnable).run2()
|
||||
}
|
||||
StateMachineChecker.check(4)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call5() as SuspendRunnable).run1()
|
||||
}
|
||||
StateMachineChecker.check(4)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
(A.call5() as SuspendRunnable).run2()
|
||||
}
|
||||
StateMachineChecker.check(2)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run1()
|
||||
}
|
||||
StateMachineChecker.check(4)
|
||||
StateMachineChecker.reset()
|
||||
builder {
|
||||
inlineMe({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run2()
|
||||
}
|
||||
StateMachineChecker.check(4)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe2 ({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run1()
|
||||
}
|
||||
StateMachineChecker.check(8)
|
||||
StateMachineChecker.reset()
|
||||
builder {
|
||||
inlineMe2 ({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run2()
|
||||
}
|
||||
StateMachineChecker.check(8)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe3 ({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run1()
|
||||
}
|
||||
StateMachineChecker.check(16)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe3 ({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run2()
|
||||
}
|
||||
StateMachineChecker.check(32)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe4 ({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run1()
|
||||
}
|
||||
StateMachineChecker.check(8)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe4 ({
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}) {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run2()
|
||||
}
|
||||
StateMachineChecker.check(8)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe5 {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run1()
|
||||
}
|
||||
StateMachineChecker.check(8)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
builder {
|
||||
inlineMe5 {
|
||||
StateMachineChecker.suspendHere()
|
||||
StateMachineChecker.suspendHere()
|
||||
}.run2()
|
||||
}
|
||||
StateMachineChecker.check(2)
|
||||
StateMachineChecker.reset()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -261,7 +261,13 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||
public final class CrossinlineKt$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
|
||||
synthetic field result: java.lang.Object
|
||||
synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$1
|
||||
|
||||
+5
@@ -271,6 +271,11 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class CrossinlineKt$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 exception: java.lang.Throwable
|
||||
synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$1
|
||||
|
||||
Vendored
+5
@@ -140,7 +140,12 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1 {
|
||||
field L$0: java.lang.Object
|
||||
field L$1: java.lang.Object
|
||||
field L$2: java.lang.Object
|
||||
field L$3: java.lang.Object
|
||||
field label: int
|
||||
synthetic field result: java.lang.Object
|
||||
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
||||
|
||||
Vendored
+4
@@ -149,6 +149,10 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1 {
|
||||
field L$0: java.lang.Object
|
||||
field L$1: java.lang.Object
|
||||
field L$2: java.lang.Object
|
||||
field L$3: java.lang.Object
|
||||
synthetic field data: java.lang.Object
|
||||
synthetic field exception: java.lang.Throwable
|
||||
synthetic final field this$0: flow.InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
||||
|
||||
+10
@@ -7426,6 +7426,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testReturnObject_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("severalCaptures.kt")
|
||||
public void testSeveralCaptures_1_2() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines.experimental");
|
||||
}
|
||||
|
||||
@TestMetadata("severalCaptures.kt")
|
||||
public void testSeveralCaptures_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||
|
||||
+10
@@ -7426,6 +7426,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testReturnObject_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("severalCaptures.kt")
|
||||
public void testSeveralCaptures_1_2() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines.experimental");
|
||||
}
|
||||
|
||||
@TestMetadata("severalCaptures.kt")
|
||||
public void testSeveralCaptures_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||
|
||||
+10
@@ -7426,6 +7426,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testReturnObject_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/returnObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("severalCaptures.kt")
|
||||
public void testSeveralCaptures_1_2() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines.experimental");
|
||||
}
|
||||
|
||||
@TestMetadata("severalCaptures.kt")
|
||||
public void testSeveralCaptures_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/javaInterop/severalCaptures.kt", "kotlin.coroutines");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/localFunctions")
|
||||
|
||||
Reference in New Issue
Block a user