From c1a9eb9d217e0004027209357e7b53874254c29b Mon Sep 17 00:00:00 2001 From: Andrey Uskov Date: Wed, 9 Dec 2020 17:33:09 +0300 Subject: [PATCH] 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). Original commit: 36f99156fd140f1ef58c7763f88b5bca18926b15 --- .../AbstractProtoComparisonTest.kt | 2 ++ .../kotlin/jps/build/KotlinBuilder.kt | 25 +++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt index 4065354f67c..da16372d4c1 100644 --- a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt +++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractProtoComparisonTest.kt @@ -90,6 +90,8 @@ abstract class AbstractProtoComparisonTest : 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() diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index d0b97301a60..04afe480d2c 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -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, val forceRecompileTogether: Set) + private fun ChangesCollector.getDirtyFiles( caches: Iterable, lookupStorageManager: JpsLookupStorageManager -): Set { +): 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 {