Incremental KAPT: when unable to process incremental changes, run non-incrementally

When analyzing incremental changes in the KAPT task, incremental compilation
can handle directory changes, Java source file changes, jar/.class file changes,
and changes to the ABI structure of the classpath. Anything else should cause
a full recompilation.

Test: KaptIncrementalWithIsolatingApt.testNonIncrementalWithUnrecognizedInputs
This commit is contained in:
Ivan Gavrilovic
2019-08-08 13:55:44 +01:00
committed by Yan Zhulanow
parent b59fba6707
commit 434fb75eb7
3 changed files with 45 additions and 1 deletions
@@ -86,6 +86,33 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
assertContains("Unable to use existing data, re-initializing classpath information for KAPT.")
}
}
@Test
fun testNonIncrementalWithUnrecognizedInputs() {
val project = getProject()
val additionalInputs = project.projectDir.resolve("additionalInputs").also { it.mkdirs() }
project.gradleBuildScript().appendText(
"""
tasks.whenTaskAdded {
if (it.name == "kaptKotlin") {
it.getInputs().files("${additionalInputs.canonicalPath}")
}
}
""".trimIndent()
)
project.build("clean", "build") {
assertSuccessful()
}
additionalInputs.resolve("layout.xml").createNewFile()
project.build("build") {
assertSuccessful()
assertContains("Incremental annotation processing (apt mode): false")
}
}
}
private const val patternApt = "Processing java sources with annotation processors:"
@@ -196,7 +196,22 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
val startTime = System.currentTimeMillis()
val previousSnapshot = if (inputs.isIncremental) {
ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(incAptCacheDir)
val loadedPrevious = ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(incAptCacheDir)
val previousAndCurrentDataFiles = lazy { loadedPrevious.getAllDataFiles() + allDataFiles }
val allChangesRecognized = changedFiles.all {
val extension = it.extension
if (extension.isEmpty() || extension == "java" || extension == "jar" || extension == "class") {
return@all true
}
// if not a directory, Java source file, jar, or class, it has to be a structure file, in order to understand changes
it in previousAndCurrentDataFiles.value
}
if (allChangesRecognized) {
loadedPrevious
} else {
ClasspathSnapshot.ClasspathSnapshotFactory.getEmptySnapshot()
}
} else {
ClasspathSnapshot.ClasspathSnapshotFactory.getEmptySnapshot()
}
@@ -56,6 +56,8 @@ open class ClasspathSnapshot protected constructor(
fun getEmptySnapshot() = UnknownSnapshot
}
fun getAllDataFiles() = dataForFiles.keys
private fun isCompatible(snapshot: ClasspathSnapshot) =
this != UnknownSnapshot
&& snapshot != UnknownSnapshot