Implement suspend lambdas of big arity

Suspend functions and callable references to suspend lambdas are already
supported.
Support callSuspendBy of suspend function of big arity.
 #KT-24854: Fixed
This commit is contained in:
Ilmir Usmanov
2018-08-28 21:47:22 +03:00
parent 769344569d
commit f3879af9f6
17 changed files with 297 additions and 20 deletions
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
// CHECK_BYTECODE_LISTING
import helpers.*
import COROUTINES_PACKAGE.*
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun call(c: suspend Long.() -> String): String {
return 1000L.c()
}
fun box(): String {
var res = ""
builder {
res = call { ->
"OK$this"
}
}
if (res != "OK1000") return res
return "OK"
}
@@ -0,0 +1,34 @@
@kotlin.coroutines.jvm.internal.DebugMetadata
@kotlin.Metadata
final class LambdaWithLongReceiverKt$box$1$1 {
field label: int
private field p$: long
inner class LambdaWithLongReceiverKt$box$1
inner class LambdaWithLongReceiverKt$box$1$1
method <init>(p0: kotlin.coroutines.Continuation): void
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public final method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object
}
@kotlin.coroutines.jvm.internal.DebugMetadata
@kotlin.Metadata
final class LambdaWithLongReceiverKt$box$1 {
synthetic final field $res: kotlin.jvm.internal.Ref$ObjectRef
field L$0: java.lang.Object
field label: int
inner class LambdaWithLongReceiverKt$box$1
inner class LambdaWithLongReceiverKt$box$1$1
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.Continuation): void
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
public final method invoke(p0: java.lang.Object): java.lang.Object
public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object
}
@kotlin.Metadata
public final class LambdaWithLongReceiverKt {
inner class LambdaWithLongReceiverKt$box$1
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
public final static @org.jetbrains.annotations.Nullable method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
}
@@ -0,0 +1,30 @@
@kotlin.Metadata
final class LambdaWithLongReceiverKt$box$1$1 {
private field p$: long
inner class LambdaWithLongReceiverKt$box$1
inner class LambdaWithLongReceiverKt$box$1$1
method <init>(p0: kotlin.coroutines.experimental.Continuation): void
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): kotlin.coroutines.experimental.Continuation
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
public final method invoke(p0: java.lang.Object, p1: java.lang.Object): java.lang.Object
}
@kotlin.Metadata
final class LambdaWithLongReceiverKt$box$1 {
synthetic final field $res: kotlin.jvm.internal.Ref$ObjectRef
field L$0: java.lang.Object
inner class LambdaWithLongReceiverKt$box$1
inner class LambdaWithLongReceiverKt$box$1$1
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.experimental.Continuation): void
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): kotlin.coroutines.experimental.Continuation
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
public final method invoke(p0: java.lang.Object): java.lang.Object
}
@kotlin.Metadata
public final class LambdaWithLongReceiverKt {
inner class LambdaWithLongReceiverKt$box$1
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
public final static @org.jetbrains.annotations.Nullable method call(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
}
@@ -0,0 +1,47 @@
// !LANGUAGE: +ReleaseCoroutines
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
// WITH_REFLECT
// WITH_COROUTINES
import kotlin.reflect.full.*
import helpers.*
import kotlin.coroutines.*
class A {
suspend fun foo(
p00: Long = 0, p01: A = A(), p02: A = A(), p03: A = A(), p04: A = A(), p05: A = A(), p06: A = A(), p07: A = A(), p08: A = A(), p09: A = A(),
p10: A = A(), p11: A = A(), p12: A = A(), p13: A = A(), p14: A = A(), p15: A = A(), p16: A = A(), p17: A = A(), p18: A = A(), p19: A = A(),
p20: A = A(), p21: A = A(), p22: A = A(), p23: A = A(), p24: A = A(), p25: A = A(), p26: A = A(), p27: A = A(), p28: A = A(), p29: String
): String {
return p29 + p00
}
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
suspend fun expectsLambdaWithBigArity(c: suspend (Long, Long, Long, Long, Long, Long, Long, Long, Long, Long,
Long, Long, Long, Long, Long, Long, Long, Long, Long, Long,
Long, Long, Long, Long, Long, Long, Long, Long, Long, String) -> String): String {
return c.invoke(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, "OK")
}
fun box(): String {
val a = A()
var res = "FAIL 1"
builder {
res = A::foo.callSuspend(a, 1L, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, "OK")
}
if (res != "OK1") return res
res = "FAIL 2"
builder {
res = A::foo.callSuspendBy(mapOf(A::foo.parameters.first() to A(), A::foo.parameters.last() to "OK")) as String
}
if (res != "OK0") return res
res = "FAIL 3"
builder {
res = expectsLambdaWithBigArity { _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, s -> s }
}
return res
}