[CHERRY PICKED FROM IJ] [cleanup] Make KotlinChunk.{dependencies, dependents}.set private

GitOrigin-RevId: b244d3f69ba56ec4514feca524620e8b91b89d3e
Original commit: https://github.com/JetBrains/intellij-community/commit/397c46637ba7e5afdeaf480b98c766d9484a7128
This commit is contained in:
Nikita Bobko
2021-11-01 19:19:17 +01:00
parent 8583808231
commit 1009ee4333
2 changed files with 70 additions and 48 deletions
@@ -6,9 +6,11 @@
package org.jetbrains.kotlin.jps.build
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModuleDependency
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.VersionView
import org.jetbrains.kotlin.jps.incremental.CacheStatus
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
@@ -24,16 +26,73 @@ import kotlin.io.path.writeText
class KotlinChunk internal constructor(val context: KotlinCompileContext, val targets: List<KotlinModuleBuildTarget<*>>) {
val containsTests = targets.any { it.isTests }
lateinit var dependencies: List<KotlinModuleBuildTarget.Dependency>
// Should be initialized only in KotlinChunk.calculateChunkDependencies
internal set
private var areChunkDependenciesCalculated: Boolean = false
lateinit var dependent: List<KotlinModuleBuildTarget.Dependency>
// Should be initialized only in KotlinChunk.calculateChunkDependencies
internal set
/**
* Dependencies of all "modules" inside the chunk collected into single [List].
* (Any of those dependencies may target "modules" outside current chunk)
*
* It would be more correct to say [KotlinModuleBuildTarget] instead of "module"
* but word "module" makes it easier to understand this doc
*/
private val _dependencies: MutableList<KotlinModuleBuildTarget.Dependency> = mutableListOf()
val dependencies: List<KotlinModuleBuildTarget.Dependency>
get() = _dependencies.takeIf { areChunkDependenciesCalculated } ?: error("Chunk dependencies are not calculated yet")
// used only during dependency calculation
internal var _dependent: MutableSet<KotlinModuleBuildTarget.Dependency>? = mutableSetOf()
/**
* Dependents of all "modules" inside the chunk collected into single [List].
* (Any of those dependants may target "modules" outside current chunk)
*
* It would be more correct to say [KotlinModuleBuildTarget] instead of "module"
* but word "module" makes it easier to understand this doc
*/
private val _dependents: MutableList<KotlinModuleBuildTarget.Dependency> = mutableListOf()
val dependents: List<KotlinModuleBuildTarget.Dependency>
get() = _dependents.takeIf { areChunkDependenciesCalculated } ?: error("Chunk dependents are not calculated yet")
companion object {
fun calculateChunkDependencies(
chunks: List<KotlinChunk>,
byJpsModuleBuildTarget: MutableMap<ModuleBuildTarget, KotlinModuleBuildTarget<*>>
) {
chunks.forEach { chunk ->
check(!chunk.areChunkDependenciesCalculated) { "Chunk dependencies should be calculated only once" }
chunk.areChunkDependenciesCalculated = true
}
chunks.forEach { chunk ->
chunk._dependencies.addAll(
chunk.targets.asSequence()
.flatMap { calculateTargetDependencies(it, byJpsModuleBuildTarget) }
.distinct() // TODO does this "distinct" really needed?
.toList()
)
chunk._dependencies.forEach { dependency ->
dependency.target.chunk._dependents.add(dependency)
}
}
}
private fun calculateTargetDependencies(
srcTarget: KotlinModuleBuildTarget<*>,
byJpsModuleBuildTarget: MutableMap<ModuleBuildTarget, KotlinModuleBuildTarget<*>>
): List<KotlinModuleBuildTarget.Dependency> {
val compileClasspathKind = JpsJavaClasspathKind.compile(srcTarget.isTests)
val jpsJavaExtensionService = JpsJavaExtensionService.getInstance()
return srcTarget.module.dependenciesList.dependencies.asSequence()
.filterIsInstance<JpsModuleDependency>()
.mapNotNull { dep ->
val extension = jpsJavaExtensionService.getDependencyExtension(dep)
?.takeIf { it.scope.isIncludedIn(compileClasspathKind) }
?: return@mapNotNull null
dep.module
?.let { byJpsModuleBuildTarget[ModuleBuildTarget(it, srcTarget.isTests)] }
?.let { KotlinModuleBuildTarget.Dependency(srcTarget, it, extension.isExported) }
}
.toList()
}
}
val representativeTarget
get() = targets.first()
@@ -109,7 +168,7 @@ class KotlinChunk internal constructor(val context: KotlinCompileContext, val ta
}
fun collectDependentChunksRecursivelyExportedOnly(result: MutableSet<KotlinChunk> = mutableSetOf()) {
dependent.forEach {
dependents.forEach {
if (result.add(it.src.chunk)) {
if (it.exported) {
it.src.chunk.collectDependentChunksRecursivelyExportedOnly(result)
@@ -54,7 +54,7 @@ internal class KotlinTargetsIndexBuilder internal constructor(
}
}
calculateChunkDependencies()
KotlinChunk.calculateChunkDependencies(chunks, byJpsModuleBuildTarget)
}
KotlinBuilder.LOG.info("KotlinTargetsIndex created in $time ms")
@@ -66,43 +66,6 @@ internal class KotlinTargetsIndexBuilder internal constructor(
)
}
private fun calculateChunkDependencies() {
chunks.forEach { chunk ->
val dependencies = mutableSetOf<KotlinModuleBuildTarget.Dependency>()
chunk.targets.forEach {
dependencies.addAll(calculateTargetDependencies(it))
}
chunk.dependencies = dependencies.toList()
chunk.dependencies.forEach { dependency ->
dependency.target.chunk._dependent!!.add(dependency)
}
}
chunks.forEach {
it.dependent = it._dependent!!.toList()
it._dependent = null
}
}
private fun calculateTargetDependencies(srcTarget: KotlinModuleBuildTarget<*>): List<KotlinModuleBuildTarget.Dependency> {
val compileClasspathKind = JpsJavaClasspathKind.compile(srcTarget.isTests)
val jpsJavaExtensionService = JpsJavaExtensionService.getInstance()
return srcTarget.module.dependenciesList.dependencies.asSequence()
.filterIsInstance<JpsModuleDependency>()
.mapNotNull { dep ->
val extension = jpsJavaExtensionService.getDependencyExtension(dep)
?.takeIf { it.scope.isIncludedIn(compileClasspathKind) }
?: return@mapNotNull null
dep.module
?.let { byJpsModuleBuildTarget[ModuleBuildTarget(it, srcTarget.isTests)] }
?.let { KotlinModuleBuildTarget.Dependency(srcTarget, it, extension.isExported) }
}
.toList()
}
private fun ensureLoaded(target: ModuleBuildTarget): KotlinModuleBuildTarget<*> {
return byJpsModuleBuildTarget.computeIfAbsent(target) {
val platform = target.module.platform?.idePlatformKind ?: DefaultIdeTargetPlatformKindProvider.defaultPlatform.idePlatformKind