Incremental annotation processing with KAPT
Add support for incremental annotation processors in KAPT. These processors conform to https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing specification. Support is provided by using javac compiler APIs and recording the source file structure. At runtime, processors are instrumented with custom Filer that is used to keep track of generated files. In order to support classpath changes, stub generation task is used to generated a list of changed FQCNs, and this is simply used by KAPT. Both worker and non-worker mode are supported. #KT-23880
This commit is contained in:
committed by
Alexey Tsvetkov
parent
600a955a51
commit
9f14daa682
+1
-1
@@ -313,7 +313,7 @@ abstract class IncrementalCompilerRunner<
|
||||
|
||||
open fun runWithNoDirtyKotlinSources(caches: CacheManager): Boolean = false
|
||||
|
||||
private fun processChangesAfterBuild(
|
||||
protected open fun processChangesAfterBuild(
|
||||
compilationMode: CompilationMode,
|
||||
currentBuildInfo: BuildInfo,
|
||||
dirtyData: DirtyData
|
||||
|
||||
+28
-1
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.io.File
|
||||
import java.io.ObjectOutputStream
|
||||
|
||||
fun makeIncrementally(
|
||||
cachesDir: File,
|
||||
@@ -109,7 +110,8 @@ class IncrementalJvmCompilerRunner(
|
||||
buildHistoryFile: File,
|
||||
outputFiles: Collection<File>,
|
||||
private val modulesApiHistory: ModulesApiHistory,
|
||||
override val kotlinSourceFilesExtensions: List<String> = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
|
||||
override val kotlinSourceFilesExtensions: List<String> = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS,
|
||||
private val classpathFqNamesHistory: File? = null
|
||||
) : IncrementalCompilerRunner<K2JVMCompilerArguments, IncrementalJvmCachesManager>(
|
||||
workingDir,
|
||||
"caches-jvm",
|
||||
@@ -126,6 +128,8 @@ class IncrementalJvmCompilerRunner(
|
||||
override fun destinationDir(args: K2JVMCompilerArguments): File =
|
||||
args.destinationAsFile
|
||||
|
||||
private var dirtyClasspathChanges: Collection<FqName> = emptySet<FqName>()
|
||||
|
||||
private val psiFileFactory: PsiFileFactory by lazy {
|
||||
val rootDisposable = Disposer.newDisposable()
|
||||
val configuration = CompilerConfiguration()
|
||||
@@ -163,6 +167,7 @@ class IncrementalJvmCompilerRunner(
|
||||
}
|
||||
is ChangesEither.Known -> {
|
||||
dirtyFiles.addByDirtySymbols(classpathChanges.lookupSymbols)
|
||||
dirtyClasspathChanges = classpathChanges.fqNames
|
||||
dirtyFiles.addByDirtyClasses(classpathChanges.fqNames)
|
||||
}
|
||||
}
|
||||
@@ -253,6 +258,28 @@ class IncrementalJvmCompilerRunner(
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
|
||||
super.processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
|
||||
|
||||
classpathFqNamesHistory ?: return
|
||||
classpathFqNamesHistory.mkdirs()
|
||||
|
||||
val historyFiles = classpathFqNamesHistory.listFiles()
|
||||
if (dirtyClasspathChanges.isEmpty() && historyFiles.isNotEmpty()) {
|
||||
// Don't write an empty file. We check there is at least one file so that downstream task can mark what it has processed.
|
||||
return
|
||||
}
|
||||
|
||||
if (historyFiles.size > 10) {
|
||||
historyFiles.minBy { it.lastModified() }!!.delete()
|
||||
}
|
||||
val newHistoryFile = classpathFqNamesHistory.resolve(System.currentTimeMillis().toString())
|
||||
ObjectOutputStream(newHistoryFile.outputStream().buffered()).use {
|
||||
val listOfNames = dirtyClasspathChanges.map { it.toString() }.toList()
|
||||
it.writeObject(listOfNames)
|
||||
}
|
||||
}
|
||||
|
||||
override fun postCompilationHook(exitCode: ExitCode) {}
|
||||
|
||||
override fun updateCaches(
|
||||
|
||||
Reference in New Issue
Block a user