Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promote deprecation levels for release 1.6.0 #3024

Merged
merged 2 commits into from Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 0 additions & 10 deletions kotlinx-coroutines-core/api/kotlinx-coroutines-core.api
Expand Up @@ -889,8 +889,6 @@ public final class kotlinx/coroutines/flow/FlowKt {
public static final fun asFlow ([Ljava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static final fun asSharedFlow (Lkotlinx/coroutines/flow/MutableSharedFlow;)Lkotlinx/coroutines/flow/SharedFlow;
public static final fun asStateFlow (Lkotlinx/coroutines/flow/MutableStateFlow;)Lkotlinx/coroutines/flow/StateFlow;
public static final fun broadcastIn (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/CoroutineStart;)Lkotlinx/coroutines/channels/BroadcastChannel;
public static synthetic fun broadcastIn$default (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/CoroutineStart;ILjava/lang/Object;)Lkotlinx/coroutines/channels/BroadcastChannel;
public static final synthetic fun buffer (Lkotlinx/coroutines/flow/Flow;I)Lkotlinx/coroutines/flow/Flow;
public static final fun buffer (Lkotlinx/coroutines/flow/Flow;ILkotlinx/coroutines/channels/BufferOverflow;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun buffer$default (Lkotlinx/coroutines/flow/Flow;IILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
Expand Down Expand Up @@ -961,10 +959,6 @@ public final class kotlinx/coroutines/flow/FlowKt {
public static final fun flowOf (Ljava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static final fun flowOf ([Ljava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static final fun flowOn (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/flow/Flow;
public static final fun flowViaChannel (ILkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun flowViaChannel$default (ILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static final fun flowWith (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun flowWith$default (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static final fun fold (Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun forEach (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)V
public static final fun getDEFAULT_CONCURRENCY ()I
Expand All @@ -981,8 +975,6 @@ public final class kotlinx/coroutines/flow/FlowKt {
public static final fun onCompletion (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
public static final fun onEach (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
public static final fun onEmpty (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
public static final fun onErrorCollect (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun onErrorCollect$default (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static final fun onErrorResume (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
public static final fun onErrorResumeNext (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
public static final fun onErrorReturn (Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
Expand All @@ -998,9 +990,7 @@ public final class kotlinx/coroutines/flow/FlowKt {
public static final fun reduce (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun replay (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
public static final fun replay (Lkotlinx/coroutines/flow/Flow;I)Lkotlinx/coroutines/flow/Flow;
public static final synthetic fun retry (Lkotlinx/coroutines/flow/Flow;ILkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
public static final fun retry (Lkotlinx/coroutines/flow/Flow;JLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun retry$default (Lkotlinx/coroutines/flow/Flow;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun retry$default (Lkotlinx/coroutines/flow/Flow;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
public static final fun retryWhen (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function4;)Lkotlinx/coroutines/flow/Flow;
public static final fun runningFold (Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
Expand Down
9 changes: 0 additions & 9 deletions kotlinx-coroutines-core/common/README.md
Expand Up @@ -66,10 +66,6 @@ This module provides debugging facilities for coroutines (run JVM with `-ea` or
and [newCoroutineContext] function to write user-defined coroutine builders that work with these
debugging facilities. See [DEBUG_PROPERTY_NAME] for more details.

This module provides a special CoroutineContext type [TestCoroutineCoroutineContext][kotlinx.coroutines.test.TestCoroutineContext] that
allows the writer of code that contains Coroutines with delays and timeouts to write non-flaky unit-tests for that code allowing these tests to
terminate in near zero time. See the documentation for this class for more information.

# Package kotlinx.coroutines

General-purpose coroutine builders, contexts, and helper functions.
Expand Down Expand Up @@ -130,7 +126,6 @@ Low-level primitives for finer-grained control of coroutines.

[kotlinx.coroutines.sync.Mutex]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/index.html
[kotlinx.coroutines.sync.Mutex.lock]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/lock.html
[kotlinx.coroutines.sync.Mutex.tryLock]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/try-lock.html

<!--- INDEX kotlinx.coroutines.channels -->

Expand All @@ -155,8 +150,4 @@ Low-level primitives for finer-grained control of coroutines.
[kotlinx.coroutines.selects.select]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.selects/select.html
[kotlinx.coroutines.selects.SelectBuilder.onTimeout]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.selects/on-timeout.html

<!--- INDEX kotlinx.coroutines.test -->

[kotlinx.coroutines.test.TestCoroutineContext]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.test/-test-coroutine-context/index.html

<!--- END -->
Expand Up @@ -136,7 +136,7 @@ internal abstract class AbstractSendChannel<E>(
return sendSuspend(element)
}

@Suppress("DEPRECATION")
@Suppress("DEPRECATION", "DEPRECATION_ERROR")
override fun offer(element: E): Boolean {
// Temporary migration for offer users who rely on onUndeliveredElement
try {
Expand Down
10 changes: 5 additions & 5 deletions kotlinx-coroutines-core/common/src/channels/Channel.kt
Expand Up @@ -157,10 +157,10 @@ public interface SendChannel<in E> {
* @suppress **Deprecated**.
*/
@Deprecated(
level = DeprecationLevel.WARNING,
level = DeprecationLevel.ERROR,
message = "Deprecated in the favour of 'trySend' method",
replaceWith = ReplaceWith("trySend(element).isSuccess")
) // Warning since 1.5.0
) // Warning since 1.5.0, error since 1.6.0
public fun offer(element: E): Boolean {
val result = trySend(element)
if (result.isSuccess) return true
Expand Down Expand Up @@ -313,12 +313,12 @@ public interface ReceiveChannel<out E> {
* @suppress **Deprecated**.
*/
@Deprecated(
level = DeprecationLevel.WARNING,
level = DeprecationLevel.ERROR,
message = "Deprecated in the favour of 'tryReceive'. " +
"Please note that the provided replacement does not rethrow channel's close cause as 'poll' did, " +
"for the precise replacement please refer to the 'poll' documentation",
replaceWith = ReplaceWith("tryReceive().getOrNull()")
) // Warning since 1.5.0
) // Warning since 1.5.0, error since 1.6.0
public fun poll(): E? {
val result = tryReceive()
if (result.isSuccess) return result.getOrThrow()
Expand Down Expand Up @@ -364,7 +364,7 @@ public interface ReceiveChannel<out E> {
message = "Deprecated in favor of onReceiveCatching extension",
level = DeprecationLevel.ERROR,
replaceWith = ReplaceWith("onReceiveCatching")
) // Warning since 1.3.0, error in 1.5.0, will be hidden or removed in 1.6.0
) // Warning since 1.3.0, error in 1.5.0, will be hidden or removed in 1.7.0
public val onReceiveOrNull: SelectClause1<E?>
get() {
return object : SelectClause1<E?> {
Expand Down
Expand Up @@ -50,7 +50,7 @@ public inline fun <E, R> BroadcastChannel<E>.consume(block: ReceiveChannel<E>.()
@Deprecated(
"Deprecated in the favour of 'receiveCatching'",
ReplaceWith("receiveCatching().getOrNull()"),
DeprecationLevel.WARNING
DeprecationLevel.ERROR
) // Warning since 1.5.0, ERROR in 1.6.0, HIDDEN in 1.7.0
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
public suspend fun <E : Any> ReceiveChannel<E>.receiveOrNull(): E? {
Expand All @@ -63,7 +63,7 @@ public suspend fun <E : Any> ReceiveChannel<E>.receiveOrNull(): E? {
*/
@Deprecated(
"Deprecated in the favour of 'onReceiveCatching'",
level = DeprecationLevel.WARNING
level = DeprecationLevel.ERROR
) // Warning since 1.5.0, ERROR in 1.6.0, HIDDEN in 1.7.0
public fun <E : Any> ReceiveChannel<E>.onReceiveOrNull(): SelectClause1<E?> {
@Suppress("DEPRECATION", "UNCHECKED_CAST")
Expand Down
19 changes: 0 additions & 19 deletions kotlinx-coroutines-core/common/src/flow/Builders.kt
Expand Up @@ -198,25 +198,6 @@ public fun LongRange.asFlow(): Flow<Long> = flow {
}
}

/**
* @suppress
*/
@FlowPreview
@Deprecated(
message = "Use channelFlow with awaitClose { } instead of flowViaChannel and invokeOnClose { }.",
level = DeprecationLevel.ERROR
) // To be removed in 1.4.x
@Suppress("DeprecatedCallableAddReplaceWith")
public fun <T> flowViaChannel(
bufferSize: Int = BUFFERED,
@BuilderInference block: CoroutineScope.(channel: SendChannel<T>) -> Unit
): Flow<T> {
return channelFlow<T> {
block(channel)
awaitClose()
}.buffer(bufferSize)
}

/**
* Creates an instance of a _cold_ [Flow] with elements that are sent to a [SendChannel]
* provided to the builder's [block] of code via [ProducerScope]. It allows elements to be
Expand Down
35 changes: 0 additions & 35 deletions kotlinx-coroutines-core/common/src/flow/Channels.kt
Expand Up @@ -178,41 +178,6 @@ public fun <T> BroadcastChannel<T>.asFlow(): Flow<T> = flow {
emitAll(openSubscription())
}

/**
* ### Deprecated
*
* **This API is deprecated.** The [BroadcastChannel] provides a complex channel-like API for hot flows.
* [SharedFlow] is an easier-to-use and more flow-centric API for the same purposes, so using
* [shareIn] operator is preferred. It is not a direct replacement, so please
* study [shareIn] documentation to see what kind of shared flow fits your use-case. As a rule of thumb:
*
* * Replace `broadcastIn(scope)` and `broadcastIn(scope, CoroutineStart.LAZY)` with `shareIn(scope, 0, SharingStarted.Lazily)`.
* * Replace `broadcastIn(scope, CoroutineStart.DEFAULT)` with `shareIn(scope, 0, SharingStarted.Eagerly)`.
*/
@Deprecated(
message = "Use shareIn operator and the resulting SharedFlow as a replacement for BroadcastChannel",
replaceWith = ReplaceWith("this.shareIn(scope, SharingStarted.Lazily, 0)"),
level = DeprecationLevel.ERROR
) // WARNING in 1.4.0, error in 1.5.0, removed in 1.6.0 (was @FlowPreview)
public fun <T> Flow<T>.broadcastIn(
scope: CoroutineScope,
start: CoroutineStart = CoroutineStart.LAZY
): BroadcastChannel<T> {
// Backwards compatibility with operator fusing
val channelFlow = asChannelFlow()
val capacity = when (channelFlow.onBufferOverflow) {
BufferOverflow.SUSPEND -> channelFlow.produceCapacity
BufferOverflow.DROP_OLDEST -> Channel.CONFLATED
BufferOverflow.DROP_LATEST ->
throw IllegalArgumentException("Broadcast channel does not support BufferOverflow.DROP_LATEST")
}
return scope.broadcast(channelFlow.context, capacity = capacity, start = start) {
collect { value ->
send(value)
}
}
}

/**
* Creates a [produce] coroutine that collects the given flow.
*
Expand Down
58 changes: 0 additions & 58 deletions kotlinx-coroutines-core/common/src/flow/operators/Context.kt
Expand Up @@ -277,64 +277,6 @@ private class CancellableFlowImpl<T>(private val flow: Flow<T>) : CancellableFlo
}
}

/**
* The operator that changes the context where all transformations applied to the given flow within a [builder] are executed.
* This operator is context preserving and does not affect the context of the preceding and subsequent operations.
*
* Example:
*
* ```
* flow // not affected
* .map { ... } // Not affected
* .flowWith(Dispatchers.IO) {
* map { ... } // in IO
* .filter { ... } // in IO
* }
* .map { ... } // Not affected
* ```
*
* For more explanation of context preservation please refer to [Flow] documentation.
*
* This operator is deprecated without replacement because it was discovered that it doesn't play well with coroutines
* and flow semantics:
*
* 1) It doesn't prevent context elements from the downstream to leak into its body
* ```
* flowOf(1).flowWith(EmptyCoroutineContext) {
* onEach { println(kotlin.coroutines.coroutineContext[CoroutineName]) } // Will print 42
* }.flowOn(CoroutineName(42))
* ```
* 2) To avoid such leaks, new primitive should be introduced to `kotlinx.coroutines` -- the subtraction of contexts.
* And this will become a new concept to learn, maintain and explain.
* 3) It defers the execution of declarative [builder] until the moment of [collection][Flow.collect] similarly
* to `Observable.defer`. But it is unexpected because nothing in the name `flowWith` reflects this fact.
* 4) It can be confused with [flowOn] operator, though [flowWith] is much rarer.
*
* @suppress
*/
@FlowPreview
@Deprecated(message = "flowWith is deprecated without replacement, please refer to its KDoc for an explanation", level = DeprecationLevel.ERROR) // Error in beta release, removal in 1.4
public fun <T, R> Flow<T>.flowWith(
flowContext: CoroutineContext,
bufferSize: Int = BUFFERED,
builder: Flow<T>.() -> Flow<R>
): Flow<R> {
checkFlowContext(flowContext)
val source = this
return unsafeFlow {
/**
* Here we should remove a Job instance from the context.
* All builders are written using scoping and no global coroutines are launched, so it is safe not to provide explicit Job.
* It is also necessary not to mess with cancellation if multiple flowWith are used.
*/
val originalContext = currentCoroutineContext().minusKey(Job)
val prepared = source.flowOn(originalContext).buffer(bufferSize)
builder(prepared).flowOn(flowContext).buffer(bufferSize).collect { value ->
return@collect emit(value)
}
}
}

private fun checkFlowContext(context: CoroutineContext) {
require(context[Job] == null) {
"Flow context cannot contain job in it. Had $context"
Expand Down
39 changes: 0 additions & 39 deletions kotlinx-coroutines-core/common/src/flow/operators/Errors.kt
Expand Up @@ -60,35 +60,6 @@ public fun <T> Flow<T>.catch(action: suspend FlowCollector<T>.(cause: Throwable)
if (exception != null) action(exception)
}

/**
* @suppress **Deprecated**: Use `(Throwable) -> Boolean` functional type
*/
@Deprecated(
level = DeprecationLevel.ERROR,
message = "Use (Throwable) -> Boolean functional type",
replaceWith = ReplaceWith("(Throwable) -> Boolean")
)
public typealias ExceptionPredicate = (Throwable) -> Boolean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand correctly that type aliases don't leave a trace in target binaries, so it doesn't make sense to make them hidden, as they would simply become useless?


/**
* Switches to the [fallback] flow if the original flow throws an exception that matches the [predicate].
* Cancellation exceptions that were caused by the direct [cancel] call are not handled by this operator.
*
* @suppress **Deprecated**: Use `catch { e -> if (predicate(e)) emitAll(fallback) else throw e }`
*/
@Deprecated(
level = DeprecationLevel.ERROR,
message = "Use catch { e -> if (predicate(e)) emitAll(fallback) else throw e }",
replaceWith = ReplaceWith("catch { e -> if (predicate(e)) emitAll(fallback) else throw e }")
)
public fun <T> Flow<T>.onErrorCollect(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one was @FlowPreview

fallback: Flow<T>,
predicate: (Throwable) -> Boolean = { true }
): Flow<T> = catch { e ->
if (!predicate(e)) throw e
emitAll(fallback)
}

/**
* Retries collection of the given flow up to [retries] times when an exception that matches the
* given [predicate] occurs in the upstream flow. This operator is *transparent* to exceptions that occur
Expand Down Expand Up @@ -124,16 +95,6 @@ public fun <T> Flow<T>.retry(
return retryWhen { cause, attempt -> attempt < retries && predicate(cause) }
}

@FlowPreview
@Deprecated(level = DeprecationLevel.HIDDEN, message = "binary compatibility with retries: Int preview version")
public fun <T> Flow<T>.retry(
retries: Int = Int.MAX_VALUE,
predicate: (Throwable) -> Boolean = { true }
): Flow<T> {
require(retries > 0) { "Expected positive amount of retries, but had $retries" }
return retryWhen { cause, attempt -> predicate(cause) && attempt < retries }
}

/**
* Retries collection of the given flow when an exception occurs in the upstream flow and the
* [predicate] returns true. The predicate also receives an `attempt` number as parameter,
Expand Down
2 changes: 1 addition & 1 deletion kotlinx-coroutines-core/common/src/sync/Mutex.kt
Expand Up @@ -65,7 +65,7 @@ public interface Mutex {
* Deprecated for removal without built-in replacement.
*/
@Deprecated(level = DeprecationLevel.WARNING, message = "Mutex.onLock deprecated without replacement. " +
"For additional details please refer to #2794")
"For additional details please refer to #2794") // WARNING since 1.6.0
public val onLock: SelectClause2<Any?, Mutex>

/**
Expand Down
2 changes: 1 addition & 1 deletion kotlinx-coroutines-core/jvm/src/channels/Actor.kt
Expand Up @@ -163,7 +163,7 @@ private class LazyActorCoroutine<E>(
return super.send(element)
}

@Suppress("DEPRECATION")
@Suppress("DEPRECATION", "DEPRECATION_ERROR")
override fun offer(element: E): Boolean {
start()
return super.offer(element)
Expand Down
4 changes: 2 additions & 2 deletions kotlinx-coroutines-core/jvm/src/channels/Channels.kt
Expand Up @@ -43,11 +43,11 @@ import kotlinx.coroutines.*
* ```
*/
@Deprecated(
level = DeprecationLevel.WARNING,
level = DeprecationLevel.ERROR,
message = "Deprecated in the favour of 'trySendBlocking'. " +
"Consider handling the result of 'trySendBlocking' explicitly and rethrow exception if necessary",
replaceWith = ReplaceWith("trySendBlocking(element)")
)
) // WARNING in 1.5.0, ERROR in 1.6.0, HIDDEN in 1.7.0
public fun <E> SendChannel<E>.sendBlocking(element: E) {
// fast path
if (trySend(element).isSuccess)
Expand Down
2 changes: 1 addition & 1 deletion kotlinx-coroutines-core/jvm/src/scheduling/Deprecated.kt
Expand Up @@ -18,7 +18,7 @@ import kotlin.coroutines.*
* To preserve backwards compatibility with Ktor 1.x, previous version of the code is
* extracted here as is and isolated from the rest of code base, so R8 can get rid of it.
*
* It should be removed after Kotlin 3.0.0 (EOL of Ktor 1.x) around 2022.
* It should be removed after Ktor 3.0.0 (EOL of Ktor 1.x) around 2022.
*/
@PublishedApi
internal open class ExperimentalCoroutineDispatcher(
Expand Down