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. */
|
/** Gets the originating type for the specified type generated by isolating AP. */
|
||||||
fun getOriginForGeneratedIsolatingType(generatedType: String, sourceFileProvider: (String) -> File?): String {
|
fun getOriginForGeneratedIsolatingType(generatedType: String, sourceFileProvider: (String) -> File): String {
|
||||||
val generatedFile = checkNotNull(sourceFileProvider(generatedType)) { "Unable to find source for $generatedType" }
|
val generatedFile = sourceFileProvider(generatedType)
|
||||||
return isolatingMapping.getValue(generatedFile)
|
return isolatingMapping.getValue(generatedFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,49 +55,40 @@ class JavaClassCacheManager(val file: File) : Closeable {
|
|||||||
|
|
||||||
val sourcesToReprocess = changedSources.toMutableSet()
|
val sourcesToReprocess = changedSources.toMutableSet()
|
||||||
val classNamesToReprocess = mutableListOf<String>()
|
val classNamesToReprocess = mutableListOf<String>()
|
||||||
var shouldProcessAggregating = false
|
|
||||||
|
|
||||||
for (impactedType in impactedTypes) {
|
if (changedSources.isNotEmpty() || impactedTypes.isNotEmpty()) {
|
||||||
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()) {
|
|
||||||
for (aggregatingOrigin in aptCache.getAggregatingOrigins()) {
|
for (aggregatingOrigin in aptCache.getAggregatingOrigins()) {
|
||||||
if (aggregatingOrigin in impactedTypes) continue
|
if (aggregatingOrigin in impactedTypes) continue
|
||||||
|
|
||||||
val originSource = javaCache.getSourceForType(aggregatingOrigin)
|
val originSource = javaCache.getSourceForType(aggregatingOrigin)
|
||||||
if (originSource?.extension == "java") {
|
if (originSource.extension == "java") {
|
||||||
sourcesToReprocess.add(originSource)
|
sourcesToReprocess.add(originSource)
|
||||||
} else if (originSource?.extension == "class") {
|
} else if (originSource.extension == "class") {
|
||||||
// This is a generated .class file that we need to reprocess.
|
// This is a generated .class file that we need to reprocess.
|
||||||
classNamesToReprocess.add(aggregatingOrigin)
|
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
|
// Invalidate state only if there are some files that will be reprocessed
|
||||||
javaCache.invalidateDataForTypes(impactedTypes)
|
javaCache.invalidateDataForTypes(impactedTypes)
|
||||||
aptCache.invalidateAggregating()
|
aptCache.invalidateAggregating()
|
||||||
@@ -111,27 +102,13 @@ class JavaClassCacheManager(val file: File) : Closeable {
|
|||||||
|
|
||||||
private fun getAllImpactedTypes(changes: Changes, aggregatingGeneratedTypes: Set<String>): MutableSet<String> {
|
private fun getAllImpactedTypes(changes: Changes, aggregatingGeneratedTypes: Set<String>): MutableSet<String> {
|
||||||
val impactedTypes = javaCache.getAllImpactedTypes(changes)
|
val impactedTypes = javaCache.getAllImpactedTypes(changes)
|
||||||
|
// check isolating with origins from the classpath
|
||||||
/**
|
impactedTypes.addAll(aptCache.getIsolatingGeneratedTypesForOrigins(changes.dirtyFqNamesFromClasspath, javaCache::getTypesForFiles))
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
if (changes.sourceChanges.isNotEmpty() || impactedTypes.isNotEmpty()) {
|
if (changes.sourceChanges.isNotEmpty() || impactedTypes.isNotEmpty()) {
|
||||||
// Any source change or any source impacted by type change invalidates aggregating APs generated types
|
// Any source change or any source impacted by type change invalidates aggregating APs generated types
|
||||||
impactedTypes.addAll(aggregatingGeneratedTypes)
|
impactedTypes.addAll(aggregatingGeneratedTypes)
|
||||||
}
|
}
|
||||||
aptCache.getIsolatingGeneratedTypesForOrigins(changes.dirtyFqNamesFromClasspath, javaCache::getTypesForFiles).let {
|
// now check isolating with origins in any of the impacted types
|
||||||
if (it.isNotEmpty()) {
|
|
||||||
impactedTypes.addAll(it)
|
|
||||||
impactedTypes.addAll(aggregatingGeneratedTypes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aptCache.getIsolatingGeneratedTypesForOrigins(impactedTypes, javaCache::getTypesForFiles).let {
|
aptCache.getIsolatingGeneratedTypesForOrigins(impactedTypes, javaCache::getTypesForFiles).let {
|
||||||
impactedTypes.addAll(it)
|
impactedTypes.addAll(it)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -10,6 +10,7 @@ import java.io.ObjectInputStream
|
|||||||
import java.io.ObjectOutputStream
|
import java.io.ObjectOutputStream
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.lang.IllegalArgumentException
|
import java.lang.IllegalArgumentException
|
||||||
|
import java.lang.IllegalStateException
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,13 +148,13 @@ class JavaClassCache() : Serializable {
|
|||||||
sourceCache.clear()
|
sourceCache.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSourceForType(type: String): File? {
|
fun getSourceForType(type: String): File {
|
||||||
sourceCache.forEach { (fileUri, typeInfo) ->
|
sourceCache.forEach { (fileUri, typeInfo) ->
|
||||||
if (type in typeInfo.getDeclaredTypes()) {
|
if (type in typeInfo.getDeclaredTypes()) {
|
||||||
return File(fileUri)
|
return File(fileUri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
throw IllegalStateException("Unable to find source file for type $type")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun invalidateDataForTypes(impactedTypes: MutableSet<String>) {
|
fun invalidateDataForTypes(impactedTypes: MutableSet<String>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user