Further design improvements for coroutines 1.3 APIs

* Documentation improvements and clarification
* Dropped legacy intrinsic functions
* Remove context parameter default from Continuation builder function
This commit is contained in:
Roman Elizarov
2018-07-03 13:08:55 +03:00
committed by Denis Zharkov
parent 719d45510a
commit 0370fac0b6
4 changed files with 20 additions and 81 deletions
@@ -32,19 +32,6 @@ public expect inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedO
completion: Continuation<T>
): Any?
@SinceKotlin("1.3")
// todo: Drop this function
public expect fun <T> (suspend () -> T).createCoroutineUnchecked(
completion: Continuation<T>
): Continuation<Unit>
@SinceKotlin("1.3")
// todo: Drop this function
public expect fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
receiver: R,
completion: Continuation<T>
): Continuation<Unit>
@SinceKotlin("1.3")
public expect fun <T> (suspend () -> T).createCoroutineUnintercepted(
completion: Continuation<T>
@@ -54,41 +54,6 @@ public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedO
// JVM declarations
/**
* Creates a coroutine without receiver and with result type [T].
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
*
* To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
* The [completion] continuation is invoked when coroutine completes with result or exception.
*
* This function is _unchecked_. Repeated invocation of any resume function on the resulting continuation corrupts the
* state machine of the coroutine and may result in arbitrary behaviour or exception.
*/
@SinceKotlin("1.3")
// todo: Drop this function
public actual fun <T> (suspend () -> T).createCoroutineUnchecked(
completion: Continuation<T>
): Continuation<Unit> =
createCoroutineUnintercepted(completion).intercepted()
/**
* Creates a coroutine with receiver type [R] and result type [T].
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
*
* To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
* The [completion] continuation is invoked when coroutine completes with result or exception.
*
* This function is _unchecked_. Repeated invocation of any resume function on the resulting continuation corrupts the
* state machine of the coroutine and may result in arbitrary behaviour or exception.
*/
@SinceKotlin("1.3")
// todo: Drop this function
public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
receiver: R,
completion: Continuation<T>
): Continuation<Unit> =
createCoroutineUnintercepted(receiver, completion).intercepted()
/**
* Creates unintercepted coroutine without receiver and with result type [T].
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
@@ -97,10 +62,15 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
* The [completion] continuation is invoked when coroutine completes with result or exception.
*
* This function returns unintercepted continuation.
* Invocation of `resume(Unit)` starts coroutine directly in the invoker's thread without going through the
* Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
* [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
* It is invoker's responsibility to ensure that the proper invocation context is established.
* Note that [completion] of this function may get invoked in an arbitrary context.
*
* [Continuation.intercepted] can be used to acquire the intercepted continuation.
* Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
* both the coroutine and [completion] happens in the invocation context established by
* [ContinuationInterceptor].
*
* Repeated invocation of any resume function on the resulting continuation corrupts the
* state machine of the coroutine and may result in arbitrary behaviour or exception.
@@ -124,10 +94,15 @@ public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
* The [completion] continuation is invoked when coroutine completes with result or exception.
*
* This function returns unintercepted continuation.
* Invocation of `resume(Unit)` starts coroutine directly in the invoker's thread without going through the
* Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
* [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
* It is invoker's responsibility to ensure that the proper invocation context is established.
* Note that [completion] of this function may get invoked in an arbitrary context.
*
* [Continuation.intercepted] can be used to acquire the intercepted continuation.
* Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
* both the coroutine and [completion] happens in the invocation context established by
* [ContinuationInterceptor].
*
* Repeated invocation of any resume function on the resulting continuation corrupts the
* state machine of the coroutine and may result in arbitrary behaviour or exception.
@@ -147,6 +122,12 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
/**
* Intercepts this continuation with [ContinuationInterceptor].
*
* This function shall be used on the immediate result of [createCoroutineUnintercepted] or [suspendCoroutineUninterceptedOrReturn],
* in which case it checks for [ContinuationInterceptor] in the continuation's [context][Continuation.context],
* invokes [ContinuationInterceptor.interceptContinuation], caches and returns result.
*
* If this function is invoked on other [Continuation] instances it returns `this` continuation unchanged.
*/
@SinceKotlin("1.3")
public actual fun <T> Continuation<T>.intercepted(): Continuation<T> =
@@ -59,7 +59,7 @@ public annotation class RestrictsSuspension
*/
@SinceKotlin("1.3")
@InlineOnly public inline fun <T> Continuation(
context: CoroutineContext = EmptyCoroutineContext,
context: CoroutineContext,
crossinline resumeWith: (SuccessOrFailure<T>) -> Unit
): Continuation<T> =
object : Continuation<T> {
@@ -146,12 +146,7 @@ public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<
}
/**
* Continuation context of current coroutine.
*
* This allows the user code to not pass an extra [CoroutineContext] parameter in basic coroutine builders
* like [launch](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/launch.html)
* and [async](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/async.html),
* but still provide easy access to coroutine context.
* Returns context of the current coroutine.
*/
@SinceKotlin("1.3")
@Suppress("WRONG_MODIFIER_TARGET")
@@ -12,30 +12,6 @@ package kotlin.coroutines.intrinsics
import kotlin.coroutines.*
import kotlin.internal.InlineOnly
/**
* Obtains the current continuation instance inside suspend functions and either suspends
* currently running coroutine or returns result immediately without suspension.
*
* If the [block] returns the special [COROUTINE_SUSPENDED] value, it means that suspend function did suspend the execution and will
* not return any result immediately. In this case, the [Continuation] provided to the [block] shall be invoked at some moment in the
* future when the result becomes available to resume the computation.
*
* Otherwise, the return value of the [block] must have a type assignable to [T] and represents the result of this suspend function.
* It means that the execution was not suspended and the [Continuation] provided to the [block] shall not be invoked.
* As the result type of the [block] is declared as `Any?` and cannot be correctly type-checked,
* its proper return type remains on the conscience of the suspend function's author.
*
* Note that it is not recommended to call either [Continuation.resume] nor [Continuation.resumeWithException] functions synchronously
* in the same stackframe where suspension function is run. Use [suspendCoroutine] as a safer way to obtain current
* continuation instance.
*/
@SinceKotlin("1.3")
@InlineOnly
@Suppress("UNUSED_PARAMETER")
// todo: Drop this function
public suspend inline fun <T> suspendCoroutineOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
suspendCoroutineUninterceptedOrReturn { cont -> block(cont.intercepted()) }
/**
* Obtains the current continuation instance inside suspend functions and either suspends
* currently running coroutine or returns result immediately without suspension.