From 42a9d64578aabf1a6c5453a645c5f88dc43035aa Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 17 Nov 2020 08:23:34 +0100 Subject: [PATCH] Track binary output class names --- .../build.gradle.kts | 1 + .../base/incremental/IncrementalAptCache.kt | 32 ++++++++++++------- .../kotlin/kapt3/base/incremental/cache.kt | 6 ++-- .../base/incremental/incrementalProcessors.kt | 24 ++++++++------ ...otationProcessorDependencyCollectorTest.kt | 8 ++--- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts index 40087aa8d88..545746fd04b 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts @@ -45,6 +45,7 @@ dependencies { // Workaround for missing transitive import of the common(project `kotlin-test-common` // for `kotlin-test-jvm` into the IDE: testCompileOnly(project(":kotlin-test:kotlin-test-common")) { isTransitive = false } + testCompileOnly("org.ow2.asm:asm:9.0") } // Aapt2 from Android Gradle Plugin 3.2 and below does not handle long paths on Windows. diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalAptCache.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalAptCache.kt index 30d20bb0242..be6f5fc7249 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalAptCache.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/IncrementalAptCache.kt @@ -10,9 +10,9 @@ import java.io.Serializable class IncrementalAptCache : Serializable { - private val aggregatingGenerated: MutableSet = mutableSetOf() + private val aggregatingGenerated: MutableMap = mutableMapOf() private val aggregatedTypes: MutableSet = linkedSetOf() - private val isolatingMapping: MutableMap = mutableMapOf() + private val isolatingMapping: MutableMap> = mutableMapOf() // Annotations claimed by aggregating annotation processors private val aggregatingClaimedAnnotations: MutableSet = mutableSetOf() @@ -37,7 +37,11 @@ class IncrementalAptCache : Serializable { } aggregatingGenerated.clear() - aggregatingGenerated.addAll(aggregating.flatMap { it.getGeneratedToSources().keys }) + aggregating.forEach { + it.getGeneratedToSourcesAll().mapValuesTo(aggregatingGenerated) { (_, value) -> + value?.first + } + } aggregatingClaimedAnnotations.clear() aggregatingClaimedAnnotations.addAll(aggregating.flatMap { it.supportedAnnotationTypes }) @@ -46,8 +50,8 @@ class IncrementalAptCache : Serializable { aggregatedTypes.addAll(aggregating.flatMap { it.getAggregatedTypes() }) for (isolatingProcessor in isolating) { - isolatingProcessor.getGeneratedToSources().forEach { - isolatingMapping[it.key] = it.value!! + isolatingProcessor.getGeneratedToSourcesAll().forEach { + isolatingMapping[it.key] = it.value!!.first to it.value!!.second!! } } return true @@ -57,8 +61,8 @@ class IncrementalAptCache : Serializable { /** Returns generated Java sources originating from aggregating APs. */ fun invalidateAggregating(): Pair, List> { - val dirtyAggregating = aggregatingGenerated.filter { it.extension == "java" } - aggregatingGenerated.forEach { it.delete() } + val dirtyAggregating = aggregatingGenerated.keys.filter { it.isJavaFileOrClass() } + aggregatingGenerated.forEach { it.key.delete() } aggregatingGenerated.clear() val dirtyAggregated = ArrayList(aggregatedTypes) @@ -68,24 +72,30 @@ class IncrementalAptCache : Serializable { } /** Returns generated Java sources originating from the specified sources, and generated by isloating APs. */ - fun invalidateIsolatingGenerated(fromSources: Set): List { + fun invalidateIsolatingGenerated(fromSources: Set): Pair, Set> { val allInvalidated = mutableListOf() + val invalidatedClassIds = mutableSetOf() var changedSources = fromSources.toSet() // We need to do it in a loop because mapping could be: [AGenerated.java -> A.java, AGeneratedGenerated.java -> AGenerated.java] while (changedSources.isNotEmpty()) { - val generated = isolatingMapping.filter { changedSources.contains(it.value) }.keys + val generated = isolatingMapping.filter { changedSources.contains(it.value.second) }.keys generated.forEach { - if (it.extension == "java") allInvalidated.add(it) + if (it.isJavaFileOrClass()) { + allInvalidated.add(it) + isolatingMapping[it]?.first?.let { invalidatedClassIds.add(it) } + } it.delete() isolatingMapping.remove(it) } changedSources = generated } - return allInvalidated + return allInvalidated to invalidatedClassIds } + private fun File.isJavaFileOrClass() = extension == "java" || extension == "class" + private fun invalidateCache() { isIncremental = false aggregatingGenerated.clear() diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt index 29ede6d3ede..25f615725ba 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/cache.kt @@ -46,8 +46,9 @@ class JavaClassCacheManager(val file: File) : Closeable { is SourcesToReprocess.Incremental -> { val toReprocess = filesToReprocess.toReprocess.toMutableSet() - val isolatingGenerated = aptCache.invalidateIsolatingGenerated(toReprocess) - val generatedDirtyTypes = javaCache.invalidateGeneratedTypes(isolatingGenerated).toMutableSet() + val (invalidatedIsolatingGenerated, invalidatedIsolatingId) = aptCache.invalidateIsolatingGenerated(toReprocess) + val generatedDirtyTypes = javaCache.invalidateGeneratedTypes(invalidatedIsolatingGenerated).toMutableSet() /*+*/ + val aggregatedTypes = mutableListOf() if (!toReprocess.isEmpty()) { // only if there are some files to reprocess we should invalidate the aggregating ones @@ -66,6 +67,7 @@ class JavaClassCacheManager(val file: File) : Closeable { aggregatedTypes.also { it.removeAll(filesToReprocess.dirtyTypes) it.removeAll(generatedDirtyTypes) + it.removeAll(invalidatedIsolatingId) }) } } diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/incrementalProcessors.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/incrementalProcessors.kt index 9cba352db3a..ae2c4361272 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/incrementalProcessors.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/incremental/incrementalProcessors.kt @@ -71,6 +71,7 @@ class IncrementalProcessor(private val processor: Processor, private val kind: D fun isUnableToRunIncrementally() = !kind.canRunIncrementally fun getGeneratedToSources() = dependencyCollector.value.getGeneratedToSources() + fun getGeneratedToSourcesAll() = dependencyCollector.value.getGeneratedToSourcesAll() fun getAggregatedTypes() = dependencyCollector.value.getAggregatedTypes() fun getRuntimeType(): RuntimeProcType = dependencyCollector.value.getRuntimeType() @@ -92,15 +93,15 @@ internal class IncrementalFiler(private val filer: Filer) : Filer by filer { internal var dependencyCollector: AnnotationProcessorDependencyCollector? = null - override fun createSourceFile(name: CharSequence?, vararg originatingElements: Element?): JavaFileObject { + override fun createSourceFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject { val createdSourceFile = filer.createSourceFile(name, *originatingElements) - dependencyCollector!!.add(createdSourceFile.toUri(), originatingElements) + dependencyCollector!!.add(createdSourceFile.toUri(), originatingElements, name.toString()) return createdSourceFile } - override fun createClassFile(name: CharSequence?, vararg originatingElements: Element?): JavaFileObject { + override fun createClassFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject { val createdClassFile = filer.createClassFile(name, *originatingElements) - dependencyCollector!!.add(createdClassFile.toUri(), originatingElements) + dependencyCollector!!.add(createdClassFile.toUri(), originatingElements, name.toString()) return createdClassFile } @@ -111,7 +112,7 @@ internal class IncrementalFiler(private val filer: Filer) : Filer by filer { vararg originatingElements: Element? ): FileObject { val createdResource = filer.createResource(location, pkg, relativeName, *originatingElements) - dependencyCollector!!.add(createdResource.toUri(), originatingElements) + dependencyCollector!!.add(createdResource.toUri(), originatingElements, null) return createdResource } @@ -121,7 +122,7 @@ internal class AnnotationProcessorDependencyCollector( private val runtimeProcType: RuntimeProcType, private val warningCollector: (String) -> Unit ) { - private val generatedToSource = mutableMapOf() + private val generatedToSource = mutableMapOf?>() private val aggregatedTypes = mutableSetOf() private var isFullRebuild = !runtimeProcType.isIncremental @@ -149,7 +150,7 @@ internal class AnnotationProcessorDependencyCollector( val generatedFile = File(createdFile) if (runtimeProcType == RuntimeProcType.AGGREGATING) { - generatedToSource[generatedFile] = null + generatedToSource[generatedFile] = classId to null } else { val srcFiles = getSrcFiles(originatingElements) if (srcFiles.size != 1) { @@ -159,12 +160,17 @@ internal class AnnotationProcessorDependencyCollector( "but detected ${srcFiles.size}: [${srcFiles.joinToString()}]." ) } else { - generatedToSource[generatedFile] = srcFiles.single() + generatedToSource[generatedFile] = classId to srcFiles.single() } } } - internal fun getGeneratedToSources(): Map = if (isFullRebuild) emptyMap() else generatedToSource + internal fun getGeneratedToSources(): Map = if (isFullRebuild) emptyMap() else generatedToSource.mapValues { (_, value) -> + value?.second + } + + internal fun getGeneratedToSourcesAll(): Map?> = + if (isFullRebuild) emptyMap() else generatedToSource internal fun getAggregatedTypes(): Set = if (isFullRebuild) emptySet() else aggregatedTypes diff --git a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/AnnotationProcessorDependencyCollectorTest.kt b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/AnnotationProcessorDependencyCollectorTest.kt index 9838eb95cb8..c714444746e 100644 --- a/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/AnnotationProcessorDependencyCollectorTest.kt +++ b/plugins/kapt3/kapt3-base/test/org/jetbrains/kotlin/kapt3/base/incremental/AnnotationProcessorDependencyCollectorTest.kt @@ -17,7 +17,7 @@ class AnnotationProcessorDependencyCollectorTest { fun testAggregating() { val aggregating = AnnotationProcessorDependencyCollector(RuntimeProcType.AGGREGATING) {} val generated = listOf("GeneratedA.java", "GeneratedB.java", "GeneratedC.java").map { File(it).toURI() } - generated.forEach { aggregating.add(it, emptyArray()) } + generated.forEach { aggregating.add(it, emptyArray(), null) } assertEquals(aggregating.getGeneratedToSources(), generated.map { File(it) to null }.toMap()) assertEquals(aggregating.getRuntimeType(), RuntimeProcType.AGGREGATING) @@ -27,7 +27,7 @@ class AnnotationProcessorDependencyCollectorTest { fun testIsolatingWithoutOrigin() { val warnings = mutableListOf() val isolating = AnnotationProcessorDependencyCollector(RuntimeProcType.ISOLATING) { s -> warnings.add(s) } - isolating.add(File("GeneratedA.java").toURI(), emptyArray()) + isolating.add(File("GeneratedA.java").toURI(), emptyArray(), null) assertEquals(isolating.getRuntimeType(), RuntimeProcType.NON_INCREMENTAL) assertEquals(isolating.getGeneratedToSources(), emptyMap()) @@ -37,8 +37,8 @@ class AnnotationProcessorDependencyCollectorTest { @Test fun testNonIncremental() { val nonIncremental = AnnotationProcessorDependencyCollector(RuntimeProcType.NON_INCREMENTAL) {} - nonIncremental.add(File("GeneratedA.java").toURI(), emptyArray()) - nonIncremental.add(File("GeneratedB.java").toURI(), emptyArray()) + nonIncremental.add(File("GeneratedA.java").toURI(), emptyArray(), null) + nonIncremental.add(File("GeneratedB.java").toURI(), emptyArray(), null) assertEquals(nonIncremental.getRuntimeType(), RuntimeProcType.NON_INCREMENTAL) assertEquals(nonIncremental.getGeneratedToSources(), emptyMap())