[Gradle] Remove ResolvedMppVariantsProvider and all related code in KPM
Mark places where ResolvedMppVariantsProvide were used with TODOs ^KT-49933
This commit is contained in:
committed by
Space Team
parent
25dbfb10b8
commit
674e7aa480
+3
-3
@@ -269,6 +269,7 @@ class KpmCachingModuleVariantResolver(private val actualResolver: KpmModuleVaria
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNREACHABLE_CODE", "UNUSED_VARIABLE")
|
||||
class KpmGradleModuleVariantResolver : KpmModuleVariantResolver {
|
||||
override fun getChosenVariant(requestingVariant: KpmVariant, dependencyModule: KpmModule): KpmVariantResolution {
|
||||
// TODO maybe improve this behavior? Currently it contradicts dependency resolution in that it may return a chosen variant for an
|
||||
@@ -288,7 +289,6 @@ class KpmGradleModuleVariantResolver : KpmModuleVariantResolver {
|
||||
|
||||
val module = requestingVariant.containingModule
|
||||
val project = module.project
|
||||
val resolvedVariantProvider = ResolvedMppVariantsProvider.get(project)
|
||||
|
||||
// This implementation can only resolve variants for the current project's KotlinModule
|
||||
require(module.representsProject(project))
|
||||
@@ -296,8 +296,8 @@ class KpmGradleModuleVariantResolver : KpmModuleVariantResolver {
|
||||
val compileClasspath = getCompileDependenciesConfigurationForVariant(project, requestingVariant)
|
||||
|
||||
val dependencyModuleId = dependencyModule.moduleIdentifier
|
||||
// FIXME check composite builds, it's likely that resolvedVariantProvider fails on them?
|
||||
val resolvedGradleVariantName = resolvedVariantProvider.getResolvedVariantName(dependencyModuleId, compileClasspath)
|
||||
/** @see SourceSetVisibilityProvider.PlatformCompilationData */
|
||||
val resolvedGradleVariantName: String = TODO("Implement Resolved Gradle Variant finder as it done in TCS")
|
||||
val kotlinVariantName = when (dependencyModule) {
|
||||
is GradleKpmModule -> {
|
||||
dependencyModule.variants.singleOrNull { resolvedGradleVariantName in it.gradleVariantNames }?.name
|
||||
|
||||
-76
@@ -57,79 +57,3 @@ internal class MppDependencyProjectStructureMetadataExtractorFactory(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun MppDependencyProjectStructureMetadataExtractor.Factory.create(
|
||||
project: Project,
|
||||
resolvedComponentResult: ResolvedComponentResult,
|
||||
configuration: Configuration,
|
||||
resolveViaAvailableAt: Boolean
|
||||
): MppDependencyProjectStructureMetadataExtractor? {
|
||||
return create(
|
||||
resolvedMppVariantsProvider = ResolvedMppVariantsProvider.get(project),
|
||||
/*
|
||||
FIXME this loses information about auxiliary module deps
|
||||
TODO check how this code works with multi-capability resolutions,
|
||||
*/
|
||||
moduleIdentifier = resolvedComponentResult.toSingleKpmModuleIdentifier(),
|
||||
configuration = configuration,
|
||||
resolveViaAvailableAt = resolveViaAvailableAt,
|
||||
resolvedComponentResult = resolvedComponentResult,
|
||||
project = project
|
||||
)
|
||||
}
|
||||
|
||||
internal fun MppDependencyProjectStructureMetadataExtractor.Factory.create(
|
||||
project: Project,
|
||||
resolvedComponentResult: ResolvedComponentResult,
|
||||
moduleIdentifier: KpmModuleIdentifier,
|
||||
configuration: Configuration
|
||||
): MppDependencyProjectStructureMetadataExtractor? {
|
||||
return create(
|
||||
resolvedMppVariantsProvider = ResolvedMppVariantsProvider.get(project),
|
||||
moduleIdentifier = moduleIdentifier,
|
||||
configuration = configuration,
|
||||
resolveViaAvailableAt = true,
|
||||
resolvedComponentResult = resolvedComponentResult,
|
||||
project = project
|
||||
)
|
||||
}
|
||||
|
||||
private fun MppDependencyProjectStructureMetadataExtractor.Factory.create(
|
||||
resolvedMppVariantsProvider: ResolvedMppVariantsProvider,
|
||||
moduleIdentifier: KpmModuleIdentifier,
|
||||
configuration: Configuration,
|
||||
resolveViaAvailableAt: Boolean,
|
||||
resolvedComponentResult: ResolvedComponentResult,
|
||||
project: Project
|
||||
): MppDependencyProjectStructureMetadataExtractor? {
|
||||
var resolvedViaAvailableAt = false
|
||||
|
||||
val metadataArtifact = resolvedMppVariantsProvider.getResolvedArtifactByPlatformModule(
|
||||
moduleIdentifier,
|
||||
configuration
|
||||
) ?: if (resolveViaAvailableAt) {
|
||||
resolvedMppVariantsProvider.getHostSpecificMetadataArtifactByRootModule(
|
||||
moduleIdentifier, configuration
|
||||
)?.also {
|
||||
resolvedViaAvailableAt = true
|
||||
}
|
||||
} else null
|
||||
|
||||
val actualComponent = if (resolvedViaAvailableAt) {
|
||||
resolvedComponentResult.dependencies.filterIsInstance<ResolvedDependencyResult>().singleOrNull()?.selected
|
||||
?: resolvedComponentResult
|
||||
} else resolvedComponentResult
|
||||
|
||||
val moduleId = actualComponent.id
|
||||
return when {
|
||||
moduleId is ProjectComponentIdentifier -> when {
|
||||
moduleId.build.isCurrentBuild ->
|
||||
ProjectMppDependencyProjectStructureMetadataExtractor(moduleIdentifier, project.project(moduleId.projectPath))
|
||||
metadataArtifact != null ->
|
||||
IncludedBuildMppDependencyProjectStructureMetadataExtractor(project, actualComponent, metadataArtifact)
|
||||
else -> null
|
||||
}
|
||||
metadataArtifact != null -> JarMppDependencyProjectStructureMetadataExtractor(metadataArtifact)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
-221
@@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
import org.gradle.api.artifacts.result.ResolvedComponentResult
|
||||
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
||||
import org.gradle.api.artifacts.result.ResolvedVariantResult
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleIdentifiers
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toSingleKpmModuleIdentifier
|
||||
import org.jetbrains.kotlin.gradle.plugin.usageByName
|
||||
import org.jetbrains.kotlin.gradle.utils.getOrPut
|
||||
import org.jetbrains.kotlin.project.model.KpmModuleIdentifier
|
||||
import java.io.File
|
||||
|
||||
internal class ResolvedMppVariantsProvider private constructor(private val project: Project) {
|
||||
companion object {
|
||||
fun get(project: Project): ResolvedMppVariantsProvider {
|
||||
val propertyName = "kotlin.mpp.internal.resolvedModuleVariantsProvider"
|
||||
return project.extensions.extraProperties.getOrPut(propertyName) {
|
||||
ResolvedMppVariantsProvider(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the name of the variant that the module specified by the [moduleIdentifier] resolved to in the given [configuration].
|
||||
* The [moduleIdentifier] may be either the root module or a platform-specific module, the result is the same for the two cases. */
|
||||
fun getResolvedVariantName(moduleIdentifier: KpmModuleIdentifier, configuration: Configuration): String? =
|
||||
getEntryForModule(moduleIdentifier).run {
|
||||
if (configuration !in resolvedVariantsByConfiguration) {
|
||||
resolveConfigurationAndSaveVariants(configuration, artifactResolutionMode = ArtifactResolutionMode.NONE)
|
||||
}
|
||||
val variants = resolvedVariantsByConfiguration.getOrPut(configuration) { null }
|
||||
variants?.singleOrNull()?.displayName
|
||||
}
|
||||
|
||||
/** Gets the artifact that contains the common code metadata for the given [rootModuleIdentifier], which can only denote the root
|
||||
* module of a multiplatform project, not one of its platform-specific modules, as seen in the given [configuration].
|
||||
* If the [configuration] requests platform artifacts and not the common code metadata, then this function will resolve its
|
||||
* dependencies to metadata separately. */
|
||||
fun getHostSpecificMetadataArtifactByRootModule(rootModuleIdentifier: KpmModuleIdentifier, configuration: Configuration): File? {
|
||||
val rootModuleEntry = getEntryForModule(rootModuleIdentifier)
|
||||
|
||||
val platformModuleEntry = rootModuleEntry.run {
|
||||
if (configuration !in chosenPlatformModuleByConfiguration) {
|
||||
resolveConfigurationAndSaveVariants(configuration, artifactResolutionMode = ArtifactResolutionMode.METADATA)
|
||||
}
|
||||
// At this point the map should contain the result if calculation above succeeded. If not, put null to avoid recalculation.
|
||||
chosenPlatformModuleByConfiguration.getOrPut(configuration) { null }
|
||||
}
|
||||
|
||||
return platformModuleEntry?.run {
|
||||
// The condition might be true if the configuration has only been resolved with resolution mode NORMAL
|
||||
if (configuration !in resolvedMetadataArtifactByConfiguration) {
|
||||
resolveConfigurationAndSaveVariants(configuration, artifactResolutionMode = ArtifactResolutionMode.METADATA)
|
||||
}
|
||||
// At this point the map should contain the result if calculation above succeeded. If not, put null to avoid recalculation.
|
||||
resolvedMetadataArtifactByConfiguration.getOrPut(configuration) { null }
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the artifact of a particular MPP platform-specific [moduleIdentifier] as resolved in the [configuration]. */
|
||||
fun getResolvedArtifactByPlatformModule(moduleIdentifier: KpmModuleIdentifier, configuration: Configuration): File? =
|
||||
getEntryForModule(moduleIdentifier).run {
|
||||
if (configuration !in resolvedArtifactByConfiguration) {
|
||||
resolveConfigurationAndSaveVariants(configuration, artifactResolutionMode = ArtifactResolutionMode.NORMAL)
|
||||
}
|
||||
// At this point the map should contain the result if the calculation above succeeded. If not, put null to avoid recalculation.
|
||||
resolvedArtifactByConfiguration.getOrPut(configuration) { null }
|
||||
}
|
||||
|
||||
private fun getEntryForModule(moduleIdentifier: KpmModuleIdentifier) =
|
||||
entriesCache.getOrPut(moduleIdentifier, { ModuleEntry(moduleIdentifier) })
|
||||
|
||||
private val entriesCache: MutableMap<KpmModuleIdentifier, ModuleEntry> = mutableMapOf()
|
||||
|
||||
private val mppComponentsByConfiguration: MutableMap<Configuration, Set<ResolvedComponentResult>> = mutableMapOf()
|
||||
|
||||
private enum class ArtifactResolutionMode {
|
||||
NONE, NORMAL, METADATA
|
||||
}
|
||||
|
||||
private fun resolveConfigurationAndSaveVariants(
|
||||
configuration: Configuration,
|
||||
artifactResolutionMode: ArtifactResolutionMode
|
||||
) {
|
||||
val mppComponentIds: Set<ResolvedComponentResult> = mppComponentsByConfiguration.getOrPut(configuration) {
|
||||
resolveMppComponents(configuration)
|
||||
}
|
||||
|
||||
if (artifactResolutionMode != ArtifactResolutionMode.NONE) {
|
||||
val artifacts = resolveArtifacts(artifactResolutionMode, configuration, mppComponentIds)
|
||||
matchMppComponentsWithResolvedArtifacts(mppComponentIds, artifacts, configuration, artifactResolutionMode)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveMppComponents(configuration: Configuration): Set<ResolvedComponentResult> {
|
||||
val result = mutableListOf<ResolvedComponentResult>()
|
||||
|
||||
configuration.incoming.resolutionResult.allComponents { component ->
|
||||
val isMpp = component.dependents.isNotEmpty() && // filter out the root of the dependency graph, we are not interested in it
|
||||
component.variants.any { variant -> variant.attributes.keySet().any { it.name == KotlinPlatformType.attribute.name } }
|
||||
if (isMpp) {
|
||||
result.add(component)
|
||||
component.dependents.forEach { dependent ->
|
||||
dependent.selected.toKpmModuleIdentifiers().forEach { moduleId ->
|
||||
val moduleEntry = getEntryForModule(moduleId)
|
||||
moduleEntry.resolvedVariantsByConfiguration[configuration] = listOf(dependent.resolvedVariant)
|
||||
|
||||
moduleEntry.dependenciesByConfiguration[configuration] = component.dependencies
|
||||
.filterIsInstance<ResolvedDependencyResult>()
|
||||
.map { dependency -> dependency.selected.toSingleKpmModuleIdentifier() }
|
||||
|
||||
if (component.id is ProjectComponentIdentifier) {
|
||||
// Then the platform variant chosen for this module is definitely inside the module itself:
|
||||
moduleEntry.chosenPlatformModuleByConfiguration[configuration] = moduleEntry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.toSet()
|
||||
}
|
||||
|
||||
private fun resolveArtifacts(
|
||||
artifactResolutionMode: ArtifactResolutionMode,
|
||||
configuration: Configuration,
|
||||
mppComponents: Set<ResolvedComponentResult>
|
||||
): Map<ResolvedComponentResult, ResolvedArtifactResult> {
|
||||
val mppComponentById = mppComponents.associateBy { it.id }
|
||||
|
||||
val artifactsConfiguration =
|
||||
if (
|
||||
artifactResolutionMode == ArtifactResolutionMode.NORMAL ||
|
||||
configuration.attributes.getAttribute(Usage.USAGE_ATTRIBUTE)?.name == KotlinUsages.KOTLIN_METADATA
|
||||
) {
|
||||
configuration
|
||||
} else {
|
||||
configuration.copyRecursive().apply {
|
||||
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
|
||||
}
|
||||
}
|
||||
|
||||
return artifactsConfiguration.incoming.artifactView { view ->
|
||||
view.componentFilter { it in mppComponentById }
|
||||
view.attributes { attrs -> attrs.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) }
|
||||
view.lenient(true)
|
||||
}.artifacts.associateBy { mppComponentById.getValue(it.id.componentIdentifier) }
|
||||
}
|
||||
|
||||
private fun matchMppComponentsWithResolvedArtifacts(
|
||||
mppComponentIds: Set<ResolvedComponentResult>,
|
||||
artifacts: Map<ResolvedComponentResult, ResolvedArtifactResult>,
|
||||
configuration: Configuration,
|
||||
artifactResolutionMode: ArtifactResolutionMode
|
||||
) {
|
||||
val mppModuleIds = mppComponentIds.flatMapTo(mutableSetOf()) { componentId ->
|
||||
componentId.toKpmModuleIdentifiers()
|
||||
}
|
||||
|
||||
mppComponentIds.forEach { componentId ->
|
||||
componentId.toKpmModuleIdentifiers().forEach { moduleId ->
|
||||
val moduleEntry = getEntryForModule(moduleId)
|
||||
val artifact = artifacts[componentId]
|
||||
when {
|
||||
// With project dependencies, we don't need the host-specific metadata artifacts, as we have the compilation outputs:
|
||||
componentId is ProjectComponentIdentifier -> {
|
||||
moduleEntry.resolvedMetadataArtifactByConfiguration[configuration] = null
|
||||
}
|
||||
|
||||
// We found a requested artifact of the MPP; it is one of: platform artifact, root metadata, host-specific metadata
|
||||
artifact != null -> {
|
||||
val resolvedArtifactMap = when (artifactResolutionMode) {
|
||||
ArtifactResolutionMode.NORMAL -> moduleEntry.resolvedArtifactByConfiguration
|
||||
ArtifactResolutionMode.METADATA -> moduleEntry.resolvedMetadataArtifactByConfiguration
|
||||
else -> error("unexpected $artifactResolutionMode")
|
||||
}
|
||||
resolvedArtifactMap[configuration] = artifact.file
|
||||
}
|
||||
|
||||
// Otherwise, this may be a root module of some MPP that resolved to a variant in another module. Take a note of that.
|
||||
else -> {
|
||||
// TODO: there's an assumption that resolving a root MPP module to a host-specific metadata artifact and to a platform
|
||||
// artifact will choose variants that are published within the same Maven module; change this code if that's not
|
||||
// true anymore.
|
||||
val singleDependencyId = moduleEntry.dependenciesByConfiguration.getValue(configuration).singleOrNull()
|
||||
if (singleDependencyId != null && singleDependencyId in mppModuleIds) {
|
||||
moduleEntry.chosenPlatformModuleByConfiguration[configuration] =
|
||||
getEntryForModule(singleDependencyId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores resolution results of the module denoted by [moduleIdentifier] in different configurations of the project.
|
||||
* The [moduleIdentifier] may point to a root module of a multiplatform project (then it has meaningful
|
||||
* [chosenPlatformModuleByConfiguration]) or to a platform module.
|
||||
*/
|
||||
private class ModuleEntry(
|
||||
@Suppress("unused") // simplify debugging
|
||||
val moduleIdentifier: KpmModuleIdentifier
|
||||
) {
|
||||
val dependenciesByConfiguration: MutableMap<Configuration, List<KpmModuleIdentifier>> = HashMap()
|
||||
val resolvedVariantsByConfiguration: MutableMap<Configuration, List<ResolvedVariantResult?>?> = HashMap()
|
||||
val resolvedArtifactByConfiguration: MutableMap<Configuration, File?> = HashMap()
|
||||
val resolvedMetadataArtifactByConfiguration: MutableMap<Configuration, File?> = HashMap()
|
||||
val chosenPlatformModuleByConfiguration: MutableMap<Configuration, ModuleEntry?> = HashMap()
|
||||
}
|
||||
}
|
||||
+5
-11
@@ -34,6 +34,7 @@ internal class GradleKpmFragmentGranularMetadataResolver(
|
||||
private val fragmentResolver = KpmDefaultFragmentsResolver(variantResolver)
|
||||
private val dependencyGraphResolver = GradleKpmDependencyGraphResolver(moduleResolver)
|
||||
|
||||
@Suppress("UNREACHABLE_CODE", "UNUSED_VARIABLE")
|
||||
private fun doResolveMetadataDependencies(): Iterable<MetadataDependencyResolution> {
|
||||
val configurationToResolve = configurationToResolveMetadataDependencies(requestingFragment.containingModule)
|
||||
val resolvedComponentsByModuleId =
|
||||
@@ -91,12 +92,8 @@ internal class GradleKpmFragmentGranularMetadataResolver(
|
||||
We can safely assume that a metadata extractor can be created, because the project structure metadata already
|
||||
had to be read in order to create the Kotlin module and infer fragment visibility.
|
||||
*/
|
||||
val projectStructureMetadataExtractor = MppDependencyProjectStructureMetadataExtractor.create(
|
||||
project, resolvedComponentResult, configurationToResolve, true
|
||||
) ?: error(
|
||||
"Failed to create 'MppDependencyProjectStructureMetadataExtractor' for ${resolvedComponentResult.id} despite " +
|
||||
"the presence of a proper Kotlin Module"
|
||||
)
|
||||
val projectStructureMetadataExtractor: MppDependencyProjectStructureMetadataExtractor =
|
||||
TODO("Implement for KPM. As it done for TCS")
|
||||
|
||||
val projectStructureMetadata = (dependencyModule as? GradleKpmExternalImportedModule)?.projectStructureMetadata
|
||||
?: checkNotNull(projectStructureMetadataExtractor.getProjectStructureMetadata())
|
||||
@@ -160,14 +157,11 @@ internal class GradleKpmFragmentGranularMetadataResolver(
|
||||
// find some of our variants that resolved a dependency's variant containing the fragment
|
||||
.find { hostSpecificFragment in it.chosenVariant.withRefinesClosure }
|
||||
// resolve the dependencies of that variant getting the host-specific metadata artifact
|
||||
@Suppress("UNREACHABLE_CODE", "UNUSED_VARIABLE")
|
||||
relevantVariantResolution?.let { resolution ->
|
||||
val configurationResolvingPlatformVariant =
|
||||
(resolution.requestingVariant as GradleKpmVariant).compileDependenciesConfiguration
|
||||
val hostSpecificArtifact = ResolvedMppVariantsProvider.get(project)
|
||||
.getHostSpecificMetadataArtifactByRootModule(
|
||||
dependencyModule.moduleIdentifier,
|
||||
configurationResolvingPlatformVariant
|
||||
)
|
||||
val hostSpecificArtifact: File? = TODO("Implement host-specific lookup for KPM as it done for TCS")
|
||||
hostSpecificArtifact?.let { hostSpecificFragment.fragmentName to it }
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
+2
-6
@@ -183,16 +183,12 @@ internal fun ComponentIdentifier.matchesModuleIdentifier(id: KpmModuleIdentifier
|
||||
else -> false
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun getProjectStructureMetadata(
|
||||
project: Project,
|
||||
module: ResolvedComponentResult,
|
||||
configuration: Configuration,
|
||||
moduleIdentifier: KpmModuleIdentifier? = null
|
||||
): KotlinProjectStructureMetadata? {
|
||||
val extractor = if (moduleIdentifier != null)
|
||||
MppDependencyProjectStructureMetadataExtractor.create(project, module, moduleIdentifier, configuration)
|
||||
else
|
||||
MppDependencyProjectStructureMetadataExtractor.create(project, module, configuration, resolveViaAvailableAt = true)
|
||||
|
||||
return extractor?.getProjectStructureMetadata()
|
||||
TODO("Implement project structure metadata extractor for KPM")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user