Minimize usage of TargetId in IC

This commit is contained in:
Alexey Tsvetkov
2017-06-30 04:54:43 +03:00
parent a076b4614e
commit d1fd88fb8e
6 changed files with 34 additions and 110 deletions
@@ -47,10 +47,9 @@ import java.util.*
val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin" val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalCacheImpl<Target>( open class IncrementalCacheImpl(
private val targetDataRoot: File, private val targetDataRoot: File,
targetOutputDir: File?, targetOutputDir: File?
target: Target
) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache { ) : IncrementalCacheCommon(File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)), IncrementalCache {
companion object { companion object {
private val PROTO_MAP = "proto" private val PROTO_MAP = "proto"
@@ -77,7 +76,7 @@ open class IncrementalCacheImpl<Target>(
// todo: try to use internal names only? // todo: try to use internal names only?
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile)) private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory: $target" } } private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory" } }
protected open fun debugLog(message: String) {} protected open fun debugLog(message: String) {}
@@ -115,7 +114,7 @@ open class IncrementalCacheImpl<Target>(
return CompilationResult.NO_CHANGES return CompilationResult.NO_CHANGES
} }
open fun saveFileToCache(generatedClass: GeneratedJvmClass<Target>): CompilationResult { open fun saveFileToCache(generatedClass: GeneratedJvmClass<*>): CompilationResult {
val sourceFiles: Collection<File> = generatedClass.sourceFiles val sourceFiles: Collection<File> = generatedClass.sourceFiles
val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass
val className = kotlinClass.className val className = kotlinClass.className
@@ -14,9 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
// these functions are used in the kotlin gradle plugin
@file:Suppress("unused")
package org.jetbrains.kotlin.incremental package org.jetbrains.kotlin.incremental
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
@@ -25,8 +22,6 @@ import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.build.JvmSourceRoot import org.jetbrains.kotlin.build.JvmSourceRoot
import org.jetbrains.kotlin.build.isModuleMappingFile import org.jetbrains.kotlin.build.isModuleMappingFile
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
@@ -35,14 +30,9 @@ import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.CompilationCanceledStatus import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.utils.keysToMap
import java.io.File import java.io.File
import java.util.* import java.util.*
fun Iterable<File>.javaSourceRoots(roots: Iterable<File>): Iterable<File> =
filter(File::isJavaFile).mapNotNull { findSrcDirRoot(it, roots) }
fun makeModuleFile( fun makeModuleFile(
name: String, name: String,
isTest: Boolean, isTest: Boolean,
@@ -86,61 +76,22 @@ fun makeCompileServices(
build() build()
} }
fun makeLookupTracker(parentLookupTracker: LookupTracker = LookupTracker.DO_NOTHING): LookupTracker = fun updateIncrementalCache(
if (IncrementalCompilation.isEnabled()) LookupTrackerImpl(parentLookupTracker) generatedFiles: List<GeneratedFile<*>>,
else parentLookupTracker cache: IncrementalCacheImpl,
compiledWithErrors: Boolean
fun<Target> makeIncrementalCachesMap(
targets: Iterable<Target>,
getDependencies: (Target) -> Iterable<Target>,
getCache: (Target) -> IncrementalCacheImpl<Target>,
getTargetId: Target.() -> TargetId
): Map<TargetId, IncrementalCacheImpl<Target>>
{
val dependents = targets.keysToMap { hashSetOf<Target>() }
val targetsWithDependents = targets.toHashSet()
for (target in targets) {
for (dependency in getDependencies(target)) {
if (dependency !in targets) continue
dependents[dependency]!!.add(target)
targetsWithDependents.add(target)
}
}
val caches = targetsWithDependents.keysToMap { getCache(it) }
for ((target, cache) in caches) {
dependents[target]?.forEach {
cache.addDependentCache(caches[it]!!)
}
}
return caches.mapKeys { it.key.getTargetId() }
}
fun<Target> updateIncrementalCaches(
targets: Iterable<Target>,
generatedFiles: List<GeneratedFile<Target>>,
compiledWithErrors: Boolean,
getIncrementalCache: (Target) -> IncrementalCacheImpl<Target>
): CompilationResult { ): CompilationResult {
var changesInfo = CompilationResult.NO_CHANGES var changesInfo = CompilationResult.NO_CHANGES
for (generatedFile in generatedFiles) { for (generatedFile in generatedFiles) {
val ic = getIncrementalCache(generatedFile.target)
when { when {
generatedFile is GeneratedJvmClass<Target> -> changesInfo += ic.saveFileToCache(generatedFile) generatedFile is GeneratedJvmClass<*> -> changesInfo += cache.saveFileToCache(generatedFile)
generatedFile.outputFile.isModuleMappingFile() -> changesInfo += ic.saveModuleMappingToCache(generatedFile.sourceFiles, generatedFile.outputFile) generatedFile.outputFile.isModuleMappingFile() -> changesInfo += cache.saveModuleMappingToCache(generatedFile.sourceFiles, generatedFile.outputFile)
} }
} }
if (!compiledWithErrors) { if (!compiledWithErrors) {
targets.forEach { val newChangesInfo = cache.clearCacheForRemovedClasses()
val newChangesInfo = getIncrementalCache(it).clearCacheForRemovedClasses() changesInfo += newChangesInfo
changesInfo += newChangesInfo
}
} }
return changesInfo return changesInfo
@@ -158,30 +109,6 @@ fun LookupStorage.update(
addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values) addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
} }
fun<Target> OutputItemsCollectorImpl.generatedFiles(
targets: Collection<Target>,
representativeTarget: Target,
getSources: (Target) -> Iterable<File>,
getOutputDir: (Target) -> File?
): List<GeneratedFile<Target>> {
// If there's only one target, this map is empty: get() always returns null, and the representativeTarget will be used below
val sourceToTarget =
if (targets.size >1) targets.flatMap { target -> getSources(target).map { Pair(it, target) } }.toMap()
else mapOf<File, Target>()
return outputs.map { outputItem ->
val target =
outputItem.sourceFiles.firstOrNull()?.let { sourceToTarget[it] } ?:
targets.singleOrNull { getOutputDir(it)?.let { outputItem.outputFile.startsWith(it) } ?: false } ?:
representativeTarget
when (outputItem.outputFile.extension) {
"class" -> GeneratedJvmClass(target, outputItem.sourceFiles, outputItem.outputFile)
else -> GeneratedFile(target, outputItem.sourceFiles, outputItem.outputFile)
}
}
}
data class DirtyData( data class DirtyData(
val dirtyLookupSymbols: Collection<LookupSymbol> = emptyList(), val dirtyLookupSymbols: Collection<LookupSymbol> = emptyList(),
val dirtyClassesFqNames: Collection<FqName> = emptyList() val dirtyClassesFqNames: Collection<FqName> = emptyList()
@@ -262,9 +189,6 @@ fun mapClassesFqNamesToFiles(
return dirtyFiles return dirtyFiles
} }
private fun findSrcDirRoot(file: File, roots: Iterable<File>): File? =
roots.firstOrNull { FileUtil.isAncestor(it, file, false) }
fun withSubtypes( fun withSubtypes(
typeFqName: FqName, typeFqName: FqName,
caches: Iterable<IncrementalCacheCommon> caches: Iterable<IncrementalCacheCommon>
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.incremental package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.modules.TargetId
import java.io.File import java.io.File
abstract class IncrementalCachesManager ( abstract class IncrementalCachesManager (
@@ -68,12 +67,11 @@ abstract class IncrementalCachesManager (
} }
class IncrementalJvmCachesManager( class IncrementalJvmCachesManager(
targetId: TargetId,
cacheDirectory: File, cacheDirectory: File,
outputDir: File, outputDir: File,
reporter: ICReporter reporter: ICReporter
) : IncrementalCachesManager(cacheDirectory, reporter) { ) : IncrementalCachesManager(cacheDirectory, reporter) {
private val jvmCacheFile = File(cacheDirectory, "jvm").apply { mkdirs() } private val jvmCacheFile = File(cacheDirectory, "jvm").apply { mkdirs() }
val jvmCache = IncrementalCacheImpl(jvmCacheFile, outputDir, targetId).apply { registerCache() } val jvmCache = IncrementalCacheImpl(jvmCacheFile, outputDir).apply { registerCache() }
} }
@@ -104,8 +104,7 @@ class IncrementalJvmCompilerRunner(
messageCollector: MessageCollector, messageCollector: MessageCollector,
getChangedFiles: (IncrementalCachesManager)->ChangedFiles getChangedFiles: (IncrementalCachesManager)->ChangedFiles
): ExitCode { ): ExitCode {
val targetId = TargetId(name = args.moduleName!!, type = "java-production") var caches = IncrementalJvmCachesManager(cacheDirectory, File(args.destination), reporter)
var caches = IncrementalJvmCachesManager(targetId, cacheDirectory, File(args.destination), reporter)
fun rebuild(): ExitCode { fun rebuild(): ExitCode {
caches.clean() caches.clean()
@@ -113,8 +112,8 @@ class IncrementalJvmCompilerRunner(
args.destinationAsFile.deleteRecursively() args.destinationAsFile.deleteRecursively()
val javaFilesProcessor = ChangedJavaFilesProcessor(reporter) val javaFilesProcessor = ChangedJavaFilesProcessor(reporter)
caches = IncrementalJvmCachesManager(targetId, cacheDirectory, args.destinationAsFile, reporter) caches = IncrementalJvmCachesManager(cacheDirectory, args.destinationAsFile, reporter)
return compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, targetId, CompilationMode.Rebuild, messageCollector) return compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, CompilationMode.Rebuild, messageCollector)
} }
return try { return try {
@@ -124,7 +123,7 @@ class IncrementalJvmCompilerRunner(
val exitCode = when (compilationMode) { val exitCode = when (compilationMode) {
is CompilationMode.Incremental -> { is CompilationMode.Incremental -> {
compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, targetId, compilationMode, messageCollector) compileIncrementally(args, caches, javaFilesProcessor, allKotlinSources, compilationMode, messageCollector)
} }
is CompilationMode.Rebuild -> { is CompilationMode.Rebuild -> {
rebuild() rebuild()
@@ -254,7 +253,6 @@ class IncrementalJvmCompilerRunner(
caches: IncrementalJvmCachesManager, caches: IncrementalJvmCachesManager,
javaFilesProcessor: ChangedJavaFilesProcessor, javaFilesProcessor: ChangedJavaFilesProcessor,
allKotlinSources: List<File>, allKotlinSources: List<File>,
targetId: TargetId,
compilationMode: CompilationMode, compilationMode: CompilationMode,
messageCollector: MessageCollector messageCollector: MessageCollector
): ExitCode { ): ExitCode {
@@ -296,7 +294,7 @@ class IncrementalJvmCompilerRunner(
val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath } val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath }
dirtySourcesSinceLastTimeFile.writeText(text) dirtySourcesSinceLastTimeFile.writeText(text)
val compilerOutput = compileChanged(listOf(targetId), sourcesToCompile.toSet(), args, caches.jvmCache, lookupTracker, messageCollector) val compilerOutput = compileChanged(sourcesToCompile.toSet(), args, caches.jvmCache, lookupTracker, messageCollector)
exitCode = compilerOutput.exitCode exitCode = compilerOutput.exitCode
val generatedFiles = compilerOutput.generatedFiles val generatedFiles = compilerOutput.generatedFiles
anyClassesCompiled = anyClassesCompiled || generatedFiles.isNotEmpty() || removedKotlinSources.isNotEmpty() anyClassesCompiled = anyClassesCompiled || generatedFiles.isNotEmpty() || removedKotlinSources.isNotEmpty()
@@ -320,9 +318,7 @@ class IncrementalJvmCompilerRunner(
allGeneratedFiles.addAll(generatedFiles) allGeneratedFiles.addAll(generatedFiles)
caches.inputsCache.registerOutputForSourceFiles(generatedFiles) caches.inputsCache.registerOutputForSourceFiles(generatedFiles)
val compilationResult = updateIncrementalCaches(listOf(targetId), generatedFiles, val compilationResult = updateIncrementalCache(generatedFiles, caches.jvmCache, compiledWithErrors = exitCode != ExitCode.OK)
compiledWithErrors = exitCode != ExitCode.OK,
getIncrementalCache = { caches.jvmCache })
caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources) caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources)
@@ -365,7 +361,7 @@ class IncrementalJvmCompilerRunner(
} }
private fun additionalDirtyFiles( private fun additionalDirtyFiles(
cache: IncrementalCacheImpl<TargetId>, cache: IncrementalCacheImpl,
generatedFiles: List<GeneratedFile<TargetId>> generatedFiles: List<GeneratedFile<TargetId>>
): Collection<File> { ): Collection<File> {
val result = HashSet<File>() val result = HashSet<File>()
@@ -403,10 +399,9 @@ class IncrementalJvmCompilerRunner(
} }
private fun compileChanged( private fun compileChanged(
targets: List<TargetId>,
sourcesToCompile: Set<File>, sourcesToCompile: Set<File>,
args: K2JVMCompilerArguments, args: K2JVMCompilerArguments,
cache: IncrementalCacheImpl<TargetId>, cache: IncrementalCacheImpl,
lookupTracker: LookupTracker, lookupTracker: LookupTracker,
messageCollector: MessageCollector messageCollector: MessageCollector
): CompileChangedResults { ): CompileChangedResults {
@@ -429,7 +424,8 @@ class IncrementalJvmCompilerRunner(
val messageCollector = MessageCollectorWrapper(messageCollector, outputItemCollector) val messageCollector = MessageCollectorWrapper(messageCollector, outputItemCollector)
try { try {
val incrementalCaches = makeIncrementalCachesMap(targets, { listOf<TargetId>() }, { cache }, { this }) val targetId = TargetId(args.moduleName, "java-production")
val incrementalCaches = mapOf(targetId to cache)
val compilationCanceledStatus = object : CompilationCanceledStatus { val compilationCanceledStatus = object : CompilationCanceledStatus {
override fun checkCanceled() { override fun checkCanceled() {
} }
@@ -439,7 +435,14 @@ class IncrementalJvmCompilerRunner(
reporter.report { "compiling with classpath: ${classpath.toList().sorted().joinToString()}" } reporter.report { "compiling with classpath: ${classpath.toList().sorted().joinToString()}" }
val compileServices = makeCompileServices(incrementalCaches, lookupTracker, compilationCanceledStatus) val compileServices = makeCompileServices(incrementalCaches, lookupTracker, compilationCanceledStatus)
val exitCode = compiler.exec(messageCollector, compileServices, args) val exitCode = compiler.exec(messageCollector, compileServices, args)
val generatedFiles = outputItemCollector.generatedFiles(targets, targets.first(), {sourcesToCompile}, {outputDir}) val generatedFiles = outputItemCollector.outputs.map {
val outputItem = it.outputFile
val sourceFiles = it.sourceFiles
when (outputItem.extension) {
"class" -> GeneratedJvmClass(targetId, sourceFiles, outputItem)
else -> GeneratedFile(targetId, sourceFiles, outputItem)
}
}
reporter.reportCompileIteration(sourcesToCompile, exitCode) reporter.reportCompileIteration(sourcesToCompile, exitCode)
return CompileChangedResults(exitCode, generatedFiles) return CompileChangedResults(exitCode, generatedFiles)
} }
@@ -424,7 +424,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
private fun doCompileModuleChunk( private fun doCompileModuleChunk(
allCompiledFiles: MutableSet<File>, chunk: ModuleChunk, commonArguments: CommonCompilerArguments, context: CompileContext, allCompiledFiles: MutableSet<File>, chunk: ModuleChunk, commonArguments: CommonCompilerArguments, context: CompileContext,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, environment: JpsCompilerEnvironment, dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>, incrementalCaches: Map<ModuleBuildTarget, IncrementalCacheImpl<*>>, filesToCompile: MultiMap<ModuleBuildTarget, File>, incrementalCaches: Map<ModuleBuildTarget, IncrementalCacheImpl>,
project: JpsProject project: JpsProject
): OutputItemsCollector? { ): OutputItemsCollector? {
@@ -827,7 +827,7 @@ private fun CompilationResult.processChangesUsingLookups(
compiledFiles: Set<File>, compiledFiles: Set<File>,
dataManager: BuildDataManager, dataManager: BuildDataManager,
fsOperations: FSOperationsHelper, fsOperations: FSOperationsHelper,
caches: Iterable<IncrementalCacheImpl<ModuleBuildTarget>> caches: Iterable<IncrementalCacheImpl>
) { ) {
val lookupStorage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider) val lookupStorage = dataManager.getStorage(KotlinDataContainerTarget, JpsLookupStorageProvider)
val allCaches = caches.flatMap { it.thisWithDependentCaches } val allCaches = caches.flatMap { it.thisWithDependentCaches }
@@ -28,7 +28,7 @@ import java.io.File
class JpsIncrementalCacheImpl( class JpsIncrementalCacheImpl(
target: ModuleBuildTarget, target: ModuleBuildTarget,
paths: BuildDataPaths paths: BuildDataPaths
) : IncrementalCacheImpl<ModuleBuildTarget>(paths.getTargetDataRoot(target), target.outputDir, target), StorageOwner { ) : IncrementalCacheImpl(paths.getTargetDataRoot(target), target.outputDir), StorageOwner {
override fun debugLog(message: String) { override fun debugLog(message: String) {
KotlinBuilder.LOG.debug(message) KotlinBuilder.LOG.debug(message)
} }