Skip to content

Commit

Permalink
Consistent toString for MainCoroutineDispatcher implementations
Browse files Browse the repository at this point in the history
So that is shows as "Dispatchers.Main" and "Dispatchers.Main.immediate"
  • Loading branch information
elizarov committed Jul 10, 2020
1 parent 5183b62 commit df3dce9
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 9 deletions.
2 changes: 2 additions & 0 deletions kotlinx-coroutines-core/api/kotlinx-coroutines-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ public class kotlinx/coroutines/JobSupport : kotlinx/coroutines/ChildJob, kotlin
public abstract class kotlinx/coroutines/MainCoroutineDispatcher : kotlinx/coroutines/CoroutineDispatcher {
public fun <init> ()V
public abstract fun getImmediate ()Lkotlinx/coroutines/MainCoroutineDispatcher;
public fun toString ()Ljava/lang/String;
protected final fun toStringInternalImpl ()Ljava/lang/String;
}

public final class kotlinx/coroutines/NonCancellable : kotlin/coroutines/AbstractCoroutineContextElement, kotlinx/coroutines/Job {
Expand Down
23 changes: 23 additions & 0 deletions kotlinx-coroutines-core/common/src/MainCoroutineDispatcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,27 @@ public abstract class MainCoroutineDispatcher : CoroutineDispatcher() {
* [Dispatchers.Main] supports immediate execution for Android, JavaFx and Swing platforms.
*/
public abstract val immediate: MainCoroutineDispatcher

/**
* Returns a name of this main dispatcher for debugging purposes. This implementation returns
* `Dispatchers.Main` or `Dispatchers.Main.immediate` if it is the same as the corresponding
* reference in [Dispatchers] or a short class-name representation with address otherwise.
*/
override fun toString(): String = toStringInternalImpl() ?: "$classSimpleName@$hexAddress"

/**
* Internal method for more specific [toString] implementations. It returns non-null
* string if this dispatcher is set in the platform as the main one.
* @suppress
*/
@InternalCoroutinesApi
protected fun toStringInternalImpl(): String? {
val main = Dispatchers.Main
if (this === main) return "Dispatchers.Main"
val immediate =
try { main.immediate }
catch (e: UnsupportedOperationException) { null }
if (this === immediate) return "Dispatchers.Main.immediate"
return null
}
}
2 changes: 1 addition & 1 deletion kotlinx-coroutines-core/js/src/Dispatchers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ private class JsMainDispatcher(val delegate: CoroutineDispatcher) : MainCoroutin

override fun dispatchYield(context: CoroutineContext, block: Runnable) = delegate.dispatchYield(context, block)

override fun toString(): String = delegate.toString()
override fun toString(): String = toStringInternalImpl() ?: delegate.toString()
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private class MissingMainCoroutineDispatcher(
}
}

override fun toString(): String = "Main[missing${if (cause != null) ", cause=$cause" else ""}]"
override fun toString(): String = "Dispatchers.Main[missing${if (cause != null) ", cause=$cause" else ""}]"
}

/**
Expand Down
18 changes: 18 additions & 0 deletions kotlinx-coroutines-core/jvm/test/DispatchersToStringTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.coroutines

import kotlin.test.*

class DispatchersToStringTest {
@Test
fun testStrings() {
assertEquals("Dispatchers.Unconfined", Dispatchers.Unconfined.toString())
assertEquals("Dispatchers.Default", Dispatchers.Default.toString())
assertEquals("Dispatchers.IO", Dispatchers.IO.toString())
assertEquals("Dispatchers.Main[missing]", Dispatchers.Main.toString())
assertEquals("Dispatchers.Main[missing]", Dispatchers.Main.immediate.toString())
}
}
2 changes: 1 addition & 1 deletion kotlinx-coroutines-core/native/src/Dispatchers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ private class NativeMainDispatcher(val delegate: CoroutineDispatcher) : MainCoro

override fun dispatchYield(context: CoroutineContext, block: Runnable) = delegate.dispatchYield(context, block)

override fun toString(): String = delegate.toString()
override fun toString(): String = toStringInternalImpl() ?: delegate.toString()
}
5 changes: 3 additions & 2 deletions ui/kotlinx-coroutines-android/src/HandlerDispatcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,13 @@ internal class HandlerContext private constructor(
}
}

override fun toString(): String =
override fun toString(): String = toStringInternalImpl() ?: run {
if (name != null) {
if (invokeImmediately) "$name [immediate]" else name
if (invokeImmediately) "$name.immediate" else name
} else {
handler.toString()
}
}

override fun equals(other: Any?): Boolean = other is HandlerContext && other.handler === handler
override fun hashCode(): Int = System.identityHashCode(handler)
Expand Down
6 changes: 6 additions & 0 deletions ui/kotlinx-coroutines-android/test/HandlerDispatcherTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,10 @@ class HandlerDispatcherTest : TestBase() {
yield() // yield back
finish(5)
}

@Test
fun testMainDispatcherToString() {
assertEquals("Dispatchers.Main", Dispatchers.Main.toString())
assertEquals("Dispatchers.Main.immediate", Dispatchers.Main.immediate.toString())
}
}
4 changes: 2 additions & 2 deletions ui/kotlinx-coroutines-javafx/src/JavaFxDispatcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private object ImmediateJavaFxDispatcher : JavaFxDispatcher() {

override fun isDispatchNeeded(context: CoroutineContext): Boolean = !Platform.isFxApplicationThread()

override fun toString() = "JavaFx [immediate]"
override fun toString() = toStringInternalImpl() ?: "JavaFx.immediate"
}

/**
Expand All @@ -85,7 +85,7 @@ internal object JavaFx : JavaFxDispatcher() {
override val immediate: MainCoroutineDispatcher
get() = ImmediateJavaFxDispatcher

override fun toString() = "JavaFx"
override fun toString() = toStringInternalImpl() ?: "JavaFx"
}

private val pulseTimer by lazy {
Expand Down
8 changes: 8 additions & 0 deletions ui/kotlinx-coroutines-javafx/test/JavaFxDispatcherTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package kotlinx.coroutines.javafx
import javafx.application.*
import kotlinx.coroutines.*
import org.junit.*
import org.junit.Test
import kotlin.test.*

class JavaFxDispatcherTest : TestBase() {
@Before
Expand Down Expand Up @@ -56,4 +58,10 @@ class JavaFxDispatcherTest : TestBase() {
finish(5)
}
}

@Test
fun testMainDispatcherToString() {
assertEquals("Dispatchers.Main", Dispatchers.Main.toString())
assertEquals("Dispatchers.Main.immediate", Dispatchers.Main.immediate.toString())
}
}
4 changes: 2 additions & 2 deletions ui/kotlinx-coroutines-swing/src/SwingDispatcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private object ImmediateSwingDispatcher : SwingDispatcher() {

override fun isDispatchNeeded(context: CoroutineContext): Boolean = !SwingUtilities.isEventDispatchThread()

override fun toString() = "Swing [immediate]"
override fun toString() = toStringInternalImpl() ?: "Swing.immediate"
}

/**
Expand All @@ -77,5 +77,5 @@ internal object Swing : SwingDispatcher() {
override val immediate: MainCoroutineDispatcher
get() = ImmediateSwingDispatcher

override fun toString() = "Swing"
override fun toString() = toStringInternalImpl() ?: "Swing"
}
6 changes: 6 additions & 0 deletions ui/kotlinx-coroutines-swing/test/SwingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,10 @@ class SwingTest : TestBase() {
yield() // yield back
finish(5)
}

@Test
fun testMainDispatcherToString() {
assertEquals("Dispatchers.Main", Dispatchers.Main.toString())
assertEquals("Dispatchers.Main.immediate", Dispatchers.Main.immediate.toString())
}
}

0 comments on commit df3dce9

Please sign in to comment.