From 396ed3642e73988a88e4f9656e00db1aa30bd5bd Mon Sep 17 00:00:00 2001 From: Anton Lakotka Date: Thu, 12 Jan 2023 09:05:37 +0100 Subject: [PATCH] [Gradle] Pass only parent's visible source sets instead of entire... ...GranularMetadataTransformation object ^KT-49933 --- .../mpp/GranularMetadataTransformation.kt | 39 ++++++++++++------- .../MetadataDependencyTransformationTask.kt | 16 ++++---- .../KotlinMetadataTargetConfigurator.kt | 4 +- .../kotlin/gradle/utils/collectionsUtils.kt | 30 ++++++++++++++ .../jetbrains/kotlin/gradle/utils/setUtils.kt | 9 ----- 5 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/collectionsUtils.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/setUtils.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt index f6a56e7a377..778b43cfe2d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt @@ -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> + parentVisibleSourceSetsProvider: () -> Iterable>> ) { + private val parentVisibleSourceSets: Map> by lazy { + parentVisibleSourceSetsProvider().reduceOrNull { acc, map -> acc mergeWith map }.orEmpty() + } + val metadataDependencyResolutions: Iterable by lazy { doTransform() } + val visibleSourceSetsByComponentId: Map> = metadataDependencyResolutions + .filterIsInstance() + .associate { it.dependency.id.uniqueKey to it.allVisibleSourceSetNames } + private val requestedDependencies: Iterable by lazy { kotlinSourceSet.internal.resolvableMetadataConfiguration.incoming.dependencies } @@ -103,11 +125,6 @@ internal class GranularMetadataTransformation( private fun doTransform(): Iterable { val result = mutableListOf() - 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, + sourceSetsVisibleInParents: Set, ): MetadataDependencyResolution { val mppDependencyMetadataExtractor = MppDependencyProjectStructureMetadataExtractor.create( project, module, configurationToResolve, @@ -215,10 +232,6 @@ internal class GranularMetadataTransformation( val allVisibleSourceSets = sourceSetVisibility.visibleSourceSetNames - val sourceSetsVisibleInParents = parentResolutionsForModule - .filterIsInstance() - .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: diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt index 97b765beb5e..31dbbdc55b6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/MetadataDependencyTransformationTask.kt @@ -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 diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index 493e31be131..2673ccd4ffd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -358,9 +358,9 @@ class KotlinMetadataTargetConfigurator : val granularMetadataTransformation = GranularMetadataTransformation( project = project, kotlinSourceSet = sourceSet, - parentTransformations = lazy { + parentVisibleSourceSetsProvider = { dependsOnClosureWithInterCompilationDependencies(sourceSet).filterIsInstance() - .map { it.compileDependenciesTransformationOrFail } + .map { it.compileDependenciesTransformationOrFail.visibleSourceSetsByComponentId } } ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/collectionsUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/collectionsUtils.kt new file mode 100644 index 00000000000..4c79af471d1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/collectionsUtils.kt @@ -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?.toSetOrEmpty(): Set = + 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 Map>.mergeWith(that: Map>): Map> { + val result = mutableMapOf>() + for ((k, setOfV) in this) { + result[k] = setOfV + that[k].orEmpty() + } + + val uniqueEntriesFromRight = that - this.keys + result.putAll(uniqueEntriesFromRight) + + return result +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/setUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/setUtils.kt deleted file mode 100644 index a5d4d422682..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/setUtils.kt +++ /dev/null @@ -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?.toSetOrEmpty(): Set = - if (this == null) emptySet() else setOf(this) \ No newline at end of file