Fixes to KAPT classpath change detection

1) Fix tests to use canonical path for comparison because Mac was failing
2) Update current classpath snapshot only with the missing entries from the previous one
3) Clean-up code and style
This commit is contained in:
Ivan Gavrilovic
2019-04-10 16:49:29 +01:00
committed by Alexey Tsvetkov
parent 7c78644eb9
commit 929fca03fd
11 changed files with 69 additions and 83 deletions
@@ -45,10 +45,10 @@ class KaptIncrementalWithAggregatingApt : KaptIncrementalIT() {
assertEquals( assertEquals(
setOf( setOf(
fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").absolutePath, fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/B.java").absolutePath, fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/B.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/baz/UtilKt.java").absolutePath, fileInWorkingDir("build/tmp/kapt3/stubs/main/baz/UtilKt.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/foo/A.java").absolutePath fileInWorkingDir("build/tmp/kapt3/stubs/main/foo/A.java").canonicalPath
), getProcessedSources(output) ), getProcessedSources(output)
) )
} }
@@ -61,11 +61,11 @@ class KaptIncrementalWithAggregatingApt : KaptIncrementalIT() {
assertSuccessful() assertSuccessful()
assertEquals( assertEquals(
setOf( setOf(
project.projectFile("JavaClass.java").absolutePath, project.projectFile("JavaClass.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").absolutePath, fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/B.java").absolutePath, fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/B.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/baz/UtilKt.java").absolutePath, fileInWorkingDir("build/tmp/kapt3/stubs/main/baz/UtilKt.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/foo/A.java").absolutePath fileInWorkingDir("build/tmp/kapt3/stubs/main/foo/A.java").canonicalPath
), ),
getProcessedSources(output) getProcessedSources(output)
) )
@@ -115,13 +115,13 @@ class KaptIncrementalWithAggregatingApt : KaptIncrementalIT() {
assertEquals( assertEquals(
setOf( setOf(
fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/AA.java").absolutePath, fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/AA.java").canonicalPath,
fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/AAA.java").absolutePath, fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/AAA.java").canonicalPath,
fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/BB.java").absolutePath, fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/BB.java").canonicalPath,
fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseAKt.java").absolutePath, fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseAKt.java").canonicalPath,
fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseBKt.java").absolutePath, fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseBKt.java").canonicalPath,
fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseAAKt.java").absolutePath, fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseAAKt.java").canonicalPath,
fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseBBKt.java").absolutePath fileInWorkingDir("app/build/tmp/kapt3/stubs/main/foo/FooUseBBKt.java").canonicalPath
), getProcessedSources(output) ), getProcessedSources(output)
) )
@@ -47,7 +47,7 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
project.build("build") { project.build("build") {
assertSuccessful() assertSuccessful()
assertEquals(setOf(fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").absolutePath), getProcessedSources(output)) assertEquals(setOf(fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").canonicalPath), getProcessedSources(output))
} }
project.projectFile("B.kt").modify { current -> project.projectFile("B.kt").modify { current ->
@@ -58,8 +58,8 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
assertSuccessful() assertSuccessful()
assertEquals( assertEquals(
setOf( setOf(
fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/B.java").absolutePath, fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/B.java").canonicalPath,
fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").absolutePath fileInWorkingDir("build/tmp/kapt3/stubs/main/bar/UseBKt.java").canonicalPath
), ),
getProcessedSources(output) getProcessedSources(output)
) )
@@ -167,48 +167,43 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
protected fun getCompiledSources() = listOfNotNull(kotlinCompileTask.destinationDir, kotlinCompileTask.javaOutputDir) protected fun getCompiledSources() = listOfNotNull(kotlinCompileTask.destinationDir, kotlinCompileTask.javaOutputDir)
protected fun getIncrementalChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges { protected fun getIncrementalChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges {
val changedFiles = getChangedFiles(inputs) if (!isIncremental) {
return if (isIncremental) {
val classpathChanges = if (changedFiles.isEmpty()) {
classpath.files
} else {
classpath.files.let { cp ->
changedFiles.filter { cp.contains(it) }
}
}
val classpathStatus = findClasspathChanges(classpathChanges)
when (classpathStatus) {
is KaptClasspathChanges.Unknown -> KaptIncrementalChanges.Unknown
is KaptClasspathChanges.Known -> KaptIncrementalChanges.Known(
changedFiles.filter { it.extension == "java" }.toSet(), classpathStatus.names
)
}
} else {
KaptIncrementalChanges.Unknown
}
}
private fun getChangedFiles(inputs: IncrementalTaskInputs): List<File> {
return if (!isIncremental || !inputs.isIncremental) {
clearLocalState() clearLocalState()
emptyList() return KaptIncrementalChanges.Unknown
} else { }
with(mutableSetOf<File>()) { if (!inputs.isIncremental) {
inputs.outOfDate { this.add(it.file) } clearLocalState()
inputs.removed { this.add(it.file) } findClasspathChanges(classpath.files)
return@with this.toList() return KaptIncrementalChanges.Unknown
} }
val changedFiles = with(mutableSetOf<File>()) {
inputs.outOfDate { this.add(it.file) }
inputs.removed { this.add(it.file) }
return@with this.toList()
}
val classpathChanges = classpath.files.let { cp -> changedFiles.filter { cp.contains(it) } }
val classpathStatus = findClasspathChanges(classpathChanges)
return when (classpathStatus) {
is KaptClasspathChanges.Unknown -> KaptIncrementalChanges.Unknown
is KaptClasspathChanges.Known -> KaptIncrementalChanges.Known(
changedFiles.filter { it.extension == "java" }.toSet(), classpathStatus.names
)
} }
} }
private fun findClasspathChanges(changedClasspath: Iterable<File>): KaptClasspathChanges { private fun findClasspathChanges(changedClasspath: Iterable<File>): KaptClasspathChanges {
incAptCache!!.mkdirs() val incAptCacheDir = incAptCache!!
incAptCacheDir.mkdirs()
val startTime = System.currentTimeMillis() val startTime = System.currentTimeMillis()
val previousSnapshot = ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(incAptCache!!) val previousSnapshot = ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(incAptCacheDir)
val currentSnapshot = ClasspathSnapshot.ClasspathSnapshotFactory.createCurrent(incAptCache!!, classpath.files.toList(), classpathStructure!!.files) val currentSnapshot = ClasspathSnapshot.ClasspathSnapshotFactory.createCurrent(
incAptCacheDir, classpath.files.toList(), classpathStructure!!.files
)
val classpathChanges = currentSnapshot.diff(previousSnapshot, changedClasspath.toSet()) val classpathChanges = currentSnapshot.diff(previousSnapshot, changedClasspath.toSet())
currentSnapshot.writeToCache() currentSnapshot.writeToCache()
@@ -75,15 +75,10 @@ open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JV
checkAnnotationProcessorClasspath() checkAnnotationProcessorClasspath()
val incrementalChanges = getIncrementalChanges(inputs) val incrementalChanges = getIncrementalChanges(inputs)
when (incrementalChanges) { if (incrementalChanges is KaptIncrementalChanges.Known) {
is KaptIncrementalChanges.Known -> { changedFiles = incrementalChanges.changedSources.toList()
changedFiles = incrementalChanges.changedSources.toList() classpathChanges = incrementalChanges.changedClasspathJvmNames.toList()
classpathChanges = incrementalChanges.changedClasspathJvmNames.toList() processIncrementally = true
processIncrementally = true
}
else -> {
// do nothing
}
} }
val args = prepareCompilerArguments() val args = prepareCompilerArguments()
@@ -66,6 +66,7 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor
if (isVerbose) add("VERBOSE") if (isVerbose) add("VERBOSE")
if (mapDiagnosticLocations) add("MAP_DIAGNOSTIC_LOCATIONS") if (mapDiagnosticLocations) add("MAP_DIAGNOSTIC_LOCATIONS")
if (includeCompileClasspath) add("INCLUDE_COMPILE_CLASSPATH") if (includeCompileClasspath) add("INCLUDE_COMPILE_CLASSPATH")
if (incrementalChanges is KaptIncrementalChanges.Known) add("INCREMENTAL_APT")
} }
val optionsForWorker = KaptOptionsForWorker( val optionsForWorker = KaptOptionsForWorker(
@@ -77,7 +78,6 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor
getCompiledSources(), getCompiledSources(),
incAptCache, incAptCache,
classpathChanges.toList(), classpathChanges.toList(),
incrementalChanges is KaptIncrementalChanges.Known,
destinationDir, destinationDir,
classesDir, classesDir,
@@ -172,7 +172,6 @@ private class KaptExecution @Inject constructor(
compiledSources, compiledSources,
incAptCache, incAptCache,
classpathChanges, classpathChanges,
processIncrementally,
sourcesOutputDir, sourcesOutputDir,
classesOutputDir, classesOutputDir,
@@ -209,7 +208,6 @@ private data class KaptOptionsForWorker(
val compiledSources: List<File>, val compiledSources: List<File>,
val incAptCache: File?, val incAptCache: File?,
val classpathChanges: List<String>, val classpathChanges: List<String>,
val processIncrementally: Boolean,
val sourcesOutputDir: File, val sourcesOutputDir: File,
val classesOutputDir: File, val classesOutputDir: File,
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.internal.kapt.incremental
import java.io.* import java.io.*
import java.util.* import java.util.*
open class ClasspathSnapshot protected constructor( open class ClasspathSnapshot protected constructor(
private val cacheDir: File, private val cacheDir: File,
private val classpath: Iterable<File>, private val classpath: Iterable<File>,
@@ -20,7 +19,7 @@ open class ClasspathSnapshot protected constructor(
val computedData = dataForFiles(missingFiles) val computedData = dataForFiles(missingFiles)
computedClasspathData.putAll(computedData) computedClasspathData.putAll(computedData)
} }
computedClasspathData.filter { files.contains(it.key) } computedClasspathData
} }
private val computedClasspathData: MutableMap<File, ClasspathEntryData> = mutableMapOf() private val computedClasspathData: MutableMap<File, ClasspathEntryData> = mutableMapOf()
@@ -95,10 +94,11 @@ open class ClasspathSnapshot protected constructor(
} }
} }
// We do not compute structural data for unchanged files of the current snapshot for performance reasons. That is why we // We do not compute structural data for unchanged files of the current snapshot for performance reasons.
// update the previous snapshot as that one contains all entries. // That is why we reuse the previous snapshot as that one contains all unchanged entries.
computedClasspathData.putAll(previousData) previousData.filter { !computedClasspathData.containsKey(it.key) }.forEach {
computedClasspathData.putAll(currentData) computedClasspathData[it.key] = it.value
}
val allImpactedClasses = findAllImpacted(changedClasses) val allImpactedClasses = findAllImpacted(changedClasses)
@@ -59,7 +59,7 @@ open class KaptContext(val options: KaptOptions, val withJdk: Boolean, val logge
cacheManager = options.incrementalCache?.let { cacheManager = options.incrementalCache?.let {
JavaClassCacheManager(it) JavaClassCacheManager(it)
} }
if (options.processIncrementally) { if (options.flags[KaptFlag.INCREMENTAL_APT]) {
sourcesToReprocess = sourcesToReprocess =
cacheManager?.invalidateAndGetDirtyFiles( cacheManager?.invalidateAndGetDirtyFiles(
options.changedFiles, options.classpathChanges options.changedFiles, options.classpathChanges
@@ -18,7 +18,6 @@ class KaptOptions(
val compiledSources: List<File>, val compiledSources: List<File>,
val incrementalCache: File?, val incrementalCache: File?,
val classpathChanges: List<String>, val classpathChanges: List<String>,
val processIncrementally: Boolean,
val sourcesOutputDir: File, val sourcesOutputDir: File,
val classesOutputDir: File, val classesOutputDir: File,
@@ -52,7 +51,6 @@ class KaptOptions(
var classesOutputDir: File? = null var classesOutputDir: File? = null
var stubsOutputDir: File? = null var stubsOutputDir: File? = null
var incrementalDataOutputDir: File? = null var incrementalDataOutputDir: File? = null
var processIncrementally: Boolean = false
val processingClasspath: MutableList<File> = mutableListOf() val processingClasspath: MutableList<File> = mutableListOf()
val processors: MutableList<String> = mutableListOf() val processors: MutableList<String> = mutableListOf()
@@ -75,7 +73,7 @@ class KaptOptions(
return KaptOptions( return KaptOptions(
projectBaseDir, compileClasspath, javaSourceRoots, projectBaseDir, compileClasspath, javaSourceRoots,
changedFiles, compiledSources, incrementalCache, classpathChanges, processIncrementally, changedFiles, compiledSources, incrementalCache, classpathChanges,
sourcesOutputDir, classesOutputDir, stubsOutputDir, incrementalDataOutputDir, sourcesOutputDir, classesOutputDir, stubsOutputDir, incrementalDataOutputDir,
processingClasspath, processors, processingOptions, javacOptions, KaptFlags.fromSet(flags), processingClasspath, processors, processingOptions, javacOptions, KaptFlags.fromSet(flags),
mode, detectMemoryLeaks mode, detectMemoryLeaks
@@ -106,7 +104,9 @@ enum class KaptFlag(val description: String) {
CORRECT_ERROR_TYPES("Correct error types"), CORRECT_ERROR_TYPES("Correct error types"),
MAP_DIAGNOSTIC_LOCATIONS("Map diagnostic locations"), MAP_DIAGNOSTIC_LOCATIONS("Map diagnostic locations"),
STRICT("Strict mode"), STRICT("Strict mode"),
INCLUDE_COMPILE_CLASSPATH("Detect annotation processors in compile classpath"); INCLUDE_COMPILE_CLASSPATH("Detect annotation processors in compile classpath"),
INCREMENTAL_APT("Incremental annotation processing (apt mode)"),
;
} }
interface KaptSelector { interface KaptSelector {
@@ -172,5 +172,4 @@ fun KaptOptions.logString(additionalInfo: String = "") = buildString {
appendln("[incremental apt] Compiled sources directories: ${compiledSources.joinToString()}") appendln("[incremental apt] Compiled sources directories: ${compiledSources.joinToString()}")
appendln("[incremental apt] Cache directory for incremental compilation: $incrementalCache") appendln("[incremental apt] Cache directory for incremental compilation: $incrementalCache")
appendln("[incremental apt] Changed classpath names: ${classpathChanges.joinToString()}") appendln("[incremental apt] Changed classpath names: ${classpathChanges.joinToString()}")
appendln("[incremental apt] If processing incrementally: $processIncrementally")
} }
@@ -211,9 +211,7 @@ class SourceFileStructure(
fun addMentionedConstant(containingClass: String, name: String) { fun addMentionedConstant(containingClass: String, name: String) {
if (!declaredTypes.contains(containingClass)) { if (!declaredTypes.contains(containingClass)) {
val names = mentionedConstants[containingClass] ?: HashSet() mentionedConstants.getOrPut(containingClass) { HashSet() }.add(name)
names.add(name)
mentionedConstants[containingClass] = names
} }
} }
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incremental package org.jetbrains.kotlin.kapt.base.test.org.jetbrains.kotlin.kapt3.base.incremental
import org.jetbrains.kotlin.base.kapt3.KaptFlag
import org.jetbrains.kotlin.base.kapt3.KaptOptions import org.jetbrains.kotlin.base.kapt3.KaptOptions
import org.jetbrains.kotlin.base.kapt3.collectJavaSourceFiles import org.jetbrains.kotlin.base.kapt3.collectJavaSourceFiles
import org.jetbrains.kotlin.kapt3.base.KaptContext import org.jetbrains.kotlin.kapt3.base.KaptContext
@@ -70,7 +71,7 @@ class IncrementalKaptTest {
incrementalCache = incrementalCacheDir incrementalCache = incrementalCacheDir
compiledSources.add(classesOutput) compiledSources.add(classesOutput)
changedFiles.add(sourcesDir.resolve("User.java")) changedFiles.add(sourcesDir.resolve("User.java"))
processIncrementally = true flags.add(KaptFlag.INCREMENTAL_APT)
}.build() }.build()
KaptContext(optionsForSecondRun, true, logger).use { KaptContext(optionsForSecondRun, true, logger).use {
@@ -144,7 +145,7 @@ class IncrementalKaptTest {
incrementalCache = incrementalCacheDir incrementalCache = incrementalCacheDir
compiledSources.add(classesOutput) compiledSources.add(classesOutput)
changedFiles.add(sourcesDir.resolve("User.java")) changedFiles.add(sourcesDir.resolve("User.java"))
processIncrementally = true flags.add(KaptFlag.INCREMENTAL_APT)
}.build() }.build()
KaptContext(optionsForSecondRun, true, logger).use { KaptContext(optionsForSecondRun, true, logger).use {
@@ -101,7 +101,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
COMPILED_SOURCES_DIR -> compiledSources.addAll(value.split(File.pathSeparator).map { File(it) }) COMPILED_SOURCES_DIR -> compiledSources.addAll(value.split(File.pathSeparator).map { File(it) })
INCREMENTAL_CACHE -> incrementalCache = File(value) INCREMENTAL_CACHE -> incrementalCache = File(value)
CLASSPATH_CHANGES -> classpathChanges.addAll(value.split(File.pathSeparator).map { it }) CLASSPATH_CHANGES -> classpathChanges.addAll(value.split(File.pathSeparator).map { it })
PROCESS_INCREMENTALLY -> processIncrementally = value.toBoolean() PROCESS_INCREMENTALLY -> setFlag(KaptFlag.INCREMENTAL_APT, value)
ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> processingClasspath += File(value) ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> processingClasspath += File(value)
ANNOTATION_PROCESSORS_OPTION -> processors.addAll(value.split(',').map { it.trim() }.filter { it.isNotEmpty() }) ANNOTATION_PROCESSORS_OPTION -> processors.addAll(value.split(',').map { it.trim() }.filter { it.isNotEmpty() })