diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 1da4e83c697..44f30bef277 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -54,9 +54,12 @@ import org.jetbrains.jps.builders.java.JavaBuilderUtil import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.jps.model.JpsProject +import java.io.FileFilter +import org.jetbrains.kotlin.jps.incremental.IncrementalCacheImpl.RecompilationDecision.* import org.jetbrains.kotlin.compilerRunner.SimpleOutputItem import org.jetbrains.kotlin.utils.LibraryUtils import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache +import org.jetbrains.jps.incremental.fs.CompilationRound public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { class object { @@ -133,7 +136,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR val recompilationDecision: IncrementalCacheImpl.RecompilationDecision if (JpsUtils.isJsKotlinModule(chunk.representativeTarget())) { - recompilationDecision = IncrementalCacheImpl.RecompilationDecision.DO_NOTHING + recompilationDecision = DO_NOTHING } else { recompilationDecision = updateKotlinIncrementalCache(compilationErrors, dirtyFilesHolder, incrementalCaches, outputsItemsAndTargets) @@ -149,15 +152,21 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR } if (IncrementalCompilation.ENABLED) { - if (recompilationDecision == IncrementalCacheImpl.RecompilationDecision.RECOMPILE_ALL) { - allCompiledFiles.clear() - val targetsCompletelyMarkedDirty = FSOperations.getTargetsCompletelyMarkedDirty(context) - FSOperations.markDirtyRecursively(context, chunk) + val fileFilter = FileFilter { file -> + KotlinSourceFileCollector.isKotlinSourceFile(file) && file !in allCompiledFiles } - if (recompilationDecision == IncrementalCacheImpl.RecompilationDecision.COMPILE_OTHERS) { - FSOperations.markDirtyRecursively(context, chunk, { file -> - KotlinSourceFileCollector.isKotlinSourceFile(file) && file !in allCompiledFiles - }) + + when (recompilationDecision) { + RECOMPILE_ALL_CHUNK_AND_DEPENDANTS -> { + allCompiledFiles.clear() + FSOperations.markDirtyRecursively(context, chunk) + } + RECOMPILE_OTHERS_WITH_DEPENDANTS -> { + FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, fileFilter) + } + RECOMPILE_OTHERS_IN_CHUNK -> { + FSOperations.markDirty(context, chunk, fileFilter) + } } return ADDITIONAL_PASS_REQUIRED } @@ -254,7 +263,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR outputsItemsAndTargets: List> ): IncrementalCacheImpl.RecompilationDecision { if (!IncrementalCompilation.ENABLED) { - return IncrementalCacheImpl.RecompilationDecision.DO_NOTHING + return DO_NOTHING } for ((target, cache) in incrementalCaches) { @@ -265,7 +274,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR ) } - var recompilationDecision = IncrementalCacheImpl.RecompilationDecision.DO_NOTHING + var recompilationDecision = DO_NOTHING for ((outputItem, target) in outputsItemsAndTargets) { val newDecision = incrementalCaches[target]!!.saveFileToCache(outputItem.getSourceFiles(), outputItem.getOutputFile()) recompilationDecision = recompilationDecision.merge(newDecision) diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt index 1e1cc3401a3..9871da6f3fc 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/IncrementalCacheImpl.kt @@ -113,26 +113,38 @@ public class IncrementalCacheImpl(targetDataRoot: File): StorageOwner, Increment val data = BitEncoding.decodeBytes(annotationDataEncoded) when { header.isCompatiblePackageFacadeKind() -> { - return if (protoMap.put(className, data)) COMPILE_OTHERS else DO_NOTHING + return if (protoMap.put(className, data)) RECOMPILE_OTHERS_IN_CHUNK else DO_NOTHING } header.isCompatibleClassKind() -> { val inlinesChanged = inlineFunctionsMap.process(className, fileBytes) val protoChanged = protoMap.put(className, data) val constantsChanged = constantsMap.process(className, fileBytes) - return if (inlinesChanged) RECOMPILE_ALL else if (protoChanged || constantsChanged) COMPILE_OTHERS else DO_NOTHING + return when { + inlinesChanged -> RECOMPILE_ALL_CHUNK_AND_DEPENDANTS + constantsChanged -> RECOMPILE_OTHERS_WITH_DEPENDANTS + protoChanged -> RECOMPILE_OTHERS_IN_CHUNK + else -> DO_NOTHING + } } else -> { throw IllegalStateException("Unexpected kind with annotationData: ${header.kind}, isCompatible: ${header.isCompatibleAbiVersion}") } } } + if (header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART) { assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" } + packagePartMap.putPackagePartSourceData(sourceFiles.first(), className) val inlinesChanged = inlineFunctionsMap.process(className, fileBytes) val constantsChanged = constantsMap.process(className, fileBytes) - return if (inlinesChanged) RECOMPILE_ALL else if (constantsChanged) COMPILE_OTHERS else DO_NOTHING + + return when { + inlinesChanged -> RECOMPILE_ALL_CHUNK_AND_DEPENDANTS + constantsChanged -> RECOMPILE_OTHERS_WITH_DEPENDANTS + else -> DO_NOTHING + } } return DO_NOTHING @@ -497,8 +509,9 @@ public class IncrementalCacheImpl(targetDataRoot: File): StorageOwner, Increment enum class RecompilationDecision { DO_NOTHING - COMPILE_OTHERS - RECOMPILE_ALL + RECOMPILE_OTHERS_IN_CHUNK + RECOMPILE_OTHERS_WITH_DEPENDANTS + RECOMPILE_ALL_CHUNK_AND_DEPENDANTS fun merge(other: RecompilationDecision): RecompilationDecision { return if (other.ordinal() > this.ordinal()) other else this diff --git a/jps-plugin/testData/incremental/multiModule/simpleDependency/module2_c.kt b/jps-plugin/testData/incremental/multiModule/simpleDependency/module2_c.kt new file mode 100644 index 00000000000..c4fab8fb00b --- /dev/null +++ b/jps-plugin/testData/incremental/multiModule/simpleDependency/module2_c.kt @@ -0,0 +1,5 @@ +package c + +fun c() { + // This file doesn't use anything from module1, so it won't be recompiled after change +} \ No newline at end of file