Import of middle HMPP target platforms is supported

This commit is contained in:
Andrey Uskov
2019-06-04 01:55:30 +03:00
parent c0594c2ee3
commit c0bf5a6566
28 changed files with 316 additions and 103 deletions
@@ -25,7 +25,6 @@ fun KotlinDependency.deepCopy(cache: MutableMap<Any, Any>): KotlinDependency {
interface KotlinModule : Serializable {
val name: String
val platform: KotlinPlatform
val dependencies: Set<KotlinDependency>
val isTestModule: Boolean
}
@@ -35,6 +34,11 @@ interface KotlinSourceSet : KotlinModule {
val sourceDirs: Set<File>
val resourceDirs: Set<File>
val dependsOnSourceSets: Set<String>
val actualPlatforms: KotlinPlatformContainer
@Deprecated("Returns single target platform", ReplaceWith("actualPlatforms.actualPlatforms"), DeprecationLevel.ERROR)
val platform: KotlinPlatform
get() = actualPlatforms.getSinglePlatform()
companion object {
const val COMMON_MAIN_SOURCE_SET_NAME = "commonMain"
@@ -73,6 +77,8 @@ interface KotlinCompilation : KotlinModule {
val arguments: KotlinCompilationArguments
val dependencyClasspath: List<String>
val disambiguationClassifier: String?
val platform: KotlinPlatform
companion object {
const val MAIN_COMPILATION_NAME = "main"
@@ -81,7 +87,7 @@ interface KotlinCompilation : KotlinModule {
}
enum class KotlinPlatform(val id: String) {
COMMON("common"),
COMMON("common"), // this platform is left only for compatibility with NMPP (should not be used in HMPP)
JVM("jvm"),
JS("js"),
NATIVE("native"),
@@ -92,6 +98,17 @@ enum class KotlinPlatform(val id: String) {
}
}
interface KotlinPlatformContainer: Serializable {
val platforms: Collection<KotlinPlatform>
fun supports(simplePlatform: KotlinPlatform): Boolean
fun addSimplePlatforms(platforms: Collection<KotlinPlatform>)
fun getSinglePlatform() = platforms.singleOrNull() ?: KotlinPlatform.COMMON
}
interface KotlinTargetJar : Serializable {
val archiveFile: File?
}
@@ -48,13 +48,18 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
val sourceSets = buildSourceSets(dependencyResolver, project) ?: return null
val sourceSetMap = sourceSets.map { it.name to it }.toMap()
val targets = buildTargets(sourceSetMap, dependencyResolver, project) ?: return null
computeSourceSetsDeferredInfo(sourceSets, targets)
computeSourceSetsDeferredInfo(sourceSetMap, targets, isHMPPEnabled(project))
val coroutinesState = getCoroutinesState(project)
reportUnresolvedDependencies(targets)
val kotlinNativeHome = KotlinNativeHomeEvaluator.getKotlinNativeHome(project) ?: NO_KOTLIN_NATIVE_HOME
return KotlinMPPGradleModelImpl(sourceSetMap, targets, ExtraFeaturesImpl(coroutinesState), kotlinNativeHome)
}
private fun isHMPPEnabled(project: Project): Boolean {
//TODO(auskov): replace with Project.isKotlinGranularMetadataEnabled after merging with gradle pranch
return (project.findProperty("kotlin.mpp.enableGranularSourceSetsMetadata") as? String)?.toBoolean() ?: false
}
private fun reportUnresolvedDependencies(targets: Collection<KotlinTarget>) {
targets
.asSequence()
@@ -73,13 +78,46 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
return getCoroutines(experimentalExt) as? String
}
private fun calculateDependsOnClosure(
sourceSet: KotlinSourceSetImpl?,
sourceSetsMap: Map<String, KotlinSourceSetImpl>,
cache: MutableMap<String, Set<String>>
): Set<String> {
return if (sourceSet == null) {
emptySet()
} else {
cache[sourceSet.name] ?: sourceSet.dependsOnSourceSets.flatMap { name ->
calculateDependsOnClosure(
sourceSetsMap[name],
sourceSetsMap,
cache
).union(setOf(name))
}.toSet().also { cache[sourceSet.name] = it }
}
}
private fun buildSourceSets(dependencyResolver: DependencyResolver, project: Project): Collection<KotlinSourceSetImpl>? {
val kotlinExt = project.extensions.findByName("kotlin") ?: return null
val getSourceSets = kotlinExt.javaClass.getMethodOrNull("getSourceSets") ?: return null
@Suppress("UNCHECKED_CAST")
val sourceSets =
(getSourceSets(kotlinExt) as? NamedDomainObjectContainer<Named>)?.asMap?.values ?: emptyList<Named>()
return sourceSets.mapNotNull { buildSourceSet(it, dependencyResolver, project) }
val allSourceSets = sourceSets.mapNotNull { buildSourceSet(it, dependencyResolver, project) }
val map = allSourceSets.map { it.name to it }.toMap()
val dependsOnCache = HashMap<String, Set<String>>()
return allSourceSets.map { sourceSet ->
KotlinSourceSetImpl(
sourceSet.name,
sourceSet.languageSettings,
sourceSet.sourceDirs,
sourceSet.resourceDirs,
sourceSet.dependencies,
calculateDependsOnClosure(sourceSet, map, dependsOnCache),
sourceSet.actualPlatforms as KotlinPlatformContainerImpl,
sourceSet.isTestModule
)
}
}
private fun buildSourceSet(
@@ -376,8 +414,9 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
}
private fun computeSourceSetsDeferredInfo(
sourceSets: Collection<KotlinSourceSetImpl>,
targets: Collection<KotlinTarget>
sourceSets: Map<String, KotlinSourceSetImpl>,
targets: Collection<KotlinTarget>,
isHMPPEnabled: Boolean
) {
val sourceSetToCompilations = LinkedHashMap<KotlinSourceSet, MutableSet<KotlinCompilation>>()
for (target in targets) {
@@ -387,22 +426,29 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
}
}
}
for (sourceSet in sourceSets) {
for (sourceSet in sourceSets.values) {
val name = sourceSet.name
if (name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) {
sourceSet.platform = KotlinPlatform.COMMON
sourceSet.isTestModule = false
continue
}
if (name == KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME) {
sourceSet.platform = KotlinPlatform.COMMON
sourceSet.isTestModule = true
continue
}
val compilations = sourceSetToCompilations[sourceSet]
if (compilations != null) {
sourceSet.platform = compilations.map { it.platform }.distinct().singleOrNull() ?: KotlinPlatform.COMMON
val platforms = compilations.map { it.platform }
sourceSet.actualPlatforms.addSimplePlatforms(platforms)
if (isHMPPEnabled) {
sourceSet.dependsOnSourceSets.mapNotNull { sourceSets[it] }.forEach {
it?.actualPlatforms?.addSimplePlatforms(platforms)
}
}
sourceSet.isTestModule = compilations.all { it.isTestModule }
} else {
// TODO: change me after design about it
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle
import java.io.File
import java.util.*
import kotlin.collections.HashSet
data class KotlinSourceSetImpl(
override val name: String,
@@ -15,7 +16,7 @@ data class KotlinSourceSetImpl(
override val resourceDirs: Set<File>,
override val dependencies: Set<KotlinDependency>,
override val dependsOnSourceSets: Set<String>,
val defaultPlatform: KotlinPlatform = KotlinPlatform.COMMON,
val defaultPlatform: KotlinPlatformContainerImpl = KotlinPlatformContainerImpl(),
val defaultIsTestModule: Boolean = false
) : KotlinSourceSet {
@@ -26,11 +27,11 @@ data class KotlinSourceSetImpl(
HashSet(kotlinSourceSet.resourceDirs),
kotlinSourceSet.dependencies.map { it.deepCopy(cloningCache) }.toSet(),
HashSet(kotlinSourceSet.dependsOnSourceSets),
kotlinSourceSet.platform,
KotlinPlatformContainerImpl(kotlinSourceSet.actualPlatforms),
kotlinSourceSet.isTestModule
)
override var platform: KotlinPlatform = defaultPlatform
override var actualPlatforms: KotlinPlatformContainer = defaultPlatform
internal set
override var isTestModule: Boolean = defaultIsTestModule
@@ -171,4 +172,23 @@ data class KotlinMPPGradleModelImpl(
ExtraFeaturesImpl(mppModel.extraFeatures.coroutinesState),
mppModel.kotlinNativeHome
)
}
}
class KotlinPlatformContainerImpl() : KotlinPlatformContainer {
private val defaultCommonPlatform = setOf(KotlinPlatform.COMMON)
private var myPlatforms: MutableSet<KotlinPlatform>? = null
constructor(platform: KotlinPlatformContainer) : this() {
myPlatforms = HashSet<KotlinPlatform>(platform.platforms)
}
override val platforms: Collection<KotlinPlatform>
get() = myPlatforms ?: defaultCommonPlatform
override fun supports(simplePlatform: KotlinPlatform): Boolean = platforms.contains(simplePlatform)
override fun addSimplePlatforms(platforms: Collection<KotlinPlatform>) {
(myPlatforms ?: HashSet<KotlinPlatform>().apply { myPlatforms = this }).addAll(platforms)
}
}