Implement callSuspend and callSuspendBy functions as KCallable's
extension methods. Also make isSuspend a member of KCallable. #KT-21972: Fixed
This commit is contained in:
committed by
Ilya Gorbunov
parent
66315cee45
commit
e93683621a
@@ -0,0 +1,65 @@
|
||||
// !LANGUAGE: +ReleaseCoroutines
|
||||
// WITH_COROUTINES
|
||||
// WITH_REFLECT
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import kotlin.reflect.full.callSuspend
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
class A {
|
||||
suspend fun noArgs() = "OK"
|
||||
|
||||
suspend fun twoArgs(a: String, b: String) = "$a$b"
|
||||
}
|
||||
|
||||
suspend fun twoArgs(a: String, b: String) = "$a$b"
|
||||
|
||||
fun ordinary() = "OK"
|
||||
|
||||
var log = ""
|
||||
|
||||
var proceed = {}
|
||||
|
||||
suspend fun suspendHere() = suspendCoroutineUninterceptedOrReturn<Unit> { cont ->
|
||||
proceed = {
|
||||
cont.resumeWith(SuccessOrFailure.success(Unit))
|
||||
}
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun suspending() {
|
||||
log += "before;"
|
||||
suspendHere()
|
||||
log += "after;"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res: String? = ""
|
||||
builder {
|
||||
res = A::class.members.find { it.name == "noArgs" }?.callSuspend(A()) as String?
|
||||
}
|
||||
if (res != "OK") return res ?: "FAIL 1"
|
||||
builder {
|
||||
res = A::class.members.find { it.name == "twoArgs" }?.callSuspend(A(), "O", "K") as String?
|
||||
}
|
||||
if (res != "OK") return res ?: "FAIL 2"
|
||||
builder {
|
||||
res = ::twoArgs.callSuspend("O", "K") as String?
|
||||
}
|
||||
if (res != "OK") return res ?: "FAIL 3"
|
||||
builder {
|
||||
res = ::ordinary.callSuspend() as String?
|
||||
}
|
||||
builder {
|
||||
::suspending.callSuspend()
|
||||
}
|
||||
log += "suspended;"
|
||||
proceed()
|
||||
if (log != "before;suspended;after;") return log
|
||||
return res ?: "FAIL 4"
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// !LANGUAGE: +ReleaseCoroutines
|
||||
// WITH_COROUTINES
|
||||
// WITH_REFLECT
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import kotlin.reflect.full.callSuspendBy
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
class A {
|
||||
suspend fun noArgs() = "OK"
|
||||
|
||||
suspend fun twoArgs(a: String, b: String) = "$a$b"
|
||||
}
|
||||
|
||||
suspend fun twoArgs(a: String, b: String) = "$a$b"
|
||||
|
||||
fun ordinary() = "OK"
|
||||
|
||||
suspend fun withDefault(s: String = "OK") = s
|
||||
|
||||
var log = ""
|
||||
|
||||
var proceed = {}
|
||||
|
||||
suspend fun suspendHere() = suspendCoroutineUninterceptedOrReturn<Unit> { cont ->
|
||||
proceed = {
|
||||
cont.resumeWith(SuccessOrFailure.success(Unit))
|
||||
}
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun suspending() {
|
||||
log += "before;"
|
||||
suspendHere()
|
||||
log += "after;"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res: String? = ""
|
||||
builder {
|
||||
val callable = A::class.members.find { it.name == "noArgs" }!!
|
||||
res = callable.callSuspendBy(mapOf(callable.parameters.first() to A())) as String?
|
||||
}
|
||||
if (res != "OK") return res ?: "FAIL 1"
|
||||
builder {
|
||||
val callable = A::class.members.find { it.name == "twoArgs" }!!
|
||||
res = callable.callSuspendBy(mapOf(callable.parameters[0] to A(), callable.parameters[1] to "O", callable.parameters[2] to "K")) as String?
|
||||
}
|
||||
if (res != "OK") return res ?: "FAIL 2"
|
||||
builder {
|
||||
res = ::twoArgs.callSuspendBy(mapOf(::twoArgs.parameters[0] to "O", ::twoArgs.parameters[1] to "K")) as String?
|
||||
}
|
||||
if (res != "OK") return res ?: "FAIL 3"
|
||||
builder {
|
||||
res = ::ordinary.callSuspendBy(emptyMap()) as String?
|
||||
}
|
||||
if (res != "OK") return res ?: "FAIL 4"
|
||||
builder {
|
||||
res = ::withDefault.callSuspendBy(emptyMap()) as String?
|
||||
}
|
||||
builder {
|
||||
::suspending.callSuspendBy(emptyMap())
|
||||
}
|
||||
log += "suspended;"
|
||||
proceed()
|
||||
if (log != "before;suspended;after;") return log
|
||||
return res ?: "FAIL 5"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// LANGUAGE_VERSION: 1.2
|
||||
// WITH_COROUTINES
|
||||
// WITH_REFLECT
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
class A {
|
||||
fun noArgs() = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (A::noArgs.isSuspend) return "FAIL"
|
||||
return "OK"
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.reflect.full.isSuspend
|
||||
|
||||
inline fun inline() {}
|
||||
class External { external fun external() }
|
||||
@@ -60,6 +61,7 @@ fun box(): String {
|
||||
assertFalse(::inlineProperty.getter.isExternal)
|
||||
assertTrue(::inlineProperty.getter.isInline)
|
||||
assertTrue(::inlineProperty.setter.isInline)
|
||||
assertFalse(::inlineProperty.isSuspend)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user