Skip to content

Commit 2d13963

Browse files
authored
Introduce JS target via common JS and WasmJS source-set
Setup a common sourceSet in between wasmJs and JS targets to publish …
2 parents 605b866 + 0a09747 commit 2d13963

38 files changed

+441
-208
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ gradle-app.setting
1313
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
1414
# gradle/wrapper/gradle-wrapper.properties
1515
/.idea/
16-
/kotlin-js-store/
16+
/kotlin-js-store/
17+
/.kotlin/

build.gradle.kts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
1+
@file:OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
22

33
plugins {
4-
kotlin("multiplatform") version "2.2.0"
4+
kotlin("multiplatform") version "2.2.20-Beta2"
55
`maven-publish`
66
signing
77
}
@@ -39,13 +39,23 @@ if (!versionSuffix.isNullOrBlank()) {
3939
}
4040

4141
kotlin {
42-
@OptIn(ExperimentalWasmDsl::class)
42+
compilerOptions {
43+
optIn.add("kotlin.js.ExperimentalWasmJsInterop")
44+
}
45+
46+
js {
47+
nodejs()
48+
}
49+
4350
wasmJs {
4451
nodejs()
4552
}
4653

54+
applyDefaultHierarchyTemplate()
55+
4756
sourceSets {
48-
val wasmJsTest by getting {
57+
val commonMain by getting
58+
val webTest by getting {
4959
dependencies {
5060
implementation(kotlin("test"))
5161
}

generator/build.gradle.kts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ task("downloadIDL", JavaExec::class) {
1818
dependsOn("build")
1919
}
2020

21-
task("generateWasmStdlibFromIDL", JavaExec::class) {
22-
mainClass = "org.jetbrains.kotlin.tools.dukat.LaunchWasmKt"
21+
task("generateStdlibFromIDL", JavaExec::class) {
22+
mainClass = "org.jetbrains.kotlin.tools.dukat.LaunchBrowserKt"
2323
classpath = sourceSets["main"].runtimeClasspath
2424
dependsOn("build")
2525
systemProperty("line.separator", "\n")
2626
}
2727

28-
task("generateWasmJsUtils", JavaExec::class) {
29-
mainClass.set("org.jetbrains.kotlin.generators.wasm.js.GenerateKt")
28+
task("generateUtils", JavaExec::class) {
29+
mainClass.set("org.jetbrains.kotlin.generators.helpers.GenerateKt")
3030
classpath = sourceSets["main"].runtimeClasspath
3131
dependsOn("build")
3232
}

generator/src/main/kotlin/dukat/launchWasm.kt renamed to generator/src/main/kotlin/dukat/launchBrowser.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.tools.dukat.wasm.translateIdlToSourceSet
1111
import java.io.File
1212

1313
fun main() {
14-
val outputDirectory = "../src/wasmJsMain/kotlin/org.w3c/"
14+
val outputDirectory = "../src/webMain/kotlin/org.w3c/"
1515
val input = "../idl/org.w3c.dom.idl"
1616

1717
val sourceSet = translateIdlToSourceSet(input)

generator/src/main/kotlin/dukat/wasm/convertToModel.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,7 @@ private class IdlFileConverter(
380380
SUPPRESS_UNUSED_PARAMETER_ANNOTATION
381381
),
382382
body = BlockStatementModel(
383-
listOf(
384-
ExpressionStatementModel(callJsFunction("return obj[${key.name}];"))
385-
)
383+
listOf(ReturnStatementModel(callJsFunction("obj[${key.name}]")))
386384
),
387385
visibilityModifier = VisibilityModifierModel.INTERNAL,
388386
comment = null,
@@ -555,8 +553,8 @@ private class IdlFileConverter(
555553

556554
fun IDLDictionaryDeclaration.generateFunctionBody(): List<StatementModel> =
557555
listOf<StatementModel>(
558-
ExpressionStatementModel(
559-
callJsFunction("return { ${members.joinToString { it.name }} };")
556+
ReturnStatementModel(
557+
callJsFunction("({ ${members.joinToString(", ") { "${it.name}: ${it.name}" }} })")
560558
)
561559
)
562560

generator/src/main/kotlin/helpers/generate.kt

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
44
*/
55

6-
package org.jetbrains.kotlin.generators.wasm.js
6+
package org.jetbrains.kotlin.generators.helpers
77

88
import org.jetbrains.kotlin.tools.dukat.getHeader
99
import java.io.File
@@ -15,25 +15,100 @@ fun main() {
1515
}
1616

1717
fun generatePublicStdlibFunctions() {
18-
FileWriter(File("../src/wasmJsMain/kotlin/arrayCopy.kt")).use { writer: FileWriter ->
18+
val conversions = listOf(
19+
Conversion("Byte", "Int8"),
20+
Conversion("UByte", "Uint8", isUnsigned = true),
21+
Conversion("Short", "Int16"),
22+
Conversion("UShort", "Uint16", isUnsigned = true),
23+
Conversion("Int", "Int32"),
24+
Conversion("UInt", "Uint32", isUnsigned = true),
25+
Conversion("Float", "Float32"),
26+
Conversion("Double", "Float64")
27+
)
28+
29+
FileWriter(File("../src/webMain/kotlin/arrayCopy.kt")).use { writer: FileWriter ->
1930
with(writer) {
2031
appendLine(getHeader(seeDetailsAt = "generator/src/main/kotlin/helpers/generate.kt"))
32+
appendLine("package org.khronos.webgl")
2133

34+
conversions.forEach { (ktType, jsType, isUnsigned) ->
35+
appendExpectConversionsForType(ktType, jsType, isUnsigned)
36+
}
37+
}
38+
}
39+
FileWriter(File("../src/jsMain/kotlin/arrayCopy.js.kt")).use { writer: FileWriter ->
40+
with(writer) {
41+
appendLine(getHeader(seeDetailsAt = "generator/src/main/kotlin/helpers/generate.kt"))
42+
43+
appendLine("package org.khronos.webgl")
44+
45+
conversions.forEach { (ktType, jsType, isUnsigned) ->
46+
appendJsConversionsForType(ktType, jsType, isUnsigned)
47+
}
48+
}
49+
}
50+
FileWriter(File("../src/wasmJsMain/kotlin/arrayCopy.wasm.kt")).use { writer: FileWriter ->
51+
with(writer) {
52+
appendLine(getHeader(seeDetailsAt = "generator/src/main/kotlin/helpers/generate.kt"))
2253
appendLine("package org.khronos.webgl")
2354

24-
appendConversionsForType("Byte", "Int8")
25-
appendConversionsForType("UByte", "Uint8", isUnsigned = true)
26-
appendConversionsForType("Short", "Int16")
27-
appendConversionsForType("UShort", "Uint16", isUnsigned = true)
28-
appendConversionsForType("Int", "Int32")
29-
appendConversionsForType("UInt", "Uint32", isUnsigned = true)
30-
appendConversionsForType("Float", "Float32")
31-
appendConversionsForType("Double", "Float64")
55+
conversions.forEach { (ktType, jsType, isUnsigned) ->
56+
appendWasmConversionsForType(ktType, jsType, isUnsigned)
57+
}
3258
}
3359
}
3460
}
3561

36-
private fun FileWriter.appendConversionsForType(
62+
63+
private fun FileWriter.appendExpectConversionsForType(
64+
ktType: String,
65+
jsType: String,
66+
isUnsigned: Boolean = false,
67+
) {
68+
val kotlinArrayType = "${ktType}Array"
69+
val jsArrayType = "${jsType}Array"
70+
71+
appendLine()
72+
appendLine("/** Returns a new [$kotlinArrayType] containing all the elements of this [$jsArrayType]. */")
73+
if (isUnsigned) {
74+
appendLine("@ExperimentalUnsignedTypes")
75+
}
76+
appendLine("public expect fun $jsArrayType.to$kotlinArrayType(): $kotlinArrayType")
77+
appendLine()
78+
appendLine("/** Returns a new [$jsArrayType] containing all the elements of this [$kotlinArrayType]. */")
79+
if (isUnsigned) {
80+
appendLine("@ExperimentalUnsignedTypes")
81+
}
82+
appendLine("public expect fun $kotlinArrayType.to$jsArrayType(): $jsArrayType")
83+
}
84+
85+
86+
private fun FileWriter.appendJsConversionsForType(
87+
ktType: String,
88+
jsType: String,
89+
isUnsigned: Boolean = false,
90+
) {
91+
val kotlinArrayType = "${ktType}Array"
92+
val jsArrayType = "${jsType}Array"
93+
94+
appendLine()
95+
appendLine("/** Returns a new [$kotlinArrayType] containing all the elements of this [$jsArrayType]. */")
96+
if (isUnsigned) {
97+
appendLine("@ExperimentalUnsignedTypes")
98+
}
99+
appendLine("public actual inline fun $jsArrayType.to$kotlinArrayType(): $kotlinArrayType =")
100+
appendLine(" unsafeCast<$kotlinArrayType>()")
101+
102+
appendLine()
103+
appendLine("/** Returns a new [$jsArrayType] containing all the elements of this [$kotlinArrayType]. */")
104+
if (isUnsigned) {
105+
appendLine("@ExperimentalUnsignedTypes")
106+
}
107+
appendLine("public actual inline fun $kotlinArrayType.to$jsArrayType(): $jsArrayType =")
108+
appendLine(" unsafeCast<$jsArrayType>()")
109+
}
110+
111+
private fun FileWriter.appendWasmConversionsForType(
37112
ktType: String,
38113
jsType: String,
39114
isUnsigned: Boolean = false,
@@ -46,7 +121,7 @@ private fun FileWriter.appendConversionsForType(
46121
if (isUnsigned) {
47122
appendLine("@ExperimentalUnsignedTypes")
48123
}
49-
appendLine("public fun $jsArrayType.to$kotlinArrayType(): $kotlinArrayType =")
124+
appendLine("public actual fun $jsArrayType.to$kotlinArrayType(): $kotlinArrayType =")
50125
if (isUnsigned) {
51126
appendLine(" $kotlinArrayType(this.length) { this[it].to$ktType() }")
52127
} else {
@@ -58,7 +133,7 @@ private fun FileWriter.appendConversionsForType(
58133
if (isUnsigned) {
59134
appendLine("@ExperimentalUnsignedTypes")
60135
}
61-
appendLine("public fun $kotlinArrayType.to$jsArrayType(): $jsArrayType {")
136+
appendLine("public actual fun $kotlinArrayType.to$jsArrayType(): $jsArrayType {")
62137
appendLine(" val result = $jsArrayType(this.size)")
63138
appendLine(" for (index in this.indices) {")
64139
if (isUnsigned) {
@@ -73,7 +148,7 @@ private fun FileWriter.appendConversionsForType(
73148
}
74149

75150
fun generateTests() {
76-
FileWriter(File("../src/wasmJsTest/kotlin/arrayCopyTest.kt")).use { writer: FileWriter ->
151+
FileWriter(File("../src/webtest/kotlin/arrayCopyTest.kt")).use { writer: FileWriter ->
77152
with(writer) {
78153
appendLine(getHeader(seeDetailsAt = "generator/src/main/kotlin/helpers/generate.kt"))
79154

@@ -146,4 +221,7 @@ private fun FileWriter.appendTestFunction(
146221
appendLine(" testJsRoundTrip($ktArrayOf(0.to$ktType(), (-42).to$ktType(), $ktType.MIN_VALUE, $ktType.MAX_VALUE))")
147222
appendLine(" testJsRoundTrip($kotlinArrayType(1000) { it.to$ktType() })")
148223
appendLine(" }")
149-
}
224+
}
225+
226+
data class Conversion(val jsType: String, val ktType: String, val isUnsigned: Boolean = false)
227+
data class InteropCorrespondence(val interopType: String, val wasmType: String, val jsType: String)

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pluginManagement {
33
gradlePluginPortal()
44
}
55
plugins {
6-
kotlin("multiplatform").version("2.2.0")
6+
kotlin("multiplatform").version("2.2.20-Beta2")
77
}
88
}
99

src/jsMain/kotlin/arrayCopy.js.kt

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
4+
*/
5+
6+
// NOTE: THIS FILE IS AUTO-GENERATED, DO NOT EDIT!
7+
// See generator/src/main/kotlin/helpers/generate.kt for details
8+
9+
10+
package org.khronos.webgl
11+
12+
/** Returns a new [ByteArray] containing all the elements of this [Int8Array]. */
13+
public actual inline fun Int8Array.toByteArray(): ByteArray =
14+
unsafeCast<ByteArray>()
15+
16+
/** Returns a new [Int8Array] containing all the elements of this [ByteArray]. */
17+
public actual inline fun ByteArray.toInt8Array(): Int8Array =
18+
unsafeCast<Int8Array>()
19+
20+
/** Returns a new [UByteArray] containing all the elements of this [Uint8Array]. */
21+
@ExperimentalUnsignedTypes
22+
public actual inline fun Uint8Array.toUByteArray(): UByteArray =
23+
unsafeCast<UByteArray>()
24+
25+
/** Returns a new [Uint8Array] containing all the elements of this [UByteArray]. */
26+
@ExperimentalUnsignedTypes
27+
public actual inline fun UByteArray.toUint8Array(): Uint8Array =
28+
unsafeCast<Uint8Array>()
29+
30+
/** Returns a new [ShortArray] containing all the elements of this [Int16Array]. */
31+
public actual inline fun Int16Array.toShortArray(): ShortArray =
32+
unsafeCast<ShortArray>()
33+
34+
/** Returns a new [Int16Array] containing all the elements of this [ShortArray]. */
35+
public actual inline fun ShortArray.toInt16Array(): Int16Array =
36+
unsafeCast<Int16Array>()
37+
38+
/** Returns a new [UShortArray] containing all the elements of this [Uint16Array]. */
39+
@ExperimentalUnsignedTypes
40+
public actual inline fun Uint16Array.toUShortArray(): UShortArray =
41+
unsafeCast<UShortArray>()
42+
43+
/** Returns a new [Uint16Array] containing all the elements of this [UShortArray]. */
44+
@ExperimentalUnsignedTypes
45+
public actual inline fun UShortArray.toUint16Array(): Uint16Array =
46+
unsafeCast<Uint16Array>()
47+
48+
/** Returns a new [IntArray] containing all the elements of this [Int32Array]. */
49+
public actual inline fun Int32Array.toIntArray(): IntArray =
50+
unsafeCast<IntArray>()
51+
52+
/** Returns a new [Int32Array] containing all the elements of this [IntArray]. */
53+
public actual inline fun IntArray.toInt32Array(): Int32Array =
54+
unsafeCast<Int32Array>()
55+
56+
/** Returns a new [UIntArray] containing all the elements of this [Uint32Array]. */
57+
@ExperimentalUnsignedTypes
58+
public actual inline fun Uint32Array.toUIntArray(): UIntArray =
59+
unsafeCast<UIntArray>()
60+
61+
/** Returns a new [Uint32Array] containing all the elements of this [UIntArray]. */
62+
@ExperimentalUnsignedTypes
63+
public actual inline fun UIntArray.toUint32Array(): Uint32Array =
64+
unsafeCast<Uint32Array>()
65+
66+
/** Returns a new [FloatArray] containing all the elements of this [Float32Array]. */
67+
public actual inline fun Float32Array.toFloatArray(): FloatArray =
68+
unsafeCast<FloatArray>()
69+
70+
/** Returns a new [Float32Array] containing all the elements of this [FloatArray]. */
71+
public actual inline fun FloatArray.toFloat32Array(): Float32Array =
72+
unsafeCast<Float32Array>()
73+
74+
/** Returns a new [DoubleArray] containing all the elements of this [Float64Array]. */
75+
public actual inline fun Float64Array.toDoubleArray(): DoubleArray =
76+
unsafeCast<DoubleArray>()
77+
78+
/** Returns a new [Float64Array] containing all the elements of this [DoubleArray]. */
79+
public actual inline fun DoubleArray.toFloat64Array(): Float64Array =
80+
unsafeCast<Float64Array>()

0 commit comments

Comments
 (0)