blob: c815adddb5a66d1a8622e0ecce00ab523a75326b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
@file:Suppress("UnstableApiUsage")
package org.jetbrains.kotlin.idea.gradle.configuration.utils
import com.google.common.graph.*
import com.intellij.openapi.util.IntellijInternalApi
import org.jetbrains.kotlin.idea.gradleTooling.KotlinMPPGradleModel
import org.jetbrains.kotlin.idea.projectModel.KotlinPlatform
import org.jetbrains.kotlin.idea.projectModel.KotlinSourceSet
@IntellijInternalApi
fun createSourceSetVisibilityGraph(model: KotlinMPPGradleModel): ImmutableGraph<KotlinSourceSet> {
val graph = createSourceSetDependsOnGraph(model)
graph.putInferredTestToProductionEdges()
return graph.immutable
}
internal fun createSourceSetDependsOnGraph(model: KotlinMPPGradleModel): MutableGraph<KotlinSourceSet> {
return createSourceSetDependsOnGraph(model.sourceSetsByName)
}
@IntellijInternalApi
fun createSourceSetDependsOnGraph(
sourceSetsByName: Map<String, KotlinSourceSet>
): MutableGraph<KotlinSourceSet> {
val graph = GraphBuilder.directed().build<KotlinSourceSet>()
val sourceSets = sourceSetsByName.values.toSet()
for (sourceSet in sourceSets) {
graph.addNode(sourceSet)
val dependsOnSourceSets = getFixedDependsOnSourceSets(sourceSetsByName, sourceSet)
for (dependsOnSourceSet in dependsOnSourceSets) {
graph.addNode(dependsOnSourceSet)
graph.putEdge(sourceSet, dependsOnSourceSet)
}
}
return graph
}
@IntellijInternalApi
fun MutableGraph<KotlinSourceSet>.putInferredTestToProductionEdges() {
val sourceSets = this.nodes()
for (sourceSet in sourceSets) {
if (sourceSet.isTestComponent) {
@OptIn(UnsafeTestSourceSetHeuristicApi::class)
val predictedMainSourceSetName = predictedProductionSourceSetName(sourceSet.name)
val predictedMainSourceSet = sourceSets.firstOrNull { it.name == predictedMainSourceSetName } ?: continue
putEdge(sourceSet, predictedMainSourceSet)
}
}
}
private fun getFixedDependsOnSourceSets(
sourceSetsByName: Map<String, KotlinSourceSet>, sourceSet: KotlinSourceSet
): Set<KotlinSourceSet> {
/*
Workaround for older Kotlin Gradle Plugin versions that did not explicitly declare a dependsOn relation
from a Kotlin source set to "commonMain"
(Can probably be dropped in Kotlin 1.5)
*/
val implicitDependsOnEdgeForAndroid = if (
sourceSet.actualPlatforms.contains(KotlinPlatform.ANDROID) && sourceSet.declaredDependsOnSourceSets.isEmpty()
) {
val commonSourceSetName = if (sourceSet.isTestComponent) KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME
else KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME
listOfNotNull(sourceSetsByName[commonSourceSetName])
} else emptyList()
return sourceSet.declaredDependsOnSourceSets.map(sourceSetsByName::getValue)
.plus(implicitDependsOnEdgeForAndroid)
/*
Gracefully filter out source sets that declare a dependency on themselves.
This also fixes KTIJ-1025
*/
.filter { dependencySourceSet -> dependencySourceSet != sourceSet }
.toSet()
}
/**
* @see Graphs.transitiveClosure
*/
@IntellijInternalApi
val <T> Graph<T>.transitiveClosure: Graph<T> get() = Graphs.transitiveClosure(this)
/**
* @see ImmutableGraph.copyOf
*/
@IntellijInternalApi
val <T> Graph<T>.immutable: ImmutableGraph<T> get() = ImmutableGraph.copyOf(this)
|