IC of sealed classes

Supported case then children of sealed classes could be declared
anywhere in a module. If list of classes implementing sealing class
changes the sealed class and all its inheritors should be recompiled
(now sealed class should be compiled together with children in order
to calculate all possible inheritors at compile time) and and
invalidated (as they could have when operators).
This commit is contained in:
Andrey Uskov
2020-12-09 17:33:09 +03:00
committed by Andrey Uskov
parent a0651cdba7
commit 36f99156fd
11 changed files with 183 additions and 20 deletions
@@ -90,6 +90,8 @@ abstract class AbstractProtoComparisonTest<PROTO_DATA> : TestWithWorkingDir() {
when (it) {
is ChangeInfo.SignatureChanged -> "CLASS_SIGNATURE"
is ChangeInfo.MembersChanged -> "MEMBERS\n ${it.names.sorted()}"
is ChangeInfo.ParentsChanged -> "PARENTS\n ${it.parentsChanged.map { it.asString()}.sorted()}"
}
}.sorted()
@@ -250,7 +250,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
removedClasses.forEach { changesCollector.collectSignature(FqName(it), areSubclassesAffected = true) }
val affectedByRemovedClasses = changesCollector.getDirtyFiles(incrementalCaches.values, kotlinContext.lookupStorageManager)
fsOperations.markFilesForCurrentRound(affectedByRemovedClasses)
fsOperations.markFilesForCurrentRound(affectedByRemovedClasses.dirtyFiles + affectedByRemovedClasses.forceRecompileTogether)
}
override fun chunkBuildFinished(context: CompileContext, chunk: ModuleChunk) {
@@ -695,21 +695,36 @@ private fun ChangesCollector.processChangesUsingLookups(
reporter.reportVerbose { "Start processing changes" }
val dirtyFiles = getDirtyFiles(allCaches, lookupStorageManager)
fsOperations.markInChunkOrDependents(dirtyFiles.asIterable(), excludeFiles = compiledFiles)
// if list of inheritors of sealed class has changed it should be recompiled with all the inheritors
// Here we have a small optimization. Do not recompile the bunch if ALL these files were recompiled during the previous round.
val excludeFiles = if (compiledFiles.containsAll(dirtyFiles.forceRecompileTogether))
compiledFiles
else
compiledFiles.minus(dirtyFiles.forceRecompileTogether)
fsOperations.markInChunkOrDependents(
(dirtyFiles.dirtyFiles + dirtyFiles.forceRecompileTogether).asIterable(),
excludeFiles = excludeFiles
)
reporter.reportVerbose { "End of processing changes" }
}
data class FilesToRecompile(val dirtyFiles: Set<File>, val forceRecompileTogether: Set<File>)
private fun ChangesCollector.getDirtyFiles(
caches: Iterable<IncrementalCacheCommon>,
lookupStorageManager: JpsLookupStorageManager
): Set<File> {
): FilesToRecompile {
val reporter = JpsICReporter()
val (dirtyLookupSymbols, dirtyClassFqNames) = getDirtyData(caches, reporter)
val (dirtyLookupSymbols, dirtyClassFqNames, forceRecompile) = getDirtyData(caches, reporter)
val dirtyFilesFromLookups = lookupStorageManager.withLookupStorage {
mapLookupSymbolsToFiles(it, dirtyLookupSymbols, reporter)
}
return dirtyFilesFromLookups + mapClassesFqNamesToFiles(caches, dirtyClassFqNames, reporter)
return FilesToRecompile(
dirtyFilesFromLookups + mapClassesFqNamesToFiles(caches, dirtyClassFqNames, reporter),
mapClassesFqNamesToFiles(caches, forceRecompile, reporter)
)
}
private fun getLookupTracker(project: JpsProject, representativeTarget: KotlinModuleBuildTarget<*>): LookupTracker {