From 5ddc8d83bb9fb1962a6958676230ef3cff80e8fe Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Mon, 3 Jul 2017 18:21:13 +0300 Subject: [PATCH] Move compileIncrementally to common IC --- .../IncrementalJvmCompilerRunner.kt | 227 +++++++++--------- 1 file changed, 108 insertions(+), 119 deletions(-) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index 85ed2840350..1156b457f5f 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -24,10 +24,7 @@ import org.jetbrains.kotlin.build.JvmSourceRoot import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.compilerRunner.* import org.jetbrains.kotlin.config.IncrementalCompilation @@ -177,6 +174,13 @@ abstract class IncrementalCompilerRunner< return dirtyFiles } + protected sealed class CompilationMode { + class Incremental(val dirtyFiles: Set) : CompilationMode() + class Rebuild(getReason: ()->String = { "" }) : CompilationMode() { + val reason: String by lazy(getReason) + } + } + protected open fun markOutputDirty(caches: CacheManager, dirtySources: List) { } @@ -189,14 +193,6 @@ abstract class IncrementalCompilerRunner< protected open fun additionalDirtyLookupSymbols(): Iterable = emptyList() - protected abstract fun compileIncrementally( - args: Args, - caches: CacheManager, - allKotlinSources: List, - compilationMode: CompilationMode, - messageCollector: MessageCollector - ): ExitCode - protected abstract fun runCompiler( sourcesToCompile: Set, args: Args, @@ -205,11 +201,108 @@ abstract class IncrementalCompilerRunner< messageCollector: MessageCollector ): ExitCode - protected sealed class CompilationMode { - class Incremental(val dirtyFiles: Set) : CompilationMode() - class Rebuild(getReason: ()->String = { "" }) : CompilationMode() { - val reason: String by lazy(getReason) + private fun compileIncrementally( + args: Args, + caches: CacheManager, + allKotlinSources: List, + compilationMode: CompilationMode, + messageCollector: MessageCollector + ): ExitCode { + preBuildHook(args, compilationMode) + + val dirtySources = when (compilationMode) { + is CompilationMode.Incremental -> ArrayList(compilationMode.dirtyFiles) + is CompilationMode.Rebuild -> allKotlinSources.toMutableList() } + + val currentBuildInfo = BuildInfo(startTS = System.currentTimeMillis()) + BuildInfo.write(currentBuildInfo, lastBuildInfoFile) + val buildDirtyLookupSymbols = HashSet() + val buildDirtyFqNames = HashSet() + val allSourcesToCompile = HashSet() + + var exitCode = ExitCode.OK + val allGeneratedFiles = hashSetOf() + + while (dirtySources.any()) { + markOutputDirty(caches, dirtySources) + caches.inputsCache.removeOutputForSourceFiles(dirtySources) + + val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) + val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists) + + // todo: more optimal to save only last iteration, but it will require adding standalone-ic specific logs + // (because jps rebuilds all files from last build if it failed and gradle rebuilds everything) + allSourcesToCompile.addAll(sourcesToCompile) + val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath } + dirtySourcesSinceLastTimeFile.writeText(text) + + val services = Services.Builder().apply { + register(LookupTracker::class.java, lookupTracker) + register(CompilationCanceledStatus::class.java, EmptyCompilationCanceledStatus) + } + + args.reportOutputFiles = true + val outputItemsCollector = OutputItemsCollectorImpl() + val messageCollectorAdapter = MessageCollectorToOutputItemsCollectorAdapter(messageCollector, outputItemsCollector) + + exitCode = runCompiler(sourcesToCompile.toSet(), args, caches, services, messageCollectorAdapter) + postCompilationHook(exitCode) + + if (exitCode != ExitCode.OK) break + + dirtySourcesSinceLastTimeFile.delete() + val generatedFiles = outputItemsCollector.outputs.map(SimpleOutputItem::toGeneratedFile) + + if (compilationMode is CompilationMode.Incremental) { + // todo: feels dirty, can this be refactored? + val dirtySourcesSet = dirtySources.toHashSet() + val additionalDirtyFiles = additionalDirtyFiles(caches, generatedFiles).filter { it !in dirtySourcesSet } + if (additionalDirtyFiles.isNotEmpty()) { + dirtySources.addAll(additionalDirtyFiles) + continue + } + } + + allGeneratedFiles.addAll(generatedFiles) + caches.inputsCache.registerOutputForSourceFiles(generatedFiles) + caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources) + val compilationResult = compareAndUpdateCache(caches, generatedFiles) + + if (compilationMode is CompilationMode.Rebuild) break + + val (dirtyLookupSymbols, dirtyClassFqNames) = compilationResult.getDirtyData(listOf(caches.platformCache), reporter) + val compiledInThisIterationSet = sourcesToCompile.toHashSet() + + with (dirtySources) { + clear() + addAll(mapLookupSymbolsToFiles(caches.lookupCache, dirtyLookupSymbols, reporter, excludes = compiledInThisIterationSet)) + addAll(mapClassesFqNamesToFiles(listOf(caches.platformCache), dirtyClassFqNames, reporter, excludes = compiledInThisIterationSet)) + } + + buildDirtyLookupSymbols.addAll(dirtyLookupSymbols) + buildDirtyFqNames.addAll(dirtyClassFqNames) + } + + if (exitCode == ExitCode.OK && compilationMode is CompilationMode.Incremental) { + buildDirtyLookupSymbols.addAll(additionalDirtyLookupSymbols()) + } + if (changesRegistry != null) { + if (compilationMode is CompilationMode.Incremental) { + val dirtyData = DirtyData(buildDirtyLookupSymbols, buildDirtyFqNames) + changesRegistry.registerChanges(currentBuildInfo.startTS, dirtyData) + } + else { + assert(compilationMode is CompilationMode.Rebuild) { "Unexpected compilation mode: ${compilationMode::class.java}" } + changesRegistry.unknownChanges(currentBuildInfo.startTS) + } + } + + if (exitCode == ExitCode.OK) { + cacheVersions.forEach { it.saveIfNeeded() } + } + + return exitCode } companion object { @@ -351,110 +444,6 @@ class IncrementalJvmCompilerRunner( override fun compareAndUpdateCache(caches: IncrementalJvmCachesManager, generatedFiles: List): CompilationResult = updateIncrementalCache(generatedFiles, caches.platformCache) - override fun compileIncrementally( - args: K2JVMCompilerArguments, - caches: IncrementalJvmCachesManager, - allKotlinSources: List, - compilationMode: CompilationMode, - messageCollector: MessageCollector - ): ExitCode { - preBuildHook(args, compilationMode) - - val dirtySources = when (compilationMode) { - is CompilationMode.Incremental -> ArrayList(compilationMode.dirtyFiles) - is CompilationMode.Rebuild -> allKotlinSources.toMutableList() - } - - val currentBuildInfo = BuildInfo(startTS = System.currentTimeMillis()) - BuildInfo.write(currentBuildInfo, lastBuildInfoFile) - val buildDirtyLookupSymbols = HashSet() - val buildDirtyFqNames = HashSet() - val allSourcesToCompile = HashSet() - - var exitCode = ExitCode.OK - val allGeneratedFiles = hashSetOf() - - while (dirtySources.any()) { - markOutputDirty(caches, dirtySources) - caches.inputsCache.removeOutputForSourceFiles(dirtySources) - - val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) - val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists) - - // todo: more optimal to save only last iteration, but it will require adding standalone-ic specific logs - // (because jps rebuilds all files from last build if it failed and gradle rebuilds everything) - allSourcesToCompile.addAll(sourcesToCompile) - val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath } - dirtySourcesSinceLastTimeFile.writeText(text) - - val services = Services.Builder().apply { - register(LookupTracker::class.java, lookupTracker) - register(CompilationCanceledStatus::class.java, EmptyCompilationCanceledStatus) - } - - args.reportOutputFiles = true - val outputItemsCollector = OutputItemsCollectorImpl() - val messageCollectorAdapter = MessageCollectorToOutputItemsCollectorAdapter(messageCollector, outputItemsCollector) - - exitCode = runCompiler(sourcesToCompile.toSet(), args, caches, services, messageCollectorAdapter) - postCompilationHook(exitCode) - - if (exitCode != ExitCode.OK) break - - dirtySourcesSinceLastTimeFile.delete() - val generatedFiles = outputItemsCollector.outputs.map(SimpleOutputItem::toGeneratedFile) - - if (compilationMode is CompilationMode.Incremental) { - // todo: feels dirty, can this be refactored? - val dirtySourcesSet = dirtySources.toHashSet() - val additionalDirtyFiles = additionalDirtyFiles(caches, generatedFiles).filter { it !in dirtySourcesSet } - if (additionalDirtyFiles.isNotEmpty()) { - dirtySources.addAll(additionalDirtyFiles) - continue - } - } - - allGeneratedFiles.addAll(generatedFiles) - caches.inputsCache.registerOutputForSourceFiles(generatedFiles) - caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources) - val compilationResult = compareAndUpdateCache(caches, generatedFiles) - - if (compilationMode is CompilationMode.Rebuild) break - - val (dirtyLookupSymbols, dirtyClassFqNames) = compilationResult.getDirtyData(listOf(caches.platformCache), reporter) - val compiledInThisIterationSet = sourcesToCompile.toHashSet() - - with (dirtySources) { - clear() - addAll(mapLookupSymbolsToFiles(caches.lookupCache, dirtyLookupSymbols, reporter, excludes = compiledInThisIterationSet)) - addAll(mapClassesFqNamesToFiles(listOf(caches.platformCache), dirtyClassFqNames, reporter, excludes = compiledInThisIterationSet)) - } - - buildDirtyLookupSymbols.addAll(dirtyLookupSymbols) - buildDirtyFqNames.addAll(dirtyClassFqNames) - } - - if (exitCode == ExitCode.OK && compilationMode is CompilationMode.Incremental) { - buildDirtyLookupSymbols.addAll(additionalDirtyLookupSymbols()) - } - if (changesRegistry != null) { - if (compilationMode is CompilationMode.Incremental) { - val dirtyData = DirtyData(buildDirtyLookupSymbols, buildDirtyFqNames) - changesRegistry.registerChanges(currentBuildInfo.startTS, dirtyData) - } - else { - assert(compilationMode is CompilationMode.Rebuild) { "Unexpected compilation mode: ${compilationMode::class.java}" } - changesRegistry.unknownChanges(currentBuildInfo.startTS) - } - } - - if (exitCode == ExitCode.OK) { - cacheVersions.forEach { it.saveIfNeeded() } - } - - return exitCode - } - override fun additionalDirtyFiles( caches: IncrementalJvmCachesManager, generatedFiles: List