From 2412b5f992f164cf33a9421bb54d2414db8869cc Mon Sep 17 00:00:00 2001 From: Ivan Gavrilovic Date: Wed, 7 Aug 2019 11:36:43 +0100 Subject: [PATCH] Delete output when unable to run KAPT incrementally When comparing previous and current classpath snapshots, and it is not possible to compute the types that changed, make sure to delete the outputs before invoking KAPT. Test: KaptIncrementalWithAggregatingApt.testIncompatibleClasspathChanges --- .../KaptIncrementalWithAggregatingApt.kt | 34 +++++++++++ .../kotlin/gradle/internal/kapt/KaptTask.kt | 61 ++++++++++--------- .../kapt/incremental/ClasspathSnapshot.kt | 2 + 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt index 17cbf09d010..832129a8422 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KaptIncrementalWithAggregatingApt.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.gradle.util.modify import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test +import kotlin.test.assertFalse class KaptIncrementalWithAggregatingApt : KaptIncrementalIT() { @@ -136,4 +137,37 @@ class KaptIncrementalWithAggregatingApt : KaptIncrementalIT() { assertTrue(getProcessedSources(output).isEmpty()) } } + + @Test + fun testIncompatibleClasspathChanges() { + val project = getProject() + project.projectFile("useB.kt").modify { current -> + current + """ + + @example.ExampleAnnotation + fun addedFunctionB() = "" + """.trimIndent() + } + project.build("clean", "build") { + assertSuccessful() + } + + project.projectFile("useB.kt").modify { current -> + current.replace("fun addedFunctionB", "fun renamedFunctionB") + } + project.gradleBuildScript().appendText(""" + + dependencies { + compile 'com.google.guava:guava:12.0' + } + """.trimIndent()) + project.build("build") { + assertSuccessful() + + assertFalse( + fileInWorkingDir("build/generated/source/kapt/main/bar/AddedFunctionBGenerated.java").exists(), + "Generated file should be deleted for renamed function when classpath changes." + ) + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt index 16169ecfc99..b83d0b4cdb1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptTask.kt @@ -170,44 +170,44 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState { protected fun getCompiledSources() = listOfNotNull(kotlinCompileTask.destinationDir, kotlinCompileTask.javaOutputDir) protected fun getIncrementalChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges { - if (!isIncremental) { + return if (isIncremental) { + findClasspathChanges(inputs) + } else { clearLocalState() - return KaptIncrementalChanges.Unknown - } - val allDataFiles = classpathStructure!!.files - if (!inputs.isIncremental) { - clearLocalState() - findClasspathChanges(allDataFiles, allDataFiles) - return KaptIncrementalChanges.Unknown - } - - val changedFiles = with(mutableSetOf()) { - inputs.outOfDate { this.add(it.file) } - inputs.removed { this.add(it.file) } - return@with this - } - - val changedDataFiles = allDataFiles.filterTo(HashSet()) { it in changedFiles } - val classpathStatus = findClasspathChanges(allDataFiles, changedDataFiles) - return when (classpathStatus) { - is KaptClasspathChanges.Unknown -> KaptIncrementalChanges.Unknown - is KaptClasspathChanges.Known -> KaptIncrementalChanges.Known( - changedFiles.filter { it.extension == "java" }.toSet(), classpathStatus.names - ) + KaptIncrementalChanges.Unknown } } - private fun findClasspathChanges(allDataFile: Set, changedDataFiles: Set): KaptClasspathChanges { + private fun findClasspathChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges { val incAptCacheDir = incAptCache!! incAptCacheDir.mkdirs() + val allDataFiles = classpathStructure!!.files + val changedFiles = if (inputs.isIncremental) { + with(mutableSetOf()) { + inputs.outOfDate { this.add(it.file) } + inputs.removed { this.add(it.file) } + return@with this + } + } else { + allDataFiles + } + val startTime = System.currentTimeMillis() - val previousSnapshot = ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(incAptCacheDir) + val previousSnapshot = if (inputs.isIncremental) { + ClasspathSnapshot.ClasspathSnapshotFactory.loadFrom(incAptCacheDir) + } else { + ClasspathSnapshot.ClasspathSnapshotFactory.getEmptySnapshot() + } val currentSnapshot = - ClasspathSnapshot.ClasspathSnapshotFactory.createCurrent(incAptCacheDir, classpath.files.toList(), allDataFile) + ClasspathSnapshot.ClasspathSnapshotFactory.createCurrent(incAptCacheDir, classpath.files.toList(), allDataFiles) - val classpathChanges = currentSnapshot.diff(previousSnapshot, changedDataFiles) + val classpathChanges = currentSnapshot.diff(previousSnapshot, changedFiles) + if (classpathChanges == KaptClasspathChanges.Unknown) { + // We are unable to determine classpath changes, so clean the local state as we will run non-incrementally + clearLocalState() + } currentSnapshot.writeToCache() if (logger.isInfoEnabled) { @@ -223,7 +223,12 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState { } } } - return classpathChanges + return when (classpathChanges) { + is KaptClasspathChanges.Unknown -> KaptIncrementalChanges.Unknown + is KaptClasspathChanges.Known -> KaptIncrementalChanges.Known( + changedFiles.filter { it.extension == "java" }.toSet(), classpathChanges.names + ) + } } private fun hasAnnotationProcessors(file: File): Boolean { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathSnapshot.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathSnapshot.kt index 0f02ea2dc56..6509abc7218 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathSnapshot.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/incremental/ClasspathSnapshot.kt @@ -43,6 +43,8 @@ open class ClasspathSnapshot protected constructor( return ClasspathSnapshot(cacheDir, classpath, data) } + + fun getEmptySnapshot() = UnknownSnapshot } private fun isCompatible(snapshot: ClasspathSnapshot) =