Refactoring: introduce DirtyFilesContainer for better code reuse in IC

This commit is contained in:
Alexey Tsvetkov
2018-07-03 14:56:18 +03:00
parent 638c1eadff
commit aeaf1d6633
4 changed files with 66 additions and 54 deletions
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.name.FqName
import java.io.File
class DirtyFilesContainer(
private val caches: IncrementalCachesManager<*>,
private val reporter: ICReporter
) {
private val myDirtyFiles = HashSet<File>()
fun toMutableList(): MutableList<File> =
ArrayList(myDirtyFiles)
fun add(files: Iterable<File>) {
val existingKotlinFiles = files.filter { it.isKotlinFile() }
if (existingKotlinFiles.isNotEmpty()) {
myDirtyFiles.addAll(existingKotlinFiles)
}
}
fun addByDirtySymbols(lookupSymbols: Collection<LookupSymbol>) {
if (lookupSymbols.isEmpty()) return
val dirtyFilesFromLookups = mapLookupSymbolsToFiles(caches.lookupCache, lookupSymbols, reporter)
add(dirtyFilesFromLookups)
}
fun addByDirtyClasses(dirtyClassesFqNames: Collection<FqName>) {
if (dirtyClassesFqNames.isEmpty()) return
val fqNamesWithSubtypes = dirtyClassesFqNames.flatMap {
withSubtypes(
it,
listOf(caches.platformCache)
)
}
val dirtyFilesFromFqNames =
mapClassesFqNamesToFiles(listOf(caches.platformCache), fqNamesWithSubtypes, reporter)
add(dirtyFilesFromFqNames)
}
}
@@ -117,11 +117,9 @@ abstract class IncrementalCompilerRunner<
protected abstract fun calculateSourcesToCompile(caches: CacheManager, changedFiles: ChangedFiles.Known, args: Args): CompilationMode
protected fun getDirtyFiles(changedFiles: ChangedFiles.Known): HashSet<File> {
val dirtyFiles = HashSet<File>(with(changedFiles) { modified.size + removed.size })
with(changedFiles) {
modified.asSequence() + removed.asSequence()
}.filterTo(dirtyFiles, File::isKotlinFile)
protected fun initDirtyFiles(dirtyFiles: DirtyFilesContainer, changedFiles: ChangedFiles.Known) {
dirtyFiles.add(changedFiles.modified)
dirtyFiles.add(changedFiles.removed)
if (dirtySourcesSinceLastTimeFile.exists()) {
val files = dirtySourcesSinceLastTimeFile.readLines().map(::File)
@@ -129,14 +127,12 @@ abstract class IncrementalCompilerRunner<
reporter.report { "Source files added since last compilation: ${reporter.pathsAsString(files)}" }
}
dirtyFiles.addAll(files)
dirtyFiles.add(files)
}
return dirtyFiles
}
protected sealed class CompilationMode {
class Incremental(val dirtyFiles: Set<File>) : CompilationMode()
class Incremental(val dirtyFiles: DirtyFilesContainer) : CompilationMode()
class Rebuild(getReason: () -> String = { "" }) : CompilationMode() {
val reason: String by lazy(getReason)
}
@@ -188,7 +184,7 @@ abstract class IncrementalCompilerRunner<
preBuildHook(args, compilationMode)
val dirtySources = when (compilationMode) {
is CompilationMode.Incremental -> ArrayList(compilationMode.dirtyFiles)
is CompilationMode.Incremental -> compilationMode.dirtyFiles.toMutableList()
is CompilationMode.Rebuild -> allKotlinSources.toMutableList()
}
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.*
import org.jetbrains.kotlin.name.FqName
import java.io.File
fun makeJsIncrementally(
@@ -91,27 +90,12 @@ class IncrementalJsCompilerRunner(
if (changedLib != null) return CompilationMode.Rebuild { "Library has been changed: $changedLib" }
val dirtyFiles = getDirtyFiles(changedFiles)
// todo: unify with JVM calculateSourcesToCompile
fun markDirtyBy(lookupSymbols: Collection<LookupSymbol>) {
if (lookupSymbols.isEmpty()) return
val dirtyFilesFromLookups = mapLookupSymbolsToFiles(caches.lookupCache, lookupSymbols, reporter)
dirtyFiles.addAll(dirtyFilesFromLookups)
}
fun markDirtyBy(dirtyClassesFqNames: Collection<FqName>) {
if (dirtyClassesFqNames.isEmpty()) return
val fqNamesWithSubtypes = dirtyClassesFqNames.flatMap { withSubtypes(it, listOf(caches.platformCache)) }
val dirtyFilesFromFqNames = mapClassesFqNamesToFiles(listOf(caches.platformCache), fqNamesWithSubtypes, reporter)
dirtyFiles.addAll(dirtyFilesFromFqNames)
}
val dirtyFiles = DirtyFilesContainer(caches, reporter)
initDirtyFiles(dirtyFiles, changedFiles)
val removedClassesChanges = getRemovedClassesChanges(caches, changedFiles)
markDirtyBy(removedClassesChanges.dirtyLookupSymbols)
markDirtyBy(removedClassesChanges.dirtyClassesFqNames)
dirtyFiles.addByDirtySymbols(removedClassesChanges.dirtyLookupSymbols)
dirtyFiles.addByDirtyClasses(removedClassesChanges.dirtyClassesFqNames)
return CompilationMode.Incremental(dirtyFiles)
}
@@ -144,22 +144,8 @@ class IncrementalJvmCompilerRunner(
changedFiles: ChangedFiles.Known,
args: K2JVMCompilerArguments
): CompilationMode {
val dirtyFiles = getDirtyFiles(changedFiles)
fun markDirtyBy(lookupSymbols: Collection<LookupSymbol>) {
if (lookupSymbols.isEmpty()) return
val dirtyFilesFromLookups = mapLookupSymbolsToFiles(caches.lookupCache, lookupSymbols, reporter)
dirtyFiles.addAll(dirtyFilesFromLookups)
}
fun markDirtyBy(dirtyClassesFqNames: Collection<FqName>) {
if (dirtyClassesFqNames.isEmpty()) return
val fqNamesWithSubtypes = dirtyClassesFqNames.flatMap { withSubtypes(it, listOf(caches.platformCache)) }
val dirtyFilesFromFqNames = mapClassesFqNamesToFiles(listOf(caches.platformCache), fqNamesWithSubtypes, reporter)
dirtyFiles.addAll(dirtyFilesFromFqNames)
}
val dirtyFiles = DirtyFilesContainer(caches, reporter)
initDirtyFiles(dirtyFiles, changedFiles)
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" }
reporter.report { "Last Kotlin Build info -- $lastBuildInfo" }
@@ -173,8 +159,8 @@ class IncrementalJvmCompilerRunner(
"Could not get classpath's changes${classpathChanges.reason?.let { ": $it" }}"
}
is ChangesEither.Known -> {
markDirtyBy(classpathChanges.lookupSymbols)
markDirtyBy(classpathChanges.fqNames)
dirtyFiles.addByDirtySymbols(classpathChanges.lookupSymbols)
dirtyFiles.addByDirtyClasses(classpathChanges.fqNames)
}
}
@@ -184,9 +170,8 @@ class IncrementalJvmCompilerRunner(
is ChangesEither.Known -> javaFilesChanges.lookupSymbols
is ChangesEither.Unknown -> return CompilationMode.Rebuild { "Could not get changes for java files" }
}
markDirtyBy(affectedJavaSymbols)
}
else {
dirtyFiles.addByDirtySymbols(affectedJavaSymbols)
} else {
if (!processChangedJava(changedFiles, caches)) {
return CompilationMode.Rebuild { "Could not get changes for java files" }
}
@@ -195,9 +180,9 @@ class IncrementalJvmCompilerRunner(
val androidLayoutChanges = processLookupSymbolsForAndroidLayouts(changedFiles)
val removedClassesChanges = getRemovedClassesChanges(caches, changedFiles)
markDirtyBy(androidLayoutChanges)
markDirtyBy(removedClassesChanges.dirtyLookupSymbols)
markDirtyBy(removedClassesChanges.dirtyClassesFqNames)
dirtyFiles.addByDirtySymbols(androidLayoutChanges)
dirtyFiles.addByDirtySymbols(removedClassesChanges.dirtyLookupSymbols)
dirtyFiles.addByDirtyClasses(removedClassesChanges.dirtyClassesFqNames)
return CompilationMode.Incremental(dirtyFiles)
}