diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt index 231e944fb73..74763c8d3c3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt @@ -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 diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MppDependencyProjectStructureMetadataExtractorFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MppDependencyProjectStructureMetadataExtractorFactory.kt index 772e1ee92e6..6305dae63f4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MppDependencyProjectStructureMetadataExtractorFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MppDependencyProjectStructureMetadataExtractorFactory.kt @@ -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().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 - } -} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/ResolvedMppVariantsProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/ResolvedMppVariantsProvider.kt deleted file mode 100644 index 2ec8565124c..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/ResolvedMppVariantsProvider.kt +++ /dev/null @@ -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 = mutableMapOf() - - private val mppComponentsByConfiguration: MutableMap> = mutableMapOf() - - private enum class ArtifactResolutionMode { - NONE, NORMAL, METADATA - } - - private fun resolveConfigurationAndSaveVariants( - configuration: Configuration, - artifactResolutionMode: ArtifactResolutionMode - ) { - val mppComponentIds: Set = 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 { - val result = mutableListOf() - - 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() - .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 - ): Map { - 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, - artifacts: Map, - 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> = HashMap() - val resolvedVariantsByConfiguration: MutableMap?> = HashMap() - val resolvedArtifactByConfiguration: MutableMap = HashMap() - val resolvedMetadataArtifactByConfiguration: MutableMap = HashMap() - val chosenPlatformModuleByConfiguration: MutableMap = HashMap() - } -} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmFragmentGranularMetadataResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmFragmentGranularMetadataResolver.kt index f1a518fa845..2c974eade38 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmFragmentGranularMetadataResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmFragmentGranularMetadataResolver.kt @@ -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 { 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() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmModuleDependencyResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmModuleDependencyResolver.kt index 1817711a212..fb5bb8f8c8f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmModuleDependencyResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmModuleDependencyResolver.kt @@ -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") }