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 0c129f7b43b..a3b87757ca3 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 @@ -231,7 +231,7 @@ internal class GranularMetadataTransformation( val compositeMetadataArtifact = params .resolvedMetadataConfiguration - .dependencyArtifacts(dependency) + .getArtifacts(dependency) .singleOrNull() // Make sure that resolved metadata artifact is actually Multiplatform one ?.takeIf { it.variant.attributes.containsMultiplatformAttributes } 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 a5172ca0bff..ae5ea35183a 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 @@ -139,7 +139,7 @@ open class MetadataDependencyTransformationTask is MetadataDependencyResolution.ChooseVisibleSourceSets -> objectFactory.transformMetadataLibrariesForBuild(resolution, outputsDir, true) is MetadataDependencyResolution.KeepOriginalDependency -> - transformationParameters.resolvedMetadataConfiguration.componentArtifacts(resolution.dependency).map { it.file } + transformationParameters.resolvedMetadataConfiguration.getArtifacts(resolution.dependency).map { it.file } is MetadataDependencyResolution.Exclude -> emptyList() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt index d18a40cd0e4..98abec52b94 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt @@ -216,7 +216,7 @@ constructor( .allDependencies .filterIsInstance() .forEach { - val dependencyFiles = exportLibrariesResolvedGraph.dependencyArtifacts(it).map { it.file }.filterKlibsPassedToCompiler() + val dependencyFiles = exportLibrariesResolvedGraph.getArtifacts(it).map { it.file }.filterKlibsPassedToCompiler() if (!apiFiles.files.containsAll(dependencyFiles)) { failed.add(it) } @@ -226,7 +226,7 @@ constructor( val failedDependenciesList = failed.joinToString(separator = "\n") { val componentId = it.selected.id when (componentId) { - is ModuleComponentIdentifier -> "|Files: ${exportLibrariesResolvedGraph.dependencyArtifacts(it).map { it.file }}" + is ModuleComponentIdentifier -> "|Files: ${exportLibrariesResolvedGraph.getArtifacts(it).map { it.file }}" is ProjectComponentIdentifier -> "|Project ${componentId.projectPath}" else -> "|${componentId.displayName}" } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index 42c477cf4db..ab6220d99f3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -784,7 +784,7 @@ internal class CacheBuilder( .filterIsInstance() .forEach { ensureDependencyPrecached(it, visitedDependencies) } - val artifactsToAddToCache = dependencyArtifacts(dependency).filter { needCache(it.file.absolutePath) } + val artifactsToAddToCache = getArtifacts(dependency).filter { needCache(it.file.absolutePath) } if (artifactsToAddToCache.isEmpty()) return @@ -848,7 +848,7 @@ internal class CacheBuilder( args += "-Xcache-directory=${it.absolutePath}" } getAllDependencies(dependency) - .flatMap { dependencyArtifacts(it) } + .flatMap { getArtifacts(it) } .map { it.file } .filterKlibsPassedToCompiler() .forEach { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/LazyResolvedConfiguration.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/LazyResolvedConfiguration.kt index 60023bf1e0d..063c76dd30b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/LazyResolvedConfiguration.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/LazyResolvedConfiguration.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.utils import org.gradle.api.artifacts.ArtifactCollection import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ResolveException +import org.gradle.api.artifacts.ResolvedConfiguration import org.gradle.api.artifacts.result.* import org.gradle.api.file.FileCollection import org.jetbrains.kotlin.tooling.core.withClosure @@ -20,8 +21,7 @@ import org.jetbrains.kotlin.tooling.core.withClosure * * Has similar API as non-configuration cache friendly Gradle's [ResolvedConfiguration] */ -internal class LazyResolvedConfiguration -private constructor( +internal class LazyResolvedConfiguration private constructor( private val resolvedComponentsRootProvider: Lazy, private val artifactCollection: ArtifactCollection, private val configurationName: String, @@ -35,80 +35,50 @@ private constructor( configurationName = configuration.name ) - val root get() = resolvedComponentsRootProvider.value val files: FileCollection get() = artifactCollection.artifactFiles - val artifacts get() = artifactCollection.artifacts - private val artifactsByComponentId by TransientLazy { artifacts.groupBy { it.id.componentIdentifier } } + val root by resolvedComponentsRootProvider - val allDependencies: List get() { - val visited = mutableSetOf() - fun DependencyResult.allDependenciesRecursive(): List { - if (this in visited) return emptyList() - visited += this - return if (this is ResolvedDependencyResult) { - listOf(this) + selected.dependencies.flatMap { it.allDependenciesRecursive() } - } else { - listOf(this) - } + private val resolvedArtifacts: Set get() = artifactCollection.artifacts + + private val artifactsByComponentId by TransientLazy { resolvedArtifacts.groupBy { it.id.componentIdentifier } } + + val allDependencies: Set by TransientLazy { + root.dependencies.withClosure { + if (it is ResolvedDependencyResult) it.selected.dependencies + else emptyList() } - - return root.dependencies.flatMap { it.allDependenciesRecursive() } } - /** - * Returns artifacts of a given dependency walking through external variants (the ones that referenced in `available-at`) - * For example given a MPP library: - * lib - * / \ - * lib-jvm lib-iosX64 - * - * And some requested dependency on `lib` in `jvmMain` source set. In this case it should be resolved to `lib-jvm` - * so requesting [dependencyArtifacts] for `lib` should actually return a jvm artifact from `lib-jvm` - * - * If you need to avoid such behavior see [moduleArtifacts] - */ - fun dependencyArtifacts(dependency: ResolvedDependencyResult): List { - val componentId = dependency.resolvedVariant.findNonExternalVariant().owner + fun getArtifacts(dependency: ResolvedDependencyResult): List { + val componentId = dependency.resolvedVariant.lastExternalVariantOrSelf().owner return artifactsByComponentId[componentId] ?: emptyList() } - fun componentArtifacts(component: ResolvedComponentResult): List { - val componentIds = component.variants.map { it.findNonExternalVariant().owner } + fun getArtifacts(component: ResolvedComponentResult): List { + val componentIds = component.variants.map { it.lastExternalVariantOrSelf().owner } return componentIds.flatMap { artifactsByComponentId[it].orEmpty() } } - private fun ResolvedVariantResult.findNonExternalVariant(): ResolvedVariantResult = - if (externalVariant.isPresent) { - externalVariant.get().findNonExternalVariant() - } else { - this - } - - /** - * Returns own artifacts of a given dependency. - * Acts in the same way as [org.gradle.api.artifacts.ResolvedDependency.getModuleArtifacts]. - * - * To get artifacts from External Variants (aka `available-at`) use [dependencyArtifacts] - */ - fun moduleArtifacts(dependency: ResolvedDependencyResult): List { - val componentId = dependency.resolvedVariant.owner - return artifactsByComponentId[componentId] ?: emptyList() + private tailrec fun ResolvedVariantResult.lastExternalVariantOrSelf(): ResolvedVariantResult { + return if (externalVariant.isPresent) externalVariant.get().lastExternalVariantOrSelf() else this } - override fun toString(): String = "ResolvedDependencyGraph(configuration='$configurationName')" + override fun toString(): String = "LazyResolvedConfiguration(configuration='$configurationName')" } -internal val LazyResolvedConfiguration.allResolvedDependencies: Set get() = allDependencies - .filterIsInstance() - .toSet() +internal val LazyResolvedConfiguration.allResolvedDependencies: Set + get() = allDependencies + .filterIsInstance() + .toSet() /** - * Same as [LazyResolvedConfiguration.dependencyArtifacts] except it returns null for cases when dependency is resolved + * Same as [LazyResolvedConfiguration.getArtifacts] except it returns null for cases when dependency is resolved * but artifact is not available. For example when host-specific part of the library is not yet published */ -internal fun LazyResolvedConfiguration.dependencyArtifactsOrNull(dependency: ResolvedDependencyResult): List? = try { - dependencyArtifacts(dependency) -} catch (_: ResolveException) { - null -} \ No newline at end of file +internal fun LazyResolvedConfiguration.dependencyArtifactsOrNull(dependency: ResolvedDependencyResult): List? = + try { + getArtifacts(dependency) + } catch (_: ResolveException) { + null + } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/cacheKlibUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/cacheKlibUtils.kt index 2cd08d57aea..b4c6aca33af 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/cacheKlibUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/cacheKlibUtils.kt @@ -51,7 +51,7 @@ private fun computeDependenciesHash(dependency: ResolvedDependencyResult, resolv if (partialLinkage) append("#__PL__#") (listOf(dependency) + getAllDependencies(dependency)) - .flatMap { resolvedConfiguration.dependencyArtifacts(it) } + .flatMap { resolvedConfiguration.getArtifacts(it) } .map { it.file.absolutePath } .distinct() .sortedBy { it } @@ -72,7 +72,7 @@ internal fun getDependenciesCacheDirectories( ): List? { return getAllDependencies(dependency) .flatMap { childDependency -> - resolvedConfiguration.dependencyArtifacts(childDependency).map { + resolvedConfiguration.getArtifacts(childDependency).map { if (libraryFilter(it)) { val cacheDirectory = getCacheDirectory( rootCacheDirectory = rootCacheDirectory,