Skip to content

Commit 61dd23c

Browse files
authored
Introduce SubclassOptInRequired to the codebase (#4115)
The initial stage of #3770 Marked: * Job, * Deferred and CompletableDeferred, * SharedFlow, StateFlow, * CancellableContinuation, * All of their `public` implementors.
1 parent 7fe0e0c commit 61dd23c

18 files changed

+73
-11
lines changed

kotlinx-coroutines-core/api/kotlinx-coroutines-core.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ public final class kotlinx/coroutines/ExecutorsKt {
367367
public abstract interface annotation class kotlinx/coroutines/ExperimentalCoroutinesApi : java/lang/annotation/Annotation {
368368
}
369369

370+
public abstract interface annotation class kotlinx/coroutines/ExperimentalForInheritanceCoroutinesApi : java/lang/annotation/Annotation {
371+
}
372+
370373
public abstract interface annotation class kotlinx/coroutines/FlowPreview : java/lang/annotation/Annotation {
371374
}
372375

@@ -378,6 +381,9 @@ public final class kotlinx/coroutines/GlobalScope : kotlinx/coroutines/Coroutine
378381
public abstract interface annotation class kotlinx/coroutines/InternalCoroutinesApi : java/lang/annotation/Annotation {
379382
}
380383

384+
public abstract interface annotation class kotlinx/coroutines/InternalForInheritanceCoroutinesApi : java/lang/annotation/Annotation {
385+
}
386+
381387
public final class kotlinx/coroutines/InterruptibleKt {
382388
public static final fun runInterruptible (Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
383389
public static synthetic fun runInterruptible$default (Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;

kotlinx-coroutines-core/api/kotlinx-coroutines-core.klib.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,12 +764,18 @@ open annotation class kotlinx.coroutines/DelicateCoroutinesApi : kotlin/Annotati
764764
open annotation class kotlinx.coroutines/ExperimentalCoroutinesApi : kotlin/Annotation { // kotlinx.coroutines/ExperimentalCoroutinesApi|null[0]
765765
constructor <init>() // kotlinx.coroutines/ExperimentalCoroutinesApi.<init>|<init>(){}[0]
766766
}
767+
open annotation class kotlinx.coroutines/ExperimentalForInheritanceCoroutinesApi : kotlin/Annotation { // kotlinx.coroutines/ExperimentalForInheritanceCoroutinesApi|null[0]
768+
constructor <init>() // kotlinx.coroutines/ExperimentalForInheritanceCoroutinesApi.<init>|<init>(){}[0]
769+
}
767770
open annotation class kotlinx.coroutines/FlowPreview : kotlin/Annotation { // kotlinx.coroutines/FlowPreview|null[0]
768771
constructor <init>() // kotlinx.coroutines/FlowPreview.<init>|<init>(){}[0]
769772
}
770773
open annotation class kotlinx.coroutines/InternalCoroutinesApi : kotlin/Annotation { // kotlinx.coroutines/InternalCoroutinesApi|null[0]
771774
constructor <init>() // kotlinx.coroutines/InternalCoroutinesApi.<init>|<init>(){}[0]
772775
}
776+
open annotation class kotlinx.coroutines/InternalForInheritanceCoroutinesApi : kotlin/Annotation { // kotlinx.coroutines/InternalForInheritanceCoroutinesApi|null[0]
777+
constructor <init>() // kotlinx.coroutines/InternalForInheritanceCoroutinesApi.<init>|<init>(){}[0]
778+
}
773779
open annotation class kotlinx.coroutines/ObsoleteCoroutinesApi : kotlin/Annotation { // kotlinx.coroutines/ObsoleteCoroutinesApi|null[0]
774780
constructor <init>() // kotlinx.coroutines/ObsoleteCoroutinesApi.<init>|<init>(){}[0]
775781
}

kotlinx-coroutines-core/common/src/AbstractCoroutine.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import kotlin.coroutines.*
3030
*
3131
* @suppress **This an internal API and should not be used from general code.**
3232
*/
33+
@OptIn(InternalForInheritanceCoroutinesApi::class)
3334
@InternalCoroutinesApi
3435
public abstract class AbstractCoroutine<in T>(
3536
parentContext: CoroutineContext,

kotlinx-coroutines-core/common/src/Annotations.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,29 @@ public annotation class ObsoleteCoroutinesApi
9090
"so stable API could be provided instead"
9191
)
9292
public annotation class InternalCoroutinesApi
93+
94+
/**
95+
* Marks declarations that cannot be safely inherited from.
96+
*/
97+
@Target(AnnotationTarget.CLASS)
98+
@RequiresOptIn(
99+
level = RequiresOptIn.Level.WARNING, message =
100+
"Inheriting from this kotlinx.coroutines API is unstable. " +
101+
"Either new methods may be added in the future, which would break the inheritance, " +
102+
"or correctly inheriting from it requires fulfilling contracts that may change in the future."
103+
)
104+
public annotation class ExperimentalForInheritanceCoroutinesApi
105+
106+
/**
107+
* Marks declarations that cannot be safely inherited from.
108+
*/
109+
@Target(AnnotationTarget.CLASS)
110+
@RequiresOptIn(
111+
level = RequiresOptIn.Level.WARNING, message =
112+
"This is a kotlinx.coroutines API that is not intended to be inherited from, " +
113+
"as the library may handle predefined instances of this in a special manner. " +
114+
"This will be an error in a future release. " +
115+
"If you need to inherit from this, please describe your use case in " +
116+
"https://github.com/Kotlin/kotlinx.coroutines/issues, so that we can provide a stable API for inheritance. "
117+
)
118+
public annotation class InternalForInheritanceCoroutinesApi

kotlinx-coroutines-core/common/src/Builders.common.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public fun <T> CoroutineScope.async(
8888
return coroutine
8989
}
9090

91+
@OptIn(InternalForInheritanceCoroutinesApi::class)
9192
@Suppress("UNCHECKED_CAST")
9293
private open class DeferredCoroutine<T>(
9394
parentContext: CoroutineContext,

kotlinx-coroutines-core/common/src/CancellableContinuation.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ import kotlin.coroutines.intrinsics.*
4141
* +-----------+
4242
* ```
4343
*/
44+
@OptIn(ExperimentalSubclassOptIn::class)
45+
@SubclassOptInRequired(InternalForInheritanceCoroutinesApi::class)
4446
public interface CancellableContinuation<in T> : Continuation<T> {
4547
/**
4648
* Returns `true` when this continuation is active -- it has not completed or cancelled yet.

kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ internal val RESUME_TOKEN = Symbol("RESUME_TOKEN")
2525
/**
2626
* @suppress **This is unstable API and it is subject to change.**
2727
*/
28+
@OptIn(InternalForInheritanceCoroutinesApi::class)
2829
@PublishedApi
2930
internal open class CancellableContinuationImpl<in T>(
3031
final override val delegate: Continuation<T>,

kotlinx-coroutines-core/common/src/CompletableDeferred.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ import kotlinx.coroutines.selects.*
1515
*
1616
* All functions on this interface are **thread-safe** and can
1717
* be safely invoked from concurrent coroutines without external synchronization.
18-
*
19-
* **The `CompletableDeferred` interface is not stable for inheritance in 3rd party libraries**,
20-
* as new methods might be added to this interface in the future, but is stable for use.
2118
*/
19+
@OptIn(ExperimentalSubclassOptIn::class)
20+
@SubclassOptInRequired(markerClass = InternalForInheritanceCoroutinesApi::class)
2221
public interface CompletableDeferred<T> : Deferred<T> {
2322
/**
2423
* Completes this deferred value with a given [value]. The result is `true` if this deferred was
@@ -73,6 +72,7 @@ public fun <T> CompletableDeferred(value: T): CompletableDeferred<T> = Completab
7372
/**
7473
* Concrete implementation of [CompletableDeferred].
7574
*/
75+
@OptIn(InternalForInheritanceCoroutinesApi::class)
7676
@Suppress("UNCHECKED_CAST")
7777
private class CompletableDeferredImpl<T>(
7878
parent: Job?

kotlinx-coroutines-core/common/src/CompletableJob.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ package kotlinx.coroutines
1010
* **The `CompletableJob` interface is not stable for inheritance in 3rd party libraries**,
1111
* as new methods might be added to this interface in the future, but is stable for use.
1212
*/
13+
@OptIn(ExperimentalSubclassOptIn::class)
14+
@SubclassOptInRequired(markerClass = InternalForInheritanceCoroutinesApi::class)
1315
public interface CompletableJob : Job {
1416
/**
1517
* Completes this job. The result is `true` if this job was completed as a result of this invocation and

kotlinx-coroutines-core/common/src/Deferred.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ import kotlinx.coroutines.selects.*
2626
*
2727
* All functions on this interface and on all interfaces derived from it are **thread-safe** and can
2828
* be safely invoked from concurrent coroutines without external synchronization.
29-
*
30-
* **`Deferred` interface and all its derived interfaces are not stable for inheritance in 3rd party libraries**,
31-
* as new methods might be added to this interface in the future, but is stable for use.
3229
*/
30+
@OptIn(ExperimentalSubclassOptIn::class)
31+
@SubclassOptInRequired(markerClass = InternalForInheritanceCoroutinesApi::class)
3332
public interface Deferred<out T> : Job {
3433

3534
/**

0 commit comments

Comments
 (0)