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 {