Add Compose compiler plugin to IDE plugin dependencies

This allows IDE to use the Compose compiler plugin from the KT compiler.

In addition, this commit reimplements the Compose compiler plugin
registrar based on the new API `CompilerPluginRegistrar` because K2 IDE
supports putting a compiler plugin to the allow-list only when the
registrar is a child class of `CompilerPluginRegistrar`.

KTIJ-30164
diff --git a/build.gradle.kts b/build.gradle.kts
index 90e37a6..0aa47baf 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -299,6 +299,8 @@
                 ":plugins:parcelize:parcelize-compiler:parcelize.k2",
                 ":plugins:parcelize:parcelize-runtime",
 
+                ":plugins:compose-compiler-plugin:compiler-hosted",
+
                 ":kotlin-sam-with-receiver-compiler-plugin.cli",
                 ":kotlin-sam-with-receiver-compiler-plugin.common",
                 ":kotlin-sam-with-receiver-compiler-plugin.k1",
@@ -400,6 +402,7 @@
 extra["compilerArtifactsForIde"] = listOfNotNull(
     ":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide",
     ":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide",
+    ":prepare:ide-plugin-dependencies:compose-compiler-plugin-for-ide",
     ":prepare:ide-plugin-dependencies:scripting-compiler-plugin-for-ide",
     ":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide",
     ":prepare:ide-plugin-dependencies:js-ir-runtime-for-ide",
diff --git a/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractCompilerTest.kt b/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractCompilerTest.kt
index a5395c9..4644f2a 100644
--- a/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractCompilerTest.kt
+++ b/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractCompilerTest.kt
@@ -22,26 +22,21 @@
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.util.Disposer
 import com.intellij.openapi.util.io.FileUtil
-import java.io.File
-import java.net.URLClassLoader
 import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
 import org.jetbrains.kotlin.backend.common.output.OutputFile
 import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
 import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots
 import org.jetbrains.kotlin.codegen.GeneratedClassLoader
-import org.jetbrains.kotlin.config.AnalysisFlag
-import org.jetbrains.kotlin.config.AnalysisFlags
-import org.jetbrains.kotlin.config.ApiVersion
-import org.jetbrains.kotlin.config.CompilerConfiguration
-import org.jetbrains.kotlin.config.JVMConfigurationKeys
-import org.jetbrains.kotlin.config.LanguageVersion
-import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
-import org.jetbrains.kotlin.config.languageVersionSettings
+import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
+import org.jetbrains.kotlin.compiler.plugin.registerExtensionsForTest
+import org.jetbrains.kotlin.config.*
 import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
 import org.junit.After
 import org.junit.BeforeClass
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
+import java.io.File
+import java.net.URLClassLoader
 
 @RunWith(Parameterized::class)
 abstract class AbstractCompilerTest(val useFir: Boolean) {
@@ -91,6 +86,7 @@
 
     protected open fun CompilerConfiguration.updateConfiguration() {}
 
+    @OptIn(ExperimentalCompilerApi::class)
     private fun createCompilerFacade(
         additionalPaths: List<File> = listOf(),
         forcedFirSetting: Boolean? = null,
@@ -127,7 +123,11 @@
             configureJdkClasspathRoots()
         },
         registerExtensions = registerExtensions ?: { configuration ->
-            ComposePluginRegistrar.registerCommonExtensions(this)
+            registerExtensionsForTest(this, configuration) {
+                with(ComposePluginRegistrar.Companion) {
+                    registerCommonExtensions()
+                }
+            }
             IrGenerationExtension.registerExtension(
                 this,
                 ComposePluginRegistrar.createComposeIrExtension(configuration)
diff --git a/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractLiveLiteralTransformTests.kt b/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractLiveLiteralTransformTests.kt
index 3540874..9e27dd9 100644
--- a/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractLiveLiteralTransformTests.kt
+++ b/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractLiveLiteralTransformTests.kt
@@ -23,6 +23,8 @@
 import org.intellij.lang.annotations.Language
 import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
 import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
+import org.jetbrains.kotlin.compiler.plugin.registerExtensionsForTest
 import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
 import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
 import org.junit.Assert.assertEquals
@@ -30,6 +32,7 @@
 abstract class AbstractLiveLiteralTransformTests(
     useFir: Boolean
 ) : AbstractIrTransformTest(useFir) {
+    @OptIn(ExperimentalCompilerApi::class)
     private fun computeKeys(files: List<SourceFile>): List<String> {
         var builtKeys = mutableSetOf<String>()
         compileToIr(
@@ -42,7 +45,11 @@
                     ComposeConfiguration.LIVE_LITERALS_V2_ENABLED_KEY
                 )
 
-                ComposePluginRegistrar.registerCommonExtensions(this)
+                registerExtensionsForTest(this, configuration) {
+                    with(ComposePluginRegistrar.Companion) {
+                        registerCommonExtensions()
+                    }
+                }
                 IrGenerationExtension.registerExtension(
                     this,
                     object : IrGenerationExtension {
diff --git a/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractMetricsTransformTest.kt b/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractMetricsTransformTest.kt
index 7189caa..ec9f461 100644
--- a/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractMetricsTransformTest.kt
+++ b/plugins/compose/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractMetricsTransformTest.kt
@@ -19,9 +19,12 @@
 import androidx.compose.compiler.plugins.kotlin.facade.KotlinCompilerFacade
 import androidx.compose.compiler.plugins.kotlin.facade.SourceFile
 import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
+import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
+import org.jetbrains.kotlin.compiler.plugin.registerExtensionsForTest
 import org.junit.Assert.assertEquals
 
 abstract class AbstractMetricsTransformTest(useFir: Boolean) : AbstractIrTransformTest(useFir) {
+    @OptIn(ExperimentalCompilerApi::class)
     private fun verifyMetrics(
         source: String,
         verify: ModuleMetrics.() -> Unit
@@ -31,7 +34,11 @@
         compileToIr(
             files,
             registerExtensions = { configuration ->
-                ComposePluginRegistrar.registerCommonExtensions(this)
+                registerExtensionsForTest(this, configuration) {
+                    with(ComposePluginRegistrar.Companion) {
+                        registerCommonExtensions()
+                    }
+                }
                 extension =
                     ComposePluginRegistrar.createComposeIrExtension(configuration) { inferencer ->
                         ModuleMetricsImpl(KotlinCompilerFacade.TEST_MODULE_NAME) { type ->
diff --git a/plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt b/plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
index 965cce3..b2bc161 100644
--- a/plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
+++ b/plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
@@ -23,8 +23,6 @@
 import androidx.compose.compiler.plugins.kotlin.k2.ComposeFirExtensionRegistrar
 import androidx.compose.compiler.plugins.kotlin.lower.ClassStabilityFieldSerializationPlugin
 import androidx.compose.compiler.plugins.kotlin.lower.hiddenfromobjc.AddHiddenFromObjCSerializationPlugin
-import com.intellij.mock.MockProject
-import com.intellij.openapi.project.Project
 import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
 import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
 import org.jetbrains.kotlin.compiler.plugin.*
@@ -526,27 +524,21 @@
     }
 }
 
-@Suppress("DEPRECATION") // CompilerPluginRegistrar does not expose project (or disposable) causing
-                         // memory leaks, see: https://youtrack.jetbrains.com/issue/KT-60952
 @OptIn(ExperimentalCompilerApi::class)
-class ComposePluginRegistrar : org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar {
+class ComposePluginRegistrar : CompilerPluginRegistrar() {
     override val supportsK2: Boolean
         get() = true
 
-    override fun registerProjectComponents(
-        project: MockProject,
-        configuration: CompilerConfiguration
-    ) {
+    override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
         if (checkCompilerVersion(configuration)) {
             val usesK2 = configuration.languageVersionSettings.languageVersion.usesK2
             val descriptorSerializerContext =
                 if (usesK2) null
                 else ComposeDescriptorSerializerContext()
 
-            registerCommonExtensions(project, descriptorSerializerContext)
+            registerCommonExtensions(descriptorSerializerContext)
 
             IrGenerationExtension.registerExtension(
-                project,
                 createComposeIrExtension(
                     configuration,
                     descriptorSerializerContext
@@ -554,7 +546,7 @@
             )
 
             if (!usesK2) {
-                registerNativeExtensions(project, descriptorSerializerContext!!)
+                registerNativeExtensions(descriptorSerializerContext!!)
             }
         }
     }
@@ -582,43 +574,35 @@
             return true
         }
 
-        fun registerCommonExtensions(
-            project: Project,
+        fun ExtensionStorage.registerCommonExtensions(
             composeDescriptorSerializerContext: ComposeDescriptorSerializerContext? = null
         ) {
             StorageComponentContainerContributor.registerExtension(
-                project,
                 ComposableCallChecker()
             )
             StorageComponentContainerContributor.registerExtension(
-                project,
                 ComposableDeclarationChecker()
             )
             StorageComponentContainerContributor.registerExtension(
-                project,
                 ComposableTargetChecker()
             )
-            DiagnosticSuppressor.registerExtension(project, ComposeDiagnosticSuppressor())
+            DiagnosticSuppressor.registerExtension(ComposeDiagnosticSuppressor())
             @Suppress("OPT_IN_USAGE_ERROR")
             TypeResolutionInterceptor.registerExtension(
-                project,
                 ComposeTypeResolutionInterceptorExtension()
             )
             DescriptorSerializerPlugin.registerExtension(
-                project,
                 ClassStabilityFieldSerializationPlugin(
                     composeDescriptorSerializerContext?.classStabilityInferredCollection
                 )
             )
-            FirExtensionRegistrarAdapter.registerExtension(project, ComposeFirExtensionRegistrar())
+            FirExtensionRegistrarAdapter.registerExtension(ComposeFirExtensionRegistrar())
         }
 
-        fun registerNativeExtensions(
-            project: Project,
+        fun ExtensionStorage.registerNativeExtensions(
             composeDescriptorSerializerContext: ComposeDescriptorSerializerContext
         ) {
             DescriptorSerializerPlugin.registerExtension(
-                project,
                 AddHiddenFromObjCSerializationPlugin(
                     composeDescriptorSerializerContext.hideFromObjCDeclarationsSet
                 )
@@ -737,4 +721,4 @@
             )
         }
     }
-}
+}
\ No newline at end of file
diff --git a/plugins/compose/compiler-hosted/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/plugins/compose/compiler-hosted/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
similarity index 100%
rename from plugins/compose/compiler-hosted/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
rename to plugins/compose/compiler-hosted/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
diff --git a/prepare/ide-plugin-dependencies/compose-compiler-plugin-for-ide/build.gradle.kts b/prepare/ide-plugin-dependencies/compose-compiler-plugin-for-ide/build.gradle.kts
new file mode 100644
index 0000000..bf0ebda
--- /dev/null
+++ b/prepare/ide-plugin-dependencies/compose-compiler-plugin-for-ide/build.gradle.kts
@@ -0,0 +1,7 @@
+plugins {
+    kotlin("jvm")
+}
+
+publishJarsForIde(
+    listOf(":plugins:compose-compiler-plugin:compiler-hosted")
+)
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 7ff8ed1..787dd16 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -397,6 +397,7 @@
             ":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide",
             ":prepare:ide-plugin-dependencies:scripting-compiler-plugin-for-ide",
             ":prepare:ide-plugin-dependencies:allopen-compiler-plugin-tests-for-ide",
+            ":prepare:ide-plugin-dependencies:compose-compiler-plugin-for-ide",
             ":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide",
             ":prepare:ide-plugin-dependencies:js-ir-runtime-for-ide",
             ":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide",