diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java index f038db1ffa4..eaa71c125a9 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java @@ -111,6 +111,10 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments { @Argument(value = "Xload-builtins-from-dependencies", description = "Load definitions of built-in declarations from module dependencies, instead of from the compiler") public boolean loadBuiltInsFromDependencies; + @Argument(value = "Xscript-resolver-environment", description = "Script resolver environment in key-value pairs (the value could be quoted and escaped)") + @ValueDescription("") + public String[] scriptResolverEnvironment; + // Paths to output directories for friend modules. public String[] friendPaths; diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index fa5461cfb6f..a0fd4e7cf86 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -214,13 +214,14 @@ class K2JVMCompiler : CLICompiler() { } } + private fun createEnvironmentWithScriptingSupport(rootDisposable: Disposable, configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments, messageCollector: MessageCollector ): KotlinCoreEnvironment? { - val scriptResolverEnv = hashMapOf() + val scriptResolverEnv = createScriptResolverEnvironment(arguments, messageCollector) ?: return null configureScriptDefinitions(arguments.scriptTemplates, configuration, messageCollector, scriptResolverEnv) if (!messageCollector.hasErrors()) { val environment = createCoreEnvironment(rootDisposable, configuration) @@ -415,6 +416,27 @@ class K2JVMCompiler : CLICompiler() { } configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) } + + fun createScriptResolverEnvironment(arguments: K2JVMCompilerArguments, messageCollector: MessageCollector): HashMap? { + val scriptResolverEnv = hashMapOf() + // parses key/value pairs in the form =, where + // - is a single word (\w+ pattern) + // - optionally quoted string with allowed escaped chars (only double-quote and backslash chars are supported) + // TODO: implement generic unescaping + val envParseRe = """(\w+)=(?:"((?:\\.|[^"])*)"|([^\s]*))""".toRegex() + val unescapeRe = """\\(["\\])""".toRegex() + if (arguments.scriptResolverEnvironment != null) { + for (envParam in arguments.scriptResolverEnvironment) { + val match = envParseRe.matchEntire(envParam) + if (match == null || match.groupValues.size < 4 || match.groupValues[1].isBlank()) { + messageCollector.report(CompilerMessageSeverity.ERROR, "Unable to parse script-resolver-environment argument $envParam", CompilerMessageLocation.NO_LOCATION) + return null + } + scriptResolverEnv.put(match.groupValues[1], match.groupValues.drop(2).firstOrNull { it.isNotEmpty() }?.let { unescapeRe.replace(it, "\$1") }) + } + } + return scriptResolverEnv + } } } diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index b8d7c4e55ba..c2458c6caae 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -11,6 +11,8 @@ where advanced options include: -Xadd-compiler-builtins Add definitions of built-in declarations to the compilation classpath (useful with -no-stdlib) -Xload-builtins-from-dependencies Load definitions of built-in declarations from module dependencies, instead of from the compiler + -Xscript-resolver-environment + Script resolver environment in key-value pairs (the value could be quoted and escaped) -Xno-inline Disable method inlining -Xrepeat Repeat compilation (for performance analysis) -Xskip-metadata-version-check Load classes with bad metadata version anyway (incl. pre-release classes) diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerApiTest.kt b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerApiTest.kt index 8e8490492ba..22c647a8bdc 100644 --- a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerApiTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerApiTest.kt @@ -92,6 +92,18 @@ class CompilerApiTest : KotlinIntegrationTestBase() { } } + fun testScriptResolverEnvironmentArgsParsing() { + + fun args(body: K2JVMCompilerArguments.() -> Unit): K2JVMCompilerArguments = + K2JVMCompilerArguments().apply(body) + + val messageCollector = TestMessageCollector() + Assert.assertEquals(hashMapOf("abc" to "def", "11" to "ab cd \\ \""), + K2JVMCompiler.createScriptResolverEnvironment( + args { scriptResolverEnvironment = arrayOf("abc=def", """11="ab cd \\ \""""") }, + messageCollector)) + } + fun testHelloAppLocal() { val messageCollector = TestMessageCollector() val jar = tmpdir.absolutePath + File.separator + "hello.jar"