Add IC metrics reporting

This commit is contained in:
Alexey Tsvetkov
2020-03-02 14:26:49 +03:00
committed by Alexander Likhachev
parent 5bde6457b1
commit 36387d97ad
69 changed files with 1396 additions and 432 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.name.FqName
import java.io.File
import java.io.IOException
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.incremental
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import java.io.File
import java.util.*
@@ -37,7 +39,7 @@ internal class ChangedJavaFilesProcessor(
if (removedJava.any()) {
reporter.report { "Some java files are removed: [${removedJava.joinToString()}]" }
return ChangesEither.Unknown()
return ChangesEither.Unknown(BuildAttribute.JAVA_CHANGE_UNTRACKED_FILE_IS_REMOVED)
}
val symbols = HashSet<LookupSymbol>()
@@ -47,7 +49,7 @@ internal class ChangedJavaFilesProcessor(
val psiFile = psiFileFactory(javaFile)
if (psiFile !is PsiJavaFile) {
reporter.report { "Expected PsiJavaFile, got ${psiFile?.javaClass}" }
return ChangesEither.Unknown()
return ChangesEither.Unknown(BuildAttribute.JAVA_CHANGE_UNEXPECTED_PSI)
}
psiFile.classes.forEach { it.addLookupSymbols(symbols) }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.name.FqName
internal sealed class ChangesEither {
@@ -24,5 +25,5 @@ internal sealed class ChangesEither {
val fqNames: Collection<FqName> = emptyList()
) : ChangesEither()
internal class Unknown(val reason: String? = null) : ChangesEither()
internal class Unknown(val reason: BuildAttribute) : ChangesEither()
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.name.FqName
import java.io.File
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.incremental.storage.IncrementalFileToPathConverter
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
@@ -18,6 +18,10 @@ package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.build.report.metrics.measure
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -41,7 +45,7 @@ abstract class IncrementalCompilerRunner<
>(
private val workingDir: File,
cacheDirName: String,
protected val reporter: ICReporter,
protected val reporter: BuildReporter,
private val buildHistoryFile: File,
// there might be some additional output directories (e.g. for generated java in kapt)
// to remove them correctly on rebuild, we pass them as additional argument
@@ -65,20 +69,33 @@ abstract class IncrementalCompilerRunner<
// otherwise we track source files changes ourselves.
providedChangedFiles: ChangedFiles?,
projectDir: File? = null
): ExitCode = reporter.measure(BuildTime.INCREMENTAL_COMPILATION) {
compileImpl(allSourceFiles, args, messageCollector, providedChangedFiles, projectDir)
}
private fun compileImpl(
allSourceFiles: List<File>,
args: Args,
messageCollector: MessageCollector,
providedChangedFiles: ChangedFiles?,
projectDir: File? = null
): ExitCode {
assert(isICEnabled()) { "Incremental compilation is not enabled" }
var caches = createCacheManager(args, projectDir)
fun rebuild(reason: () -> String): ExitCode {
reporter.report(reason)
fun rebuild(reason: BuildAttribute): ExitCode {
reporter.report { "Non-incremental compilation will be performed: $reason" }
caches.close(false)
clearLocalStateOnRebuild(args)
// todo: we can recompile all files incrementally (not cleaning caches), so rebuild won't propagate
reporter.measure(BuildTime.CLEAR_OUTPUT_ON_REBUILD) {
clearLocalStateOnRebuild(args)
}
caches = createCacheManager(args, projectDir)
if (providedChangedFiles == null) {
caches.inputsCache.sourceSnapshotMap.compareAndUpdate(allSourceFiles)
}
val allKotlinFiles = allSourceFiles.filter { it.isKotlinFile(kotlinSourceFilesExtensions) }
return compileIncrementally(args, caches, allKotlinFiles, CompilationMode.Rebuild(), messageCollector)
return compileIncrementally(args, caches, allKotlinFiles, CompilationMode.Rebuild(reason), messageCollector)
}
return try {
@@ -90,16 +107,17 @@ abstract class IncrementalCompilerRunner<
compileIncrementally(args, caches, allSourceFiles, compilationMode, messageCollector)
}
is CompilationMode.Rebuild -> {
rebuild { "Non-incremental compilation will be performed: ${compilationMode.reason}" }
rebuild(compilationMode.reason)
}
}
if (!caches.close(flush = true)) throw RuntimeException("Could not flush caches")
return exitCode
} catch (e: Exception) {
} catch (e: Exception) { // todo: catch only cache corruption
// todo: warn?
rebuild { "Possible cache corruption. Rebuilding. $e" }
reporter.report { "Rebuilding because of possible caches corruption: $e" }
rebuild(BuildAttribute.CACHE_CORRUPTION)
}
}
@@ -139,10 +157,17 @@ abstract class IncrementalCompilerRunner<
): CompilationMode =
when (changedFiles) {
is ChangedFiles.Known -> calculateSourcesToCompile(caches, changedFiles, args, messageCollector)
is ChangedFiles.Unknown -> CompilationMode.Rebuild { "inputs' changes are unknown (first or clean build)" }
is ChangedFiles.Unknown -> CompilationMode.Rebuild(BuildAttribute.UNKNOWN_CHANGES_IN_GRADLE_INPUTS)
}
protected abstract fun calculateSourcesToCompile(
private fun calculateSourcesToCompile(
caches: CacheManager, changedFiles: ChangedFiles.Known, args: Args, messageCollector: MessageCollector
): CompilationMode =
reporter.measure(BuildTime.IC_CALCULATE_INITIAL_DIRTY_SET) {
calculateSourcesToCompileImpl(caches, changedFiles, args, messageCollector)
}
protected abstract fun calculateSourcesToCompileImpl(
caches: CacheManager,
changedFiles: ChangedFiles.Known,
args: Args,
@@ -161,9 +186,7 @@ abstract class IncrementalCompilerRunner<
protected sealed class CompilationMode {
class Incremental(val dirtyFiles: DirtyFilesContainer) : CompilationMode()
class Rebuild(getReason: () -> String = { "" }) : CompilationMode() {
val reason: String by lazy(getReason)
}
class Rebuild(val reason: BuildAttribute) : CompilationMode()
}
protected abstract fun updateCaches(
@@ -211,9 +234,17 @@ abstract class IncrementalCompilerRunner<
): ExitCode {
preBuildHook(args, compilationMode)
val buildTimeMode: BuildTime
val dirtySources = when (compilationMode) {
is CompilationMode.Incremental -> compilationMode.dirtyFiles.toMutableList()
is CompilationMode.Rebuild -> allKotlinSources.toMutableList()
is CompilationMode.Incremental -> {
buildTimeMode = BuildTime.INCREMENTAL_ITERATION
compilationMode.dirtyFiles.toMutableList()
}
is CompilationMode.Rebuild -> {
buildTimeMode = BuildTime.NON_INCREMENTAL_ITERATION
reporter.addAttribute(compilationMode.reason)
allKotlinSources.toMutableList()
}
}
val currentBuildInfo = BuildInfo(startTS = System.currentTimeMillis())
@@ -247,7 +278,9 @@ abstract class IncrementalCompilerRunner<
val bufferingMessageCollector = BufferingMessageCollector()
val messageCollectorAdapter = MessageCollectorToOutputItemsCollectorAdapter(bufferingMessageCollector, outputItemsCollector)
exitCode = runCompiler(sourcesToCompile.toSet(), args, caches, services, messageCollectorAdapter)
exitCode = reporter.measure(buildTimeMode) {
runCompiler(sourcesToCompile.toSet(), args, caches, services, messageCollectorAdapter)
}
val generatedFiles = outputItemsCollector.outputs.map(SimpleOutputItem::toGeneratedFile)
if (compilationMode is CompilationMode.Incremental) {
@@ -268,12 +301,13 @@ abstract class IncrementalCompilerRunner<
dirtySourcesSinceLastTimeFile.delete()
caches.platformCache.updateComplementaryFiles(dirtySources, expectActualTracker)
caches.inputsCache.registerOutputForSourceFiles(generatedFiles)
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
val changesCollector = ChangesCollector()
updateCaches(services, caches, generatedFiles, changesCollector)
reporter.measure(BuildTime.IC_UPDATE_CACHES) {
caches.platformCache.updateComplementaryFiles(dirtySources, expectActualTracker)
caches.inputsCache.registerOutputForSourceFiles(generatedFiles)
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
updateCaches(services, caches, generatedFiles, changesCollector)
}
if (compilationMode is CompilationMode.Rebuild) break
val (dirtyLookupSymbols, dirtyClassFqNames) = changesCollector.getDirtyData(listOf(caches.platformCache), reporter)
@@ -339,7 +373,7 @@ abstract class IncrementalCompilerRunner<
compilationMode: CompilationMode,
currentBuildInfo: BuildInfo,
dirtyData: DirtyData
) {
) = reporter.measure(BuildTime.IC_WRITE_HISTORY_FILE) {
val prevDiffs = BuildDiffsStorage.readFromFile(buildHistoryFile, reporter)?.buildDiffs ?: emptyList()
val newDiff = if (compilationMode is CompilationMode.Incremental) {
BuildDifference(currentBuildInfo.startTS, true, dirtyData)
@@ -17,6 +17,10 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.isIrBackendEnabled
@@ -45,9 +49,10 @@ fun makeJsIncrementally(
.filter { it.isFile && it.extension.equals("kt", ignoreCase = true) }.toList()
val buildHistoryFile = File(cachesDir, "build-history.bin")
val buildReporter = BuildReporter(icReporter = reporter, buildMetricsReporter = DoNothingBuildMetricsReporter)
withJsIC {
val compiler = IncrementalJsCompilerRunner(
cachesDir, reporter,
cachesDir, buildReporter,
buildHistoryFile = buildHistoryFile,
modulesApiHistory = EmptyModulesApiHistory,
scopeExpansion = scopeExpansion
@@ -69,7 +74,7 @@ inline fun <R> withJsIC(fn: () -> R): R {
class IncrementalJsCompilerRunner(
private val workingDir: File,
reporter: ICReporter,
reporter: BuildReporter,
buildHistoryFile: File,
private val modulesApiHistory: ModulesApiHistory,
private val scopeExpansion: CompileScopeExpansionMode = CompileScopeExpansionMode.NEVER
@@ -90,14 +95,14 @@ class IncrementalJsCompilerRunner(
override fun destinationDir(args: K2JSCompilerArguments): File =
File(args.outputFile).parentFile
override fun calculateSourcesToCompile(
override fun calculateSourcesToCompileImpl(
caches: IncrementalJsCachesManager,
changedFiles: ChangedFiles.Known,
args: K2JSCompilerArguments,
messageCollector: MessageCollector
): CompilationMode {
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile)
?: return CompilationMode.Rebuild { "No information on previous build" }
?: return CompilationMode.Rebuild(BuildAttribute.NO_BUILD_HISTORY)
val dirtyFiles = DirtyFilesContainer(caches, reporter, kotlinSourceFilesExtensions)
initDirtyFiles(dirtyFiles, changedFiles)
@@ -107,9 +112,9 @@ class IncrementalJsCompilerRunner(
@Suppress("UNUSED_VARIABLE") // for sealed when
val unused = when (classpathChanges) {
is ChangesEither.Unknown -> return CompilationMode.Rebuild {
// todo: we can recompile all files incrementally (not cleaning caches), so rebuild won't propagate
"Could not get classpath's changes${classpathChanges.reason?.let { ": $it" }}"
is ChangesEither.Unknown -> {
reporter.report { "Could not get classpath's changes: ${classpathChanges.reason}" }
return CompilationMode.Rebuild(classpathChanges.reason)
}
is ChangesEither.Known -> {
dirtyFiles.addByDirtySymbols(classpathChanges.lookupSymbols)
@@ -117,7 +122,6 @@ class IncrementalJsCompilerRunner(
}
}
val removedClassesChanges = getRemovedClassesChanges(caches, changedFiles)
dirtyFiles.addByDirtySymbols(removedClassesChanges.dirtyLookupSymbols)
dirtyFiles.addByDirtyClasses(removedClassesChanges.dirtyClassesFqNames)
@@ -25,6 +25,10 @@ import com.intellij.psi.PsiJavaFile
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.build.report.ICReporterBase
import org.jetbrains.kotlin.build.report.metrics.*
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
@@ -64,11 +68,12 @@ fun makeIncrementally(
val sourceFiles = files.filter { it.extension.toLowerCase() in allExtensions }.toList()
val buildHistoryFile = File(cachesDir, "build-history.bin")
args.javaSourceRoots = sourceRoots.map { it.absolutePath }.toTypedArray()
val buildReporter = BuildReporter(icReporter = reporter, buildMetricsReporter = DoNothingBuildMetricsReporter)
withIC {
val compiler = IncrementalJvmCompilerRunner(
cachesDir,
reporter,
buildReporter,
// Use precise setting in case of non-Gradle build
usePreciseJavaTracking = true,
outputFiles = emptyList(),
@@ -104,7 +109,7 @@ inline fun <R> withIC(enabled: Boolean = true, fn: () -> R): R {
class IncrementalJvmCompilerRunner(
workingDir: File,
reporter: ICReporter,
reporter: BuildReporter,
private val usePreciseJavaTracking: Boolean,
buildHistoryFile: File,
outputFiles: Collection<File>,
@@ -154,7 +159,7 @@ class IncrementalJvmCompilerRunner(
else
null
override fun calculateSourcesToCompile(
override fun calculateSourcesToCompileImpl(
caches: IncrementalJvmCachesManager,
changedFiles: ChangedFiles.Known,
args: K2JVMCompilerArguments,
@@ -176,16 +181,20 @@ class IncrementalJvmCompilerRunner(
val dirtyFiles = DirtyFilesContainer(caches, reporter, kotlinSourceFilesExtensions)
initDirtyFiles(dirtyFiles, changedFiles)
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" }
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild(BuildAttribute.NO_BUILD_HISTORY)
reporter.reportVerbose { "Last Kotlin Build info -- $lastBuildInfo" }
val classpathChanges = getClasspathChanges(args.classpathAsList, changedFiles, lastBuildInfo, modulesApiHistory, reporter)
val classpathChanges = reporter.measure(BuildTime.IC_ANALYZE_CHANGES_IN_DEPENDENCIES) {
getClasspathChanges(args.classpathAsList, changedFiles, lastBuildInfo, modulesApiHistory, reporter)
}
@Suppress("UNUSED_VARIABLE") // for sealed when
val unused = when (classpathChanges) {
is ChangesEither.Unknown -> return CompilationMode.Rebuild {
// todo: we can recompile all files incrementally (not cleaning caches), so rebuild won't propagate
"Could not get classpath's changes${classpathChanges.reason?.let { ": $it" }}"
is ChangesEither.Unknown -> {
reporter.report {
"Could not get classpath's changes: ${classpathChanges.reason}"
}
return CompilationMode.Rebuild(classpathChanges.reason)
}
is ChangesEither.Known -> {
dirtyFiles.addByDirtySymbols(classpathChanges.lookupSymbols)
@@ -194,21 +203,26 @@ class IncrementalJvmCompilerRunner(
}
}
if (!usePreciseJavaTracking) {
val javaFilesChanges = javaFilesProcessor!!.process(changedFiles)
val affectedJavaSymbols = when (javaFilesChanges) {
is ChangesEither.Known -> javaFilesChanges.lookupSymbols
is ChangesEither.Unknown -> return CompilationMode.Rebuild { "Could not get changes for java files" }
}
dirtyFiles.addByDirtySymbols(affectedJavaSymbols)
} else {
if (!processChangedJava(changedFiles, caches)) {
return CompilationMode.Rebuild { "Could not get changes for java files" }
reporter.measure(BuildTime.IC_ANALYZE_CHANGES_IN_JAVA_SOURCES) {
if (!usePreciseJavaTracking) {
val javaFilesChanges = javaFilesProcessor!!.process(changedFiles)
val affectedJavaSymbols = when (javaFilesChanges) {
is ChangesEither.Known -> javaFilesChanges.lookupSymbols
is ChangesEither.Unknown -> return CompilationMode.Rebuild(javaFilesChanges.reason)
}
dirtyFiles.addByDirtySymbols(affectedJavaSymbols)
} else {
val rebuildReason = processChangedJava(changedFiles, caches)
if (rebuildReason != null) return CompilationMode.Rebuild(rebuildReason)
}
}
val androidLayoutChanges = processLookupSymbolsForAndroidLayouts(changedFiles)
val removedClassesChanges = getRemovedClassesChanges(caches, changedFiles)
val androidLayoutChanges = reporter.measure(BuildTime.IC_ANALYZE_CHANGES_IN_ANDROID_LAYOUTS) {
processLookupSymbolsForAndroidLayouts(changedFiles)
}
val removedClassesChanges = reporter.measure(BuildTime.IC_DETECT_REMOVED_CLASSES) {
getRemovedClassesChanges(caches, changedFiles)
}
dirtyFiles.addByDirtySymbols(androidLayoutChanges)
dirtyFiles.addByDirtySymbols(removedClassesChanges.dirtyLookupSymbols)
@@ -217,7 +231,7 @@ class IncrementalJvmCompilerRunner(
return CompilationMode.Incremental(dirtyFiles)
}
private fun processChangedJava(changedFiles: ChangedFiles.Known, caches: IncrementalJvmCachesManager): Boolean {
private fun processChangedJava(changedFiles: ChangedFiles.Known, caches: IncrementalJvmCachesManager): BuildAttribute? {
val javaFiles = (changedFiles.modified + changedFiles.removed).filter(File::isJavaFile)
for (javaFile in javaFiles) {
@@ -225,20 +239,20 @@ class IncrementalJvmCompilerRunner(
if (!javaFile.exists()) {
// todo: can we do this more optimal?
reporter.report { "Could not get changed for untracked removed java file $javaFile" }
return false
return BuildAttribute.JAVA_CHANGE_UNTRACKED_FILE_IS_REMOVED
}
val psiFile = psiFileProvider.javaFile(javaFile)
if (psiFile !is PsiJavaFile) {
reporter.report { "[Precise Java tracking] Expected PsiJavaFile, got ${psiFile?.javaClass}" }
return false
return BuildAttribute.JAVA_CHANGE_UNEXPECTED_PSI
}
for (psiClass in psiFile.classes) {
val qualifiedName = psiClass.qualifiedName
if (qualifiedName == null) {
reporter.report { "[Precise Java tracking] Class with unknown qualified name in $javaFile" }
return false
return BuildAttribute.JAVA_CHANGE_UNKNOWN_QUALIFIER
}
processChangedUntrackedJavaClass(psiClass, ClassId.topLevel(FqName(qualifiedName)))
@@ -247,7 +261,7 @@ class IncrementalJvmCompilerRunner(
}
caches.platformCache.markDirty(javaFiles)
return true
return null
}
private fun processChangedUntrackedJavaClass(psiClass: PsiClass, classId: ClassId) {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.incremental
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.incremental.snapshots.FileSnapshotMap
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.incremental.storage.SourceToOutputFilesMap
@@ -5,6 +5,10 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.build.report.metrics.measure
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory
import org.jetbrains.kotlin.incremental.util.Either
import org.jetbrains.kotlin.name.FqName
@@ -15,7 +19,7 @@ internal fun getClasspathChanges(
changedFiles: ChangedFiles.Known,
lastBuildInfo: BuildInfo,
modulesApiHistory: ModulesApiHistory,
reporter: ICReporter?
reporter: BuildReporter
): ChangesEither {
val classpathSet = HashSet<File>()
for (file in classpath) {
@@ -29,7 +33,10 @@ internal fun getClasspathChanges(
val removedClasspath = changedFiles.removed.filterTo(HashSet()) { it in classpathSet }
// todo: removed classes could be processed normally
if (removedClasspath.isNotEmpty()) return ChangesEither.Unknown("Some files are removed from classpath $removedClasspath")
if (removedClasspath.isNotEmpty()) {
reporter.report { "Some files are removed from classpath: $removedClasspath" }
return ChangesEither.Unknown(BuildAttribute.DEP_CHANGE_REMOVED_ENTRY)
}
if (modifiedClasspath.isEmpty()) return ChangesEither.Known()
@@ -38,28 +45,47 @@ internal fun getClasspathChanges(
val symbols = HashSet<LookupSymbol>()
val fqNames = HashSet<FqName>()
val historyFilesEither = modulesApiHistory.historyFilesForChangedFiles(modifiedClasspath)
val historyFilesEither =
reporter.measure(BuildTime.IC_FIND_HISTORY_FILES) {
modulesApiHistory.historyFilesForChangedFiles(modifiedClasspath)
}
val historyFiles = when (historyFilesEither) {
is Either.Success<Set<File>> -> historyFilesEither.value
is Either.Error -> return ChangesEither.Unknown(historyFilesEither.reason)
}
for (historyFile in historyFiles) {
val allBuilds = BuildDiffsStorage.readDiffsFromFile(historyFile, reporter = reporter)
?: return ChangesEither.Unknown("Could not read diffs from $historyFile")
val (knownBuilds, newBuilds) = allBuilds.partition { it.ts <= lastBuildTS }
if (knownBuilds.isEmpty()) {
return ChangesEither.Unknown("No previously known builds for $historyFile")
}
for (buildDiff in newBuilds) {
if (!buildDiff.isIncremental) return ChangesEither.Unknown("Non-incremental build from dependency $historyFile")
val dirtyData = buildDiff.dirtyData
symbols.addAll(dirtyData.dirtyLookupSymbols)
fqNames.addAll(dirtyData.dirtyClassesFqNames)
is Either.Error -> {
reporter.report { "Could not find history files: ${historyFilesEither.reason}" }
return ChangesEither.Unknown(BuildAttribute.DEP_CHANGE_HISTORY_IS_NOT_FOUND)
}
}
return ChangesEither.Known(symbols, fqNames)
fun analyzeHistoryFiles(): ChangesEither {
for (historyFile in historyFiles) {
val allBuilds = BuildDiffsStorage.readDiffsFromFile(historyFile, reporter = reporter)
?: return run {
reporter.report { "Could not read diffs from $historyFile" }
ChangesEither.Unknown(BuildAttribute.DEP_CHANGE_HISTORY_CANNOT_BE_READ)
}
val (knownBuilds, newBuilds) = allBuilds.partition { it.ts <= lastBuildTS }
if (knownBuilds.isEmpty()) {
reporter.report { "No previously known builds for $historyFile" }
return ChangesEither.Unknown(BuildAttribute.DEP_CHANGE_HISTORY_NO_KNOWN_BUILDS)
}
for (buildDiff in newBuilds) {
if (!buildDiff.isIncremental) {
reporter.report { "Non-incremental build from dependency $historyFile" }
return ChangesEither.Unknown(BuildAttribute.DEP_CHANGE_NON_INCREMENTAL_BUILD_IN_DEP)
}
val dirtyData = buildDiff.dirtyData
symbols.addAll(dirtyData.dirtyLookupSymbols)
fqNames.addAll(dirtyData.dirtyClassesFqNames)
}
}
return ChangesEither.Known(symbols, fqNames)
}
return reporter.measure(BuildTime.IC_ANALYZE_HISTORY_FILES) {
analyzeHistoryFiles()
}
}
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.incremental.utils
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.incremental.ICReporterBase
import org.jetbrains.kotlin.build.report.ICReporterBase
import java.io.File
class TestICReporter : ICReporterBase() {