Skip to content

Commit 5664713

Browse files
authored
Formalize the internal IDEA dependencies for binary compatibility (#3746)
Using the list in the issue KTIJ-24102.
1 parent c485118 commit 5664713

12 files changed

+165
-62
lines changed

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

+75-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public final class kotlinx/coroutines/CancellableContinuation$DefaultImpls {
5151
public static synthetic fun tryResume$default (Lkotlinx/coroutines/CancellableContinuation;Ljava/lang/Object;Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;
5252
}
5353

54-
public class kotlinx/coroutines/CancellableContinuationImpl : kotlin/coroutines/jvm/internal/CoroutineStackFrame, kotlinx/coroutines/CancellableContinuation, kotlinx/coroutines/Waiter {
54+
public class kotlinx/coroutines/CancellableContinuationImpl : kotlinx/coroutines/DispatchedTask, kotlin/coroutines/jvm/internal/CoroutineStackFrame, kotlinx/coroutines/CancellableContinuation, kotlinx/coroutines/Waiter {
5555
public fun <init> (Lkotlin/coroutines/Continuation;I)V
5656
public final fun callCancelHandler (Lkotlinx/coroutines/CancelHandler;Ljava/lang/Throwable;)V
5757
public final fun callOnCancellation (Lkotlin/jvm/functions/Function1;Ljava/lang/Throwable;)V
@@ -84,6 +84,13 @@ public final class kotlinx/coroutines/CancellableContinuationKt {
8484
public static final fun suspendCancellableCoroutine (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
8585
}
8686

87+
public final class kotlinx/coroutines/ChildContinuation {
88+
public final field child Lkotlinx/coroutines/CancellableContinuationImpl;
89+
public fun <init> (Lkotlinx/coroutines/CancellableContinuationImpl;)V
90+
public synthetic fun invoke (Ljava/lang/Object;)Ljava/lang/Object;
91+
public fun invoke (Ljava/lang/Throwable;)V
92+
}
93+
8794
public abstract interface class kotlinx/coroutines/ChildHandle : kotlinx/coroutines/DisposableHandle {
8895
public abstract fun childCancelled (Ljava/lang/Throwable;)Z
8996
public abstract fun getParent ()Lkotlinx/coroutines/Job;
@@ -200,6 +207,25 @@ public final class kotlinx/coroutines/CoroutineExceptionHandlerKt {
200207
public static final fun handleCoroutineException (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Throwable;)V
201208
}
202209

210+
public final class kotlinx/coroutines/CoroutineId : kotlin/coroutines/AbstractCoroutineContextElement, kotlinx/coroutines/ThreadContextElement {
211+
public static final field Key Lkotlinx/coroutines/CoroutineId$Key;
212+
public fun <init> (J)V
213+
public final fun component1 ()J
214+
public final fun copy (J)Lkotlinx/coroutines/CoroutineId;
215+
public static synthetic fun copy$default (Lkotlinx/coroutines/CoroutineId;JILjava/lang/Object;)Lkotlinx/coroutines/CoroutineId;
216+
public fun equals (Ljava/lang/Object;)Z
217+
public final fun getId ()J
218+
public fun hashCode ()I
219+
public synthetic fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Object;)V
220+
public fun restoreThreadContext (Lkotlin/coroutines/CoroutineContext;Ljava/lang/String;)V
221+
public fun toString ()Ljava/lang/String;
222+
public synthetic fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Ljava/lang/Object;
223+
public fun updateThreadContext (Lkotlin/coroutines/CoroutineContext;)Ljava/lang/String;
224+
}
225+
226+
public final class kotlinx/coroutines/CoroutineId$Key : kotlin/coroutines/CoroutineContext$Key {
227+
}
228+
203229
public final class kotlinx/coroutines/CoroutineName : kotlin/coroutines/AbstractCoroutineContextElement {
204230
public static final field Key Lkotlinx/coroutines/CoroutineName$Key;
205231
public fun <init> (Ljava/lang/String;)V
@@ -288,6 +314,15 @@ public final class kotlinx/coroutines/DelayKt {
288314
public abstract interface annotation class kotlinx/coroutines/DelicateCoroutinesApi : java/lang/annotation/Annotation {
289315
}
290316

317+
public final class kotlinx/coroutines/DispatchedCoroutine {
318+
public static final fun get_decision$FU ()Ljava/util/concurrent/atomic/AtomicIntegerFieldUpdater;
319+
}
320+
321+
public abstract class kotlinx/coroutines/DispatchedTask : kotlinx/coroutines/scheduling/Task {
322+
public field resumeMode I
323+
public final fun run ()V
324+
}
325+
291326
public final class kotlinx/coroutines/DispatchedTaskKt {
292327
public static final field MODE_CANCELLABLE I
293328
}
@@ -877,9 +912,7 @@ public final class kotlinx/coroutines/channels/TickerMode : java/lang/Enum {
877912
}
878913

879914
public final class kotlinx/coroutines/debug/internal/DebugCoroutineInfo {
880-
public fun <init> (Lkotlinx/coroutines/debug/internal/DebugCoroutineInfoImpl;Lkotlin/coroutines/CoroutineContext;)V
881915
public final fun getContext ()Lkotlin/coroutines/CoroutineContext;
882-
public final fun getCreationStackBottom ()Lkotlin/coroutines/jvm/internal/CoroutineStackFrame;
883916
public final fun getCreationStackTrace ()Ljava/util/List;
884917
public final fun getLastObservedFrame ()Lkotlin/coroutines/jvm/internal/CoroutineStackFrame;
885918
public final fun getLastObservedThread ()Ljava/lang/Thread;
@@ -888,6 +921,35 @@ public final class kotlinx/coroutines/debug/internal/DebugCoroutineInfo {
888921
public final fun lastObservedStackTrace ()Ljava/util/List;
889922
}
890923

924+
public final class kotlinx/coroutines/debug/internal/DebugCoroutineInfoImpl {
925+
public field _lastObservedFrame Ljava/lang/ref/WeakReference;
926+
public field _state Ljava/lang/String;
927+
public field lastObservedThread Ljava/lang/Thread;
928+
public final field sequenceNumber J
929+
public final fun getContext ()Lkotlin/coroutines/CoroutineContext;
930+
public final fun getCreationStackTrace ()Ljava/util/List;
931+
public fun toString ()Ljava/lang/String;
932+
}
933+
934+
public final class kotlinx/coroutines/debug/internal/DebugProbesImpl {
935+
public static final field INSTANCE Lkotlinx/coroutines/debug/internal/DebugProbesImpl;
936+
public final fun dumpCoroutinesInfo ()Ljava/util/List;
937+
public final fun dumpCoroutinesInfoAsJsonAndReferences ()[Ljava/lang/Object;
938+
public final fun dumpDebuggerInfo ()Ljava/util/List;
939+
public final fun enhanceStackTraceWithThreadDump (Lkotlinx/coroutines/debug/internal/DebugCoroutineInfo;Ljava/util/List;)Ljava/util/List;
940+
public final fun enhanceStackTraceWithThreadDumpAsJson (Lkotlinx/coroutines/debug/internal/DebugCoroutineInfo;)Ljava/lang/String;
941+
public final fun isInstalled ()Z
942+
}
943+
944+
public final class kotlinx/coroutines/debug/internal/DebugProbesImpl$CoroutineOwner : kotlin/coroutines/Continuation, kotlin/coroutines/jvm/internal/CoroutineStackFrame {
945+
public final field info Lkotlinx/coroutines/debug/internal/DebugCoroutineInfoImpl;
946+
public fun getCallerFrame ()Lkotlin/coroutines/jvm/internal/CoroutineStackFrame;
947+
public fun getContext ()Lkotlin/coroutines/CoroutineContext;
948+
public fun getStackTraceElement ()Ljava/lang/StackTraceElement;
949+
public fun resumeWith (Ljava/lang/Object;)V
950+
public fun toString ()Ljava/lang/String;
951+
}
952+
891953
public final class kotlinx/coroutines/debug/internal/DebuggerInfo : java/io/Serializable {
892954
public fun <init> (Lkotlinx/coroutines/debug/internal/DebugCoroutineInfoImpl;Lkotlin/coroutines/CoroutineContext;)V
893955
public final fun getCoroutineId ()Ljava/lang/Long;
@@ -900,6 +962,12 @@ public final class kotlinx/coroutines/debug/internal/DebuggerInfo : java/io/Seri
900962
public final fun getState ()Ljava/lang/String;
901963
}
902964

965+
public final class kotlinx/coroutines/debug/internal/StackTraceFrame : kotlin/coroutines/jvm/internal/CoroutineStackFrame {
966+
public final field stackTraceElement Ljava/lang/StackTraceElement;
967+
public fun getCallerFrame ()Lkotlin/coroutines/jvm/internal/CoroutineStackFrame;
968+
public fun getStackTraceElement ()Ljava/lang/StackTraceElement;
969+
}
970+
903971
public abstract class kotlinx/coroutines/flow/AbstractFlow : kotlinx/coroutines/flow/CancellableFlow, kotlinx/coroutines/flow/Flow {
904972
public fun <init> ()V
905973
public final fun collect (Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@@ -1210,6 +1278,10 @@ public class kotlinx/coroutines/scheduling/ExperimentalCoroutineDispatcher : kot
12101278
public fun toString ()Ljava/lang/String;
12111279
}
12121280

1281+
public abstract class kotlinx/coroutines/scheduling/Task : java/lang/Runnable {
1282+
public field submissionTime J
1283+
}
1284+
12131285
public final class kotlinx/coroutines/selects/OnTimeoutKt {
12141286
public static final fun onTimeout (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V
12151287
public static final fun onTimeout-8Mi8wO0 (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,16 @@ private const val SUSPENDED = 1
218218
private const val RESUMED = 2
219219

220220
// Used by withContext when context dispatcher changes
221-
internal class DispatchedCoroutine<in T>(
221+
@PublishedApi
222+
internal class DispatchedCoroutine<in T> internal constructor(
222223
context: CoroutineContext,
223224
uCont: Continuation<T>
224225
) : ScopeCoroutine<T>(context, uCont) {
225226
// this is copy-and-paste of a decision state machine inside AbstractionContinuation
226227
// todo: we may some-how abstract it via inline class
227-
private val _decision = atomic(UNDECIDED)
228+
// Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102
229+
@JvmField
230+
public val _decision = atomic(UNDECIDED)
228231

229232
private fun trySuspend(): Boolean {
230233
_decision.loop { decision ->
@@ -258,7 +261,7 @@ internal class DispatchedCoroutine<in T>(
258261
uCont.intercepted().resumeCancellableWith(recoverResult(state, uCont))
259262
}
260263

261-
fun getResult(): Any? {
264+
internal fun getResult(): Any? {
262265
if (trySuspend()) return COROUTINE_SUSPENDED
263266
// otherwise, onCompletionInternal was already invoked & invoked tryResume, and the result is in the state
264267
val state = this.state.unboxState()

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

+3
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren
124124
*/
125125

126126
// Note: use shared objects while we have no listeners
127+
// Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102
127128
private val _state = atomic<Any?>(if (active) EMPTY_ACTIVE else EMPTY_NEW)
128129

129130
private val _parentHandle = atomic<ChildHandle?>(null)
@@ -1440,7 +1441,9 @@ internal class ChildHandleNode(
14401441
}
14411442

14421443
// Same as ChildHandleNode, but for cancellable continuation
1444+
@PublishedApi
14431445
internal class ChildContinuation(
1446+
// Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102
14441447
@JvmField val child: CancellableContinuationImpl<*>
14451448
) : JobCancellingNode() {
14461449
override fun invoke(cause: Throwable?) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
package kotlinx.coroutines
66

7-
internal expect abstract class SchedulerTask() : Runnable
7+
internal expect abstract class SchedulerTask internal constructor() : Runnable
88

99
internal expect interface SchedulerTaskContext
1010

kotlinx-coroutines-core/common/src/internal/DispatchedContinuation.kt

+12-10
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ private val UNDEFINED = Symbol("UNDEFINED")
1313
@JvmField
1414
internal val REUSABLE_CLAIMED = Symbol("REUSABLE_CLAIMED")
1515

16+
@PublishedApi
1617
internal class DispatchedContinuation<in T>(
17-
@JvmField val dispatcher: CoroutineDispatcher,
18+
@JvmField internal val dispatcher: CoroutineDispatcher,
19+
// Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102
1820
@JvmField val continuation: Continuation<T>
1921
) : DispatchedTask<T>(MODE_UNINITIALIZED), CoroutineStackFrame, Continuation<T> by continuation {
2022
@JvmField
@@ -58,7 +60,7 @@ internal class DispatchedContinuation<in T>(
5860
private val reusableCancellableContinuation: CancellableContinuationImpl<*>?
5961
get() = _reusableCancellableContinuation.value as? CancellableContinuationImpl<*>
6062

61-
fun isReusable(): Boolean {
63+
internal fun isReusable(): Boolean {
6264
/*
6365
Invariant: caller.resumeMode.isReusableMode
6466
* Reusability control:
@@ -72,13 +74,13 @@ internal class DispatchedContinuation<in T>(
7274
* Awaits until previous call to `suspendCancellableCoroutineReusable` will
7375
* stop mutating cached instance
7476
*/
75-
fun awaitReusability() {
77+
internal fun awaitReusability() {
7678
_reusableCancellableContinuation.loop {
7779
if (it !== REUSABLE_CLAIMED) return
7880
}
7981
}
8082

81-
fun release() {
83+
internal fun release() {
8284
/*
8385
* Called from `releaseInterceptedContinuation`, can be concurrent with
8486
* the code in `getResult` right after `trySuspend` returned `true`, so we have
@@ -93,7 +95,7 @@ internal class DispatchedContinuation<in T>(
9395
* so all cancellations will be postponed.
9496
*/
9597
@Suppress("UNCHECKED_CAST")
96-
fun claimReusableCancellableContinuation(): CancellableContinuationImpl<T>? {
98+
internal fun claimReusableCancellableContinuation(): CancellableContinuationImpl<T>? {
9799
/*
98100
* Transitions:
99101
* 1) `null` -> claimed, caller will instantiate CC instance
@@ -142,7 +144,7 @@ internal class DispatchedContinuation<in T>(
142144
*
143145
* See [CancellableContinuationImpl.getResult].
144146
*/
145-
fun tryReleaseClaimedContinuation(continuation: CancellableContinuation<*>): Throwable? {
147+
internal fun tryReleaseClaimedContinuation(continuation: CancellableContinuation<*>): Throwable? {
146148
_reusableCancellableContinuation.loop { state ->
147149
// not when(state) to avoid Intrinsics.equals call
148150
when {
@@ -162,7 +164,7 @@ internal class DispatchedContinuation<in T>(
162164
* Tries to postpone cancellation if reusable CC is currently in [REUSABLE_CLAIMED] state.
163165
* Returns `true` if cancellation is (or previously was) postponed, `false` otherwise.
164166
*/
165-
fun postponeCancellation(cause: Throwable): Boolean {
167+
internal fun postponeCancellation(cause: Throwable): Boolean {
166168
_reusableCancellableContinuation.loop { state ->
167169
when (state) {
168170
REUSABLE_CLAIMED -> {
@@ -208,7 +210,7 @@ internal class DispatchedContinuation<in T>(
208210
// We inline it to save an entry on the stack in cases where it shows (unconfined dispatcher)
209211
// It is used only in Continuation<T>.resumeCancellableWith
210212
@Suppress("NOTHING_TO_INLINE")
211-
inline fun resumeCancellableWith(
213+
internal inline fun resumeCancellableWith(
212214
result: Result<T>,
213215
noinline onCancellation: ((cause: Throwable) -> Unit)?
214216
) {
@@ -237,7 +239,7 @@ internal class DispatchedContinuation<in T>(
237239

238240
// inline here is to save us an entry on the stack for the sake of better stacktraces
239241
@Suppress("NOTHING_TO_INLINE")
240-
inline fun resumeCancelled(state: Any?): Boolean {
242+
internal inline fun resumeCancelled(state: Any?): Boolean {
241243
val job = context[Job]
242244
if (job != null && !job.isActive) {
243245
val cause = job.getCancellationException()
@@ -249,7 +251,7 @@ internal class DispatchedContinuation<in T>(
249251
}
250252

251253
@Suppress("NOTHING_TO_INLINE")
252-
inline fun resumeUndispatchedWith(result: Result<T>) {
254+
internal inline fun resumeUndispatchedWith(result: Result<T>) {
253255
withContinuationContext(continuation, countOrElement) {
254256
continuation.resumeWith(result)
255257
}

kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt

+5-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ internal const val MODE_UNINITIALIZED = -1
4747
internal val Int.isCancellableMode get() = this == MODE_CANCELLABLE || this == MODE_CANCELLABLE_REUSABLE
4848
internal val Int.isReusableMode get() = this == MODE_CANCELLABLE_REUSABLE
4949

50-
internal abstract class DispatchedTask<in T>(
50+
@PublishedApi
51+
internal abstract class DispatchedTask<in T> internal constructor(
52+
// Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102
5153
@JvmField public var resumeMode: Int
5254
) : SchedulerTask() {
5355
internal abstract val delegate: Continuation<T>
@@ -78,7 +80,7 @@ internal abstract class DispatchedTask<in T>(
7880
internal open fun getExceptionalResult(state: Any?): Throwable? =
7981
(state as? CompletedExceptionally)?.cause
8082

81-
public final override fun run() {
83+
final override fun run() {
8284
assert { resumeMode != MODE_UNINITIALIZED } // should have been set before dispatching
8385
val taskContext = this.taskContext
8486
var fatalException: Throwable? = null
@@ -134,7 +136,7 @@ internal abstract class DispatchedTask<in T>(
134136
* Fatal exception handling can be intercepted with [CoroutineExceptionHandler] element in the context of
135137
* a failed coroutine, but such exceptions should be reported anyway.
136138
*/
137-
public fun handleFatalException(exception: Throwable?, finallyException: Throwable?) {
139+
internal fun handleFatalException(exception: Throwable?, finallyException: Throwable?) {
138140
if (exception === null && finallyException === null) return
139141
if (exception !== null && finallyException !== null) {
140142
exception.addSuppressedThrowable(finallyException)

kotlinx-coroutines-core/jvm/src/CoroutineContext.kt

+3
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,12 @@ internal actual val CoroutineContext.coroutineName: String? get() {
282282
private const val DEBUG_THREAD_NAME_SEPARATOR = " @"
283283

284284
@IgnoreJreRequirement // desugared hashcode implementation
285+
@PublishedApi
285286
internal data class CoroutineId(
287+
// Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102
286288
val id: Long
287289
) : ThreadContextElement<String>, AbstractCoroutineContextElement(CoroutineId) {
290+
// Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102
288291
companion object Key : CoroutineContext.Key<CoroutineId>
289292
override fun toString(): String = "CoroutineId($id)"
290293

kotlinx-coroutines-core/jvm/src/debug/internal/DebugCoroutineInfo.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import kotlin.coroutines.jvm.internal.*
1515
*/
1616
@Suppress("unused")
1717
@PublishedApi
18-
internal class DebugCoroutineInfo(
18+
internal class DebugCoroutineInfo internal constructor(
1919
source: DebugCoroutineInfoImpl,
2020
public val context: CoroutineContext // field is used as of 1.4-M3
2121
) {
22-
public val creationStackBottom: CoroutineStackFrame? = source.creationStackBottom // field is used as of 1.4-M3
22+
internal val creationStackBottom: CoroutineStackFrame? = source.creationStackBottom // field is used as of 1.4-M3
2323
public val sequenceNumber: Long = source.sequenceNumber // field is used as of 1.4-M3
2424
public val creationStackTrace = source.creationStackTrace // getter is used as of 1.4-M3
2525
public val state: String = source.state // getter is used as of 1.4-M3

0 commit comments

Comments
 (0)