Reformat stdlib: new coroutines

This commit is contained in:
Ilya Gorbunov
2018-04-27 05:41:12 +03:00
parent 2854e6b7a1
commit 2c9c6eb746
10 changed files with 93 additions and 88 deletions
@@ -16,7 +16,7 @@ import kotlin.coroutines.Continuation
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
public expect inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( public expect inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn(
completion: Continuation<T> completion: Continuation<T>
): Any? ): Any?
/** /**
@@ -28,17 +28,17 @@ public expect inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrRetu
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
public expect inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedOrReturn( public expect inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedOrReturn(
receiver: R, receiver: R,
completion: Continuation<T> completion: Continuation<T>
): Any? ): Any?
@SinceKotlin("1.3") @SinceKotlin("1.3")
public expect fun <T> (suspend () -> T).createCoroutineUnchecked( public expect fun <T> (suspend () -> T).createCoroutineUnchecked(
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> ): Continuation<Unit>
@SinceKotlin("1.3") @SinceKotlin("1.3")
public expect fun <R, T> (suspend R.() -> T).createCoroutineUnchecked( public expect fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
receiver: R, receiver: R,
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> ): Continuation<Unit>
@@ -2,7 +2,6 @@
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file. * that can be found in the license/LICENSE.txt file.
*/ */
package kotlin.coroutines package kotlin.coroutines
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
@@ -13,8 +12,8 @@ import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
@SinceKotlin("1.3") @SinceKotlin("1.3")
internal actual class SafeContinuation<in T> internal actual class SafeContinuation<in T>
internal actual constructor( internal actual constructor(
private val delegate: Continuation<T>, private val delegate: Continuation<T>,
initialResult: Any? initialResult: Any?
) : Continuation<T> { ) : Continuation<T> {
@PublishedApi @PublishedApi
@@ -33,7 +32,8 @@ internal actual constructor(
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@JvmStatic @JvmStatic
private val RESULT = AtomicReferenceFieldUpdater.newUpdater<SafeContinuation<*>, Any?>( private val RESULT = AtomicReferenceFieldUpdater.newUpdater<SafeContinuation<*>, Any?>(
SafeContinuation::class.java, Any::class.java as Class<Any?>, "result") SafeContinuation::class.java, Any::class.java as Class<Any?>, "result"
)
} }
private class Fail(val exception: Throwable) private class Fail(val exception: Throwable)
@@ -55,7 +55,7 @@ internal actual constructor(
actual override fun resumeWithException(exception: Throwable) { actual override fun resumeWithException(exception: Throwable) {
while (true) { // lock-free loop while (true) { // lock-free loop
val result = this.result // atomic read val result = this.result // atomic read
when { when {
result === UNDECIDED -> if (RESULT.compareAndSet(this, UNDECIDED, Fail(exception))) return result === UNDECIDED -> if (RESULT.compareAndSet(this, UNDECIDED, Fail(exception))) return
result === COROUTINE_SUSPENDED -> if (RESULT.compareAndSet(this, COROUTINE_SUSPENDED, RESUMED)) { result === COROUTINE_SUSPENDED -> if (RESULT.compareAndSet(this, COROUTINE_SUSPENDED, RESUMED)) {
delegate.resumeWithException(exception) delegate.resumeWithException(exception)
@@ -6,6 +6,7 @@
@file:kotlin.jvm.JvmName("IntrinsicsKt") @file:kotlin.jvm.JvmName("IntrinsicsKt")
@file:kotlin.jvm.JvmMultifileClass @file:kotlin.jvm.JvmMultifileClass
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") @file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
package kotlin.coroutines.intrinsics package kotlin.coroutines.intrinsics
import kotlin.coroutines.* import kotlin.coroutines.*
@@ -21,7 +22,7 @@ import kotlin.coroutines.*
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public actual inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn( public actual inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn(
completion: Continuation<T> completion: Continuation<T>
): Any? = (this as Function1<Continuation<T>, Any?>).invoke(completion) ): Any? = (this as Function1<Continuation<T>, Any?>).invoke(completion)
/** /**
@@ -35,8 +36,8 @@ public actual inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrRetu
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedOrReturn( public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedOrReturn(
receiver: R, receiver: R,
completion: Continuation<T> completion: Continuation<T>
): Any? = (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion) ): Any? = (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
@@ -54,15 +55,15 @@ public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedO
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
public actual fun <T> (suspend () -> T).createCoroutineUnchecked( public actual fun <T> (suspend () -> T).createCoroutineUnchecked(
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> = ): Continuation<Unit> =
if (this !is kotlin.coroutines.jvm.internal.CoroutineImpl) if (this !is kotlin.coroutines.jvm.internal.CoroutineImpl)
buildContinuationByInvokeCall(completion) { buildContinuationByInvokeCall(completion) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
(this as Function1<Continuation<T>, Any?>).invoke(completion) (this as Function1<Continuation<T>, Any?>).invoke(completion)
} }
else else
(this.create(completion) as kotlin.coroutines.jvm.internal.CoroutineImpl).facade (this.create(completion) as kotlin.coroutines.jvm.internal.CoroutineImpl).facade
/** /**
* Creates a coroutine with receiver type [R] and result type [T]. * Creates a coroutine with receiver type [R] and result type [T].
@@ -76,36 +77,36 @@ public actual fun <T> (suspend () -> T).createCoroutineUnchecked(
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked( public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
receiver: R, receiver: R,
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> = ): Continuation<Unit> =
if (this !is kotlin.coroutines.jvm.internal.CoroutineImpl) if (this !is kotlin.coroutines.jvm.internal.CoroutineImpl)
buildContinuationByInvokeCall(completion) { buildContinuationByInvokeCall(completion) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
(this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion) (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
} }
else else
(this.create(receiver, completion) as kotlin.coroutines.jvm.internal.CoroutineImpl).facade (this.create(receiver, completion) as kotlin.coroutines.jvm.internal.CoroutineImpl).facade
// INTERNAL DEFINITIONS // INTERNAL DEFINITIONS
private inline fun <T> buildContinuationByInvokeCall( private inline fun <T> buildContinuationByInvokeCall(
completion: Continuation<T>, completion: Continuation<T>,
crossinline block: () -> Any? crossinline block: () -> Any?
): Continuation<Unit> { ): Continuation<Unit> {
val continuation = val continuation =
object : Continuation<Unit> { object : Continuation<Unit> {
override val context: CoroutineContext override val context: CoroutineContext
get() = completion.context get() = completion.context
override fun resume(value: Unit) { override fun resume(value: Unit) {
processBareContinuationResume(completion, block) processBareContinuationResume(completion, block)
} }
override fun resumeWithException(exception: Throwable) { override fun resumeWithException(exception: Throwable) {
completion.resumeWithException(exception) completion.resumeWithException(exception)
} }
} }
return kotlin.coroutines.jvm.internal.interceptContinuationIfNeeded(completion.context, continuation) return kotlin.coroutines.jvm.internal.interceptContinuationIfNeeded(completion.context, continuation)
} }
@@ -16,9 +16,9 @@ import kotlin.jvm.internal.Lambda
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
public abstract class CoroutineImpl( public abstract class CoroutineImpl(
arity: Int, arity: Int,
@JvmField @JvmField
protected var completion: Continuation<Any?>? protected var completion: Continuation<Any?>?
) : Lambda(arity), Continuation<Any?> { ) : Lambda(arity), Continuation<Any?> {
// label == -1 when coroutine cannot be started (it is just a factory object) or has already finished execution // label == -1 when coroutine cannot be started (it is just a factory object) or has already finished execution
@@ -4,6 +4,7 @@
*/ */
@file:JvmName("CoroutineIntrinsics") @file:JvmName("CoroutineIntrinsics")
package kotlin.coroutines.jvm.internal package kotlin.coroutines.jvm.internal
import kotlin.coroutines.Continuation import kotlin.coroutines.Continuation
@@ -15,10 +16,10 @@ import kotlin.coroutines.CoroutineContext
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
public fun <T> normalizeContinuation(continuation: Continuation<T>): Continuation<T> = public fun <T> normalizeContinuation(continuation: Continuation<T>): Continuation<T> =
(continuation as? CoroutineImpl)?.facade ?: continuation (continuation as? CoroutineImpl)?.facade ?: continuation
@SinceKotlin("1.3") @SinceKotlin("1.3")
internal fun <T> interceptContinuationIfNeeded( internal fun <T> interceptContinuationIfNeeded(
context: CoroutineContext, context: CoroutineContext,
continuation: Continuation<T> continuation: Continuation<T>
) = context[ContinuationInterceptor]?.interceptContinuation(continuation) ?: continuation ) = context[ContinuationInterceptor]?.interceptContinuation(continuation) ?: continuation
@@ -30,19 +30,19 @@ public interface CoroutineContext {
* The elements from this context with the same key as in the other one are dropped. * The elements from this context with the same key as in the other one are dropped.
*/ */
public operator fun plus(context: CoroutineContext): CoroutineContext = public operator fun plus(context: CoroutineContext): CoroutineContext =
if (context === EmptyCoroutineContext) this else // fast path -- avoid lambda creation if (context === EmptyCoroutineContext) this else // fast path -- avoid lambda creation
context.fold(this) { acc, element -> context.fold(this) { acc, element ->
val removed = acc.minusKey(element.key) val removed = acc.minusKey(element.key)
if (removed === EmptyCoroutineContext) element else { if (removed === EmptyCoroutineContext) element else {
// make sure interceptor is always last in the context (and thus is fast to get when present) // make sure interceptor is always last in the context (and thus is fast to get when present)
val interceptor = removed[ContinuationInterceptor] val interceptor = removed[ContinuationInterceptor]
if (interceptor == null) CombinedContext(removed, element) else { if (interceptor == null) CombinedContext(removed, element) else {
val left = removed.minusKey(ContinuationInterceptor) val left = removed.minusKey(ContinuationInterceptor)
if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else
CombinedContext(CombinedContext(left, element), interceptor) CombinedContext(CombinedContext(left, element), interceptor)
}
} }
} }
}
/** /**
* Returns a context containing elements from this context, but without an element with * Returns a context containing elements from this context, but without an element with
@@ -62,13 +62,13 @@ public interface CoroutineContext {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public override operator fun <E : Element> get(key: Key<E>): E? = public override operator fun <E : Element> get(key: Key<E>): E? =
if (this.key === key) this as E else null if (this.key === key) this as E else null
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R = public override fun <R> fold(initial: R, operation: (R, Element) -> R): R =
operation(initial, this) operation(initial, this)
public override fun minusKey(key: Key<*>): CoroutineContext = public override fun minusKey(key: Key<*>): CoroutineContext =
if (this.key === key) EmptyCoroutineContext else this if (this.key === key) EmptyCoroutineContext else this
} }
/** /**
@@ -46,7 +46,7 @@ internal class CombinedContext(val left: CoroutineContext, val element: Element)
} }
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R = public override fun <R> fold(initial: R, operation: (R, Element) -> R): R =
operation(left.fold(initial, operation), element) operation(left.fold(initial, operation), element)
public override fun minusKey(key: Key<*>): CoroutineContext { public override fun minusKey(key: Key<*>): CoroutineContext {
element[key]?.let { return left } element[key]?.let { return left }
@@ -59,10 +59,10 @@ internal class CombinedContext(val left: CoroutineContext, val element: Element)
} }
private fun size(): Int = private fun size(): Int =
if (left is CombinedContext) left.size() + 1 else 2 if (left is CombinedContext) left.size() + 1 else 2
private fun contains(element: Element): Boolean = private fun contains(element: Element): Boolean =
get(element.key) == element get(element.key) == element
private fun containsAll(context: CombinedContext): Boolean { private fun containsAll(context: CombinedContext): Boolean {
var cur = context var cur = context
@@ -78,12 +78,12 @@ internal class CombinedContext(val left: CoroutineContext, val element: Element)
} }
override fun equals(other: Any?): Boolean = override fun equals(other: Any?): Boolean =
this === other || other is CombinedContext && other.size() == size() && other.containsAll(this) this === other || other is CombinedContext && other.size() == size() && other.containsAll(this)
override fun hashCode(): Int = left.hashCode() + element.hashCode() override fun hashCode(): Int = left.hashCode() + element.hashCode()
override fun toString(): String = override fun toString(): String =
"[" + fold("") { acc, element -> "[" + fold("") { acc, element ->
if (acc.isEmpty()) element.toString() else acc + ", " + element if (acc.isEmpty()) element.toString() else acc + ", " + element
} + "]" } + "]"
} }
@@ -5,6 +5,7 @@
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") @file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@file:kotlin.jvm.JvmName("CoroutinesKt") @file:kotlin.jvm.JvmName("CoroutinesKt")
package kotlin.coroutines package kotlin.coroutines
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
@@ -20,8 +21,8 @@ import kotlin.internal.InlineOnly
@SinceKotlin("1.3") @SinceKotlin("1.3")
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public fun <R, T> (suspend R.() -> T).startCoroutine( public fun <R, T> (suspend R.() -> T).startCoroutine(
receiver: R, receiver: R,
completion: Continuation<T> completion: Continuation<T>
) { ) {
createCoroutineUnchecked(receiver, completion).resume(Unit) createCoroutineUnchecked(receiver, completion).resume(Unit)
} }
@@ -33,8 +34,8 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public fun <T> (suspend () -> T).startCoroutine( public fun <T> (suspend () -> T).startCoroutine(
completion: Continuation<T> completion: Continuation<T>
) { ) {
createCoroutineUnchecked(completion).resume(Unit) createCoroutineUnchecked(completion).resume(Unit)
} }
@@ -50,8 +51,8 @@ public fun <T> (suspend () -> T).startCoroutine(
@SinceKotlin("1.3") @SinceKotlin("1.3")
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public fun <R, T> (suspend R.() -> T).createCoroutine( public fun <R, T> (suspend R.() -> T).createCoroutine(
receiver: R, receiver: R,
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(receiver, completion), COROUTINE_SUSPENDED) ): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(receiver, completion), COROUTINE_SUSPENDED)
/** /**
@@ -65,7 +66,7 @@ public fun <R, T> (suspend R.() -> T).createCoroutine(
@SinceKotlin("1.3") @SinceKotlin("1.3")
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public fun <T> (suspend () -> T).createCoroutine( public fun <T> (suspend () -> T).createCoroutine(
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(completion), COROUTINE_SUSPENDED) ): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(completion), COROUTINE_SUSPENDED)
/** /**
@@ -78,11 +79,11 @@ public fun <T> (suspend () -> T).createCoroutine(
*/ */
@SinceKotlin("1.3") @SinceKotlin("1.3")
public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T = public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T =
suspendCoroutineOrReturn { c: Continuation<T> -> suspendCoroutineOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c) val safe = SafeContinuation(c)
block(safe) block(safe)
safe.getResult() safe.getResult()
} }
/** /**
* Continuation context of current coroutine. * Continuation context of current coroutine.
@@ -32,7 +32,7 @@ import kotlin.coroutines.*
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
public suspend inline fun <T> suspendCoroutineOrReturn(crossinline block: (Continuation<T>) -> Any?): T = public suspend inline fun <T> suspendCoroutineOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
suspendCoroutineUninterceptedOrReturn { cont -> block(cont.intercepted()) } suspendCoroutineUninterceptedOrReturn { cont -> block(cont.intercepted()) }
/** /**
* Obtains the current continuation instance inside suspend functions and either suspends * Obtains the current continuation instance inside suspend functions and either suspends
@@ -43,7 +43,7 @@ public suspend inline fun <T> suspendCoroutineOrReturn(crossinline block: (Conti
@SinceKotlin("1.3") @SinceKotlin("1.3")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T = public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic") throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic")
/** /**
* Intercept continuation with [ContinuationInterceptor]. * Intercept continuation with [ContinuationInterceptor].
@@ -51,7 +51,7 @@ public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline
@SinceKotlin("1.3") @SinceKotlin("1.3")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun <T> Continuation<T>.intercepted(): Continuation<T> = public inline fun <T> Continuation<T>.intercepted(): Continuation<T> =
throw NotImplementedError("Implementation of intercepted is intrinsic") throw NotImplementedError("Implementation of intercepted is intrinsic")
/** /**
* This value is used as a return value of [suspendCoroutineOrReturn] `block` argument to state that * This value is used as a return value of [suspendCoroutineOrReturn] `block` argument to state that
@@ -5,6 +5,7 @@
@file:kotlin.jvm.JvmMultifileClass @file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("SequenceBuilderKt") @file:kotlin.jvm.JvmName("SequenceBuilderKt")
package kotlin.sequences package kotlin.sequences
import kotlin.* import kotlin.*
@@ -85,6 +86,7 @@ public abstract class SequenceBuilder<in T> internal constructor() {
} }
private typealias State = Int private typealias State = Int
private const val State_NotReady: State = 0 private const val State_NotReady: State = 0
private const val State_ManyNotReady: State = 1 private const val State_ManyNotReady: State = 1
private const val State_ManyReady: State = 2 private const val State_ManyReady: State = 2
@@ -130,7 +132,7 @@ private class SequenceBuilderIterator<T> : SequenceBuilder<T>(), Iterator<T>, Co
} }
State_Ready -> { State_Ready -> {
state = State_NotReady state = State_NotReady
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val result = nextValue as T val result = nextValue as T
nextValue = null nextValue = null
return result return result