diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.kt index d35865dedbb..1569a420f61 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.kt @@ -28,6 +28,8 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.LOGGING import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser +import org.jetbrains.kotlin.cli.jvm.plugins.processCompilerPluginsOptions +import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.Services @@ -45,6 +47,7 @@ import java.io.PrintStream abstract class CLICompiler : CLITool() { companion object { const val SCRIPT_PLUGIN_REGISTRAR_NAME = "org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar" + const val SCRIPT_PLUGIN_COMMANDLINE_PROCESSOR_NAME = "org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCommandLineProcessor" } abstract val defaultPerformanceManager: CommonCompilerPerformanceManager @@ -174,9 +177,10 @@ abstract class CLICompiler : CLITool() { } if (!arguments.disableDefaultScriptingPlugin) { + pluginOptions.addPlatformOptions(arguments) val explicitOrLoadedScriptingPlugin = pluginClasspaths.any { File(it).name.startsWith(PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME) } || - tryLoadScriptingPluginFromCurrentClassLoader(configuration) + tryLoadScriptingPluginFromCurrentClassLoader(configuration, pluginOptions) if (!explicitOrLoadedScriptingPlugin) { val kotlinPaths = paths ?: PathUtil.kotlinPathsForCompiler val libPath = kotlinPaths.libPath.takeIf { it.exists() && it.isDirectory } ?: File(".") @@ -191,23 +195,31 @@ abstract class CLICompiler : CLITool() { ) } } - pluginOptions.addPlatformOptions(arguments) } else { pluginOptions.add("plugin:kotlin.scripting:disable=true") } return PluginCliParser.loadPluginsSafe(pluginClasspaths, pluginOptions, configuration) } - private fun tryLoadScriptingPluginFromCurrentClassLoader(configuration: CompilerConfiguration): Boolean = try { - val pluginRegistrarClass = PluginCliParser::class.java.classLoader.loadClass(SCRIPT_PLUGIN_REGISTRAR_NAME) - val pluginRegistrar = pluginRegistrarClass.newInstance() as? ComponentRegistrar - if (pluginRegistrar != null) { - configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, pluginRegistrar) - true - } else false - } catch (_: Throwable) { - // TODO: add finer error processing and logging - false - } + private fun tryLoadScriptingPluginFromCurrentClassLoader(configuration: CompilerConfiguration, pluginOptions: List): Boolean = + try { + val pluginRegistrarClass = PluginCliParser::class.java.classLoader.loadClass(SCRIPT_PLUGIN_REGISTRAR_NAME) + val pluginRegistrar = pluginRegistrarClass.getDeclaredConstructor().newInstance() as? ComponentRegistrar + if (pluginRegistrar != null) { + val cmdlineProcessorClass = + if (pluginOptions.isEmpty()) null + else PluginCliParser::class.java.classLoader.loadClass(SCRIPT_PLUGIN_COMMANDLINE_PROCESSOR_NAME)!! + val cmdlineProcessor = cmdlineProcessorClass?.getDeclaredConstructor()?.newInstance() as? CommandLineProcessor + configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, pluginRegistrar) + if (cmdlineProcessor != null) { + processCompilerPluginsOptions(configuration, pluginOptions, listOf(cmdlineProcessor)) + } + true + } else false + } catch (e: Throwable) { + val messageCollector = configuration.getNotNull(MESSAGE_COLLECTOR_KEY) + messageCollector.report(LOGGING, "Exception on loading scripting plugin: $e") + false + } } diff --git a/compiler/testData/integration/ant/js/verbose/build.log.expected b/compiler/testData/integration/ant/js/verbose/build.log.expected index 8d2194b6fe8..3547c07936c 100644 --- a/compiler/testData/integration/ant/js/verbose/build.log.expected +++ b/compiler/testData/integration/ant/js/verbose/build.log.expected @@ -4,6 +4,7 @@ Buildfile: [TestData]/build.xml build: [kotlin2js] Compiling [[TestData]/root1] => [[Temp]/out.js] [kotlin2js] logging: using Kotlin home directory [KotlinProjectHome]/dist/kotlinc +[kotlin2js] logging: exception on loading scripting plugin: java.lang.ClassNotFoundException: org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar [kotlin2js] logging: configure scripting: Added template org.jetbrains.kotlin.mainKts.MainKtsScript from [[CompilerLib]/kotlin-main-kts.jar, [CompilerLib]/kotlin-reflect.jar, [CompilerLib]/kotlin-script-runtime.jar, [CompilerLib]/kotlin-stdlib.jar] [kotlin2js] logging: compiling source files: [TestData]/root1/foo.kt diff --git a/compiler/testData/integration/ant/jvm/verbose/build.log.expected b/compiler/testData/integration/ant/jvm/verbose/build.log.expected index 66a43fb0592..01b50dabf9d 100644 --- a/compiler/testData/integration/ant/jvm/verbose/build.log.expected +++ b/compiler/testData/integration/ant/jvm/verbose/build.log.expected @@ -4,6 +4,7 @@ Buildfile: [TestData]/build.xml build: [kotlinc] Compiling [[TestData]/hello.kt] => [[Temp]/hello.jar] [kotlinc] logging: using Kotlin home directory [KotlinProjectHome]/dist/kotlinc + [kotlinc] logging: exception on loading scripting plugin: java.lang.ClassNotFoundException: org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar [kotlinc] logging: using JVM IR backend [kotlinc] logging: configuring the compilation environment [kotlinc] logging: configure scripting: Added template org.jetbrains.kotlin.mainKts.MainKtsScript from [[CompilerLib]/kotlin-main-kts.jar, [CompilerLib]/kotlin-reflect.jar, [CompilerLib]/kotlin-script-runtime.jar, [CompilerLib]/kotlin-stdlib.jar] diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/configuration/ScriptingConfigurationKeys.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/configuration/ScriptingConfigurationKeys.kt index ce3b9c3cc94..dda19dcaf44 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/configuration/ScriptingConfigurationKeys.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/configuration/ScriptingConfigurationKeys.kt @@ -29,6 +29,9 @@ object ScriptingConfigurationKeys { val DISABLE_SCRIPT_DEFINITIONS_FROM_CLASSPATH_OPTION: CompilerConfigurationKey = CompilerConfigurationKey.create("Do not extract script definitions from the compilation classpath") + val DISABLE_SCRIPT_DEFINITIONS_AUTOLOADING_OPTION: CompilerConfigurationKey = + CompilerConfigurationKey.create("Do not automatically load compiler-supplied script definitions, like main-kts") + val LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION: CompilerConfigurationKey> = CompilerConfigurationKey.create("Script resolver environment") } \ No newline at end of file diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCommandLineProcessor.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCommandLineProcessor.kt index 1c46da6fe38..d21f33fa51f 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCommandLineProcessor.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCommandLineProcessor.kt @@ -15,23 +15,6 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys import java.io.File -object ScriptingConfigurationKeys { - val DISABLE_SCRIPTING_PLUGIN_OPTION: CompilerConfigurationKey = - CompilerConfigurationKey.create("Disable scripting plugin") - - val SCRIPT_DEFINITIONS: CompilerConfigurationKey> = - CompilerConfigurationKey.create("Script definition classes") - - val SCRIPT_DEFINITIONS_CLASSPATH: CompilerConfigurationKey> = - CompilerConfigurationKey.create("Additional classpath for the script definitions") - - val DISABLE_SCRIPT_DEFINITIONS_FROM_CLASSPATH_OPTION: CompilerConfigurationKey = - CompilerConfigurationKey.create("Do not extract script definitions from the compilation classpath") - - val LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION: CompilerConfigurationKey> = - CompilerConfigurationKey.create("Script resolver environment") -} - class ScriptingCommandLineProcessor : CommandLineProcessor { companion object { val DISABLE_SCRIPTING_PLUGIN_OPTION = CliOption( @@ -54,6 +37,10 @@ class ScriptingCommandLineProcessor : CommandLineProcessor { "disable-script-definitions-from-classpath", "true/false", "Do not extract script definitions from the compilation classpath", required = false, allowMultipleOccurrences = false ) + val DISABLE_SCRIPT_DEFINITIONS_AUTOLOADING_OPTION = CliOption( + "disable-script-definitions-autoloading", "true/false", "Do not automatically load compiler-supplied script definitions, like main-kts", + required = false, allowMultipleOccurrences = false + ) val LEGACY_SCRIPT_TEMPLATES_OPTION = CliOption( "script-templates", "", "Script definition template classes", required = false, allowMultipleOccurrences = true @@ -73,6 +60,7 @@ class ScriptingCommandLineProcessor : CommandLineProcessor { SCRIPT_DEFINITIONS_CLASSPATH_OPTION, DISABLE_STANDARD_SCRIPT_DEFINITION_OPTION, DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION, + DISABLE_SCRIPT_DEFINITIONS_AUTOLOADING_OPTION, LEGACY_SCRIPT_TEMPLATES_OPTION, LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION ) @@ -107,6 +95,12 @@ class ScriptingCommandLineProcessor : CommandLineProcessor { value.takeUnless { it.isBlank() }?.toBoolean() ?: true ) } + DISABLE_SCRIPT_DEFINITIONS_AUTOLOADING_OPTION -> { + configuration.put( + ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_AUTOLOADING_OPTION, + value.takeUnless { it.isBlank() }?.toBoolean() ?: true + ) + } LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION -> { val currentEnv = configuration.getMap(ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION).toMutableMap() // parses key/value pairs in the form =, where diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerConfigurationExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerConfigurationExtension.kt index 328db81c517..8729826f22f 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerConfigurationExtension.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingCompilerConfigurationExtension.kt @@ -67,16 +67,21 @@ class ScriptingCompilerConfigurationExtension( ) } - configuration.addAll( - ScriptingConfigurationKeys.SCRIPT_DEFINITIONS_SOURCES, - listOf( + val definitionsFromClasspath = + if (configuration.getBoolean(ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_FROM_CLASSPATH_OPTION)) null + else ScriptDefinitionsFromClasspathDiscoverySource( configuration.jvmClasspathRoots, hostConfiguration, messageCollector.reporter - ), - AutoloadedScriptDefinitions(hostConfiguration, this::class.java.classLoader, messageCollector.reporter) - ) + ) + val autoloadedScriptDefinitions = + if (configuration.getBoolean(ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_AUTOLOADING_OPTION)) null + else AutoloadedScriptDefinitions(hostConfiguration, this::class.java.classLoader, messageCollector.reporter) + + configuration.addAll( + ScriptingConfigurationKeys.SCRIPT_DEFINITIONS_SOURCES, + listOfNotNull(definitionsFromClasspath, autoloadedScriptDefinitions) ) val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) as? CliScriptDefinitionProvider