Get caches for targets transitively for exported dependencies
Original commit: a9fb5647b8
This commit is contained in:
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.jps.build
|
|||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import gnu.trove.THashSet
|
import gnu.trove.THashSet
|
||||||
import org.jetbrains.jps.ModuleChunk
|
import org.jetbrains.jps.ModuleChunk
|
||||||
@@ -35,6 +36,9 @@ import org.jetbrains.jps.incremental.storage.BuildDataManager
|
|||||||
import org.jetbrains.jps.model.JpsProject
|
import org.jetbrains.jps.model.JpsProject
|
||||||
import org.jetbrains.jps.model.JpsSimpleElement
|
import org.jetbrains.jps.model.JpsSimpleElement
|
||||||
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
|
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
|
||||||
|
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
|
||||||
|
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||||
|
import org.jetbrains.jps.model.module.JpsModule
|
||||||
import org.jetbrains.kotlin.cli.common.KotlinVersion
|
import org.jetbrains.kotlin.cli.common.KotlinVersion
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||||
@@ -255,9 +259,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
return OK
|
return OK
|
||||||
}
|
}
|
||||||
|
|
||||||
val caches = filesToCompile.keySet().map { incrementalCaches[it]!! }
|
processChanges(filesToCompile.values().toSet(), allCompiledFiles, dataManager, incrementalCaches.values, changesInfo, fsOperations)
|
||||||
processChanges(filesToCompile.values().toSet(), allCompiledFiles, dataManager, caches, changesInfo, fsOperations)
|
incrementalCaches.values.forEach { it.cleanDirtyInlineFunctions() }
|
||||||
caches.forEach { it.cleanDirtyInlineFunctions() }
|
|
||||||
|
|
||||||
return ADDITIONAL_PASS_REQUIRED
|
return ADDITIONAL_PASS_REQUIRED
|
||||||
}
|
}
|
||||||
@@ -773,6 +776,9 @@ private fun doProcessChangesUsingLookups(
|
|||||||
/**
|
/**
|
||||||
* Gets subtypes of given types inclusively
|
* Gets subtypes of given types inclusively
|
||||||
*/
|
*/
|
||||||
|
/* TODO: in case of chunk containing more than one target,
|
||||||
|
depending targets would be asked about same subtype more than once.
|
||||||
|
Can be solved by putting all caches in set */
|
||||||
private fun getSubtypesOf(
|
private fun getSubtypesOf(
|
||||||
typeFqNames: Iterable<FqName>,
|
typeFqNames: Iterable<FqName>,
|
||||||
caches: Collection<IncrementalCacheImpl>
|
caches: Collection<IncrementalCacheImpl>
|
||||||
@@ -811,40 +817,55 @@ private fun getLookupTracker(project: JpsProject): LookupTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): Map<ModuleBuildTarget, IncrementalCacheImpl> {
|
private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): Map<ModuleBuildTarget, IncrementalCacheImpl> {
|
||||||
|
val dependentTargets = getDependentTargets(chunk, context)
|
||||||
|
|
||||||
val dataManager = context.projectDescriptor.dataManager
|
val dataManager = context.projectDescriptor.dataManager
|
||||||
val targets = chunk.targets
|
val chunkCaches = chunk.targets.keysToMap { dataManager.getKotlinCache(it) }
|
||||||
|
val dependentCaches = dependentTargets.map { dataManager.getKotlinCache(it) }
|
||||||
|
|
||||||
val buildRegistry = BuildTargetRegistryImpl(context.projectDescriptor.model)
|
for (chunkCache in chunkCaches.values) {
|
||||||
val outputIndex = TargetOutputIndexImpl(targets, context)
|
for (dependentCache in dependentCaches) {
|
||||||
|
chunkCache.addDependentCache(dependentCache)
|
||||||
val allTargets = buildRegistry.allTargets.moduleTargets
|
|
||||||
val allDependencies = allTargets.keysToMap { target ->
|
|
||||||
target.computeDependencies(buildRegistry, outputIndex).moduleTargets
|
|
||||||
}
|
|
||||||
|
|
||||||
val dependents = targets.keysToMap { hashSetOf<ModuleBuildTarget>() }
|
|
||||||
val targetsWithDependents = HashSet<ModuleBuildTarget>(targets)
|
|
||||||
|
|
||||||
for ((target, dependencies) in allDependencies) {
|
|
||||||
for (dependency in dependencies) {
|
|
||||||
if (dependency !in targets) continue
|
|
||||||
|
|
||||||
dependents[dependency]!!.add(target)
|
|
||||||
targetsWithDependents.add(target)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val caches = targetsWithDependents.keysToMap { dataManager.getKotlinCache(it) }
|
return chunkCaches
|
||||||
|
|
||||||
for ((target, cache) in caches) {
|
|
||||||
dependents[target]?.forEach {
|
|
||||||
cache.addDependentCache(caches[it]!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return caches
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getDependentTargets(
|
||||||
|
compilingChunk: ModuleChunk,
|
||||||
|
context: CompileContext
|
||||||
|
): Set<ModuleBuildTarget> {
|
||||||
|
val classpathKind = JpsJavaClasspathKind.compile(compilingChunk.targets.any { it.isTests })
|
||||||
|
|
||||||
|
fun dependsOnCompilingChunk(target: BuildTarget<*>): Boolean {
|
||||||
|
if (target !is ModuleBuildTarget) return false
|
||||||
|
|
||||||
|
val dependencies = getDependenciesRecursively(target.module, classpathKind)
|
||||||
|
return ContainerUtil.intersects(dependencies, compilingChunk.modules)
|
||||||
|
}
|
||||||
|
|
||||||
|
val dependentTargets = HashSet<ModuleBuildTarget>()
|
||||||
|
val sortedChunks = context.projectDescriptor.buildTargetIndex.getSortedTargetChunks(context).iterator()
|
||||||
|
|
||||||
|
// skip chunks that are compiled before compilingChunk
|
||||||
|
while (sortedChunks.hasNext()) {
|
||||||
|
if (sortedChunks.next().targets == compilingChunk.targets) break
|
||||||
|
}
|
||||||
|
|
||||||
|
// process chunks that compiled after compilingChunk
|
||||||
|
for (followingChunk in sortedChunks) {
|
||||||
|
if (followingChunk.targets.none(::dependsOnCompilingChunk)) continue
|
||||||
|
|
||||||
|
dependentTargets.addAll(followingChunk.targets.filterIsInstance<ModuleBuildTarget>())
|
||||||
|
}
|
||||||
|
|
||||||
|
return dependentTargets
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDependenciesRecursively(module: JpsModule, kind: JpsJavaClasspathKind): Set<JpsModule> =
|
||||||
|
JpsJavaExtensionService.dependencies(module).includedIn(kind).recursivelyExportedOnly().modules
|
||||||
|
|
||||||
// TODO: investigate thread safety
|
// TODO: investigate thread safety
|
||||||
private val ALL_COMPILED_FILES_KEY = Key.create<MutableSet<File>>("_all_kotlin_compiled_files_")
|
private val ALL_COMPILED_FILES_KEY = Key.create<MutableSet<File>>("_all_kotlin_compiled_files_")
|
||||||
private fun getAllCompiledFilesContainer(context: CompileContext): MutableSet<File> {
|
private fun getAllCompiledFilesContainer(context: CompileContext): MutableSet<File> {
|
||||||
|
|||||||
Reference in New Issue
Block a user