[Gradle] Pass only parent's visible source sets instead of entire...

...GranularMetadataTransformation object

^KT-49933
This commit is contained in:
Anton Lakotka
2023-01-12 09:05:37 +01:00
committed by Space Team
parent 7ec72b568d
commit 396ed3642e
5 changed files with 66 additions and 32 deletions
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.component.ComponentIdentifier
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.artifacts.result.ResolvedComponentResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
@@ -17,6 +19,7 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ArtifactMetadataProvider
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.utils.mergeWith
import java.util.*
internal sealed class MetadataDependencyResolution(
@@ -86,14 +89,33 @@ internal sealed class MetadataDependencyResolution(
}
}
private typealias ComponentIdentifierKey = String
/**
* This unique key can be used to lookup various info for related Resolved Dependency
* that gets serialized
*/
private val ComponentIdentifier.uniqueKey get(): ComponentIdentifierKey =
when (this) {
is ProjectComponentIdentifier -> "project ${build.name} :$projectPath"
is ModuleComponentIdentifier -> "module $group:$module:$version"
else -> error("Unexpected Component Identifier: '$this' of type $javaClass")
}
internal class GranularMetadataTransformation(
val project: Project,
val kotlinSourceSet: KotlinSourceSet,
/** A configuration that holds the dependencies of the appropriate scope for all Kotlin source sets in the project */
private val parentTransformations: Lazy<Iterable<GranularMetadataTransformation>>
parentVisibleSourceSetsProvider: () -> Iterable<Map<ComponentIdentifierKey, Set<String>>>
) {
private val parentVisibleSourceSets: Map<ComponentIdentifierKey, Set<String>> by lazy {
parentVisibleSourceSetsProvider().reduceOrNull { acc, map -> acc mergeWith map }.orEmpty()
}
val metadataDependencyResolutions: Iterable<MetadataDependencyResolution> by lazy { doTransform() }
val visibleSourceSetsByComponentId: Map<ComponentIdentifierKey, Set<String>> = metadataDependencyResolutions
.filterIsInstance<MetadataDependencyResolution.ChooseVisibleSourceSets>()
.associate { it.dependency.id.uniqueKey to it.allVisibleSourceSetNames }
private val requestedDependencies: Iterable<Dependency> by lazy {
kotlinSourceSet.internal.resolvableMetadataConfiguration.incoming.dependencies
}
@@ -103,11 +125,6 @@ internal class GranularMetadataTransformation(
private fun doTransform(): Iterable<MetadataDependencyResolution> {
val result = mutableListOf<MetadataDependencyResolution>()
val parentResolutions =
parentTransformations.value.flatMap { it.metadataDependencyResolutions }.groupBy {
ModuleIds.fromComponent(project, it.dependency)
}
val allRequestedDependencies = requestedDependencies
val resolutionResult = configurationToResolve.incoming.resolutionResult
@@ -139,7 +156,7 @@ internal class GranularMetadataTransformation(
val dependencyResult = processDependency(
resolvedDependency,
parentResolutions[ModuleIds.fromComponent(project, resolvedDependency)].orEmpty()
parentVisibleSourceSets[resolvedDependency.id.uniqueKey].orEmpty()
)
result.add(dependencyResult)
@@ -189,7 +206,7 @@ internal class GranularMetadataTransformation(
*/
private fun processDependency(
module: ResolvedComponentResult,
parentResolutionsForModule: Iterable<MetadataDependencyResolution>,
sourceSetsVisibleInParents: Set<String>,
): MetadataDependencyResolution {
val mppDependencyMetadataExtractor = MppDependencyProjectStructureMetadataExtractor.create(
project, module, configurationToResolve,
@@ -215,10 +232,6 @@ internal class GranularMetadataTransformation(
val allVisibleSourceSets = sourceSetVisibility.visibleSourceSetNames
val sourceSetsVisibleInParents = parentResolutionsForModule
.filterIsInstance<MetadataDependencyResolution.ChooseVisibleSourceSets>()
.flatMapTo(mutableSetOf()) { it.allVisibleSourceSetNames }
// Keep only the transitive dependencies requested by the visible source sets:
// Visit the transitive dependencies visible by parents, too (i.e. allVisibleSourceSets), as this source set might get a more
// concrete view on them:
@@ -84,15 +84,15 @@ open class MetadataDependencyTransformationTask
private val transformation: GranularMetadataTransformation by lazy {
GranularMetadataTransformation(
project,
kotlinSourceSet,
lazy {
dependsOnClosureWithInterCompilationDependencies(kotlinSourceSet).map {
project.tasks.withType(MetadataDependencyTransformationTask::class.java)
.getByName(KotlinMetadataTargetConfigurator.transformGranularMetadataTaskName(it.name))
.transformation
}
kotlinSourceSet
) {
dependsOnClosureWithInterCompilationDependencies(kotlinSourceSet).map {
project.tasks.withType(MetadataDependencyTransformationTask::class.java)
.getByName(KotlinMetadataTargetConfigurator.transformGranularMetadataTaskName(it.name))
.transformation
.visibleSourceSetsByComponentId
}
)
}
}
@get:Internal
@@ -358,9 +358,9 @@ class KotlinMetadataTargetConfigurator :
val granularMetadataTransformation = GranularMetadataTransformation(
project = project,
kotlinSourceSet = sourceSet,
parentTransformations = lazy {
parentVisibleSourceSetsProvider = {
dependsOnClosureWithInterCompilationDependencies(sourceSet).filterIsInstance<DefaultKotlinSourceSet>()
.map { it.compileDependenciesTransformationOrFail }
.map { it.compileDependenciesTransformationOrFail.visibleSourceSetsByComponentId }
}
)
@@ -0,0 +1,30 @@
/*
* 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.utils
fun <T : Any> T?.toSetOrEmpty(): Set<T> =
if (this == null) emptySet() else setOf(this)
/**
* Merges two Map of Sets to new map
* Example:
* { 1: ['a', 'b'], 2: ['c'] }
* merge
* { 0: ['x'], 1: ['c'], 42: ['y'] }
* =
* { 0: ['x'], 1: ['a', 'b', 'c'], 2: ['c'], 42: ['y'] }
*/
infix fun <K, V> Map<K, Set<V>>.mergeWith(that: Map<K, Set<V>>): Map<K, Set<V>> {
val result = mutableMapOf<K, Set<V>>()
for ((k, setOfV) in this) {
result[k] = setOfV + that[k].orEmpty()
}
val uniqueEntriesFromRight = that - this.keys
result.putAll(uniqueEntriesFromRight)
return result
}
@@ -1,9 +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.utils
fun <T : Any> T?.toSetOrEmpty(): Set<T> =
if (this == null) emptySet() else setOf(this)