From 266a2234604fb49bd773f7575f89726ac7a73d56 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Tue, 16 May 2023 17:52:22 +0200 Subject: [PATCH] Update scripting plugin autoload logic for K2 --- .../kotlin/cli/common/CLICompiler.kt | 68 +++++++++++++------ .../kotlin/mainKts/test/mainKtsIT.kt | 2 +- 2 files changed, 49 insertions(+), 21 deletions(-) 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 8ec994a8032..b3a917da175 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.kt @@ -28,8 +28,10 @@ import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback import org.jetbrains.kotlin.cli.common.messages.* import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser +import org.jetbrains.kotlin.cli.plugins.extractPluginClasspathAndOptions import org.jetbrains.kotlin.cli.plugins.processCompilerPluginsOptions import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor +import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.ir.util.IrMessageLogger @@ -175,22 +177,25 @@ abstract class CLICompiler : CLITool() { val messageCollector = configuration.getNotNull(MESSAGE_COLLECTOR_KEY) val useK2 = configuration.get(CommonConfigurationKeys.USE_FIR) == true - if (!checkPluginsArguments(messageCollector, useK2, pluginClasspaths, pluginOptions, pluginConfigurations)) { - return INTERNAL_ERROR - } + + val scriptingPluginClasspath = mutableListOf() + val scriptingPluginOptions = mutableListOf() if (!arguments.disableDefaultScriptingPlugin) { - pluginOptions.addPlatformOptions(arguments) - val explicitOrLoadedScriptingPlugin = - pluginClasspaths.any { File(it).name.startsWith(PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME) } || - tryLoadScriptingPluginFromCurrentClassLoader(configuration, pluginOptions) + scriptingPluginOptions.addPlatformOptions(arguments) + val explicitScriptingPlugin = + extractPluginClasspathAndOptions(pluginConfigurations).any { (_, classpath, _) -> + classpath.any { File(it).name.startsWith(PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME) } + } || pluginClasspaths.any { File(it).name.startsWith(PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME) } + val explicitOrLoadedScriptingPlugin = explicitScriptingPlugin || + tryLoadScriptingPluginFromCurrentClassLoader(configuration, pluginOptions, useK2) if (!explicitOrLoadedScriptingPlugin) { val kotlinPaths = paths ?: PathUtil.kotlinPathsForCompiler val libPath = kotlinPaths.libPath.takeIf { it.exists() && it.isDirectory } ?: File(".") val (jars, missingJars) = PathUtil.KOTLIN_SCRIPTING_PLUGIN_CLASSPATH_JARS.map { File(libPath, it) }.partition { it.exists() } if (missingJars.isEmpty()) { - pluginClasspaths.addAll(0, jars.map { it.canonicalPath }) + scriptingPluginClasspath.addAll(0, jars.map { it.canonicalPath }) } else { messageCollector.report( LOGGING, @@ -199,24 +204,37 @@ abstract class CLICompiler : CLITool() { } } } else { - pluginOptions.add("plugin:kotlin.scripting:disable=true") + scriptingPluginOptions.add("plugin:kotlin.scripting:disable=true") } + + pluginClasspaths.addAll(scriptingPluginClasspath) + pluginOptions.addAll(scriptingPluginOptions) + + if (!checkPluginsArguments(messageCollector, useK2, pluginClasspaths, pluginOptions, pluginConfigurations)) { + return INTERNAL_ERROR + } + return PluginCliParser.loadPluginsSafe(pluginClasspaths, pluginOptions, pluginConfigurations, configuration) } - private fun tryLoadScriptingPluginFromCurrentClassLoader(configuration: CompilerConfiguration, pluginOptions: List): Boolean = + private fun tryLoadScriptingPluginFromCurrentClassLoader( + configuration: CompilerConfiguration, + pluginOptions: List, + useK2: Boolean + ): 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)) + val pluginRegistrar = (pluginRegistrarClass.getDeclaredConstructor().newInstance() as? ComponentRegistrar)?.also { + configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, it) + } + val pluginK2Registrar = if (useK2) { + val pluginK2RegistrarClass = PluginCliParser::class.java.classLoader.loadClass(SCRIPT_PLUGIN_K2_REGISTRAR_NAME) + (pluginK2RegistrarClass.getDeclaredConstructor().newInstance() as? CompilerPluginRegistrar)?.also { + configuration.add(CompilerPluginRegistrar.COMPILER_PLUGIN_REGISTRARS, it) } + } else null + if (pluginRegistrar != null || pluginK2Registrar != null) { + processScriptPluginCliOptions(pluginOptions, configuration) true } else false } catch (e: Throwable) { @@ -224,6 +242,16 @@ abstract class CLICompiler : CLITool() { messageCollector.report(LOGGING, "Exception on loading scripting plugin: $e") false } + + private fun processScriptPluginCliOptions(pluginOptions: List, configuration: CompilerConfiguration) { + val cmdlineProcessorClass = + if (pluginOptions.isEmpty()) null + else PluginCliParser::class.java.classLoader.loadClass(SCRIPT_PLUGIN_COMMANDLINE_PROCESSOR_NAME)!! + val cmdlineProcessor = cmdlineProcessorClass?.getDeclaredConstructor()?.newInstance() as? CommandLineProcessor + if (cmdlineProcessor != null) { + processCompilerPluginsOptions(configuration, pluginOptions, listOf(cmdlineProcessor)) + } + } } fun checkPluginsArguments( @@ -231,7 +259,7 @@ fun checkPluginsArguments( useK2: Boolean, pluginClasspaths: List, pluginOptions: List, - pluginConfigurations: MutableList + pluginConfigurations: List ): Boolean { var hasErrors = false diff --git a/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt b/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt index 98b211f13b1..14fbef967ba 100644 --- a/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt +++ b/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt @@ -147,7 +147,7 @@ class MainKtsIT { val serializationPlugin = paths.jar(KotlinPaths.Jar.SerializationPlugin) runWithKotlinc( arrayOf( - "-Xplugin", serializationPlugin.absolutePath, + "-Xplugin=${serializationPlugin.absolutePath}", "-cp", paths.jar(KotlinPaths.Jar.MainKts).absolutePath, "-script", File("$TEST_DATA_ROOT/hello-kotlinx-serialization.main.kts").absolutePath ),