[K/JS] Introduce the ability to consume platform-specific cli arguments inside the main function ^KT-16981 Fixed
This commit is contained in:
+1
@@ -57,6 +57,7 @@ fun copyK2JSCompilerArguments(from: K2JSCompilerArguments, to: K2JSCompilerArgum
|
||||
to.outputPrefix = from.outputPrefix
|
||||
to.partialLinkageLogLevel = from.partialLinkageLogLevel
|
||||
to.partialLinkageMode = from.partialLinkageMode
|
||||
to.platformArgumentsProviderJsExpression = from.platformArgumentsProviderJsExpression
|
||||
to.sourceMap = from.sourceMap
|
||||
to.sourceMapBaseDirs = from.sourceMapBaseDirs
|
||||
to.sourceMapEmbedSources = from.sourceMapEmbedSources
|
||||
|
||||
+10
@@ -494,6 +494,16 @@ In combination with '-meta-info', this generates both IR and pre-IR versions of
|
||||
field = value
|
||||
}
|
||||
|
||||
@Argument(
|
||||
value = "-Xplatform-arguments-in-main-function",
|
||||
description = "JS expression that will be executed in runtime and be put as an Array<String> parameter of the main function"
|
||||
)
|
||||
var platformArgumentsProviderJsExpression: String? = null
|
||||
set(value) {
|
||||
checkFrozen()
|
||||
field = value
|
||||
}
|
||||
|
||||
@GradleOption(
|
||||
value = DefaultValue.BOOLEAN_TRUE_DEFAULT,
|
||||
gradleInputType = GradleInputTypes.INPUT,
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.RUNTIME_DIAGNOSTIC_EXCEPTION
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.RUNTIME_DIAGNOSTIC_LOG
|
||||
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.fir.reportToMessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
@@ -211,6 +210,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
configurationJs.put(JSConfigurationKeys.GENERATE_DTS, arguments.generateDts)
|
||||
configurationJs.put(JSConfigurationKeys.GENERATE_INLINE_ANONYMOUS_FUNCTIONS, arguments.irGenerateInlineAnonymousFunctions)
|
||||
|
||||
arguments.platformArgumentsProviderJsExpression?.let {
|
||||
configurationJs.put(JSConfigurationKeys.DEFINE_PLATFORM_MAIN_FUNCTION_ARGUMENTS, it)
|
||||
}
|
||||
|
||||
val zipAccessor = DisposableZipFileSystemAccessor(64)
|
||||
Disposer.register(rootDisposable, zipAccessor)
|
||||
configurationJs.put(JSConfigurationKeys.ZIP_FILE_SYSTEM_ACCESSOR, zipAccessor)
|
||||
|
||||
@@ -105,6 +105,7 @@ class JsIrBackendContext(
|
||||
val devMode = configuration[JSConfigurationKeys.DEVELOPER_MODE] ?: false
|
||||
val errorPolicy = configuration[JSConfigurationKeys.ERROR_TOLERANCE_POLICY] ?: ErrorTolerancePolicy.DEFAULT
|
||||
override val es6mode = configuration[JSConfigurationKeys.USE_ES6_CLASSES] ?: false
|
||||
val platformArgumentsProviderJsExpression = configuration[JSConfigurationKeys.DEFINE_PLATFORM_MAIN_FUNCTION_ARGUMENTS]
|
||||
|
||||
val externalPackageFragment = mutableMapOf<IrFileSymbol, IrFile>()
|
||||
|
||||
|
||||
+7
-1
@@ -179,7 +179,13 @@ internal class ICHasher {
|
||||
hashCalculator.update(value.ordinal)
|
||||
}
|
||||
|
||||
hashCalculator.updateConfigKeys(config, listOf(JSConfigurationKeys.SOURCE_MAP_PREFIX)) { value: String ->
|
||||
hashCalculator.updateConfigKeys(
|
||||
config,
|
||||
listOf(
|
||||
JSConfigurationKeys.SOURCE_MAP_PREFIX,
|
||||
JSConfigurationKeys.DEFINE_PLATFORM_MAIN_FUNCTION_ARGUMENTS
|
||||
)
|
||||
) { value: String ->
|
||||
hashCalculator.update(value)
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -72,7 +72,11 @@ class MainFunctionCallWrapperLowering(private val context: JsIrBackendContext) :
|
||||
|
||||
return listOfNotNull(
|
||||
runIf(generateArgv) {
|
||||
JsIrBuilder.buildArray(
|
||||
context.platformArgumentsProviderJsExpression?.let {
|
||||
JsIrBuilder.buildCall(context.intrinsics.jsCode).apply {
|
||||
putValueArgument(0, it.toIrConst(context.irBuiltIns.stringType))
|
||||
}
|
||||
} ?: JsIrBuilder.buildArray(
|
||||
mainFunctionArgs.map { it.toIrConst(context.irBuiltIns.stringType) },
|
||||
valueParameters.first().type,
|
||||
context.irBuiltIns.stringType
|
||||
|
||||
+2
@@ -49,6 +49,8 @@ where advanced options include:
|
||||
Define the compile-time log level for partial linkage.
|
||||
-Xpartial-linkage={enable|disable}
|
||||
Use partial linkage mode.
|
||||
-Xplatform-arguments-in-main-function
|
||||
JS expression that will be executed in runtime and be put as an Array<String> parameter of the main function
|
||||
-Xstrict-implicit-export-types Generate strict types for implicitly exported entities inside d.ts files. This is available in the IR backend only.
|
||||
-Xtyped-arrays Translate primitive arrays into JS typed arrays.
|
||||
-Xes-classes Let generated JavaScript code use ES2015 classes.
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider;
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer;
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -80,6 +81,9 @@ public class JSConfigurationKeys {
|
||||
public static final CompilerConfigurationKey<Boolean> GENERATE_POLYFILLS =
|
||||
CompilerConfigurationKey.create("generate polyfills for newest properties, methods and classes from ES6+");
|
||||
|
||||
public static final CompilerConfigurationKey<String> DEFINE_PLATFORM_MAIN_FUNCTION_ARGUMENTS =
|
||||
CompilerConfigurationKey.create("provide platform specific args as a parameter of the main function");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> GENERATE_DTS =
|
||||
CompilerConfigurationKey.create("generate TypeScript definition file");
|
||||
|
||||
|
||||
+18
@@ -47,6 +47,24 @@ class Kotlin2JsIrGradlePluginIT : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("nodejs main function arguments")
|
||||
@GradleTest
|
||||
fun testNodeJsMainArguments(gradleVersion: GradleVersion) {
|
||||
project("kotlin-js-nodejs-project", gradleVersion) {
|
||||
buildGradle.appendText(
|
||||
"""
|
||||
|
|
||||
|tasks.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExec).configureEach {
|
||||
| args += ["test", "'Hello, World'"]
|
||||
|}
|
||||
""".trimMargin()
|
||||
)
|
||||
build("nodeRun") {
|
||||
assertOutputContains("ACCEPTED: test;'Hello, World'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("stale output is cleaned")
|
||||
@GradleTest
|
||||
fun testCleanOutputWithEmptySources(gradleVersion: GradleVersion) {
|
||||
|
||||
+1
@@ -17,6 +17,7 @@ kotlin {
|
||||
useCommonJs()
|
||||
binaries.executable()
|
||||
nodejs {
|
||||
passProcessArgvToMainFunction()
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -11,4 +11,8 @@ fun best(): Int {
|
||||
|
||||
fun simpleBest(): Int {
|
||||
return 73
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println("ACCEPTED: ${args.drop(2).joinToString(";")}")
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.dsl
|
||||
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalMainFunctionArgumentsDsl
|
||||
+9
@@ -47,6 +47,12 @@ interface KotlinJsTargetDsl : KotlinTarget, KotlinTargetWithNodeJsDsl {
|
||||
fun useCommonJs()
|
||||
fun useEsModules()
|
||||
|
||||
/**
|
||||
* The function accepts [jsExpression] and puts this expression as the "args: Array<String>" argument in place of main-function call
|
||||
*/
|
||||
@ExperimentalMainFunctionArgumentsDsl
|
||||
fun passAsArgumentToMainFunction(jsExpression: String)
|
||||
|
||||
fun generateTypeScriptDefinitions()
|
||||
|
||||
val binaries: KotlinJsBinaryContainer
|
||||
@@ -98,4 +104,7 @@ interface KotlinJsBrowserDsl : KotlinJsSubTargetDsl {
|
||||
|
||||
interface KotlinJsNodeDsl : KotlinJsSubTargetDsl {
|
||||
fun runTask(body: Action<NodeJsExec>)
|
||||
|
||||
@ExperimentalMainFunctionArgumentsDsl
|
||||
fun passProcessArgvToMainFunction()
|
||||
}
|
||||
+13
@@ -433,6 +433,19 @@ constructor(
|
||||
|
||||
}
|
||||
|
||||
override fun passAsArgumentToMainFunction(jsExpression: String) {
|
||||
compilations
|
||||
.all {
|
||||
it.binaries
|
||||
.withType(JsIrBinary::class.java)
|
||||
.all {
|
||||
it.linkTask.configure { linkTask ->
|
||||
linkTask.compilerOptions.freeCompilerArgs.add("-Xplatform-arguments-in-main-function=$jsExpression")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinJsOptions.configureCommonJsOptions() {
|
||||
moduleKind = "commonjs"
|
||||
sourceMap = true
|
||||
|
||||
+4
@@ -32,6 +32,10 @@ abstract class KotlinNodeJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
||||
project.tasks.withType<NodeJsExec>().named(runTaskName).configure(body)
|
||||
}
|
||||
|
||||
override fun passProcessArgvToMainFunction() {
|
||||
target.passAsArgumentToMainFunction("process.argv")
|
||||
}
|
||||
|
||||
override fun locateOrRegisterRunTask(binary: JsIrBinary, name: String) {
|
||||
if (project.locateTask<NodeJsExec>(name) != null) return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user