CoroutineContext Key and Element are now inside CoroutineContext interface itself (just like Map.Entry)
ContinuationInterceptor companion object is named Key CoroutineContext.Element property for key is named just key AbstractCoroutineContextElement implements all of CoroutineContext.Element, including key
This commit is contained in:
@@ -16,23 +16,25 @@
|
||||
|
||||
package kotlin.coroutines
|
||||
|
||||
import kotlin.coroutines.CoroutineContext.*
|
||||
|
||||
/**
|
||||
* Base class for [CoroutineContextElement] implementations.
|
||||
* Base class for [CoroutineContext.Element] implementations.
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public abstract class AbstractCoroutineContextElement : CoroutineContextElement {
|
||||
public abstract class AbstractCoroutineContextElement(public override val key: Key<*>) : Element {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public override operator fun <E : CoroutineContextElement> get(key: CoroutineContextKey<E>): E? =
|
||||
if (this.contextKey == key) this as E else null
|
||||
public override operator fun <E : Element> get(key: Key<E>): E? =
|
||||
if (this.key == key) this as E else null
|
||||
|
||||
public override fun <R> fold(initial: R, operation: (R, CoroutineContextElement) -> R): R =
|
||||
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R =
|
||||
operation(initial, this)
|
||||
|
||||
public override operator fun plus(context: CoroutineContext): CoroutineContext =
|
||||
plusImpl(context)
|
||||
|
||||
public override fun minusKey(key: CoroutineContextKey<*>): CoroutineContext =
|
||||
if (this.contextKey == key) EmptyCoroutineContext else this
|
||||
public override fun minusKey(key: Key<*>): CoroutineContext =
|
||||
if (this.key == key) EmptyCoroutineContext else this
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,10 +42,10 @@ public abstract class AbstractCoroutineContextElement : CoroutineContextElement
|
||||
*/
|
||||
@SinceKotlin("1.1")
|
||||
public object EmptyCoroutineContext : CoroutineContext {
|
||||
public override fun <E : CoroutineContextElement> get(key: CoroutineContextKey<E>): E? = null
|
||||
public override fun <R> fold(initial: R, operation: (R, CoroutineContextElement) -> R): R = initial
|
||||
public override fun <E : Element> get(key: Key<E>): E? = null
|
||||
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R = initial
|
||||
public override fun plus(context: CoroutineContext): CoroutineContext = context
|
||||
public override fun minusKey(key: CoroutineContextKey<*>): CoroutineContext = this
|
||||
public override fun minusKey(key: Key<*>): CoroutineContext = this
|
||||
public override fun hashCode(): Int = 0
|
||||
public override fun toString(): String = "EmptyCoroutineContext"
|
||||
}
|
||||
@@ -52,8 +54,8 @@ public object EmptyCoroutineContext : CoroutineContext {
|
||||
|
||||
// this class is not exposed, but is hidden inside implementations
|
||||
// this is a left-biased list, so that `plus` works naturally
|
||||
private class CombinedContext(val left: CoroutineContext, val element: CoroutineContextElement) : CoroutineContext {
|
||||
override fun <E : CoroutineContextElement> get(key: CoroutineContextKey<E>): E? {
|
||||
private class CombinedContext(val left: CoroutineContext, val element: Element) : CoroutineContext {
|
||||
override fun <E : Element> get(key: Key<E>): E? {
|
||||
var cur = this
|
||||
while (true) {
|
||||
cur.element[key]?.let { return it }
|
||||
@@ -66,13 +68,13 @@ private class CombinedContext(val left: CoroutineContext, val element: Coroutine
|
||||
}
|
||||
}
|
||||
|
||||
public override fun <R> fold(initial: R, operation: (R, CoroutineContextElement) -> R): R =
|
||||
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R =
|
||||
operation(left.fold(initial, operation), element)
|
||||
|
||||
public override operator fun plus(context: CoroutineContext): CoroutineContext =
|
||||
plusImpl(context)
|
||||
|
||||
public override fun minusKey(key: CoroutineContextKey<*>): CoroutineContext {
|
||||
public override fun minusKey(key: Key<*>): CoroutineContext {
|
||||
element[key]?.let { return left }
|
||||
val newLeft = left.minusKey(key)
|
||||
return when (newLeft) {
|
||||
@@ -85,8 +87,8 @@ private class CombinedContext(val left: CoroutineContext, val element: Coroutine
|
||||
private fun size(): Int =
|
||||
if (left is CombinedContext) left.size() + 1 else 2
|
||||
|
||||
private fun contains(element: CoroutineContextElement): Boolean =
|
||||
get(element.contextKey) == element
|
||||
private fun contains(element: Element): Boolean =
|
||||
get(element.key) == element
|
||||
|
||||
private fun containsAll(context: CombinedContext): Boolean {
|
||||
var cur = context
|
||||
@@ -96,7 +98,7 @@ private class CombinedContext(val left: CoroutineContext, val element: Coroutine
|
||||
if (next is CombinedContext) {
|
||||
cur = next
|
||||
} else {
|
||||
return contains(next as CoroutineContextElement)
|
||||
return contains(next as Element)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +117,7 @@ private class CombinedContext(val left: CoroutineContext, val element: Coroutine
|
||||
private fun CoroutineContext.plusImpl(context: CoroutineContext): CoroutineContext =
|
||||
if (context == EmptyCoroutineContext) this else // fast path -- avoid lambda creation
|
||||
context.fold(this) { acc, element ->
|
||||
val removed = acc.minusKey(element.contextKey)
|
||||
val removed = acc.minusKey(element.key)
|
||||
if (removed == EmptyCoroutineContext) element else {
|
||||
// make sure interceptor is always last in the context (and thus is fast to get when present)
|
||||
val interceptor = removed[ContinuationInterceptor]
|
||||
|
||||
@@ -21,30 +21,25 @@ import org.junit.Test
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class CoroutineContextTest {
|
||||
data class CtxA(val i: Int) : AbstractCoroutineContextElement() {
|
||||
companion object : CoroutineContextKey<CtxA>
|
||||
override val contextKey get() = CtxA
|
||||
data class CtxA(val i: Int) : AbstractCoroutineContextElement(CtxA) {
|
||||
companion object Key : CoroutineContext.Key<CtxA>
|
||||
}
|
||||
|
||||
data class CtxB(val i: Int) : AbstractCoroutineContextElement() {
|
||||
companion object : CoroutineContextKey<CtxB>
|
||||
override val contextKey get() = CtxB
|
||||
data class CtxB(val i: Int) : AbstractCoroutineContextElement(CtxB) {
|
||||
companion object Key : CoroutineContext.Key<CtxB>
|
||||
}
|
||||
|
||||
data class CtxC(val i: Int) : AbstractCoroutineContextElement() {
|
||||
companion object : CoroutineContextKey<CtxC>
|
||||
override val contextKey get() = CtxC
|
||||
data class CtxC(val i: Int) : AbstractCoroutineContextElement(CtxC) {
|
||||
companion object Key : CoroutineContext.Key<CtxC>
|
||||
}
|
||||
|
||||
object Disp1 : AbstractCoroutineContextElement(), ContinuationInterceptor {
|
||||
object Disp1 : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
|
||||
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> = continuation
|
||||
override val contextKey: CoroutineContextKey<*> = ContinuationInterceptor
|
||||
override fun toString(): String = "Disp1"
|
||||
}
|
||||
|
||||
object Disp2 : AbstractCoroutineContextElement(), ContinuationInterceptor {
|
||||
object Disp2 : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
|
||||
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> = continuation
|
||||
override val contextKey: CoroutineContextKey<*> = ContinuationInterceptor
|
||||
override fun toString(): String = "Disp2"
|
||||
}
|
||||
|
||||
@@ -171,10 +166,10 @@ class CoroutineContextTest {
|
||||
assertNotEquals(ctx3, ctx4)
|
||||
}
|
||||
|
||||
private fun assertContents(ctx: CoroutineContext, vararg elements: CoroutineContextElement) {
|
||||
private fun assertContents(ctx: CoroutineContext, vararg elements: CoroutineContext.Element) {
|
||||
val set = ctx.fold(setOf<CoroutineContext>()) { a, b -> a + b }
|
||||
assertEquals(listOf(*elements), set.toList())
|
||||
for (elem in elements)
|
||||
assertTrue(ctx[elem.contextKey] == elem)
|
||||
assertTrue(ctx[elem.key] == elem)
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -185,26 +185,26 @@ public abstract interface class kotlin/coroutines/Continuation {
|
||||
public abstract fun resumeWithException (Ljava/lang/Throwable;)V
|
||||
}
|
||||
|
||||
public abstract interface class kotlin/coroutines/ContinuationInterceptor : kotlin/coroutines/CoroutineContextElement {
|
||||
public static final field Companion Lkotlin/coroutines/ContinuationInterceptor$Companion;
|
||||
public abstract interface class kotlin/coroutines/ContinuationInterceptor : kotlin/coroutines/CoroutineContext$Element {
|
||||
public static final field Key Lkotlin/coroutines/ContinuationInterceptor$Key;
|
||||
public abstract fun interceptContinuation (Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
|
||||
}
|
||||
|
||||
public final class kotlin/coroutines/ContinuationInterceptor$Companion : kotlin/coroutines/CoroutineContextKey {
|
||||
public final class kotlin/coroutines/ContinuationInterceptor$Key : kotlin/coroutines/CoroutineContext$Key {
|
||||
}
|
||||
|
||||
public abstract interface class kotlin/coroutines/CoroutineContext {
|
||||
public abstract fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||
public abstract fun get (Lkotlin/coroutines/CoroutineContextKey;)Lkotlin/coroutines/CoroutineContextElement;
|
||||
public abstract fun minusKey (Lkotlin/coroutines/CoroutineContextKey;)Lkotlin/coroutines/CoroutineContext;
|
||||
public abstract fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
|
||||
public abstract fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
|
||||
public abstract fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
|
||||
}
|
||||
|
||||
public abstract interface class kotlin/coroutines/CoroutineContextElement : kotlin/coroutines/CoroutineContext {
|
||||
public abstract fun getContextKey ()Lkotlin/coroutines/CoroutineContextKey;
|
||||
public abstract interface class kotlin/coroutines/CoroutineContext$Element : kotlin/coroutines/CoroutineContext {
|
||||
public abstract fun getKey ()Lkotlin/coroutines/CoroutineContext$Key;
|
||||
}
|
||||
|
||||
public abstract interface class kotlin/coroutines/CoroutineContextKey {
|
||||
public abstract interface class kotlin/coroutines/CoroutineContext$Key {
|
||||
}
|
||||
|
||||
public abstract interface annotation class kotlin/coroutines/RestrictsSuspension : java/lang/annotation/Annotation {
|
||||
|
||||
+7
-6
@@ -1754,11 +1754,12 @@ public final class kotlin/concurrent/TimersKt {
|
||||
public static final fun timer (Ljava/lang/String;Z)Ljava/util/Timer;
|
||||
}
|
||||
|
||||
public abstract class kotlin/coroutines/AbstractCoroutineContextElement : kotlin/coroutines/CoroutineContextElement {
|
||||
public fun <init> ()V
|
||||
public abstract class kotlin/coroutines/AbstractCoroutineContextElement : kotlin/coroutines/CoroutineContext$Element {
|
||||
public fun <init> (Lkotlin/coroutines/CoroutineContext$Key;)V
|
||||
public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||
public fun get (Lkotlin/coroutines/CoroutineContextKey;)Lkotlin/coroutines/CoroutineContextElement;
|
||||
public fun minusKey (Lkotlin/coroutines/CoroutineContextKey;)Lkotlin/coroutines/CoroutineContext;
|
||||
public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
|
||||
public fun getKey ()Lkotlin/coroutines/CoroutineContext$Key;
|
||||
public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
|
||||
public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
|
||||
}
|
||||
|
||||
@@ -1773,9 +1774,9 @@ public final class kotlin/coroutines/CoroutinesKt {
|
||||
public final class kotlin/coroutines/EmptyCoroutineContext : kotlin/coroutines/CoroutineContext {
|
||||
public static final field INSTANCE Lkotlin/coroutines/EmptyCoroutineContext;
|
||||
public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||
public fun get (Lkotlin/coroutines/CoroutineContextKey;)Lkotlin/coroutines/CoroutineContextElement;
|
||||
public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
|
||||
public fun hashCode ()I
|
||||
public fun minusKey (Lkotlin/coroutines/CoroutineContextKey;)Lkotlin/coroutines/CoroutineContext;
|
||||
public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
|
||||
public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user