More work on draft coroutines 1.3 ABI & API:
* SuspendFunction[01] interfaces removed, moved to RestrictedContinuationImpl * validateContext introduced to check restricted coroutines * Distinguish SuspendLambda as being lambda/coroutine and provide a separate toString implementation (draft) in its coroutine incarnation.
This commit is contained in:
committed by
Denis Zharkov
parent
29dcc4f18c
commit
8e2fae3322
@@ -12,8 +12,6 @@ package kotlin.coroutines.intrinsics
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.jvm.internal.ContinuationImpl
|
||||
import kotlin.coroutines.jvm.internal.RestrictedContinuationImpl
|
||||
import kotlin.coroutines.jvm.internal.SuspendFunction0
|
||||
import kotlin.coroutines.jvm.internal.SuspendFunction1
|
||||
import kotlin.internal.InlineOnly
|
||||
|
||||
/**
|
||||
@@ -111,7 +109,7 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
|
||||
public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
|
||||
completion: Continuation<T>
|
||||
): Continuation<Unit> =
|
||||
if (this is SuspendFunction0)
|
||||
if (this is RestrictedContinuationImpl)
|
||||
create(completion)
|
||||
else
|
||||
createCoroutineFromSuspendFunction(completion) {
|
||||
@@ -139,7 +137,7 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
|
||||
receiver: R,
|
||||
completion: Continuation<T>
|
||||
): Continuation<Unit> =
|
||||
if (this is SuspendFunction1)
|
||||
if (this is RestrictedContinuationImpl)
|
||||
create(receiver, completion)
|
||||
else {
|
||||
createCoroutineFromSuspendFunction(completion) {
|
||||
|
||||
+46
-19
@@ -17,20 +17,40 @@ internal abstract class RestrictedContinuationImpl protected constructor(
|
||||
@JvmField
|
||||
protected val completion: Continuation<Any?>?
|
||||
) : Continuation<Any?>, Serializable {
|
||||
init {
|
||||
@Suppress("LeakingThis")
|
||||
validateContext()
|
||||
}
|
||||
|
||||
protected open fun validateContext() {
|
||||
completion?.let {
|
||||
require(it.context === EmptyCoroutineContext) { "Coroutines with restricted suspension must have EmptyCoroutineContext" }
|
||||
}
|
||||
}
|
||||
|
||||
public override val context: CoroutineContext
|
||||
get() = EmptyCoroutineContext
|
||||
|
||||
public override fun resumeWith(result: SuccessOrFailure<Any?>) {
|
||||
val completion = completion!! // fail fast when trying to resume continuation without completion
|
||||
try {
|
||||
val outcome = invokeSuspend(result)
|
||||
if (outcome === CoroutineSingletons.COROUTINE_SUSPENDED) return
|
||||
completion!!.resume(outcome)
|
||||
completion.resume(outcome)
|
||||
} catch (exception: Throwable) {
|
||||
completion!!.resumeWithException(exception)
|
||||
completion.resumeWithException(exception)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun invokeSuspend(result: SuccessOrFailure<Any?>): Any?
|
||||
|
||||
public open fun create(completion: Continuation<*>): Continuation<Unit> {
|
||||
throw UnsupportedOperationException("create(Continuation) has not been overridden")
|
||||
}
|
||||
|
||||
public open fun create(value: Any?, completion: Continuation<*>): Continuation<Unit> {
|
||||
throw UnsupportedOperationException("create(Any?;Continuation) has not been overridden")
|
||||
}
|
||||
}
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
@@ -41,6 +61,10 @@ internal abstract class ContinuationImpl protected constructor(
|
||||
) : RestrictedContinuationImpl(completion) {
|
||||
protected constructor(completion: Continuation<Any?>?) : this(completion, completion?.context)
|
||||
|
||||
override fun validateContext() {
|
||||
// nothing to do here -- supports any context
|
||||
}
|
||||
|
||||
override val context: CoroutineContext
|
||||
get() = _context!!
|
||||
|
||||
@@ -53,14 +77,15 @@ internal abstract class ContinuationImpl protected constructor(
|
||||
.also { intercepted = this }
|
||||
|
||||
public override fun resumeWith(result: SuccessOrFailure<Any?>) {
|
||||
val completion = completion!! // fail fast when trying to resume continuation without completion
|
||||
try {
|
||||
val outcome = invokeSuspend(result)
|
||||
if (outcome === CoroutineSingletons.COROUTINE_SUSPENDED) return
|
||||
disposeIntercepted()
|
||||
completion!!.resume(outcome)
|
||||
completion.resume(outcome)
|
||||
} catch (exception: Throwable) {
|
||||
disposeIntercepted()
|
||||
completion!!.resumeWithException(exception)
|
||||
completion.resumeWithException(exception)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +96,11 @@ internal abstract class ContinuationImpl protected constructor(
|
||||
}
|
||||
this.intercepted = CompletedContinuation // just in case
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
// todo: how continuation shall be rendered?
|
||||
return "Continuation @ ${this::class.java.name}"
|
||||
}
|
||||
}
|
||||
|
||||
// todo: Do we really need it?
|
||||
@@ -80,7 +110,7 @@ internal object CompletedContinuation : Continuation<Any?> {
|
||||
|
||||
override fun resumeWith(result: SuccessOrFailure<Any?>) {
|
||||
error("This continuation is already complete")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class RestrictedSuspendLambda protected constructor(
|
||||
@@ -91,7 +121,11 @@ internal abstract class RestrictedSuspendLambda protected constructor(
|
||||
|
||||
public override fun getArity(): Int = arity
|
||||
|
||||
public override fun toString(): String = Reflection.renderLambdaToString(this)
|
||||
public override fun toString(): String =
|
||||
if (completion == null)
|
||||
Reflection.renderLambdaToString(this) // this is lambda
|
||||
else
|
||||
super.toString() // this is continuation
|
||||
}
|
||||
|
||||
internal abstract class SuspendLambda protected constructor(
|
||||
@@ -102,16 +136,9 @@ internal abstract class SuspendLambda protected constructor(
|
||||
|
||||
public override fun getArity(): Int = arity
|
||||
|
||||
public override fun toString(): String = Reflection.renderLambdaToString(this)
|
||||
}
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
internal interface SuspendFunction0 : Function1<Continuation<Any?>, Any?> {
|
||||
fun create(completion: Continuation<*>): Continuation<Unit>
|
||||
}
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
internal interface SuspendFunction1 : Function2<Any?, Continuation<Any?>, Any?> {
|
||||
fun create(receiver: Any?, completion: Continuation<*>): Continuation<Unit>
|
||||
}
|
||||
|
||||
public override fun toString(): String =
|
||||
if (completion == null)
|
||||
Reflection.renderLambdaToString(this) // this is lambda
|
||||
else
|
||||
super.toString() // this is continuation
|
||||
}
|
||||
Reference in New Issue
Block a user