customize compiler plugin set via custom target

GitOrigin-RevId: ad790785ccd29b1922210547b7555e82761c7a00
This commit is contained in:
Vladimir Krivosheev
2025-05-09 20:49:36 +00:00
committed by intellij-monorepo-bot
parent 5bbb4bfbe0
commit 3023c3224b
18 changed files with 98 additions and 81 deletions
+8 -9
View File
@@ -11,11 +11,17 @@ label_flag(
)
label_flag(
name = "worker-impl",
name = "resource-packager",
build_setting_default = "//src/misc:worker-jvm",
visibility = ["//visibility:public"],
)
label_flag(
name = "jvm-builder",
build_setting_default = "//src/jvm-builder",
visibility = ["//visibility:public"],
)
kt_kotlinc_options(
name = "default-kotlinc-opts-value",
visibility = ["//visibility:public"],
@@ -436,13 +442,6 @@ jvm_import(
visibility = ["//visibility:public"],
)
jvm_import(
name = "expects-compiler-plugin",
jar = "@expects-compiler-plugin//file",
source_jar = "@expects-compiler-plugin-sources//file",
visibility = ["//visibility:public"],
)
jvm_import(
name = "asm-all",
jar = "@asm-all//file",
@@ -474,4 +473,4 @@ jvm_import(
],
)
### auto-generated section `libraries` end
### auto-generated section `libraries` end
-14
View File
@@ -674,20 +674,6 @@ http_file(
url = "https://cache-redirector.jetbrains.com/packages.jetbrains.team/maven/p/ij/intellij-dependencies/com/intellij/platform/kotlinx-coroutines-core-jvm/1.10.1-intellij-4/kotlinx-coroutines-core-jvm-1.10.1-intellij-4-sources.jar",
)
http_file(
name = "expects-compiler-plugin",
downloaded_file_path = "expects-compiler-plugin-2.1.20-0.2.jar",
sha256 = "53f345b9ec17aa821e8e4acce59b6584f55a2193f5c48dcea9ffc41eaac4add4",
url = "https://cache-redirector.jetbrains.com/packages.jetbrains.team/maven/p/ij/intellij-dependencies/jetbrains/fleet/expects-compiler-plugin/2.1.20-0.2/expects-compiler-plugin-2.1.20-0.2.jar",
)
http_file(
name = "expects-compiler-plugin-sources",
downloaded_file_path = "expects-compiler-plugin-2.1.20-0.2-sources.jar",
sha256 = "a9125f58235ac48fbc657210b43eb2a8a80d2c6cc9538219764d5d64a852c49f",
url = "https://cache-redirector.jetbrains.com/packages.jetbrains.team/maven/p/ij/intellij-dependencies/jetbrains/fleet/expects-compiler-plugin/2.1.20-0.2/expects-compiler-plugin-2.1.20-0.2-sources.jar",
)
http_file(
name = "asm-all",
downloaded_file_path = "asm-all-9.6.1.jar",
-4
View File
@@ -107,10 +107,6 @@
"d6fdaf0f04724d5c9362db2f809fd21f36e95c9c039d22fe695692d606107bff",
"dd827c172d20f046d5bf6a9df772290b0eaafb59589b6b98fd742c6bc78c2d37"
],
"jetbrains.fleet:expects-compiler-plugin:2.1.20-0.2": [
"53f345b9ec17aa821e8e4acce59b6584f55a2193f5c48dcea9ffc41eaac4add4",
"a9125f58235ac48fbc657210b43eb2a8a80d2c6cc9538219764d5d64a852c49f"
],
"org.apache.arrow:arrow-format:18.2.0": [
"6d977352a232559c97a38dfdd786f014e87489d3bb3f33f12cfed30bdd164669",
"6b0e19b1d0270a5fd51182d815738e7b2aba4f00b6cf9a3a41d13aebb4e12d0a"
-2
View File
@@ -126,8 +126,6 @@
libs:
- id: com.intellij.platform:kotlinx-coroutines-core-jvm
version: 1.10.1-intellij-4
- id: jetbrains.fleet:expects-compiler-plugin
version: 2.1.20-0.2
- id: org.jetbrains.intellij.deps:asm-all
version: 9.6.1
- id: org.jetbrains.intellij.deps.fastutil:intellij-deps-fastutil
+1 -1
View File
@@ -92,7 +92,7 @@ common_attr = add_dicts(
providers = [_JavacOptions],
),
"_jvm_builder": attr.label(
default = "//src/jvm-builder:jvm-builder",
default = "//:jvm-builder",
executable = True,
allow_files = True,
cfg = "exec",
+1 -1
View File
@@ -59,7 +59,7 @@ jvm_resources = rule(
),
# see https://bazel.build/extending/rules#private_attributes_and_implicit_dependencies about implicit dependencies
"_worker": attr.label(
default = Label("//:worker-impl"),
default = Label("//:resource-packager"),
executable = True,
allow_files = True,
cfg = "exec",
@@ -1,4 +1,3 @@
load("@rules_java//java:defs.bzl", "java_binary")
load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
load("//:jvm.bzl", "jvm_import")
load("//:src/jvm-args.bzl", "get_jvm_flags")
@@ -7,6 +6,8 @@ kt_jvm_library(
name = "jvm-builder-core",
srcs = glob(["**/*.kt"]),
kotlinc_opts = "//:rules_jvm_bootstrap_kotlinc_options",
visibility = ["//visibility:public"],
# buildifier: leave-alone
deps = [
"//src/kotlin/kotlin-shadow",
"//:collection",
@@ -21,7 +22,6 @@ kt_jvm_library(
"//src/kotlin/kotlin-compiler",
"//:netty-buffer",
"//:netty-common",
"//:opentelemetry-api"
"//:opentelemetry-api",
],
visibility = ["//visibility:public"],
)
@@ -1,10 +1,13 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:OptIn(ExperimentalCompilerApi::class)
package org.jetbrains.bazel.jvm.worker.core
import com.intellij.openapi.util.UserDataHolderBase
import com.intellij.util.EventDispatcher
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.isActive
import org.jetbrains.bazel.jvm.kotlin.CompilerPluginProvider
import org.jetbrains.jps.ModuleChunk
import org.jetbrains.jps.api.CanceledStatus
import org.jetbrains.jps.builders.BuildTarget
@@ -18,8 +21,16 @@ import org.jetbrains.jps.incremental.messages.BuildMessage
import org.jetbrains.jps.incremental.messages.FileDeletedEvent
import org.jetbrains.jps.incremental.messages.FileGeneratedEvent
import org.jetbrains.jps.incremental.messages.ProgressMessage
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import java.lang.invoke.MethodHandle
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
import kotlin.coroutines.CoroutineContext
@Suppress("SpellCheckingInspection")
class BazelCompileContext(
@JvmField val scope: BazelCompileScope,
private val projectDescriptor: ProjectDescriptor,
@@ -28,6 +39,25 @@ class BazelCompileContext(
) : UserDataHolderBase(), CompileContext {
private val cancelStatus = CanceledStatus { !coroutineContext.isActive }
@JvmField
val pluginProvider: CompilerPluginProvider = object : CompilerPluginProvider {
// todo configure via build setting label
private val expects by getConstructor("fleet.multiplatform.expects.ExpectsPluginRegistrar", null)
private val rhizomeDb by getConstructor(
registrar = "com.jetbrains.rhizomedb.plugin.RhizomedbComponentRegistrar",
commandLineProcessor = "com.jetbrains.rhizomedb.plugin.RhizomedbCommandLineProcessor",
)
@Suppress("SpellCheckingInspection")
override fun provide(id: String): PluginCliParser.RegisteredPluginInfo {
return when (id) {
"jetbrains.fleet.expects-compiler-plugin" -> createPluginInfo(expects)
"org.jetbrains.fleet.rhizomedb-compiler-plugin" -> createPluginInfo(rhizomeDb)
else -> throw IllegalArgumentException("plugin requires classpath: $id")
}
}
}
private var isMarkedAsNonIncremental = false
@Volatile
private var compilationStartStamp = 0L
@@ -102,4 +132,24 @@ class BazelCompileContext(
}
override fun getProjectDescriptor(): ProjectDescriptor = projectDescriptor
}
private fun createPluginInfo(data: Pair<MethodHandle, MethodHandle?>): PluginCliParser.RegisteredPluginInfo {
return PluginCliParser.RegisteredPluginInfo(
componentRegistrar = null,
compilerPluginRegistrar = data.first.invoke() as CompilerPluginRegistrar,
commandLineProcessor = data.second?.invoke() as CommandLineProcessor?,
pluginOptions = emptyList(),
)
}
private fun getConstructor(registrar: String, commandLineProcessor: String?): Lazy<Pair<MethodHandle, MethodHandle?>> {
return lazy {
findConstructor(registrar) to commandLineProcessor?.let { findConstructor(it) }
}
}
private fun findConstructor(name: String): MethodHandle {
val aClass = BazelCompileContext::class.java.classLoader.loadClass(name)
return MethodHandles.lookup().findConstructor(aClass, MethodType.methodType(Void.TYPE))
}
@@ -105,7 +105,7 @@ import java.nio.file.Files
import java.nio.file.Path
import kotlin.coroutines.coroutineContext
private val classesToLoadByParent = ClassCondition { className ->
private val classesToLoadByParent = ClassCondition { _ ->
throw IllegalStateException("Should never be called")
}
@@ -289,7 +289,7 @@ class IncrementalKotlinBuilder(
importTracker = ImportTrackerImpl(),
chunk = chunk,
messageCollector = messageCollector
) ?: return ModuleLevelBuilder.ExitCode.ABORT
)
val generatedFiles = doCompileModuleChunk(
prevOutputVirtualDir = prevOutputVirtualDir,
@@ -539,6 +539,7 @@ private suspend fun doCompileModuleChunk(
args = bazelConfigurationHolder.args,
kotlinArgs = bazelConfigurationHolder.kotlinArgs,
baseDir = bazelConfigurationHolder.classPathRootDir,
pluginProvider = context.pluginProvider,
abiOutputConsumer = {
outputConsumer.registerKotlincAbiOutput(it)
},
@@ -616,7 +617,7 @@ private fun createCompileEnvironment(
chunk: ModuleChunk,
messageCollector: MessageCollectorAdapter,
outputItemCollector: OutputItemsCollectorImpl
): JpsCompilerEnvironment? {
): JpsCompilerEnvironment {
val builder = Services.Builder()
builder.register(LookupTracker::class.java, implementation = lookupTracker)
builder.register(ExpectActualTracker::class.java, implementation = exceptActualTracer)
@@ -800,5 +801,5 @@ private object DummyKotlinPaths : KotlinPaths {
override fun klib(jar: KotlinPaths.Jar): File = throw kotlin.IllegalStateException()
override fun sourcesJar(jar: KotlinPaths.Jar): File? = throw kotlin.IllegalStateException()
override fun sourcesJar(jar: KotlinPaths.Jar): File = throw kotlin.IllegalStateException()
}
@@ -6,10 +6,6 @@ package org.jetbrains.bazel.jvm.kotlin
import io.opentelemetry.api.trace.Span
import kotlinx.coroutines.Job
import kotlinx.coroutines.ensureActive
import org.jetbrains.bazel.jvm.kotlin.configureModule
import org.jetbrains.bazel.jvm.kotlin.createJvmPipeline
import org.jetbrains.bazel.jvm.kotlin.executeJvmPipeline
import org.jetbrains.bazel.jvm.kotlin.prepareCompilerConfiguration
import org.jetbrains.bazel.jvm.worker.core.BazelCompileContext
import org.jetbrains.bazel.jvm.worker.core.BazelConfigurationHolder
import org.jetbrains.bazel.jvm.worker.core.BazelDirtyFileHolder
@@ -62,6 +58,7 @@ class NonIncrementalKotlinBuilder(
args = bazelConfigurationHolder.args,
kotlinArgs = bazelConfigurationHolder.kotlinArgs,
baseDir = bazelConfigurationHolder.classPathRootDir,
pluginProvider = context.pluginProvider,
abiOutputConsumer = {
outputConsumer.registerKotlincAbiOutput(it)
},
@@ -4,13 +4,12 @@ kt_jvm_library(
name = "kotlin-compiler",
srcs = glob(["*.kt"]),
kotlinc_opts = "//:rules_jvm_bootstrap_kotlinc_options",
deps = [
"//src/worker-util",
"//:kotlin-compiler",
"//src/kotlin/kotlin-plugins/abi",
"//:kotlin-compose-compiler-plugin",
"//:expects-compiler-plugin",
"//:kotlin-serialization-compiler-plugin",
],
visibility = ["//visibility:public"],
)
deps = [
"//:kotlin-compiler",
"//:kotlin-compose-compiler-plugin",
"//:kotlin-serialization-compiler-plugin",
"//src/kotlin/kotlin-plugins/abi",
"//src/worker-util",
],
)
@@ -68,6 +68,7 @@ fun prepareCompilerConfiguration(
args: ArgMap<JvmBuilderFlags>,
kotlinArgs: K2JVMCompilerArguments,
baseDir: Path,
pluginProvider: CompilerPluginProvider,
abiOutputConsumer: (List<OutputFile>) -> Unit,
): CompilerConfiguration {
val config = configTemplate.copy()
@@ -75,6 +76,7 @@ fun prepareCompilerConfiguration(
configurePlugins(
args = args,
workingDir = baseDir,
pluginProvider = pluginProvider,
abiOutputConsumer = abiOutputConsumer,
) {
config.add(CompilerPluginRegistrar.COMPILER_PLUGIN_REGISTRARS, it.compilerPluginRegistrar!!)
@@ -164,9 +166,9 @@ fun configureModule(
}
@OptIn(ExperimentalCompilerApi::class)
fun getDebugInfoAboutPlugins(args: ArgMap<JvmBuilderFlags>, baseDir: Path, targetLabel: String): String {
fun getDebugInfoAboutPlugins(args: ArgMap<JvmBuilderFlags>, baseDir: Path, pluginProvider: CompilerPluginProvider): String {
val sb = StringBuilder()
configurePlugins(args = args, workingDir = baseDir, abiOutputConsumer = null) { info ->
configurePlugins(args = args, workingDir = baseDir, pluginProvider = pluginProvider, abiOutputConsumer = null) { info ->
sb.append(info.compilerPluginRegistrar!!.toString())
if (!info.pluginOptions.isEmpty()) {
sb.append("(" + info.pluginOptions.joinToString(separator = ", ") + ")")
@@ -219,7 +221,7 @@ private class BazelJvmConfigurationPipelinePhase(
postActions = setOf(CheckCompilationErrors.CheckMessageCollector),
configurationUpdaters = emptyList()
) {
override fun executePhase(input: ArgumentsPipelineArtifact<K2JVMCompilerArguments>): ConfigurationPipelineArtifact? {
override fun executePhase(input: ArgumentsPipelineArtifact<K2JVMCompilerArguments>): ConfigurationPipelineArtifact {
return ConfigurationPipelineArtifact(config, input.diagnosticCollector, input.rootDisposable)
}
@@ -242,7 +244,7 @@ private class BazelJvmBackendPipelinePhase(
CheckCompilationErrors.CheckDiagnosticCollector
)
) {
override fun executePhase(input: JvmFir2IrPipelineArtifact): JvmBinaryPipelineArtifact? {
override fun executePhase(input: JvmFir2IrPipelineArtifact): JvmBinaryPipelineArtifact {
val (fir2IrResult, configuration, environment, diagnosticCollector) = input
val project = environment.project
val classResolver = FirJvmBackendClassResolver(fir2IrResult.components)
@@ -3,7 +3,6 @@ package org.jetbrains.bazel.jvm.kotlin
import androidx.compose.compiler.plugins.kotlin.ComposeCommandLineProcessor
import androidx.compose.compiler.plugins.kotlin.ComposePluginRegistrar
import fleet.multiplatform.expects.ExpectsPluginRegistrar
import org.jetbrains.bazel.jvm.util.ArgMap
import org.jetbrains.kotlin.backend.common.output.OutputFile
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser.RegisteredPluginInfo
@@ -24,11 +23,16 @@ import java.nio.file.Path
@Suppress("SameParameterValue")
private fun cliOptionValue(name: String, value: String) = CliOptionValue(pluginId = "<NO_ID>", optionName = name, value = value)
interface CompilerPluginProvider {
fun provide(id: String): RegisteredPluginInfo
}
@OptIn(ExperimentalCompilerApi::class)
internal inline fun configurePlugins(
internal fun configurePlugins(
args: ArgMap<JvmBuilderFlags>,
workingDir: Path,
noinline abiOutputConsumer: ((List<OutputFile>) -> Unit)?,
abiOutputConsumer: ((List<OutputFile>) -> Unit)?,
pluginProvider: CompilerPluginProvider,
consumer: (RegisteredPluginInfo) -> Unit,
) {
// put user plugins first
@@ -64,17 +68,9 @@ internal inline fun configurePlugins(
))
}
// todo it should be in maven central / not in the default image of jvm-builder
"jetbrains.fleet.expects-compiler-plugin" -> {
consumer(RegisteredPluginInfo(
componentRegistrar = null,
compilerPluginRegistrar = ExpectsPluginRegistrar(),
commandLineProcessor = null,
pluginOptions = emptyList(),
))
else -> {
consumer(pluginProvider.provide(id))
}
else -> throw IllegalArgumentException("plugin requires classpath: $id")
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
### --- ###
common --@rules_jvm//:default-kotlinc-opts=@community//:k17
common --@rules_jvm//:worker-impl=@rules_jvm//src/misc:worker-jvm
common --@rules_jvm//:resource-packager=@rules_jvm//src/misc:worker-jvm
common --@rules_jvm//:koltin_inc_threshold=0 --@rules_jvm//:java_inc_threshold=0
# configure resources
+1
View File
@@ -17,6 +17,7 @@ jvm_library(
visibility = ["//visibility:public"],
srcs = glob(["srcCommonMain/**/*.kt", "srcCommonMain/**/*.java", "srcJvmMain/**/*.kt", "srcJvmMain/**/*.java"], allow_empty = True, exclude = ["**/module-info.java"]),
kotlinc_opts = ":custom",
exported_compiler_plugins = ["@lib//:rhizomedb-plugin"],
deps = [
"//fleet/util/core",
"//fleet/multiplatform.shims",
-9
View File
@@ -13,9 +13,6 @@ kt_compiler_plugin(
kt_compiler_plugin(
name = "rhizomedb-plugin",
id = "org.jetbrains.fleet.rhizomedb-compiler-plugin",
deps = [
":rhizomedb-compiler-plugin-lib"
],
visibility = ["//visibility:public"]
)
@@ -25,11 +22,6 @@ kt_compiler_plugin(
visibility = ["//visibility:public"]
)
kt_jvm_import(
name = "rhizomedb-compiler-plugin-lib",
jar = "@rhizomedb-compiler-plugin-2_1_20-0_3_http//file",
)
kt_compiler_plugin(
name = "compose-plugin",
id = "org.jetbrains.kotlin.kotlin-compose-compiler-plugin",
@@ -8594,7 +8586,6 @@ jvm_import(
name = "rhizomedb-compiler-plugin",
jar = "@rhizomedb-compiler-plugin-2_1_20-0_3_http//file",
source_jar = "@rhizomedb-compiler-plugin-2_1_20-0_3-sources_http//file",
exported_compiler_plugins = ["@lib//:rhizomedb-plugin"],
visibility = ["//visibility:public"]
)
@@ -371,6 +371,10 @@ internal class BazelBuildFileGenerator(
if (module.name == "fleet.util.multiplatform" || module.name == "intellij.platform.syntax.multiplatformSupport") {
option("exported_compiler_plugins", arrayOf("@lib//:expects-plugin"))
}
else if (module.name == "fleet.rhizomedb") {
// https://youtrack.jetbrains.com/issue/IJI-2662/RhizomedbCommandLineProcessor-requires-output-dir-but-we-dont-have-it-for-Bazel-compilation
//option("exported_compiler_plugins", arrayOf("@lib//:rhizomedb-plugin"))
}
var deps = moduleList.deps.get(moduleDescriptor)
if (deps != null && deps.provided.isNotEmpty()) {
@@ -101,9 +101,6 @@ internal fun BuildFile.generateMavenLib(
exportedCompilerPlugins = listOf("@lib//:kotlin-serialization-plugin")
option("exported_compiler_plugins", exportedCompilerPlugins)
}
if (targetName == "rhizomedb-compiler-plugin") {
option("exported_compiler_plugins", arrayOf("@lib//:rhizomedb-plugin"))
}
libVisibility?.let {
visibility(arrayOf(it))