From 5fdf36790f0191ca9d480a99509c0b7b77bdf290 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Fri, 5 Apr 2024 11:51:44 +0200 Subject: [PATCH] Remove the `@PublishedApi` that are no longer needed According to @mvicsokolova, the following entry points are not used by IDEA since 2020: kotlinx.coroutines.debug.internal.StackTraceFrame field callerFrame field stackTraceElement kotlinx.coroutines.StandaloneCoroutine field _state field context kotlinx.coroutines.ChildContinuation field child kotlinx.coroutines.CancellableContinuationImpl field _decision field delegate field resumeMode field submissionTime field context kotlinx.coroutines.DispatchedContinuation field continuation This leaves only the following *internal* entry points: kotlinx.coroutines.debug.internal.DebugCoroutineInfo method getCreationStackTrace() method getState() method lastObservedStackTrace() field context field sequenceNumber field lastObservedFrame field lastObservedThread kotlinx.coroutines.debug.internal.DebugCoroutineInfoImpl method getCreationStackTrace() method getContext() field lastObservedThread field _state field _lastObservedFrame field sequenceNumber kotlinx.coroutines.debug.internal.DebugProbesImpl field INSTANCE method isInstalled$kotlinx_coroutines_debug() method isInstalled$kotlinx_coroutines_core() method enhanceStackTraceWithThreadDump() method dumpCoroutinesInfo() method dumpCoroutinesInfoAsJsonAndReferences() method enhanceStackTraceWithThreadDumpAsJson() kotlinx.coroutines.debug.internal.DebugProbesImpl$CoroutineOwner field info kotlinx.coroutines.CoroutineId field Key method getId() ... the following *public* entry points: kotlinx.coroutines.CoroutineName field Key method getName() kotlinx.coroutines.Job field Key kotlinx.coroutines.CoroutineDispatcher field Key ... and these entry points outside of the library: kotlin.coroutines.CombinedContext method get() kotlin.coroutines.jvm.internal.DebugMetadataKt method getStackTraceElement() method getSpilledVariableFieldMapping() This commit updates the comments and removes the extraneous `@PublishedApi` annotations, giving us more flexibility to change code. --- .../api/kotlinx-coroutines-core.api | 27 +------------------ .../common/src/Builders.common.kt | 7 ++--- .../common/src/CancellableContinuationImpl.kt | 9 +++++++ .../common/src/JobSupport.kt | 15 +---------- .../src/internal/DispatchedContinuation.kt | 2 -- .../common/src/internal/DispatchedTask.kt | 4 +-- .../debug/internal/DebugCoroutineInfoImpl.kt | 2 ++ .../jvm/src/debug/internal/StackTraceFrame.kt | 6 ++--- .../jvm/src/scheduling/Tasks.kt | 7 ++--- .../ReusableCancellableContinuationTest.kt | 5 +++- 10 files changed, 24 insertions(+), 60 deletions(-) diff --git a/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api b/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api index 2674d739c7..3e91bad57c 100644 --- a/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api +++ b/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api @@ -51,7 +51,7 @@ public final class kotlinx/coroutines/CancellableContinuation$DefaultImpls { public static synthetic fun tryResume$default (Lkotlinx/coroutines/CancellableContinuation;Ljava/lang/Object;Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object; } -public class kotlinx/coroutines/CancellableContinuationImpl : kotlinx/coroutines/DispatchedTask, kotlin/coroutines/jvm/internal/CoroutineStackFrame, kotlinx/coroutines/CancellableContinuation, kotlinx/coroutines/Waiter { +public class kotlinx/coroutines/CancellableContinuationImpl : kotlin/coroutines/jvm/internal/CoroutineStackFrame, kotlinx/coroutines/CancellableContinuation, kotlinx/coroutines/Waiter { public fun (Lkotlin/coroutines/Continuation;I)V public final fun callCancelHandler (Lkotlinx/coroutines/CancelHandler;Ljava/lang/Throwable;)V public final fun callOnCancellation (Lkotlin/jvm/functions/Function1;Ljava/lang/Throwable;)V @@ -84,12 +84,6 @@ public final class kotlinx/coroutines/CancellableContinuationKt { public static final fun suspendCancellableCoroutine (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public final class kotlinx/coroutines/ChildContinuation { - public final field child Lkotlinx/coroutines/CancellableContinuationImpl; - public fun (Lkotlinx/coroutines/CancellableContinuationImpl;)V - public fun invoke (Ljava/lang/Throwable;)V -} - public abstract interface class kotlinx/coroutines/ChildHandle : kotlinx/coroutines/DisposableHandle { public abstract fun childCancelled (Ljava/lang/Throwable;)Z public abstract fun getParent ()Lkotlinx/coroutines/Job; @@ -318,15 +312,6 @@ public final class kotlinx/coroutines/DelayKt { public abstract interface annotation class kotlinx/coroutines/DelicateCoroutinesApi : java/lang/annotation/Annotation { } -public final class kotlinx/coroutines/DispatchedCoroutine { - public static final synthetic fun get_decision$volatile$FU$kotlinx_coroutines_core ()Ljava/util/concurrent/atomic/AtomicIntegerFieldUpdater; -} - -public abstract class kotlinx/coroutines/DispatchedTask : kotlinx/coroutines/scheduling/Task { - public field resumeMode I - public final fun run ()V -} - public final class kotlinx/coroutines/DispatchedTaskKt { public static final field MODE_CANCELLABLE I } @@ -970,12 +955,6 @@ public final class kotlinx/coroutines/debug/internal/DebuggerInfo : java/io/Seri public final fun getState ()Ljava/lang/String; } -public final class kotlinx/coroutines/debug/internal/StackTraceFrame : kotlin/coroutines/jvm/internal/CoroutineStackFrame { - public final field stackTraceElement Ljava/lang/StackTraceElement; - public fun getCallerFrame ()Lkotlin/coroutines/jvm/internal/CoroutineStackFrame; - public fun getStackTraceElement ()Ljava/lang/StackTraceElement; -} - public abstract class kotlinx/coroutines/flow/AbstractFlow : kotlinx/coroutines/flow/CancellableFlow, kotlinx/coroutines/flow/Flow { public fun ()V public final fun collect (Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -1287,10 +1266,6 @@ public class kotlinx/coroutines/scheduling/ExperimentalCoroutineDispatcher : kot public fun toString ()Ljava/lang/String; } -public abstract class kotlinx/coroutines/scheduling/Task : java/lang/Runnable { - public field submissionTime J -} - public final class kotlinx/coroutines/selects/OnTimeoutKt { public static final fun onTimeout (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V public static final fun onTimeout-8Mi8wO0 (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V diff --git a/kotlinx-coroutines-core/common/src/Builders.common.kt b/kotlinx-coroutines-core/common/src/Builders.common.kt index 95c1be8a8c..2caf982799 100644 --- a/kotlinx-coroutines-core/common/src/Builders.common.kt +++ b/kotlinx-coroutines-core/common/src/Builders.common.kt @@ -214,16 +214,13 @@ private const val SUSPENDED = 1 private const val RESUMED = 2 // Used by withContext when context dispatcher changes -@PublishedApi -internal class DispatchedCoroutine internal constructor( +internal class DispatchedCoroutine( context: CoroutineContext, uCont: Continuation ) : ScopeCoroutine(context, uCont) { // this is copy-and-paste of a decision state machine inside AbstractionContinuation // todo: we may some-how abstract it via inline class - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 - @JvmField - public val _decision = atomic(UNDECIDED) + private val _decision = atomic(UNDECIDED) private fun trySuspend(): Boolean { _decision.loop { decision -> diff --git a/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt b/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt index b7c6111303..10f62d598c 100644 --- a/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt +++ b/kotlinx-coroutines-core/common/src/CancellableContinuationImpl.kt @@ -678,3 +678,12 @@ private data class CompletedContinuation( onCancellation?.let { cont.callOnCancellation(it, cause) } } } + +// Same as ChildHandleNode, but for cancellable continuation +private class ChildContinuation( + @JvmField val child: CancellableContinuationImpl<*> +) : JobCancellingNode() { + override fun invoke(cause: Throwable?) { + child.parentCancelled(child.getContinuationCancellationCause(job)) + } +} diff --git a/kotlinx-coroutines-core/common/src/JobSupport.kt b/kotlinx-coroutines-core/common/src/JobSupport.kt index a4a5a2957c..fa9235d251 100644 --- a/kotlinx-coroutines-core/common/src/JobSupport.kt +++ b/kotlinx-coroutines-core/common/src/JobSupport.kt @@ -121,7 +121,6 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren */ // Note: use shared objects while we have no listeners - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 private val _state = atomic(if (active) EMPTY_ACTIVE else EMPTY_NEW) private val _parentHandle = atomic(null) @@ -1439,22 +1438,10 @@ private class InvokeOnCancelling( } } -internal class ChildHandleNode( +private class ChildHandleNode( @JvmField val childJob: ChildJob ) : JobCancellingNode(), ChildHandle { override val parent: Job get() = job override fun invoke(cause: Throwable?) = childJob.parentCancelled(job) override fun childCancelled(cause: Throwable): Boolean = job.childCancelled(cause) } - -// Same as ChildHandleNode, but for cancellable continuation -@PublishedApi -internal class ChildContinuation( - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 - @JvmField val child: CancellableContinuationImpl<*> -) : JobCancellingNode() { - override fun invoke(cause: Throwable?) { - child.parentCancelled(child.getContinuationCancellationCause(job)) - } -} - diff --git a/kotlinx-coroutines-core/common/src/internal/DispatchedContinuation.kt b/kotlinx-coroutines-core/common/src/internal/DispatchedContinuation.kt index e21f1ed456..9c0c0b08c0 100644 --- a/kotlinx-coroutines-core/common/src/internal/DispatchedContinuation.kt +++ b/kotlinx-coroutines-core/common/src/internal/DispatchedContinuation.kt @@ -9,10 +9,8 @@ private val UNDEFINED = Symbol("UNDEFINED") @JvmField internal val REUSABLE_CLAIMED = Symbol("REUSABLE_CLAIMED") -@PublishedApi internal class DispatchedContinuation( @JvmField internal val dispatcher: CoroutineDispatcher, - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 @JvmField val continuation: Continuation ) : DispatchedTask(MODE_UNINITIALIZED), CoroutineStackFrame, Continuation by continuation { @JvmField diff --git a/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt b/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt index 5a38d0de9e..e892cd9743 100644 --- a/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt +++ b/kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt @@ -43,10 +43,8 @@ internal const val MODE_UNINITIALIZED = -1 internal val Int.isCancellableMode get() = this == MODE_CANCELLABLE || this == MODE_CANCELLABLE_REUSABLE internal val Int.isReusableMode get() = this == MODE_CANCELLABLE_REUSABLE -@PublishedApi internal abstract class DispatchedTask internal constructor( - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 - @JvmField public var resumeMode: Int + @JvmField var resumeMode: Int ) : SchedulerTask() { internal abstract val delegate: Continuation diff --git a/kotlinx-coroutines-core/jvm/src/debug/internal/DebugCoroutineInfoImpl.kt b/kotlinx-coroutines-core/jvm/src/debug/internal/DebugCoroutineInfoImpl.kt index 66bb904f0a..47d69363c8 100644 --- a/kotlinx-coroutines-core/jvm/src/debug/internal/DebugCoroutineInfoImpl.kt +++ b/kotlinx-coroutines-core/jvm/src/debug/internal/DebugCoroutineInfoImpl.kt @@ -30,8 +30,10 @@ internal class DebugCoroutineInfoImpl internal constructor( */ private val _context = WeakReference(context) public val context: CoroutineContext? // can be null when the coroutine was already garbage-collected + // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 get() = _context.get() + // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 public val creationStackTrace: List get() = creationStackTrace() /** diff --git a/kotlinx-coroutines-core/jvm/src/debug/internal/StackTraceFrame.kt b/kotlinx-coroutines-core/jvm/src/debug/internal/StackTraceFrame.kt index d78054592a..5ab67dcaee 100644 --- a/kotlinx-coroutines-core/jvm/src/debug/internal/StackTraceFrame.kt +++ b/kotlinx-coroutines-core/jvm/src/debug/internal/StackTraceFrame.kt @@ -5,11 +5,9 @@ import kotlin.coroutines.jvm.internal.* /** * A stack-trace represented as [CoroutineStackFrame]. */ -@PublishedApi -internal class StackTraceFrame internal constructor( +internal class StackTraceFrame( override val callerFrame: CoroutineStackFrame?, - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 - @JvmField public val stackTraceElement: StackTraceElement + private val stackTraceElement: StackTraceElement ) : CoroutineStackFrame { override fun getStackTraceElement(): StackTraceElement = stackTraceElement } diff --git a/kotlinx-coroutines-core/jvm/src/scheduling/Tasks.kt b/kotlinx-coroutines-core/jvm/src/scheduling/Tasks.kt index eefccd514a..b82d31b445 100644 --- a/kotlinx-coroutines-core/jvm/src/scheduling/Tasks.kt +++ b/kotlinx-coroutines-core/jvm/src/scheduling/Tasks.kt @@ -75,12 +75,9 @@ internal val NonBlockingContext: TaskContext = TaskContextImpl(TASK_NON_BLOCKING @JvmField internal val BlockingContext: TaskContext = TaskContextImpl(TASK_PROBABLY_BLOCKING) -@PublishedApi -internal abstract class Task internal constructor( - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 +internal abstract class Task( @JvmField var submissionTime: Long, - // Used by the IDEA debugger via reflection and must be kept binary-compatible, see KTIJ-24102 - @JvmField internal var taskContext: TaskContext + @JvmField var taskContext: TaskContext ) : Runnable { internal constructor() : this(0, NonBlockingContext) internal inline val mode: Int get() = taskContext.taskMode // TASK_XXX diff --git a/kotlinx-coroutines-core/jvm/test/ReusableCancellableContinuationTest.kt b/kotlinx-coroutines-core/jvm/test/ReusableCancellableContinuationTest.kt index d9f455a964..5e88521f79 100644 --- a/kotlinx-coroutines-core/jvm/test/ReusableCancellableContinuationTest.kt +++ b/kotlinx-coroutines-core/jvm/test/ReusableCancellableContinuationTest.kt @@ -210,6 +210,9 @@ class ReusableCancellableContinuationTest : TestBase() { for (value in channel) { delay(1) } - FieldWalker.assertReachableCount(1, coroutineContext[Job]) { it is ChildContinuation } + FieldWalker.assertReachableCount(1, coroutineContext[Job]) { + // could be `it is ChildContinuation` if `ChildContinuation` wasn't private + it::class.simpleName == "ChildContinuation" + } } }