Incremental KAPT: simplify impacted types computation
Process aggregating types first, and when computing impacted types compute isolating generated impacted by classpath changes first.
This commit is contained in:
committed by
Mikhael Bogdanov
parent
c7e5beece5
commit
05e47da458
+2
-2
@@ -115,8 +115,8 @@ class IncrementalAptCache : Serializable {
|
||||
}
|
||||
|
||||
/** Gets the originating type for the specified type generated by isolating AP. */
|
||||
fun getOriginForGeneratedIsolatingType(generatedType: String, sourceFileProvider: (String) -> File?): String {
|
||||
val generatedFile = checkNotNull(sourceFileProvider(generatedType)) { "Unable to find source for $generatedType" }
|
||||
fun getOriginForGeneratedIsolatingType(generatedType: String, sourceFileProvider: (String) -> File): String {
|
||||
val generatedFile = sourceFileProvider(generatedType)
|
||||
return isolatingMapping.getValue(generatedFile)
|
||||
}
|
||||
|
||||
|
||||
@@ -55,49 +55,40 @@ class JavaClassCacheManager(val file: File) : Closeable {
|
||||
|
||||
val sourcesToReprocess = changedSources.toMutableSet()
|
||||
val classNamesToReprocess = mutableListOf<String>()
|
||||
var shouldProcessAggregating = false
|
||||
|
||||
for (impactedType in impactedTypes) {
|
||||
if (impactedType !in isolatingGeneratedTypes && impactedType !in aggregatingGeneratedTypes) {
|
||||
// Reprocess only if original source
|
||||
javaCache.getSourceForType(impactedType)?.let {
|
||||
sourcesToReprocess.add(it)
|
||||
}
|
||||
} else if (impactedType in isolatingGeneratedTypes) {
|
||||
// this is a generated type by isolating AP
|
||||
val isolatingOrigin = aptCache.getOriginForGeneratedIsolatingType(impactedType, javaCache::getSourceForType)
|
||||
if (isolatingOrigin in impactedTypes) {
|
||||
// we'll process origin, no need to do it now
|
||||
continue
|
||||
}
|
||||
val originSource = javaCache.getSourceForType(isolatingOrigin)
|
||||
if (originSource?.extension == "java") {
|
||||
sourcesToReprocess.add(originSource)
|
||||
} else if (originSource?.extension == "class") {
|
||||
// This is a generated .class file that we need to reprocess.
|
||||
classNamesToReprocess.add(isolatingOrigin)
|
||||
} else {
|
||||
// This is a type from classpath that was used as origin, just ignore it. It is used just to remove the generated file.
|
||||
}
|
||||
} else {
|
||||
// processed separately
|
||||
shouldProcessAggregating = true
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldProcessAggregating || sourcesToReprocess.isNotEmpty() || classNamesToReprocess.isNotEmpty()) {
|
||||
if (changedSources.isNotEmpty() || impactedTypes.isNotEmpty()) {
|
||||
for (aggregatingOrigin in aptCache.getAggregatingOrigins()) {
|
||||
if (aggregatingOrigin in impactedTypes) continue
|
||||
|
||||
val originSource = javaCache.getSourceForType(aggregatingOrigin)
|
||||
if (originSource?.extension == "java") {
|
||||
if (originSource.extension == "java") {
|
||||
sourcesToReprocess.add(originSource)
|
||||
} else if (originSource?.extension == "class") {
|
||||
} else if (originSource.extension == "class") {
|
||||
// This is a generated .class file that we need to reprocess.
|
||||
classNamesToReprocess.add(aggregatingOrigin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (impactedType in impactedTypes) {
|
||||
if (impactedType !in isolatingGeneratedTypes && impactedType !in aggregatingGeneratedTypes) {
|
||||
sourcesToReprocess.add(javaCache.getSourceForType(impactedType))
|
||||
} else if (impactedType in isolatingGeneratedTypes) {
|
||||
// this is a generated type by isolating AP
|
||||
val isolatingOrigin = aptCache.getOriginForGeneratedIsolatingType(impactedType, javaCache::getSourceForType)
|
||||
if (isolatingOrigin in impactedTypes || isolatingOrigin in dirtyClasspathFqNames) {
|
||||
continue
|
||||
}
|
||||
val originSource = javaCache.getSourceForType(isolatingOrigin)
|
||||
if (originSource.extension == "java") {
|
||||
sourcesToReprocess.add(originSource)
|
||||
} else if (originSource.extension == "class") {
|
||||
classNamesToReprocess.add(isolatingOrigin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sourcesToReprocess.isNotEmpty() || classNamesToReprocess.isNotEmpty()) {
|
||||
// Invalidate state only if there are some files that will be reprocessed
|
||||
javaCache.invalidateDataForTypes(impactedTypes)
|
||||
aptCache.invalidateAggregating()
|
||||
@@ -111,27 +102,13 @@ class JavaClassCacheManager(val file: File) : Closeable {
|
||||
|
||||
private fun getAllImpactedTypes(changes: Changes, aggregatingGeneratedTypes: Set<String>): MutableSet<String> {
|
||||
val impactedTypes = javaCache.getAllImpactedTypes(changes)
|
||||
|
||||
/**
|
||||
* In order to find all impacted types we do the following:
|
||||
* - impacted types is a set of types that have changed from the previous compilation
|
||||
* - if there is a changed source or a source file that is impacted by type changes, we'll need to run aggregating APs, so we
|
||||
* invalidate all aggregating generated types, and add them to set of impacted types.
|
||||
* - using this new impacted types set, we find all types generated by isolating APs with origins in those types
|
||||
* - if there are some generated types by isolating APs, we'll need to run aggregating APs, so we invalidate all aggregating types
|
||||
* and add them to impacted types.
|
||||
* - using the final value of impacted types we get all generated types by isolating APs and add them to impacted types
|
||||
*/
|
||||
// check isolating with origins from the classpath
|
||||
impactedTypes.addAll(aptCache.getIsolatingGeneratedTypesForOrigins(changes.dirtyFqNamesFromClasspath, javaCache::getTypesForFiles))
|
||||
if (changes.sourceChanges.isNotEmpty() || impactedTypes.isNotEmpty()) {
|
||||
// Any source change or any source impacted by type change invalidates aggregating APs generated types
|
||||
impactedTypes.addAll(aggregatingGeneratedTypes)
|
||||
}
|
||||
aptCache.getIsolatingGeneratedTypesForOrigins(changes.dirtyFqNamesFromClasspath, javaCache::getTypesForFiles).let {
|
||||
if (it.isNotEmpty()) {
|
||||
impactedTypes.addAll(it)
|
||||
impactedTypes.addAll(aggregatingGeneratedTypes)
|
||||
}
|
||||
}
|
||||
// now check isolating with origins in any of the impacted types
|
||||
aptCache.getIsolatingGeneratedTypesForOrigins(impactedTypes, javaCache::getTypesForFiles).let {
|
||||
impactedTypes.addAll(it)
|
||||
}
|
||||
|
||||
+3
-2
@@ -10,6 +10,7 @@ import java.io.ObjectInputStream
|
||||
import java.io.ObjectOutputStream
|
||||
import java.io.Serializable
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.lang.IllegalStateException
|
||||
import java.net.URI
|
||||
|
||||
/**
|
||||
@@ -147,13 +148,13 @@ class JavaClassCache() : Serializable {
|
||||
sourceCache.clear()
|
||||
}
|
||||
|
||||
fun getSourceForType(type: String): File? {
|
||||
fun getSourceForType(type: String): File {
|
||||
sourceCache.forEach { (fileUri, typeInfo) ->
|
||||
if (type in typeInfo.getDeclaredTypes()) {
|
||||
return File(fileUri)
|
||||
}
|
||||
}
|
||||
return null
|
||||
throw IllegalStateException("Unable to find source file for type $type")
|
||||
}
|
||||
|
||||
fun invalidateDataForTypes(impactedTypes: MutableSet<String>) {
|
||||
|
||||
Reference in New Issue
Block a user