[WASM] Support for mjs universal launcher
This commit is contained in:
+1
-1
@@ -503,10 +503,10 @@ tasks {
|
||||
":kotlin-test:kotlin-test-js-ir:kotlin-test-js-ir-it".takeIf { !kotlinBuildProperties.isInJpsBuildIdeaSync },
|
||||
":kotlinx-metadata-jvm",
|
||||
":tools:binary-compatibility-validator",
|
||||
//":kotlin-stdlib-wasm",
|
||||
)).forEach {
|
||||
dependsOn("$it:check")
|
||||
}
|
||||
dependsOn(":kotlin-stdlib-wasm:runWasmStdLibTestsWithD8") //Instead of :kotlin-stdlib-wasm:check
|
||||
}
|
||||
|
||||
register("gradlePluginTest") {
|
||||
|
||||
-7
@@ -249,13 +249,6 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(value = "-Xwasm-debug-info", description = "Add debug info to WebAssembly compiled module")
|
||||
var wasmDebug: Boolean by FreezableVar(true)
|
||||
|
||||
@Argument(
|
||||
value = "-Xwasm-launcher",
|
||||
valueDescription = "esm|nodejs|d8",
|
||||
description = "Picks flavor for the wasm launcher. Default is ESM."
|
||||
)
|
||||
var wasmLauncher: String? by NullableStringFreezableVar("esm")
|
||||
|
||||
@Argument(value = "-Xwasm-kclass-fqn", description = "Enable support for FQ names in KClass")
|
||||
var wasmKClassFqn: Boolean by FreezableVar(false)
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.backend.common.CompilationException
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
|
||||
import org.jetbrains.kotlin.backend.wasm.WasmLoaderKind
|
||||
import org.jetbrains.kotlin.backend.wasm.compileWasm
|
||||
import org.jetbrains.kotlin.backend.wasm.compileToLoweredIr
|
||||
import org.jetbrains.kotlin.backend.wasm.wasmPhases
|
||||
@@ -362,18 +361,9 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
generateWat = true,
|
||||
)
|
||||
|
||||
val launcherKind = when (arguments.wasmLauncher) {
|
||||
"esm" -> WasmLoaderKind.BROWSER
|
||||
"nodejs" -> WasmLoaderKind.NODE
|
||||
"d8" -> WasmLoaderKind.D8
|
||||
"d8NodeCompatible" -> WasmLoaderKind.D8NodeCompatible
|
||||
else -> throw IllegalArgumentException("Unrecognized flavor for the wasm launcher")
|
||||
}
|
||||
|
||||
writeCompilationResult(
|
||||
result = res,
|
||||
dir = outputFile.parentFile,
|
||||
loaderKind = launcherKind,
|
||||
fileNameBase = outputFile.nameWithoutExtension
|
||||
)
|
||||
|
||||
|
||||
@@ -120,66 +120,49 @@ fun WasmCompiledModuleFragment.generateJs(): String {
|
||||
return runtime + jsCode
|
||||
}
|
||||
|
||||
enum class WasmLoaderKind {
|
||||
D8,
|
||||
D8NodeCompatible,
|
||||
NODE,
|
||||
BROWSER,
|
||||
}
|
||||
|
||||
fun generateJsWasmLoader(kind: WasmLoaderKind, wasmFilePath: String, externalJs: String): String {
|
||||
val nodeExitOnD8 =
|
||||
if (kind == WasmLoaderKind.D8NodeCompatible) "if ((typeof process !== 'undefined') && (typeof process.versions.node !== 'undefined')) process.exit(0)\n"
|
||||
else ""
|
||||
|
||||
val instantiation = when (kind) {
|
||||
WasmLoaderKind.D8, WasmLoaderKind.D8NodeCompatible ->
|
||||
"""
|
||||
const wasmModule = new WebAssembly.Module(read('$wasmFilePath', 'binary'));
|
||||
const wasmInstance = new WebAssembly.Instance(wasmModule, { js_code });
|
||||
""".trimIndent()
|
||||
|
||||
WasmLoaderKind.NODE ->
|
||||
"""
|
||||
const fs = require('fs');
|
||||
var path = require('path');
|
||||
const wasmBuffer = fs.readFileSync(path.resolve(__dirname, './$wasmFilePath'));
|
||||
const wasmModule = new WebAssembly.Module(wasmBuffer);
|
||||
const wasmInstance = new WebAssembly.Instance(wasmModule, { js_code });
|
||||
""".trimIndent()
|
||||
|
||||
WasmLoaderKind.BROWSER ->
|
||||
"""
|
||||
const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(fetch("$wasmFilePath"), { js_code });
|
||||
""".trimIndent()
|
||||
fun generateJsWasmLoader(wasmFilePath: String, externalJs: String): String =
|
||||
externalJs + """
|
||||
|
||||
const isNodeJs = (typeof process !== 'undefined') && (process.release.name === 'node');
|
||||
const isD8 = !isNodeJs && (typeof d8 !== 'undefined');
|
||||
const isBrowser = !isNodeJs && !isD8 && (typeof window !== 'undefined');
|
||||
|
||||
if (!isNodeJs && !isD8 && !isBrowser) {
|
||||
throw "Supported JS engine not detected";
|
||||
}
|
||||
|
||||
val init =
|
||||
"""
|
||||
|
||||
const wasmExports = wasmInstance.exports;
|
||||
wasmExports.__init();
|
||||
wasmExports.startUnitTests?.();
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
val export = when (kind) {
|
||||
WasmLoaderKind.D8, WasmLoaderKind.BROWSER ->
|
||||
"export default wasmExports;\n"
|
||||
|
||||
WasmLoaderKind.NODE ->
|
||||
"module.exports = wasmExports;\n"
|
||||
|
||||
WasmLoaderKind.D8NodeCompatible -> ""
|
||||
|
||||
let wasmInstance;
|
||||
let require; // Placed here to give access to it from externals (js_code)
|
||||
if (isNodeJs) {
|
||||
const module = await import('node:module');
|
||||
require = module.createRequire(import.meta.url);
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
||||
const wasmBuffer = fs.readFileSync(path.resolve(__dirname, './$wasmFilePath'));
|
||||
const wasmModule = new WebAssembly.Module(wasmBuffer);
|
||||
wasmInstance = new WebAssembly.Instance(wasmModule, { js_code });
|
||||
}
|
||||
|
||||
return nodeExitOnD8 + externalJs + instantiation + init + export
|
||||
}
|
||||
|
||||
if (isD8) {
|
||||
const wasmBuffer = read('$wasmFilePath', 'binary');
|
||||
const wasmModule = new WebAssembly.Module(wasmBuffer);
|
||||
wasmInstance = new WebAssembly.Instance(wasmModule, { js_code });
|
||||
}
|
||||
|
||||
if (isBrowser) {
|
||||
wasmInstance = (await WebAssembly.instantiateStreaming(fetch('$wasmFilePath'), { js_code })).instance;
|
||||
}
|
||||
|
||||
const wasmExports = wasmInstance.exports;
|
||||
wasmExports.__init();
|
||||
export default wasmExports;
|
||||
""".trimIndent()
|
||||
|
||||
fun writeCompilationResult(
|
||||
result: WasmCompilerResult,
|
||||
dir: File,
|
||||
loaderKind: WasmLoaderKind,
|
||||
fileNameBase: String = "index",
|
||||
) {
|
||||
dir.mkdirs()
|
||||
@@ -187,6 +170,7 @@ fun writeCompilationResult(
|
||||
File(dir, "$fileNameBase.wat").writeText(result.wat)
|
||||
}
|
||||
File(dir, "$fileNameBase.wasm").writeBytes(result.wasm)
|
||||
val jsWithLoader = generateJsWasmLoader(loaderKind, "./$fileNameBase.wasm", result.js)
|
||||
File(dir, "$fileNameBase.js").writeText(jsWithLoader)
|
||||
|
||||
val jsWithLoader = generateJsWasmLoader("./$fileNameBase.wasm", result.js)
|
||||
File(dir, "$fileNameBase.mjs").writeText(jsWithLoader)
|
||||
}
|
||||
|
||||
-1
@@ -45,7 +45,6 @@ where advanced options include:
|
||||
Turn on range checks for the array access functions
|
||||
-Xwasm-enable-asserts Turn on asserts
|
||||
-Xwasm-kclass-fqn Enable support for FQ names in KClass
|
||||
-Xwasm-launcher=esm|nodejs|d8 Picks flavor for the wasm launcher. Default is ESM.
|
||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
||||
-Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type
|
||||
-Xbuiltins-from-sources Compile builtIns from sources
|
||||
|
||||
@@ -148,7 +148,7 @@ abstract class BasicWasmBoxTest(
|
||||
)
|
||||
|
||||
val testJsQuiet = """
|
||||
import exports from './index.js';
|
||||
import exports from './index.mjs';
|
||||
|
||||
let actualResult
|
||||
try {
|
||||
@@ -176,19 +176,19 @@ abstract class BasicWasmBoxTest(
|
||||
val path = dir.absolutePath
|
||||
println(" ------ $name WAT file://$path/index.wat")
|
||||
println(" ------ $name WASM file://$path/index.wasm")
|
||||
println(" ------ $name JS file://$path/index.js")
|
||||
println(" ------ $name Test file://$path/test.js")
|
||||
println(" ------ $name JS file://$path/index.mjs")
|
||||
println(" ------ $name Test file://$path/test.mjs")
|
||||
}
|
||||
|
||||
writeCompilationResult(res, dir, WasmLoaderKind.D8)
|
||||
File(dir, "test.js").writeText(testJs)
|
||||
writeCompilationResult(res, dir)
|
||||
File(dir, "test.mjs").writeText(testJs)
|
||||
ExternalTool(System.getProperty("javascript.engine.path.V8"))
|
||||
.run(
|
||||
"--experimental-wasm-gc",
|
||||
"--experimental-wasm-eh",
|
||||
*jsFilesBefore.map { File(it).absolutePath }.toTypedArray(),
|
||||
"--module",
|
||||
"./test.js",
|
||||
"./test.mjs",
|
||||
*jsFilesAfter.map { File(it).absolutePath }.toTypedArray(),
|
||||
workingDirectory = dir
|
||||
)
|
||||
@@ -200,14 +200,14 @@ abstract class BasicWasmBoxTest(
|
||||
if (debugMode >= DebugMode.SUPER_DEBUG) {
|
||||
fun writeBrowserTest(name: String, res: WasmCompilerResult) {
|
||||
val dir = File(outputDirBase, name)
|
||||
writeCompilationResult(res, dir, WasmLoaderKind.BROWSER)
|
||||
File(dir, "test.js").writeText(testJsVerbose)
|
||||
writeCompilationResult(res, dir)
|
||||
File(dir, "test.mjs").writeText(testJsVerbose)
|
||||
File(dir, "index.html").writeText(
|
||||
"""
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<body>
|
||||
<script src="test.js" type="module"></script>
|
||||
<script src="test.mjs" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
""".trimIndent()
|
||||
@@ -215,8 +215,8 @@ abstract class BasicWasmBoxTest(
|
||||
val path = dir.absolutePath
|
||||
println(" ------ $name WAT file://$path/index.wat")
|
||||
println(" ------ $name WASM file://$path/index.wasm")
|
||||
println(" ------ $name JS file://$path/index.js")
|
||||
println(" ------ $name TEST file://$path/test.js")
|
||||
println(" ------ $name JS file://$path/index.mjs")
|
||||
println(" ------ $name TEST file://$path/test.mjs")
|
||||
println(" ------ $name HTML file://$path/index.html")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
|
||||
import java.io.OutputStream
|
||||
|
||||
plugins {
|
||||
`maven-publish`
|
||||
@@ -77,13 +76,7 @@ val commonTestSources by task<Sync> {
|
||||
|
||||
kotlin {
|
||||
wasm {
|
||||
nodejs {
|
||||
testTask {
|
||||
useMocha {
|
||||
timeout = "10s"
|
||||
}
|
||||
}
|
||||
}
|
||||
nodejs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@@ -144,33 +137,7 @@ val compileTestKotlinWasm by tasks.existing(KotlinCompile::class) {
|
||||
}
|
||||
|
||||
val compileTestDevelopmentExecutableKotlinWasm = tasks.named<KotlinJsIrLink>("compileTestDevelopmentExecutableKotlinWasm") {
|
||||
(this as KotlinCompile<*>).kotlinOptions.freeCompilerArgs += listOf("-Xwasm-enable-array-range-checks", "-Xwasm-launcher=d8")
|
||||
}
|
||||
|
||||
val runWasmStdLibTestsWithD8 by tasks.registering(Exec::class) {
|
||||
dependsOn(":js:js.tests:unzipV8")
|
||||
dependsOn(compileTestDevelopmentExecutableKotlinWasm)
|
||||
|
||||
val unzipV8Task = tasks.getByPath(":js:js.tests:unzipV8")
|
||||
val d8Path = File(unzipV8Task.outputs.files.single(), "d8")
|
||||
executable = d8Path.toString()
|
||||
|
||||
val compiledFile = compileTestDevelopmentExecutableKotlinWasm
|
||||
.get()
|
||||
.kotlinOptions
|
||||
.outputFile
|
||||
?.let { File(it) }
|
||||
check(compiledFile != null)
|
||||
|
||||
if (System.getenv("TEAMCITY_VERSION") == null) {
|
||||
standardOutput = object : OutputStream() {
|
||||
override fun write(b: Int) = Unit
|
||||
}
|
||||
errorOutput = standardOutput
|
||||
}
|
||||
|
||||
workingDir = compiledFile.parentFile
|
||||
args = listOf("--experimental-wasm-gc", "--experimental-wasm-eh", "--module", compiledFile.name)
|
||||
(this as KotlinCompile<*>).kotlinOptions.freeCompilerArgs += listOf("-Xwasm-enable-array-range-checks")
|
||||
}
|
||||
|
||||
val runtimeElements by configurations.creating {}
|
||||
|
||||
+2
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinTargetTestRun
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetContainerDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmSubTargetContainerDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.testing.KotlinReportAggregatingTestRun
|
||||
import org.jetbrains.kotlin.gradle.testing.KotlinTaskTestRun
|
||||
@@ -82,6 +83,7 @@ open class KotlinJsReportAggregatingTestRun(
|
||||
|
||||
target.whenBrowserConfigured { doConfigureInChildren(this) }
|
||||
target.whenNodejsConfigured { doConfigureInChildren(this) }
|
||||
(target as? KotlinWasmSubTargetContainerDsl)?.whenD8Configured { doConfigureInChildren(this) }
|
||||
}
|
||||
|
||||
override fun filter(configureFilter: Closure<*>) = filter { target.project.configure(this, configureFilter) }
|
||||
|
||||
-3
@@ -63,9 +63,6 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
||||
}
|
||||
}
|
||||
|
||||
override val additionalCompilerOption: String?
|
||||
get() = "-Xwasm-launcher=esm".takeIf { target.platformType == KotlinPlatformType.wasm }
|
||||
|
||||
override fun commonWebpackConfig(body: KotlinWebpackConfig.() -> Unit) {
|
||||
webpackTaskConfigurations.add {
|
||||
webpackConfigApplier(body)
|
||||
|
||||
-4
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.targets.js.d8.D8Exec
|
||||
import org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmD8Dsl
|
||||
@@ -34,7 +33,4 @@ open class KotlinD8Ir @Inject constructor(target: KotlinJsIrTarget) :
|
||||
override fun configureTestDependencies(test: KotlinJsTest) {
|
||||
test.dependsOn(d8.setupTaskProvider)
|
||||
}
|
||||
|
||||
override val additionalCompilerOption: String?
|
||||
get() = "-Xwasm-launcher=d8".takeIf { target.platformType == KotlinPlatformType.wasm }
|
||||
}
|
||||
+8
@@ -52,6 +52,10 @@ constructor(
|
||||
(this as KotlinJsIrSubTarget).produceExecutable()
|
||||
}
|
||||
|
||||
target.whenD8Configured {
|
||||
(this as KotlinJsIrSubTarget).produceExecutable()
|
||||
}
|
||||
|
||||
return compilation.binaries.executableIrInternal(compilation)
|
||||
}
|
||||
|
||||
@@ -106,6 +110,10 @@ constructor(
|
||||
(this as KotlinJsIrSubTarget).produceLibrary()
|
||||
}
|
||||
|
||||
target.whenD8Configured {
|
||||
(this as KotlinJsIrSubTarget).produceLibrary()
|
||||
}
|
||||
|
||||
return createBinaries(
|
||||
compilation = compilation,
|
||||
jsBinaryType = KotlinJsBinaryType.LIBRARY,
|
||||
|
||||
-14
@@ -102,17 +102,6 @@ abstract class KotlinJsIrSubTarget(
|
||||
}
|
||||
}
|
||||
|
||||
private fun addLinkOptions(compilation: KotlinJsIrCompilation) {
|
||||
val additionalCompilerOption = additionalCompilerOption ?: return
|
||||
compilation.binaries
|
||||
.withType(JsIrBinary::class.java)
|
||||
.all {
|
||||
it.linkTask.configure { linkTask ->
|
||||
linkTask.kotlinOptions.freeCompilerArgs += additionalCompilerOption
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureTestsRun(testRun: KotlinJsPlatformTestRun, compilation: KotlinJsIrCompilation) {
|
||||
fun KotlinJsPlatformTestRun.subtargetTestTaskName(): String = disambiguateCamelCased(
|
||||
lowerCamelCaseName(
|
||||
@@ -121,8 +110,6 @@ abstract class KotlinJsIrSubTarget(
|
||||
)
|
||||
)
|
||||
|
||||
addLinkOptions(compilation)
|
||||
|
||||
val testJs = project.registerTask<KotlinJsTest>(
|
||||
testRun.subtargetTestTaskName(),
|
||||
listOf(compilation)
|
||||
@@ -177,7 +164,6 @@ abstract class KotlinJsIrSubTarget(
|
||||
|
||||
protected abstract fun configureDefaultTestFramework(test: KotlinJsTest)
|
||||
protected abstract fun configureTestDependencies(test: KotlinJsTest)
|
||||
protected abstract val additionalCompilerOption: String?
|
||||
|
||||
private fun configureMain() {
|
||||
target.compilations.all { compilation ->
|
||||
|
||||
-3
@@ -43,7 +43,4 @@ open class KotlinNodeJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
||||
test.testFramework = KotlinWasmNode(test)
|
||||
}
|
||||
}
|
||||
|
||||
override val additionalCompilerOption: String?
|
||||
get() = "-Xwasm-launcher=nodejs".takeIf { target.platformType == KotlinPlatformType.wasm }
|
||||
}
|
||||
+4
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.process.ExecSpec
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
|
||||
@@ -28,6 +29,8 @@ val KotlinJsCompilation.npmProject: NpmProject
|
||||
open class NpmProject(@Transient val compilation: KotlinJsCompilation) : Serializable {
|
||||
val compilationName = compilation.disambiguatedName
|
||||
|
||||
private val extension = if (compilation.platformType == KotlinPlatformType.wasm) ".mjs" else ".js"
|
||||
|
||||
val name: String by lazy {
|
||||
buildNpmProjectName()
|
||||
}
|
||||
@@ -65,7 +68,7 @@ open class NpmProject(@Transient val compilation: KotlinJsCompilation) : Seriali
|
||||
get() = dir.resolve(DIST_FOLDER)
|
||||
|
||||
val main: String
|
||||
get() = "$DIST_FOLDER/$name.js"
|
||||
get() = "$DIST_FOLDER/$name$extension"
|
||||
|
||||
val externalsDirRoot by lazy {
|
||||
project.buildDir.resolve("externals").resolve(name)
|
||||
|
||||
+10
-11
@@ -14,14 +14,19 @@ import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.d8.D8RootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
||||
import org.jetbrains.kotlin.gradle.targets.js.isTeamCity
|
||||
import org.jetbrains.kotlin.gradle.targets.js.writeWasmUnitTestRunner
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
|
||||
internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTestFramework {
|
||||
override val settingsState: String = "KotlinWasmD8"
|
||||
@Transient
|
||||
override val compilation: KotlinJsCompilation = kotlinJsTest.compilation
|
||||
@Transient
|
||||
private val project: Project = compilation.target.project
|
||||
|
||||
private val d8 = D8RootPlugin.apply(project.rootProject)
|
||||
private val d8Executable by project.provider { d8.requireConfigured().executablePath }
|
||||
private val isTeamCity by lazy { project.isTeamCity }
|
||||
|
||||
init {
|
||||
kotlinJsTest.outputs.upToDateWhen { false }
|
||||
@@ -33,10 +38,10 @@ internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTe
|
||||
nodeJsArgs: MutableList<String>,
|
||||
debug: Boolean
|
||||
): TCServiceMessagesTestExecutionSpec {
|
||||
val compiledFile = task.inputFileProperty.get().asFile
|
||||
val testRunnerFile = writeWasmUnitTestRunner(task.inputFileProperty.get().asFile)
|
||||
|
||||
forkOptions.executable = d8Executable.absolutePath
|
||||
forkOptions.workingDir = compiledFile.parentFile
|
||||
forkOptions.workingDir = testRunnerFile.parentFile
|
||||
|
||||
val clientSettings = TCServiceMessagesClientSettings(
|
||||
task.name,
|
||||
@@ -44,7 +49,7 @@ internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTe
|
||||
prependSuiteName = true,
|
||||
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
|
||||
ignoreOutOfRootNodes = true,
|
||||
escapeTCMessagesInLog = project.isTeamCity
|
||||
escapeTCMessagesInLog = isTeamCity
|
||||
)
|
||||
|
||||
val cliArgs = KotlinTestRunnerCliArgs(
|
||||
@@ -53,26 +58,20 @@ internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTe
|
||||
)
|
||||
|
||||
val args = mutableListOf(
|
||||
"--module",
|
||||
compiledFile.absolutePath,
|
||||
"--experimental-wasm-typed-funcref",
|
||||
"--experimental-wasm-gc",
|
||||
"--experimental-wasm-eh",
|
||||
testRunnerFile.absolutePath,
|
||||
)
|
||||
|
||||
args.add("--")
|
||||
args.addAll(cliArgs.toList())
|
||||
|
||||
val dryRunArgs = mutableListOf<String>()
|
||||
dryRunArgs.addAll(args)
|
||||
dryRunArgs.add("--dryRun")
|
||||
|
||||
return TCServiceMessagesTestExecutionSpec(
|
||||
forkOptions = forkOptions,
|
||||
args = args,
|
||||
checkExitCode = false,
|
||||
clientSettings = clientSettings,
|
||||
dryRunArgs = dryRunArgs
|
||||
dryRunArgs = args + "--dryRun"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+7
-11
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.testing
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.process.ProcessForkOptions
|
||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
|
||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
||||
@@ -13,11 +12,13 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
||||
import org.jetbrains.kotlin.gradle.targets.js.isTeamCity
|
||||
import org.jetbrains.kotlin.gradle.targets.js.writeWasmUnitTestRunner
|
||||
|
||||
internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJsTestFramework {
|
||||
override val settingsState: String = "KotlinWasmNode"
|
||||
@Transient
|
||||
override val compilation: KotlinJsCompilation = kotlinJsTest.compilation
|
||||
private val project: Project = compilation.target.project
|
||||
private val isTeamCity by lazy { compilation.target.project.isTeamCity }
|
||||
|
||||
init {
|
||||
kotlinJsTest.outputs.upToDateWhen { false }
|
||||
@@ -29,7 +30,7 @@ internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJs
|
||||
nodeJsArgs: MutableList<String>,
|
||||
debug: Boolean
|
||||
): TCServiceMessagesTestExecutionSpec {
|
||||
val compiledFile = task.inputFileProperty.get().asFile
|
||||
val testRunnerFile = writeWasmUnitTestRunner(task.inputFileProperty.get().asFile)
|
||||
|
||||
val clientSettings = TCServiceMessagesClientSettings(
|
||||
task.name,
|
||||
@@ -37,7 +38,7 @@ internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJs
|
||||
prependSuiteName = true,
|
||||
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
|
||||
ignoreOutOfRootNodes = true,
|
||||
escapeTCMessagesInLog = project.isTeamCity
|
||||
escapeTCMessagesInLog = isTeamCity
|
||||
)
|
||||
|
||||
val cliArgs = KotlinTestRunnerCliArgs(
|
||||
@@ -47,22 +48,17 @@ internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJs
|
||||
|
||||
val args = mutableListOf<String>()
|
||||
with(args) {
|
||||
add("--experimental-wasm-typed-funcref")
|
||||
add("--experimental-wasm-gc")
|
||||
add("--experimental-wasm-eh")
|
||||
add(compiledFile.absolutePath)
|
||||
add(testRunnerFile.absolutePath)
|
||||
addAll(cliArgs.toList())
|
||||
}
|
||||
val dryRunArgs = mutableListOf<String>()
|
||||
dryRunArgs.addAll(args)
|
||||
dryRunArgs.add("--dryRun")
|
||||
|
||||
return TCServiceMessagesTestExecutionSpec(
|
||||
forkOptions = forkOptions,
|
||||
args = args,
|
||||
checkExitCode = false,
|
||||
clientSettings = clientSettings,
|
||||
dryRunArgs = dryRunArgs
|
||||
dryRunArgs = args + "--dryRun"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -61,6 +61,7 @@ class KotlinKarma(
|
||||
private var configDirectory: File by property {
|
||||
defaultConfigDirectory
|
||||
}
|
||||
private val isTeamCity by lazy { project.isTeamCity }
|
||||
|
||||
override val requiredNpmDependencies: Set<RequiredKotlinJsDependency>
|
||||
get() = requiredDependencies + webpackConfig.getRequiredDependencies(versions)
|
||||
@@ -380,7 +381,7 @@ class KotlinKarma(
|
||||
prependSuiteName = true,
|
||||
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
|
||||
ignoreOutOfRootNodes = true,
|
||||
escapeTCMessagesInLog = project.isTeamCity
|
||||
escapeTCMessagesInLog = isTeamCity
|
||||
)
|
||||
|
||||
config.basePath = npmProject.nodeModulesDir.absolutePath
|
||||
|
||||
+2
-1
@@ -28,6 +28,7 @@ class KotlinMocha(@Transient override val compilation: KotlinJsCompilation, priv
|
||||
private val project: Project = compilation.target.project
|
||||
private val npmProject = compilation.npmProject
|
||||
private val versions = NodeJsRootPlugin.apply(project.rootProject).versions
|
||||
private val isTeamCity by lazy { project.isTeamCity }
|
||||
|
||||
override val settingsState: String
|
||||
get() = "mocha"
|
||||
@@ -59,7 +60,7 @@ class KotlinMocha(@Transient override val compilation: KotlinJsCompilation, priv
|
||||
prependSuiteName = true,
|
||||
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
|
||||
ignoreOutOfRootNodes = true,
|
||||
escapeTCMessagesInLog = project.isTeamCity
|
||||
escapeTCMessagesInLog = isTeamCity
|
||||
)
|
||||
|
||||
val cliArgs = KotlinTestRunnerCliArgs(
|
||||
|
||||
+11
@@ -68,3 +68,14 @@ val Project.isTeamCity: Boolean
|
||||
} else {
|
||||
project.hasProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY)
|
||||
}
|
||||
|
||||
internal fun writeWasmUnitTestRunner(compiledFile: File): File {
|
||||
val testRunnerFile = compiledFile.parentFile.resolve("runUnitTests.mjs")
|
||||
testRunnerFile.writeText(
|
||||
"""
|
||||
import exports from '${compiledFile.absolutePath}';
|
||||
exports.startUnitTests?.();
|
||||
""".trimIndent()
|
||||
)
|
||||
return testRunnerFile
|
||||
}
|
||||
+3
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.tasks.configuration
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.isProduceUnzippedKlib
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
@@ -27,8 +28,9 @@ internal open class BaseKotlin2JsCompileConfig<TASK : Kotlin2JsCompile>(
|
||||
task.incrementalJsKlib = propertiesProvider.incrementalJsKlib ?: true
|
||||
|
||||
task.outputFileProperty.value(task.project.provider {
|
||||
val extensionName = if (compilation.platformType == KotlinPlatformType.wasm) ".mjs" else ".js"
|
||||
task.kotlinOptions.outputFile?.let(::File)
|
||||
?: task.destinationDirectory.locationOnly.get().asFile.resolve("${compilation.ownModuleName}.js")
|
||||
?: task.destinationDirectory.locationOnly.get().asFile.resolve("${compilation.ownModuleName}$extensionName")
|
||||
}).disallowChanges()
|
||||
|
||||
task.optionalOutputFile.fileProvider(task.outputFileProperty.flatMap { outputFile ->
|
||||
|
||||
Reference in New Issue
Block a user