Skip to content

Commit 0d98f08

Browse files
committed
AMEND Create intermediate js-wasm sourceSet
1 parent 76faca7 commit 0d98f08

14 files changed

+154
-62
lines changed

build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ configure(subprojects.findAll { !sourceless.contains(it.name) && it.name != core
161161
apply from: rootProject.file("gradle/compile-native-multiplatform.gradle")
162162
}
163163

164+
apply from: rootProject.file("gradle/compile-jsAndWasmShared-multiplatform.gradle")
165+
164166
apply from: rootProject.file("gradle/compile-js-multiplatform.gradle")
165167

166168
apply from: rootProject.file("gradle/compile-wasm-multiplatform.gradle")

gradle/compile-js-multiplatform.gradle

+3-6
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@ kotlin {
1313

1414
sourceSets {
1515
jsMain {
16-
kotlin {
17-
srcDir 'jsAndWasmShared/src'
18-
}
16+
dependsOn(jsAndWasmSharedMain)
1917
}
2018
jsTest {
21-
kotlin {
22-
srcDir 'jsAndWasmShared/test'
23-
}
19+
dependsOn(jsAndWasmSharedTest)
2420
}
21+
2522
jsTest.dependencies {
2623
api "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version"
2724
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
kotlin {
6+
sourceSets {
7+
jsAndWasmSharedMain {
8+
dependsOn(commonMain)
9+
}
10+
jsAndWasmSharedTest {
11+
dependsOn(commonTest)
12+
}
13+
}
14+
}
15+
16+
// Disable intermediate sourceSet compilation because we do not need js-wasmJs artifact
17+
tasks.configureEach {
18+
if (name == 'compileJsAndWasmSharedMainKotlinMetadata') {
19+
enabled = false
20+
}
21+
}

gradle/compile-wasm-multiplatform.gradle

+3-6
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@ kotlin {
1313

1414
sourceSets {
1515
wasmJsMain {
16-
kotlin {
17-
srcDir 'jsAndWasmShared/src'
18-
}
16+
dependsOn(jsAndWasmSharedMain)
1917
}
2018
wasmJsTest {
21-
kotlin {
22-
srcDir 'jsAndWasmShared/test'
23-
}
19+
dependsOn(jsAndWasmSharedTest)
2420
}
21+
2522
wasmJsTest.dependencies {
2623
api "org.jetbrains.kotlin:kotlin-test-wasm-js:$kotlin_version"
2724
}

kotlinx-coroutines-core/build.gradle

+6-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ if (rootProject.ext.native_targets_enabled) {
1515
apply from: rootProject.file("gradle/compile-native-multiplatform.gradle")
1616
}
1717

18+
apply from: rootProject.file("gradle/compile-jsAndWasmShared-multiplatform.gradle")
19+
1820
apply from: rootProject.file("gradle/compile-js-multiplatform.gradle")
1921

2022
apply from: rootProject.file("gradle/compile-wasm-multiplatform.gradle")
@@ -26,11 +28,8 @@ apply from: rootProject.file('gradle/publish.gradle')
2628
2729
TARGETS SOURCE SETS
2830
------- ----------------------------------------------
29-
wasmJs -------------------------------------------------+
30-
|
31-
|
32-
js -----------------------------------------------------+
33-
|
31+
wasmJs \----------> jsAndWasmShared --------------------+
32+
js / |
3433
V
3534
jvmCore\ --------> jvm ---------> concurrent -------> common
3635
jdk8 / ^
@@ -237,7 +236,7 @@ kotlin.sourceSets {
237236

238237
kotlin.sourceSets.configureEach {
239238
// Do not apply 'ExperimentalForeignApi' where we have allWarningsAsErrors set
240-
if (it.name in ["jvmMain", "jvmCoreMain", "jsMain", "concurrentMain", "commonMain"]) return
239+
if (it.name in ["jvmMain", "jvmCoreMain", "jsMain", 'wasmJsMain', 'jsAndWasmSharedMain', "concurrentMain", "commonMain"]) return
241240
languageSettings {
242241
optIn('kotlinx.cinterop.ExperimentalForeignApi')
243242
optIn('kotlin.experimental.ExperimentalNativeApi')
@@ -380,4 +379,4 @@ task testsJar(type: Jar, dependsOn: jvmTestClasses) {
380379

381380
artifacts {
382381
archives testsJar
383-
}
382+
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private external val navigator: dynamic
1212
private const val UNDEFINED = "undefined"
1313
internal external val process: dynamic
1414

15-
internal fun createDefaultDispatcher(): CoroutineDispatcher = when {
15+
internal actual fun createDefaultDispatcher(): CoroutineDispatcher = when {
1616
// Check if we are running under jsdom. WindowDispatcher doesn't work under jsdom because it accesses MessageEvent#source.
1717
// It is not implemented in jsdom, see https://github.com/jsdom/jsdom/blob/master/Changelog.md
1818
// "It's missing a few semantics, especially around origins, as well as MessageEvent source."

kotlinx-coroutines-core/js/src/JSDispatcher.kt

+32-11
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,35 @@ package kotlinx.coroutines
77
import org.w3c.dom.*
88
import kotlin.js.Promise
99

10-
internal class ScheduledMessageQueue(private val dispatcher: SetTimeoutBasedDispatcher) : MessageQueue() {
11-
val processQueue: dynamic = { process() }
10+
@AllowDifferentMembersInActual
11+
public actual typealias W3CWindow = Window
1212

13-
override fun schedule() {
13+
internal actual fun w3cSetTimeout(window: W3CWindow, handler: () -> Unit, timeout: Int): Int =
14+
setTimeout(window, handler, timeout)
15+
16+
internal actual fun w3cSetTimeout(handler: () -> Unit, timeout: Int): Int =
17+
setTimeout(handler, timeout)
18+
19+
internal actual fun w3cClearTimeout(window: W3CWindow, handle: Int) =
20+
window.clearTimeout(handle)
21+
22+
internal actual fun w3cClearTimeout(handle: Int) =
23+
clearTimeout(handle)
24+
25+
internal actual class ScheduledMessageQueue actual constructor(private val dispatcher: SetTimeoutBasedDispatcher) : MessageQueue() {
26+
internal val processQueue: dynamic = { process() }
27+
28+
actual override fun schedule() {
1429
dispatcher.scheduleQueueProcessing()
1530
}
1631

17-
override fun reschedule() {
32+
actual override fun reschedule() {
1833
setTimeout(processQueue, 0)
1934
}
35+
36+
internal actual fun setTimeout(timeout: Int) {
37+
setTimeout(processQueue, timeout)
38+
}
2039
}
2140

2241
internal object NodeDispatcher : SetTimeoutBasedDispatcher() {
@@ -25,7 +44,7 @@ internal object NodeDispatcher : SetTimeoutBasedDispatcher() {
2544
}
2645
}
2746

28-
internal class WindowMessageQueue(private val window: Window) : MessageQueue() {
47+
internal actual class WindowMessageQueue actual constructor(private val window: W3CWindow) : MessageQueue() {
2948
private val messageName = "dispatchCoroutine"
3049

3150
init {
@@ -37,18 +56,20 @@ internal class WindowMessageQueue(private val window: Window) : MessageQueue() {
3756
}, true)
3857
}
3958

40-
override fun schedule() {
59+
actual override fun schedule() {
4160
Promise.resolve(Unit).then({ process() })
4261
}
4362

44-
override fun reschedule() {
63+
actual override fun reschedule() {
4564
window.postMessage(messageName, "*")
4665
}
4766
}
4867

4968
// We need to reference global setTimeout and clearTimeout so that it works on Node.JS as opposed to
5069
// using them via "window" (which only works in browser)
51-
internal external fun setTimeout(handler: dynamic, timeout: Int = definedExternally): Int
52-
internal external fun clearTimeout(handle: Int = definedExternally)
53-
internal fun setTimeout(window: WindowOrWorkerGlobalScope, handler: () -> Unit, timeout: Int): Int =
54-
window.setTimeout(handler, timeout)
70+
private external fun setTimeout(handler: dynamic, timeout: Int = definedExternally): Int
71+
72+
private external fun clearTimeout(handle: Int = definedExternally)
73+
74+
private fun setTimeout(window: Window, handler: () -> Unit, timeout: Int): Int =
75+
window.setTimeout(handler, timeout)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines.internal
6+
7+
import kotlinx.coroutines.*
8+
9+
internal actual fun propagateExceptionFinalResort(exception: Throwable) {
10+
// log exception
11+
console.error(exception.toString())
12+
}

kotlinx-coroutines-core/jsAndWasmShared/src/Dispatchers.kt

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package kotlinx.coroutines
66

77
import kotlin.coroutines.*
88

9+
internal expect fun createDefaultDispatcher(): CoroutineDispatcher
10+
911
public actual object Dispatchers {
1012
public actual val Default: CoroutineDispatcher = createDefaultDispatcher()
1113
public actual val Main: MainCoroutineDispatcher

kotlinx-coroutines-core/jsAndWasmShared/src/internal/CoroutineExceptionHandlerImpl.kt

-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ internal actual fun ensurePlatformExceptionHandlerLoaded(callback: CoroutineExce
1616
platformExceptionHandlers_ += callback
1717
}
1818

19-
internal actual fun propagateExceptionFinalResort(exception: Throwable) {
20-
// log exception
21-
console.error(exception.toString())
22-
}
23-
2419
internal actual class DiagnosticCoroutineContextException actual constructor(context: CoroutineContext) :
2520
RuntimeException(context.toString())
2621

kotlinx-coroutines-core/jsAndWasmShared/src/internal/JSDispatcher.kt

+27-12
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,32 @@
55
package kotlinx.coroutines
66

77
import kotlinx.coroutines.internal.*
8-
import org.w3c.dom.*
98
import kotlin.coroutines.*
109

10+
public expect abstract class W3CWindow
11+
internal expect fun w3cSetTimeout(window: W3CWindow, handler: () -> Unit, timeout: Int): Int
12+
internal expect fun w3cSetTimeout(handler: () -> Unit, timeout: Int): Int
13+
internal expect fun w3cClearTimeout(handle: Int)
14+
internal expect fun w3cClearTimeout(window: W3CWindow, handle: Int)
15+
16+
internal expect class ScheduledMessageQueue(dispatcher: SetTimeoutBasedDispatcher) : MessageQueue {
17+
override fun schedule()
18+
override fun reschedule()
19+
internal fun setTimeout(timeout: Int)
20+
}
21+
22+
internal expect class WindowMessageQueue(window: W3CWindow) : MessageQueue {
23+
override fun schedule()
24+
override fun reschedule()
25+
}
26+
1127
private const val MAX_DELAY = Int.MAX_VALUE.toLong()
1228

1329
private fun delayToInt(timeMillis: Long): Int =
1430
timeMillis.coerceIn(0, MAX_DELAY).toInt()
1531

16-
internal sealed class SetTimeoutBasedDispatcher: CoroutineDispatcher(), Delay {
17-
val messageQueue = ScheduledMessageQueue(this)
32+
internal abstract class SetTimeoutBasedDispatcher: CoroutineDispatcher(), Delay {
33+
internal val messageQueue = ScheduledMessageQueue(this)
1834

1935
abstract fun scheduleQueueProcessing()
2036

@@ -28,48 +44,47 @@ internal sealed class SetTimeoutBasedDispatcher: CoroutineDispatcher(), Delay {
2844
}
2945

3046
override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle {
31-
val handle = setTimeout({ block.run() }, delayToInt(timeMillis))
47+
val handle = w3cSetTimeout({ block.run() }, delayToInt(timeMillis))
3248
return ClearTimeout(handle)
3349
}
3450

3551
override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
36-
val handle = setTimeout({ with(continuation) { resumeUndispatched(Unit) } }, delayToInt(timeMillis))
52+
val handle = w3cSetTimeout({ with(continuation) { resumeUndispatched(Unit) } }, delayToInt(timeMillis))
3753
continuation.invokeOnCancellation(handler = ClearTimeout(handle).asHandler)
3854
}
3955
}
4056

41-
internal class WindowDispatcher(private val window: Window) : CoroutineDispatcher(), Delay {
57+
internal class WindowDispatcher(private val window: W3CWindow) : CoroutineDispatcher(), Delay {
4258
private val queue = WindowMessageQueue(window)
4359

4460
override fun dispatch(context: CoroutineContext, block: Runnable) = queue.enqueue(block)
4561

4662
override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
47-
val handle = setTimeout(window, { with(continuation) { resumeUndispatched(Unit) } }, delayToInt(timeMillis))
63+
val handle = w3cSetTimeout(window, { with(continuation) { resumeUndispatched(Unit) } }, delayToInt(timeMillis))
4864
continuation.invokeOnCancellation(handler = WindowClearTimeout(handle).asHandler)
4965
}
5066

5167
override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle {
52-
val handle = setTimeout(window, block::run, delayToInt(timeMillis))
68+
val handle = w3cSetTimeout(window, block::run, delayToInt(timeMillis))
5369
return WindowClearTimeout(handle)
5470
}
5571

5672
private inner class WindowClearTimeout(handle: Int) : ClearTimeout(handle) {
5773
override fun dispose() {
58-
window.clearTimeout(handle)
74+
w3cClearTimeout(window, handle)
5975
}
6076
}
6177
}
6278

6379
internal object SetTimeoutDispatcher : SetTimeoutBasedDispatcher() {
6480
override fun scheduleQueueProcessing() {
65-
setTimeout(messageQueue.processQueue, 0)
81+
messageQueue.setTimeout(0)
6682
}
6783
}
6884

6985
private open class ClearTimeout(protected val handle: Int) : CancelHandler(), DisposableHandle {
70-
7186
override fun dispose() {
72-
clearTimeout(handle)
87+
w3cClearTimeout(handle)
7388
}
7489

7590
override fun invoke(cause: Throwable?) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal fun tryGetProcess(): JsProcess? =
1818
internal fun tryGetWindow(): Window? =
1919
js("(typeof(window) !== 'undefined' && window != null && typeof(window.addEventListener) === 'function') ? window : null")
2020

21-
internal fun createDefaultDispatcher(): CoroutineDispatcher =
21+
internal actual fun createDefaultDispatcher(): CoroutineDispatcher =
2222
tryGetProcess()?.let(::NodeDispatcher)
2323
?: tryGetWindow()?.let(::WindowDispatcher)
2424
?: SetTimeoutDispatcher

0 commit comments

Comments
 (0)