Pull implementations up from AbstractCoroutineContextElemenet
Fixes KT-18671
This commit is contained in:
@@ -40,7 +40,20 @@ public interface CoroutineContext {
|
|||||||
* Returns a context containing elements from this context and elements from other [context].
|
* Returns a context containing elements from this context and elements from other [context].
|
||||||
* 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
|
||||||
|
context.fold(this) { acc, element ->
|
||||||
|
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]
|
||||||
|
if (interceptor == null) CombinedContext(removed, element) else {
|
||||||
|
val left = removed.minusKey(ContinuationInterceptor)
|
||||||
|
if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else
|
||||||
|
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
|
||||||
@@ -57,6 +70,16 @@ public interface CoroutineContext {
|
|||||||
* A key of this coroutine context element.
|
* A key of this coroutine context element.
|
||||||
*/
|
*/
|
||||||
public val key: Key<*>
|
public val key: Key<*>
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
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, Element) -> R): R =
|
||||||
|
operation(initial, this)
|
||||||
|
|
||||||
|
public override fun minusKey(key: Key<*>): CoroutineContext =
|
||||||
|
if (this.key === key) EmptyCoroutineContext else this
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,20 +22,7 @@ import kotlin.coroutines.experimental.CoroutineContext.*
|
|||||||
* Base class for [CoroutineContext.Element] implementations.
|
* Base class for [CoroutineContext.Element] implementations.
|
||||||
*/
|
*/
|
||||||
@SinceKotlin("1.1")
|
@SinceKotlin("1.1")
|
||||||
public abstract class AbstractCoroutineContextElement(public override val key: Key<*>) : Element {
|
public abstract class AbstractCoroutineContextElement(public override val key: Key<*>) : Element
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
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, Element) -> R): R =
|
|
||||||
operation(initial, this)
|
|
||||||
|
|
||||||
public override operator fun plus(context: CoroutineContext): CoroutineContext =
|
|
||||||
plusImpl(context)
|
|
||||||
|
|
||||||
public override fun minusKey(key: Key<*>): CoroutineContext =
|
|
||||||
if (this.key === key) EmptyCoroutineContext else this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An empty coroutine context.
|
* An empty coroutine context.
|
||||||
@@ -50,11 +37,11 @@ public object EmptyCoroutineContext : CoroutineContext {
|
|||||||
public override fun toString(): String = "EmptyCoroutineContext"
|
public override fun toString(): String = "EmptyCoroutineContext"
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------- private impl ---------------------
|
//--------------------- internal impl ---------------------
|
||||||
|
|
||||||
// this class is not exposed, but is hidden inside implementations
|
// this class is not exposed, but is hidden inside implementations
|
||||||
// this is a left-biased list, so that `plus` works naturally
|
// this is a left-biased list, so that `plus` works naturally
|
||||||
private class CombinedContext(val left: CoroutineContext, val element: Element) : CoroutineContext {
|
internal class CombinedContext(val left: CoroutineContext, val element: Element) : CoroutineContext {
|
||||||
override fun <E : Element> get(key: Key<E>): E? {
|
override fun <E : Element> get(key: Key<E>): E? {
|
||||||
var cur = this
|
var cur = this
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -71,9 +58,6 @@ private 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 operator fun plus(context: CoroutineContext): CoroutineContext =
|
|
||||||
plusImpl(context)
|
|
||||||
|
|
||||||
public override fun minusKey(key: Key<*>): CoroutineContext {
|
public override fun minusKey(key: Key<*>): CoroutineContext {
|
||||||
element[key]?.let { return left }
|
element[key]?.let { return left }
|
||||||
val newLeft = left.minusKey(key)
|
val newLeft = left.minusKey(key)
|
||||||
@@ -113,19 +97,3 @@ private class CombinedContext(val left: CoroutineContext, val element: Element)
|
|||||||
if (acc.isEmpty()) element.toString() else acc + ", " + element
|
if (acc.isEmpty()) element.toString() else acc + ", " + element
|
||||||
} + "]"
|
} + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
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.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]
|
|
||||||
if (interceptor == null) CombinedContext(removed, element) else {
|
|
||||||
val left = removed.minusKey(ContinuationInterceptor)
|
|
||||||
if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else
|
|
||||||
CombinedContext(CombinedContext(left, element), interceptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+21
@@ -1959,6 +1959,13 @@ public abstract interface class kotlin/coroutines/experimental/ContinuationInter
|
|||||||
public abstract fun interceptContinuation (Lkotlin/coroutines/experimental/Continuation;)Lkotlin/coroutines/experimental/Continuation;
|
public abstract fun interceptContinuation (Lkotlin/coroutines/experimental/Continuation;)Lkotlin/coroutines/experimental/Continuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class kotlin/coroutines/experimental/ContinuationInterceptor$DefaultImpls {
|
||||||
|
public static fun fold (Lkotlin/coroutines/experimental/ContinuationInterceptor;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||||
|
public static fun get (Lkotlin/coroutines/experimental/ContinuationInterceptor;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext$Element;
|
||||||
|
public static fun minusKey (Lkotlin/coroutines/experimental/ContinuationInterceptor;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
public static fun plus (Lkotlin/coroutines/experimental/ContinuationInterceptor;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
}
|
||||||
|
|
||||||
public final class kotlin/coroutines/experimental/ContinuationInterceptor$Key : kotlin/coroutines/experimental/CoroutineContext$Key {
|
public final class kotlin/coroutines/experimental/ContinuationInterceptor$Key : kotlin/coroutines/experimental/CoroutineContext$Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1969,8 +1976,22 @@ public abstract interface class kotlin/coroutines/experimental/CoroutineContext
|
|||||||
public abstract fun plus (Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
public abstract fun plus (Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class kotlin/coroutines/experimental/CoroutineContext$DefaultImpls {
|
||||||
|
public static fun plus (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Element : kotlin/coroutines/experimental/CoroutineContext {
|
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Element : kotlin/coroutines/experimental/CoroutineContext {
|
||||||
|
public abstract fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||||
|
public abstract fun get (Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext$Element;
|
||||||
public abstract fun getKey ()Lkotlin/coroutines/experimental/CoroutineContext$Key;
|
public abstract fun getKey ()Lkotlin/coroutines/experimental/CoroutineContext$Key;
|
||||||
|
public abstract fun minusKey (Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class kotlin/coroutines/experimental/CoroutineContext$Element$DefaultImpls {
|
||||||
|
public static fun fold (Lkotlin/coroutines/experimental/CoroutineContext$Element;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||||
|
public static fun get (Lkotlin/coroutines/experimental/CoroutineContext$Element;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext$Element;
|
||||||
|
public static fun minusKey (Lkotlin/coroutines/experimental/CoroutineContext$Element;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
public static fun plus (Lkotlin/coroutines/experimental/CoroutineContext$Element;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Key {
|
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Key {
|
||||||
|
|||||||
@@ -1778,6 +1778,13 @@ public abstract interface class kotlin/coroutines/experimental/ContinuationInter
|
|||||||
public abstract fun interceptContinuation (Lkotlin/coroutines/experimental/Continuation;)Lkotlin/coroutines/experimental/Continuation;
|
public abstract fun interceptContinuation (Lkotlin/coroutines/experimental/Continuation;)Lkotlin/coroutines/experimental/Continuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class kotlin/coroutines/experimental/ContinuationInterceptor$DefaultImpls {
|
||||||
|
public static fun fold (Lkotlin/coroutines/experimental/ContinuationInterceptor;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||||
|
public static fun get (Lkotlin/coroutines/experimental/ContinuationInterceptor;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext$Element;
|
||||||
|
public static fun minusKey (Lkotlin/coroutines/experimental/ContinuationInterceptor;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
public static fun plus (Lkotlin/coroutines/experimental/ContinuationInterceptor;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
}
|
||||||
|
|
||||||
public final class kotlin/coroutines/experimental/ContinuationInterceptor$Key : kotlin/coroutines/experimental/CoroutineContext$Key {
|
public final class kotlin/coroutines/experimental/ContinuationInterceptor$Key : kotlin/coroutines/experimental/CoroutineContext$Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1788,8 +1795,22 @@ public abstract interface class kotlin/coroutines/experimental/CoroutineContext
|
|||||||
public abstract fun plus (Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
public abstract fun plus (Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class kotlin/coroutines/experimental/CoroutineContext$DefaultImpls {
|
||||||
|
public static fun plus (Lkotlin/coroutines/experimental/CoroutineContext;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Element : kotlin/coroutines/experimental/CoroutineContext {
|
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Element : kotlin/coroutines/experimental/CoroutineContext {
|
||||||
|
public abstract fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||||
|
public abstract fun get (Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext$Element;
|
||||||
public abstract fun getKey ()Lkotlin/coroutines/experimental/CoroutineContext$Key;
|
public abstract fun getKey ()Lkotlin/coroutines/experimental/CoroutineContext$Key;
|
||||||
|
public abstract fun minusKey (Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class kotlin/coroutines/experimental/CoroutineContext$Element$DefaultImpls {
|
||||||
|
public static fun fold (Lkotlin/coroutines/experimental/CoroutineContext$Element;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
|
||||||
|
public static fun get (Lkotlin/coroutines/experimental/CoroutineContext$Element;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext$Element;
|
||||||
|
public static fun minusKey (Lkotlin/coroutines/experimental/CoroutineContext$Element;Lkotlin/coroutines/experimental/CoroutineContext$Key;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
|
public static fun plus (Lkotlin/coroutines/experimental/CoroutineContext$Element;Lkotlin/coroutines/experimental/CoroutineContext;)Lkotlin/coroutines/experimental/CoroutineContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Key {
|
public abstract interface class kotlin/coroutines/experimental/CoroutineContext$Key {
|
||||||
|
|||||||
Reference in New Issue
Block a user