Track binary output class names

This commit is contained in:
Mikhael Bogdanov
2020-11-17 08:23:34 +01:00
committed by max-kammerer
parent 6748560184
commit 42a9d64578
5 changed files with 45 additions and 26 deletions
@@ -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.
@@ -10,9 +10,9 @@ import java.io.Serializable
class IncrementalAptCache : Serializable {
private val aggregatingGenerated: MutableSet<File> = mutableSetOf()
private val aggregatingGenerated: MutableMap<File, String?> = mutableMapOf()
private val aggregatedTypes: MutableSet<String> = linkedSetOf()
private val isolatingMapping: MutableMap<File, File> = mutableMapOf()
private val isolatingMapping: MutableMap<File, Pair<String?, File>> = mutableMapOf()
// Annotations claimed by aggregating annotation processors
private val aggregatingClaimedAnnotations: MutableSet<String> = 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<File>, List<String>> {
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<File>): List<File> {
fun invalidateIsolatingGenerated(fromSources: Set<File>): Pair<List<File>, Set<String>> {
val allInvalidated = mutableListOf<File>()
val invalidatedClassIds = mutableSetOf<String>()
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()
@@ -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<String>()
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)
})
}
}
@@ -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<File, File?>()
private val generatedToSource = mutableMapOf<File, Pair<String?, File?>?>()
private val aggregatedTypes = mutableSetOf<String>()
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<File, File?> = if (isFullRebuild) emptyMap() else generatedToSource
internal fun getGeneratedToSources(): Map<File, File?> = if (isFullRebuild) emptyMap() else generatedToSource.mapValues { (_, value) ->
value?.second
}
internal fun getGeneratedToSourcesAll(): Map<File, Pair<String?, File?>?> =
if (isFullRebuild) emptyMap() else generatedToSource
internal fun getAggregatedTypes(): Set<String> = if (isFullRebuild) emptySet() else aggregatedTypes
@@ -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<String>()
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<File, File?>())
@@ -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<File, File?>())