Skip to content

Update to Kotlin 2.0-RC3 #4129

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

Merged
merged 2 commits into from
May 16, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Kotlin
version=1.8.1-SNAPSHOT
group=org.jetbrains.kotlinx
kotlin_version=1.9.21
kotlin_version=2.0.0-RC3
kotlin_language_version=2.0
# DO NOT rename this property without adapting kotlinx.train build chain:
atomicfu_version=0.23.2

Expand Down
2 changes: 1 addition & 1 deletion integration-testing/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlin_version=1.9.21
kotlin_version=2.0.0-RC3
coroutines_version=1.8.1-SNAPSHOT
asm_version=9.3

Expand Down
158 changes: 79 additions & 79 deletions kotlinx-coroutines-core/api/kotlinx-coroutines-core.klib.api

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions kotlinx-coroutines-core/common/src/internal/Concurrent.common.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ internal expect fun <E> identitySet(expectedSize: Int): MutableSet<E>
internal expect annotation class BenignDataRace()

// Used **only** as a workaround for #3820 in StateFlow. Do not use anywhere else
internal expect class WorkaroundAtomicReference<T>(value: T) {
public fun get(): T
public fun set(value: T)
public fun getAndSet(value: T): T
public fun compareAndSet(expected: T, value: T): Boolean
internal expect class WorkaroundAtomicReference<V>(value: V) {
public fun get(): V
public fun set(value: V)
public fun getAndSet(value: V): V
public fun compareAndSet(expected: V, value: V): Boolean
}

@Suppress("UNUSED_PARAMETER", "EXTENSION_SHADOWED_BY_MEMBER")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ internal class NoOpLock {

internal actual fun <E> identitySet(expectedSize: Int): MutableSet<E> = HashSet(expectedSize)

internal actual class WorkaroundAtomicReference<T> actual constructor(private var value: T) {
internal actual class WorkaroundAtomicReference<V> actual constructor(private var value: V) {

public actual fun get(): T = value
public actual fun get(): V = value

public actual fun set(value: T) {
public actual fun set(value: V) {
this.value = value
}

public actual fun getAndSet(value: T): T {
public actual fun getAndSet(value: V): V {
val prev = this.value
this.value = value
return prev
}

public actual fun compareAndSet(expected: T, value: T): Boolean {
public actual fun compareAndSet(expected: V, value: V): Boolean {
if (this.value === expected) {
this.value = value
return true
Expand Down
Binary file modified kotlinx-coroutines-core/jvm/resources/DebugProbesKt.bin
Binary file not shown.
12 changes: 6 additions & 6 deletions kotlinx-coroutines-core/native/src/internal/Concurrent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ internal actual fun <E> identitySet(expectedSize: Int): MutableSet<E> = HashSet(
@Suppress("ACTUAL_WITHOUT_EXPECT") // This suppress can be removed in 2.0: KT-59355
internal actual typealias BenignDataRace = kotlin.concurrent.Volatile

internal actual class WorkaroundAtomicReference<T> actual constructor(value: T) {
internal actual class WorkaroundAtomicReference<V> actual constructor(value: V) {

private val nativeAtomic = kotlin.concurrent.AtomicReference<T>(value)
private val nativeAtomic = kotlin.concurrent.AtomicReference<V>(value)

public actual fun get(): T = nativeAtomic.value
public actual fun get(): V= nativeAtomic.value

public actual fun set(value: T) {
public actual fun set(value: V) {
nativeAtomic.value = value
}

public actual fun getAndSet(value: T): T = nativeAtomic.getAndSet(value)
public actual fun getAndSet(value: V): V = nativeAtomic.getAndSet(value)

public actual fun compareAndSet(expected: T, value: T): Boolean = nativeAtomic.compareAndSet(expected, value)
public actual fun compareAndSet(expected: V, value: V): Boolean = nativeAtomic.compareAndSet(expected, value)
}
56 changes: 29 additions & 27 deletions kotlinx-coroutines-test/api/kotlinx-coroutines-test.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/advanceUnt
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runCurrent() // kotlinx.coroutines.test/runCurrent|[email protected](){}[0]
final fun (kotlinx.coroutines/Dispatchers).kotlinx.coroutines.test/resetMain() // kotlinx.coroutines.test/resetMain|[email protected](){}[0]
final fun (kotlinx.coroutines/Dispatchers).kotlinx.coroutines.test/setMain(kotlinx.coroutines/CoroutineDispatcher) // kotlinx.coroutines.test/setMain|[email protected](kotlinx.coroutines.CoroutineDispatcher){}[0]
final fun kotlinx.coroutines.test/StandardTestDispatcher(kotlinx.coroutines.test/TestCoroutineScheduler? =..., kotlin/String? =...): kotlinx.coroutines.test/TestDispatcher // kotlinx.coroutines.test/StandardTestDispatcher|StandardTestDispatcher(kotlinx.coroutines.test.TestCoroutineScheduler?;kotlin.String?){}[0]
final fun kotlinx.coroutines.test/TestScope(kotlin.coroutines/CoroutineContext =...): kotlinx.coroutines.test/TestScope // kotlinx.coroutines.test/TestScope|TestScope(kotlin.coroutines.CoroutineContext){}[0]
final fun kotlinx.coroutines.test/UnconfinedTestDispatcher(kotlinx.coroutines.test/TestCoroutineScheduler? =..., kotlin/String? =...): kotlinx.coroutines.test/TestDispatcher // kotlinx.coroutines.test/UnconfinedTestDispatcher|UnconfinedTestDispatcher(kotlinx.coroutines.test.TestCoroutineScheduler?;kotlin.String?){}[0]
final fun kotlinx.coroutines.test/StandardTestDispatcher(kotlinx.coroutines.test/TestCoroutineScheduler? = ..., kotlin/String? = ...): kotlinx.coroutines.test/TestDispatcher // kotlinx.coroutines.test/StandardTestDispatcher|StandardTestDispatcher(kotlinx.coroutines.test.TestCoroutineScheduler?;kotlin.String?){}[0]
final fun kotlinx.coroutines.test/TestScope(kotlin.coroutines/CoroutineContext = ...): kotlinx.coroutines.test/TestScope // kotlinx.coroutines.test/TestScope|TestScope(kotlin.coroutines.CoroutineContext){}[0]
final fun kotlinx.coroutines.test/UnconfinedTestDispatcher(kotlinx.coroutines.test/TestCoroutineScheduler? = ..., kotlin/String? = ...): kotlinx.coroutines.test/TestDispatcher // kotlinx.coroutines.test/UnconfinedTestDispatcher|UnconfinedTestDispatcher(kotlinx.coroutines.test.TestCoroutineScheduler?;kotlin.String?){}[0]
final val kotlinx.coroutines.test/currentTime // kotlinx.coroutines.test/currentTime|@kotlinx.coroutines.test.TestScope{}currentTime[0]
final fun (kotlinx.coroutines.test/TestScope).<get-currentTime>(): kotlin/Long // kotlinx.coroutines.test/currentTime.<get-currentTime>|<get-currentTime>@kotlinx.coroutines.test.TestScope(){}[0]
final val kotlinx.coroutines.test/testTimeSource // kotlinx.coroutines.test/testTimeSource|@kotlinx.coroutines.test.TestScope{}testTimeSource[0]
final fun (kotlinx.coroutines.test/TestScope).<get-testTimeSource>(): kotlin.time/TimeSource.WithComparableMarks // kotlinx.coroutines.test/testTimeSource.<get-testTimeSource>|<get-testTimeSource>@kotlinx.coroutines.test.TestScope(){}[0]
final var kotlinx.coroutines.test/catchNonTestRelatedExceptions // kotlinx.coroutines.test/catchNonTestRelatedExceptions|<get-catchNonTestRelatedExceptions>(){}[0]
final var kotlinx.coroutines.test/catchNonTestRelatedExceptions // kotlinx.coroutines.test/catchNonTestRelatedExceptions|{}catchNonTestRelatedExceptions[0]
final fun <get-catchNonTestRelatedExceptions>(): kotlin/Boolean // kotlinx.coroutines.test/catchNonTestRelatedExceptions.<get-catchNonTestRelatedExceptions>|<get-catchNonTestRelatedExceptions>(){}[0]
final fun <set-catchNonTestRelatedExceptions>(kotlin/Boolean) // kotlinx.coroutines.test/catchNonTestRelatedExceptions.<set-catchNonTestRelatedExceptions>|<set-catchNonTestRelatedExceptions>(kotlin.Boolean){}[0]
sealed interface kotlinx.coroutines.test/TestScope : kotlinx.coroutines/CoroutineScope { // kotlinx.coroutines.test/TestScope|null[0]
Expand All @@ -49,32 +49,34 @@ sealed interface kotlinx.coroutines.test/TestScope : kotlinx.coroutines/Coroutin
abstract fun <get-testScheduler>(): kotlinx.coroutines.test/TestCoroutineScheduler // kotlinx.coroutines.test/TestScope.testScheduler.<get-testScheduler>|<get-testScheduler>(){}[0]
}
// Targets: [native]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin.time/Duration =..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>) // kotlinx.coroutines.test/runTest|[email protected](kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin.time/Duration = ..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>) // kotlinx.coroutines.test/runTest|[email protected](kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [native]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>) // kotlinx.coroutines.test/runTest|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [native]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTestLegacy(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>, kotlin/Int, kotlin/Any?) // kotlinx.coroutines.test/runTestLegacy|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>;kotlin.Int;kotlin.Any?){}[0]
// Targets: [native]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext =..., kotlin.time/Duration =..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>) // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext = ..., kotlin.time/Duration = ..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>) // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [native]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext =..., kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>) // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin.time/Duration =..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin/Unit> // kotlinx.coroutines.test/runTest|[email protected](kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin/Unit> // kotlinx.coroutines.test/runTest|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTestLegacy(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>, kotlin/Int, kotlin/Any?): kotlin.js/Promise<kotlin/Unit> // kotlinx.coroutines.test/runTestLegacy|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>;kotlin.Int;kotlin.Any?){}[0]
// Targets: [js]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext =..., kotlin.time/Duration =..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin/Unit> // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext =..., kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin/Unit> // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [wasmJs]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin.time/Duration =..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin.js/JsAny?> // kotlinx.coroutines.test/runTest|[email protected](kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [wasmJs]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin.js/JsAny?> // kotlinx.coroutines.test/runTest|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [wasmJs]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTestLegacy(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>, kotlin/Int, kotlin/Any?): kotlin.js/Promise<kotlin.js/JsAny?> // kotlinx.coroutines.test/runTestLegacy|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>;kotlin.Int;kotlin.Any?){}[0]
// Targets: [wasmJs]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext =..., kotlin.time/Duration =..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin.js/JsAny?> // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [wasmJs]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext =..., kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlin.js/Promise<kotlin.js/JsAny?> // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext = ..., kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>) // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js, wasmJs]
final class kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting { // kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting|null[0]
constructor <init>() // kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting.<init>|<init>(){}[0]
// Targets: [js]
final fun then(kotlin/Function1<kotlin/Unit, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting.then|then(kotlin.Function1<kotlin.Unit,kotlin.Unit>){}[0]
// Targets: [js]
final fun then(kotlin/Function1<kotlin/Unit, kotlin/Unit>, kotlin/Function1<kotlin/Throwable, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting.then|then(kotlin.Function1<kotlin.Unit,kotlin.Unit>;kotlin.Function1<kotlin.Throwable,kotlin.Unit>){}[0]
// Targets: [wasmJs]
final fun then(kotlin/Function1<kotlin.js/JsAny, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting.then|then(kotlin.Function1<kotlin.js.JsAny,kotlin.Unit>){}[0]
// Targets: [wasmJs]
final fun then(kotlin/Function1<kotlin.js/JsAny, kotlin/Unit>, kotlin/Function1<kotlin.js/JsAny, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting.then|then(kotlin.Function1<kotlin.js.JsAny,kotlin.Unit>;kotlin.Function1<kotlin.js.JsAny,kotlin.Unit>){}[0]
}
// Targets: [js, wasmJs]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin.time/Duration = ..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test/runTest|[email protected](kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js, wasmJs]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTest(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test/runTest|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js, wasmJs]
final fun (kotlinx.coroutines.test/TestScope).kotlinx.coroutines.test/runTestLegacy(kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>, kotlin/Int, kotlin/Any?): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test/runTestLegacy|[email protected](kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>;kotlin.Int;kotlin.Any?){}[0]
// Targets: [js, wasmJs]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext = ..., kotlin.time/Duration = ..., kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.time.Duration;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
// Targets: [js, wasmJs]
final fun kotlinx.coroutines.test/runTest(kotlin.coroutines/CoroutineContext = ..., kotlin/Long, kotlin.coroutines/SuspendFunction1<kotlinx.coroutines.test/TestScope, kotlin/Unit>): kotlinx.coroutines.test.internal/JsPromiseInterfaceForTesting // kotlinx.coroutines.test/runTest|runTest(kotlin.coroutines.CoroutineContext;kotlin.Long;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.test.TestScope,kotlin.Unit>){}[0]
12 changes: 7 additions & 5 deletions kotlinx-coroutines-test/js/src/TestBuilders.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package kotlinx.coroutines.test

import kotlinx.coroutines.*
import kotlin.js.*
import kotlinx.coroutines.test.internal.*

@Suppress("ACTUAL_WITHOUT_EXPECT", "ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE")
public actual typealias TestResult = Promise<Unit>
public actual typealias TestResult = JsPromiseInterfaceForTesting

internal actual fun systemPropertyImpl(name: String): String? = null

@Suppress("CAST_NEVER_SUCCEEDS")
internal actual fun createTestResult(testProcedure: suspend CoroutineScope.() -> Unit): TestResult =
GlobalScope.promise {
testProcedure()
}
} as JsPromiseInterfaceForTesting

internal actual fun dumpCoroutines() { }

internal actual fun systemPropertyImpl(name: String): String? = null
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kotlinx.coroutines.test.internal

/* This is a declaration of JS's `Promise<Unit>`. We need to keep it a separate class, because
Copy link

Choose a reason for hiding this comment

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

Worth linking to https://youtrack.jetbrains.com/issue/KT-60561 ?

I just hope it gets fixed soon tbh, this workaround means everyone is going to have their own promise types, a mess.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Huh? Is everyone really creating their own Promise types? The TestResult class has a very specific and technical purpose: to let Kotlin know that it should handle the values returned from @Test fun on JS in a specific manner. Do many other codebases maintain their own test frameworks instead of using kotlinx-coroutines-test?

Copy link

Choose a reason for hiding this comment

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

Well it's not really just for testing. I have some typealiases to Promise<T> in my KMP project and I can work with them in K1. In K2 I have to remove the typealias or have to create an intermediate class, just like JsPromiseInterfaceForTesting.

Copy link
Collaborator

Choose a reason for hiding this comment

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

typealias Future<T> = Promise<T> should still work. Is your use case covered by it?

Copy link

@lppedd lppedd May 14, 2024

Choose a reason for hiding this comment

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

It works because you have the type parameter in Future, but something like typealias HostValue = Promise<Int> won't work. This plus KT-61043 makes working with typealiases a lot more cumbersome.

`actual typealias TestResult = Promise<Unit>` fails: you can't instantiate an `expect class` with a typealias to
a parametric class. So, we make a non-parametric class just for this. */
/**
* @suppress
*/
@JsName("Promise")
public external class JsPromiseInterfaceForTesting {
/**
* @suppress
*/
public fun then(onFulfilled: ((Unit) -> Unit), onRejected: ((Throwable) -> Unit)): JsPromiseInterfaceForTesting
/**
* @suppress
*/
public fun then(onFulfilled: ((Unit) -> Unit)): JsPromiseInterfaceForTesting
}
Loading