Repository: detekt/detekt (kotlin)

Issue:
Split detekt-kotlin-analysis-api into detekt-kotlin-analysis-api and detekt-kotlin-analysis-api-standalone
## Expected Behavior
Projects that depend on `detekt-api` only have access to Kotlin's `analysis-api`, but not `analysis-api-standalone`.

## Current Behavior
Currently the `detekt-kotlin-analysis-api` project repackages both `analysis-api` and `analysis-api-standalone` (plus dependencies).

## Context
If `detekt-kotlin-analysis-api` is added as an `api` dependency to `detekt-api` it will expose `analysis-api-standalone` to any project that depends on `detekt-api`.

Instead, only `analysis-api` should be exposed by projects that depend on `detekt-api`. `analysis-api-standalone` should only be used as an implementation dependency where needed in detekt itself.

Pull request:
Also exposes Kotlin Analysis API to detekt-api consumers so the `analyze` entry point is available to rule authors, and `analysis-api-k2` so that specific diagnostics can be filtered as described in https://kotlin.github.io/analysis-api/diagnostics.html

Fixes #8102

Patch:
diff --git a/detekt-api/build.gradle.kts b/detekt-api/build.gradle.kts
index 96cc0733140f..70ffe42becb9 100644
--- a/detekt-api/build.gradle.kts
+++ b/detekt-api/build.gradle.kts
@@ -7,6 +7,7 @@ plugins {
 
 dependencies {
     api(libs.kotlin.compiler)
+    api(projects.detektKotlinAnalysisApi)
     implementation(projects.detektUtils)
 
     testImplementation(projects.detektTest)
diff --git a/detekt-core/build.gradle.kts b/detekt-core/build.gradle.kts
index 846406a977f9..9227d8dbd04e 100644
--- a/detekt-core/build.gradle.kts
+++ b/detekt-core/build.gradle.kts
@@ -6,7 +6,7 @@ dependencies {
     api(projects.detektApi)
     api(projects.detektParser)
     api(projects.detektTooling)
-    implementation(projects.detektKotlinAnalysisApi)
+    implementation(projects.detektKotlinAnalysisApiStandalone)
     implementation(libs.snakeyaml.engine)
     implementation(libs.kotlin.reflect)
     implementation(projects.detektMetrics)
diff --git a/detekt-kotlin-analysis-api-standalone/build.gradle.kts b/detekt-kotlin-analysis-api-standalone/build.gradle.kts
new file mode 100644
index 000000000000..9643feeb05a7
--- /dev/null
+++ b/detekt-kotlin-analysis-api-standalone/build.gradle.kts
@@ -0,0 +1,42 @@
+// This package can be retired once this is closed: https://youtrack.jetbrains.com/issue/KT-56203/AA-Publish-analysis-api-standalone-and-dependencies-to-Maven-Central
+
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
+plugins {
+    kotlin("jvm") // Plugin can be removed when KspLibraryModuleBuilder is retired. Blocked by https://youtrack.jetbrains.com/issue/KT-71706
+    id("packaging")
+    id("com.gradleup.shadow") version "8.3.6"
+}
+
+dependencies {
+    // Exclude transitive dependencies due to https://youtrack.jetbrains.com/issue/KT-61639
+    api(libs.kotlin.analysisApiStandalone) { isTransitive = false }
+
+    // The following dependencies should be removed when KspLibraryModuleBuilder is retired. Blocked by https://youtrack.jetbrains.com/issue/KT-71706
+    implementation(libs.kotlin.analysisApi) { isTransitive = false }
+    implementation(libs.kotlin.analysisApiImplBase) { isTransitive = false }
+    compileOnly(libs.kotlin.compiler)
+}
+
+kotlin {
+    compilerOptions.jvmTarget = JvmTarget.JVM_1_8
+}
+
+java {
+    targetCompatibility = JavaVersion.VERSION_1_8
+}
+
+configurations.shadowRuntimeElements {
+    attributes {
+        // This is not needed in shadow plugin 9+: https://github.com/GradleUp/shadow/pull/1199
+        attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, JavaVersion.VERSION_1_8.majorVersion.toInt())
+    }
+}
+
+val javaComponent = components["java"] as AdhocComponentWithVariants
+javaComponent.withVariantsFromConfiguration(configurations["apiElements"]) {
+    skip()
+}
+javaComponent.withVariantsFromConfiguration(configurations["runtimeElements"]) {
+    skip()
+}
diff --git a/detekt-kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/standalone/KspLibraryModuleBuilder.kt b/detekt-kotlin-analysis-api-standalone/src/main/kotlin/com/google/devtools/ksp/standalone/KspLibraryModuleBuilder.kt
similarity index 100%
rename from detekt-kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/standalone/KspLibraryModuleBuilder.kt
rename to detekt-kotlin-analysis-api-standalone/src/main/kotlin/com/google/devtools/ksp/standalone/KspLibraryModuleBuilder.kt
diff --git a/detekt-kotlin-analysis-api/build.gradle.kts b/detekt-kotlin-analysis-api/build.gradle.kts
index 8b4fbf4a7359..f4ad49ebfb5f 100644
--- a/detekt-kotlin-analysis-api/build.gradle.kts
+++ b/detekt-kotlin-analysis-api/build.gradle.kts
@@ -1,9 +1,6 @@
 // This package can be retired once this is closed: https://youtrack.jetbrains.com/issue/KT-56203/AA-Publish-analysis-api-standalone-and-dependencies-to-Maven-Central
 
-import org.jetbrains.kotlin.gradle.dsl.JvmTarget
-
 plugins {
-    kotlin("jvm")
     id("packaging")
     id("com.gradleup.shadow") version "8.3.6"
 }
@@ -11,9 +8,9 @@ plugins {
 dependencies {
     // Exclude transitive dependencies due to https://youtrack.jetbrains.com/issue/KT-61639
     api(libs.kotlin.analysisApi) { isTransitive = false }
-    api(libs.kotlin.analysisApiStandalone) { isTransitive = false }
+    api(libs.kotlin.analysisApiK2) { isTransitive = false }
+
     implementation(libs.kotlin.analysisApiImplBase) { isTransitive = false }
-    implementation(libs.kotlin.analysisApiK2) { isTransitive = false }
     implementation(libs.kotlin.analysisApiPlatformInterface) { isTransitive = false }
     implementation(libs.kotlin.lowLevelApiFir) { isTransitive = false }
     implementation(libs.kotlin.symbolLightClasses) { isTransitive = false }
@@ -24,11 +21,6 @@ dependencies {
             attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
         }
     }
-    compileOnly(libs.kotlin.compiler)
-}
-
-kotlin {
-    compilerOptions.jvmTarget = JvmTarget.JVM_1_8
 }
 
 java {
diff --git a/detekt-parser/build.gradle.kts b/detekt-parser/build.gradle.kts
index 43aeba761b92..e3e50f1dee17 100644
--- a/detekt-parser/build.gradle.kts
+++ b/detekt-parser/build.gradle.kts
@@ -6,7 +6,7 @@ plugins {
 
 dependencies {
     api(libs.kotlin.compiler)
-    implementation(projects.detektKotlinAnalysisApi)
+    implementation(projects.detektKotlinAnalysisApiStandalone)
     testImplementation(projects.detektTestUtils)
     testImplementation(libs.assertj.core)
 }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index ba95605d0fff..e5f93bd4c52b 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -15,6 +15,7 @@ include("detekt-formatting:ktlint-repackage")
 include("detekt-generator")
 includeBuild("detekt-gradle-plugin")
 include("detekt-kotlin-analysis-api")
+include("detekt-kotlin-analysis-api-standalone")
 include("detekt-metrics")
 include("detekt-parser")
 include("detekt-psi-utils")


Test patch:
diff --git a/detekt-test-utils/build.gradle.kts b/detekt-test-utils/build.gradle.kts
index b146646da959..63e1db4294a6 100644
--- a/detekt-test-utils/build.gradle.kts
+++ b/detekt-test-utils/build.gradle.kts
@@ -7,6 +7,7 @@ dependencies {
     api(libs.kotlin.stdlib)
     api(libs.junit.jupiterApi)
     implementation(projects.detektKotlinAnalysisApi)
+    implementation(projects.detektKotlinAnalysisApiStandalone)
     implementation(projects.detektParser)
     implementation(libs.kotlin.mainKts) {
         isTransitive = false
diff --git a/detekt-test/build.gradle.kts b/detekt-test/build.gradle.kts
index de5462624d7c..16eac85ae637 100644
--- a/detekt-test/build.gradle.kts
+++ b/detekt-test/build.gradle.kts
@@ -6,7 +6,7 @@ plugins {
 dependencies {
     api(projects.detektApi)
     api(projects.detektTestUtils)
-    implementation(projects.detektKotlinAnalysisApi)
+    implementation(projects.detektKotlinAnalysisApiStandalone)
     implementation(projects.detektUtils)
     implementation(libs.kotlin.reflect)
     compileOnly(libs.assertj.core)