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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
// 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.
package org.jetbrains.kotlin.idea.gradleTooling
import org.gradle.api.Project
import org.jetbrains.kotlin.idea.projectModel.*
internal interface MultiplatformModelImportingContext: KotlinSourceSetContainer {
val project: Project
val compilerArgumentsCacheMapper: CompilerArgumentsCacheMapper
val targets: Collection<KotlinTarget>
val compilations: Collection<KotlinCompilation>
/**
* All source sets in a project, including those that are created but not included into any compilations
* (so-called "orphan" source sets). Use [isOrphanSourceSet] to get only compiled source sets
*/
val sourceSets: Collection<KotlinSourceSetImpl> get() = sourceSetsByName.values
override val sourceSetsByName: Map<String, KotlinSourceSetImpl>
/**
* Platforms, which are actually used in this project (i.e. platforms, for which targets has been created)
*/
val projectPlatforms: Collection<KotlinPlatform>
fun sourceSetByName(name: String): KotlinSourceSet?
fun compilationsBySourceSet(sourceSet: KotlinSourceSet): Collection<KotlinCompilation>?
/**
* "Orphan" is a source set which is not actually compiled by the compiler, i.e. the one
* which doesn't belong to any [KotlinCompilation].
*
* Orphan source sets might appear if one creates a source-set manually and doesn't link
* it anywhere (essentially this is a misconfiguration)
*/
fun isOrphanSourceSet(sourceSet: KotlinSourceSet): Boolean = compilationsBySourceSet(sourceSet) == null
/**
* "Declared" source-set is a source-set which is included into compilation directly, rather
* through closure over dependsOn-relation.
*
* See also KDoc for [KotlinCompilation.declaredSourceSets]
*/
fun isDeclaredSourceSet(sourceSet: KotlinSourceSet): Boolean
}
internal fun MultiplatformModelImportingContext.getProperty(property: GradleImportProperties): Boolean = project.getProperty(property)
internal fun Project.getProperty(property: GradleImportProperties): Boolean {
val explicitValueIfAny = try {
(findProperty(property.id) as? String)?.toBoolean()
} catch (e: Exception) {
logger.error("Error while trying to read property $property from project $project", e)
null
}
return explicitValueIfAny ?: property.defaultValue
}
internal enum class GradleImportProperties(val id: String, val defaultValue: Boolean) {
IS_HMPP_ENABLED("kotlin.mpp.enableGranularSourceSetsMetadata", false),
COERCE_ROOT_SOURCE_SETS_TO_COMMON("kotlin.mpp.coerceRootSourceSetsToCommon", true),
ENABLE_NATIVE_DEPENDENCY_PROPAGATION("kotlin.native.enableDependencyPropagation", true),
BUILD_METADATA_DEPENDENCIES("build_metadata_dependencies_for_actualised_source_sets", true),
IMPORT_ORPHAN_SOURCE_SETS("import_orphan_source_sets", true),
INCLUDE_ANDROID_DEPENDENCIES("kotlin.include.android.dependencies", false)
;
}
internal class MultiplatformModelImportingContextImpl(
override val project: Project,
override val compilerArgumentsCacheMapper: CompilerArgumentsCacheMapper
) : MultiplatformModelImportingContext {
/** see [initializeSourceSets] */
override lateinit var sourceSetsByName: Map<String, KotlinSourceSetImpl>
private set
/** see [initializeCompilations] */
override lateinit var compilations: Collection<KotlinCompilation>
private set
private lateinit var sourceSetToParticipatedCompilations: Map<KotlinSourceSet, Set<KotlinCompilation>>
private lateinit var allDeclaredSourceSets: Set<KotlinSourceSet>
/** see [initializeTargets] */
override lateinit var targets: Collection<KotlinTarget>
private set
override lateinit var projectPlatforms: Collection<KotlinPlatform>
private set
internal fun initializeSourceSets(sourceSetsByNames: Map<String, KotlinSourceSetImpl>) {
require(!this::sourceSetsByName.isInitialized) {
"Attempt to re-initialize source sets for $this. Previous value: ${this.sourceSetsByName}"
}
this.sourceSetsByName = sourceSetsByNames
}
@OptIn(ExperimentalGradleToolingApi::class)
internal fun initializeCompilations(compilations: Collection<KotlinCompilation>) {
require(!this::compilations.isInitialized) { "Attempt to re-initialize compilations for $this. Previous value: ${this.compilations}" }
this.compilations = compilations
val sourceSetToCompilations = LinkedHashMap<KotlinSourceSet, MutableSet<KotlinCompilation>>()
for (target in targets) {
for (compilation in target.compilations) {
for (sourceSet in compilation.allSourceSets) {
sourceSetToCompilations.getOrPut(sourceSet) { LinkedHashSet() } += compilation
resolveAllDependsOnSourceSets(sourceSet).forEach {
sourceSetToCompilations.getOrPut(it) { LinkedHashSet() } += compilation
}
}
}
}
this.sourceSetToParticipatedCompilations = sourceSetToCompilations
this.allDeclaredSourceSets = compilations.flatMapTo(mutableSetOf()) { it.declaredSourceSets }
}
internal fun initializeTargets(targets: Collection<KotlinTarget>) {
require(!this::targets.isInitialized) { "Attempt to re-initialize targets for $this. Previous value: ${this.targets}" }
this.targets = targets
this.projectPlatforms = targets.map { it.platform }
}
// overload for small optimization
override fun isOrphanSourceSet(sourceSet: KotlinSourceSet): Boolean = sourceSet !in sourceSetToParticipatedCompilations.keys
override fun isDeclaredSourceSet(sourceSet: KotlinSourceSet): Boolean = sourceSet in allDeclaredSourceSets
override fun compilationsBySourceSet(sourceSet: KotlinSourceSet): Collection<KotlinCompilation>? =
sourceSetToParticipatedCompilations[sourceSet]
override fun sourceSetByName(name: String): KotlinSourceSet? = sourceSetsByName[name]
}
|