From e21bc4da05264fda59e3fc13f5ba4c4f2dbe8ac8 Mon Sep 17 00:00:00 2001 From: Anders Fugmann Date: Thu, 4 Jun 2026 16:54:50 +0200 Subject: [PATCH] Kotlin 2.4.0: Fix plugin service file to be version-conditional The CompilerPluginRegistrar service file must only be included in the 2.4.0 jar. Older Kotlin versions (2.3.x and below) read this service file and try to cast the class to CompilerPluginRegistrar, but the older version extractor only implements ComponentRegistrar, causing a ClassCastException at runtime. For 2.4.0, the registrar implements both ComponentRegistrar (no-op, as extensionArea was removed) and CompilerPluginRegistrar (actual registration via ExtensionStorage). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- java/kotlin-extractor/BUILD.bazel | 19 ++++++++++++++++--- .../v_2_4_0/Kotlin2ComponentRegistrar.kt | 17 +++++++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/java/kotlin-extractor/BUILD.bazel b/java/kotlin-extractor/BUILD.bazel index a4356af1835..21ba2bea1aa 100644 --- a/java/kotlin-extractor/BUILD.bazel +++ b/java/kotlin-extractor/BUILD.bazel @@ -64,8 +64,14 @@ _resources = [ r[len("src/main/resources/"):], ) for r in glob(["src/main/resources/**"]) + if r != "src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar" ] +_compiler_plugin_registrar_service = ( + "src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar", + "META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar", +) + kt_javac_options( name = "javac-options", release = "8", @@ -91,19 +97,26 @@ kt_javac_options( # * `resource_strip_prefix` is unique per jar, so we must also put other resources under the same version prefix genrule( name = "resources-%s" % v, - srcs = [src for src, _ in _resources], + srcs = [src for src, _ in _resources] + ( + [_compiler_plugin_registrar_service[0]] if not version_less(v, "2.4.0") else [] + ), outs = [ "%s/com/github/codeql/extractor.name" % v, ] + [ "%s/%s" % (v, target) for _, target in _resources - ], + ] + ( + ["%s/%s" % (v, _compiler_plugin_registrar_service[1])] if not version_less(v, "2.4.0") else [] + ), cmd = "\n".join([ "echo %s-%s > $(RULEDIR)/%s/com/github/codeql/extractor.name" % (_extractor_name_prefix, v, v), ] + [ "cp $(execpath %s) $(RULEDIR)/%s/%s" % (source, v, target) for source, target in _resources - ]), + ] + ( + ["cp $(execpath %s) $(RULEDIR)/%s/%s" % (_compiler_plugin_registrar_service[0], v, _compiler_plugin_registrar_service[1])] + if not version_less(v, "2.4.0") else [] + )), ), kt_jvm_library( name = "%s-%s" % (_extractor_name_prefix, v), diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/Kotlin2ComponentRegistrar.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/Kotlin2ComponentRegistrar.kt index 3dcd1231fed..0ee06810f8a 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/Kotlin2ComponentRegistrar.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/Kotlin2ComponentRegistrar.kt @@ -1,21 +1,34 @@ -@file:Suppress("DEPRECATION") +@file:Suppress("DEPRECATION", "DEPRECATION_ERROR") @file:OptIn(ExperimentalCompilerApi::class) package com.github.codeql +import com.intellij.mock.MockProject import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension +import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.jetbrains.kotlin.config.CompilerConfiguration -abstract class Kotlin2ComponentRegistrar : CompilerPluginRegistrar() { +abstract class Kotlin2ComponentRegistrar : CompilerPluginRegistrar(), ComponentRegistrar { override val supportsK2: Boolean get() = true override val pluginId: String get() = "com.github.codeql.kotlin-extractor" + // ComponentRegistrar implementation (legacy path, still called by Kotlin compiler) + override fun registerProjectComponents( + project: MockProject, + configuration: CompilerConfiguration + ) { + // In 2.4.0, we use CompilerPluginRegistrar path instead. + // This is only called if the compiler uses the ComponentRegistrar service file. + // We do nothing here since registerExtensions will be called separately. + } + private var extensionStorage: CompilerPluginRegistrar.ExtensionStorage? = null + private var registeredExtension: IrGenerationExtension? = null override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) { this@Kotlin2ComponentRegistrar.extensionStorage = this