Skip to content

Commit b21f7c9

Browse files
committed
Move KSP to an independent Gradle task
Also turn incremental compilation back on. Note that incremental processing is still under construction.
1 parent 1acad60 commit b21f7c9

File tree

5 files changed

+57
-36
lines changed

5 files changed

+57
-36
lines changed

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/KotlinSymbolProcessingExtension.kt

+2-21
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ class KotlinSymbolProcessingExtension(
5959

6060
abstract class AbstractKotlinSymbolProcessingExtension(val options: KspOptions, val logger: KSPLogger, val testMode: Boolean) :
6161
AnalysisHandlerExtension {
62-
private var completed = false
63-
6462
override fun doAnalysis(
6563
project: Project,
6664
module: ModuleDescriptor,
@@ -69,9 +67,6 @@ abstract class AbstractKotlinSymbolProcessingExtension(val options: KspOptions,
6967
bindingTrace: BindingTrace,
7068
componentProvider: ComponentProvider
7169
): AnalysisResult? {
72-
if (completed)
73-
return null
74-
7570
val psiManager = PsiManager.getInstance(project)
7671
val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
7772
val javaFiles = options.javaSourceRoots
@@ -101,7 +96,7 @@ abstract class AbstractKotlinSymbolProcessingExtension(val options: KspOptions,
10196

10297
KSObjectCacheManager.clear()
10398

104-
return AnalysisResult.success(BindingContext.EMPTY, module, shouldGenerateCode = false)
99+
return AnalysisResult.EMPTY
105100
}
106101

107102
abstract fun loadProcessors(): List<SymbolProcessor>
@@ -112,21 +107,7 @@ abstract class AbstractKotlinSymbolProcessingExtension(val options: KspOptions,
112107
bindingTrace: BindingTrace,
113108
files: Collection<KtFile>
114109
): AnalysisResult? {
115-
if (completed)
116-
return null
117-
118-
completed = true
119-
120-
if (testMode)
121-
return null
122-
123-
return AnalysisResult.RetryWithAdditionalRoots(
124-
BindingContext.EMPTY,
125-
module,
126-
listOf(options.javaOutputDir),
127-
listOf(options.kotlinOutputDir),
128-
addToEnvironment = true
129-
)
110+
return AnalysisResult.success(BindingContext.EMPTY, module, shouldGenerateCode = false)
130111
}
131112

132113
private var annotationProcessingComplete = false

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/KotlinSymbolProcessingPlugin.kt

-11
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,6 @@ class KotlinSymbolProcessingCommandLineProcessor : CommandLineProcessor {
6565

6666
class KotlinSymbolProcessingComponentRegistrar : ComponentRegistrar {
6767
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
68-
// Don't bother with KAPT tasks.
69-
// There is no way to pass KSP options to compileKotlin only. Have to workaround here.
70-
val outputDir = configuration[JVMConfigurationKeys.OUTPUT_DIRECTORY]
71-
val kaptOutputDirs = listOf(
72-
listOf("tmp", "kapt3", "stubs"),
73-
listOf("tmp", "kapt3", "incrementalData"),
74-
listOf("tmp", "kapt3", "incApCache")
75-
).map { File(it.joinToString(File.separator)) }
76-
if (kaptOutputDirs.any { outputDir?.parentFile?.endsWith(it) == true })
77-
return
78-
7968
val contentRoots = configuration[CLIConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
8069
val options = configuration[KSP_OPTIONS]?.apply {
8170
javaSourceRoots.addAll(contentRoots.filterIsInstance<JavaSourceRoot>().map { it.file })

gradle-plugin/build.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ plugins {
1616

1717
dependencies {
1818
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:$kotlinBaseVersion")
19+
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinBaseVersion")
20+
compileOnly("org.jetbrains.kotlin:kotlin-compiler:$kotlinBaseVersion")
1921

2022
compileOnly(gradleApi())
2123

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.google.devtools.ksp.gradle;
2+
3+
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation;
4+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData;
5+
6+
// FIXME: Ask upstream to open these API
7+
public class InternalTrampoline {
8+
public static void KotlinCompileTaskData_register(String taskName, KotlinCompilation<?> kotlinCompilation) {
9+
KotlinCompileTaskData kotlinCompileTaskData = KotlinCompileTaskData.Companion.register(taskName, kotlinCompilation);
10+
}
11+
}

gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt

+42-4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import com.google.devtools.ksp.gradle.KspGradleSubplugin.Companion.getKspKotlinO
3232
import com.google.devtools.ksp.gradle.KspGradleSubplugin.Companion.getKspResourceOutputDir
3333
import java.io.File
3434
import javax.inject.Inject
35+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
3536

3637
class KspGradleSubplugin @Inject internal constructor(private val registry: ToolingModelBuilderRegistry) : Plugin<Project> {
3738
companion object {
@@ -67,6 +68,8 @@ class KspGradleSubplugin @Inject internal constructor(private val registry: Tool
6768
class KspKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
6869
companion object {
6970
const val KSP_ARTIFACT_NAME = "symbol-processing"
71+
const val KSP_PLUGIN_ID = "com.google.devtools.ksp.symbol-processing"
72+
7073
}
7174

7275
override fun isApplicable(project: Project, task: AbstractCompile) = KspGradleSubplugin.isEnabled(project)
@@ -88,8 +91,6 @@ class KspKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
8891

8992
kotlinCompile.dependsOn(kspConfiguration.buildDependencies)
9093

91-
kotlinCompile.setProperty("incremental", false)
92-
9394
val options = mutableListOf<SubpluginOption>()
9495

9596
options += FilesSubpluginOption("apclasspath", kspConfiguration)
@@ -114,10 +115,47 @@ class KspKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
114115
javaCompile.source(generatedJavaSources)
115116
}
116117

117-
return options
118+
val kspTaskName = kotlinCompile.name.replaceFirst("compile", "ksp")
119+
InternalTrampoline.KotlinCompileTaskData_register(kspTaskName, kotlinCompilation)
120+
121+
val kspTaskProvider = project.tasks.register(kspTaskName, KspTask::class.java) { kspTask ->
122+
kspTask.setDestinationDir(File(project.buildDir, "generated/ksp"))
123+
kspTask.mapClasspath { kotlinCompile.classpath }
124+
kspTask.options = options
125+
}.apply {
126+
configure {
127+
kotlinCompilation?.allKotlinSourceSets?.forEach { sourceSet -> it.source(sourceSet.kotlin) }
128+
}
129+
}
130+
131+
kotlinCompile.dependsOn(kspTaskProvider)
132+
kotlinCompile.source(kotlinOutputDir, javaOutputDir)
133+
134+
return emptyList()
118135
}
119136

120-
override fun getCompilerPluginId() = "com.google.devtools.ksp.symbol-processing"
137+
override fun getCompilerPluginId() = KSP_PLUGIN_ID
121138
override fun getPluginArtifact(): SubpluginArtifact =
122139
SubpluginArtifact(groupId = "com.google.devtools.ksp", artifactId = KSP_ARTIFACT_NAME, version = javaClass.`package`.implementationVersion)
123140
}
141+
142+
open class KspTask : KotlinCompile() {
143+
lateinit var options: List<SubpluginOption>
144+
145+
init {
146+
// kotlinc's incremental compilation isn't compatible with symbol processing in a few ways:
147+
// * It doesn't consider private / internal changes when computing dirty sets.
148+
// * It compiles iteratively; Sources can be compiled in different rounds.
149+
incremental = false
150+
}
151+
152+
override fun setupCompilerArgs(
153+
args: org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments,
154+
defaultsOnly: Boolean,
155+
ignoreClasspathResolutionErrors: Boolean
156+
) {
157+
fun SubpluginOption.toArg() = "plugin:${KspKotlinGradleSubplugin.KSP_PLUGIN_ID}:${key}=${value}"
158+
super.setupCompilerArgs(args, defaultsOnly, ignoreClasspathResolutionErrors)
159+
args.pluginOptions = (options.map { it.toArg() } + args.pluginOptions!!).toTypedArray()
160+
}
161+
}

0 commit comments

Comments
 (0)