From 50050154d32cbcf5035ec603377734e4752a5365 Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Wed, 29 Sep 2021 12:31:09 +0300 Subject: [PATCH] [gradle, mpp] Change how outputs of associated compilations are handled --- .../kotlin/gradle/plugin/KotlinCompilation.kt | 3 + .../gradle/plugin/mpp/kotlinCompilations.kt | 66 +++++++++++++------ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt index 6abd2a1898e..14c6545ab8a 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt @@ -95,6 +95,9 @@ interface KotlinCompilationToRunnableFiles : KotlinComp get() = super.relatedConfigurationNames + runtimeDependencyConfigurationName } +val KotlinCompilation.runtimeDependencyConfigurationName: String? + get() = (this as? KotlinCompilationToRunnableFiles)?.runtimeDependencyConfigurationName + interface KotlinCompilationWithResources : KotlinCompilation { val processResourcesTaskName: String } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index a75c2ebe16b..a2c607e395d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -10,6 +10,7 @@ import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.UnknownTaskException +import org.gradle.api.artifacts.Dependency import org.gradle.api.attributes.AttributeContainer import org.gradle.api.execution.TaskExecutionListener import org.gradle.api.file.FileCollection @@ -31,7 +32,6 @@ import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.utils.* -import java.io.File import java.util.* import java.util.concurrent.Callable @@ -254,28 +254,56 @@ abstract class AbstractKotlinCompilation( KotlinCompilationsModuleGroups.unionModules(this, other) } - protected open fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) { - with(target.project) { - dependencies.add( - compileOnlyConfigurationName, - project.files(Callable { other.output.classesDirs }) - ) - - configurations.named(compileOnlyConfigurationName).configure { - it.extendsFrom(configurations.findByName(other.compileDependencyConfigurationName)) - } - - if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { - dependencies.add(runtimeOnlyConfigurationName, project.files(Callable { other.output.allOutputs })) - if (other is KotlinCompilationToRunnableFiles<*>) { - configurations.named(runtimeOnlyConfigurationName).configure { - it.extendsFrom(configurations.findByName(other.runtimeDependencyConfigurationName)) - } + /** + * Adds `allDependencies` of configurations mentioned in `configurationNames` to configuration named [this] in + * a lazy manner + */ + private fun String.addAllDependenciesFromOtherConfigurations(project: Project, vararg configurationNames: String) { + project.configurations.named(this).configure { receiverConfiguration -> + receiverConfiguration.dependencies.addAllLater( + project.objects.listProperty(Dependency::class.java).apply { + set( + project.provider { + configurationNames + .map { project.configurations.getByName(it) } + .flatMap { it.allDependencies } + } + ) } - } + ) } } + @OptIn(ExperimentalStdlibApi::class) + protected open fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) { + /* + we add dependencies to compileDependencyConfiguration ('compileClasspath' usually) and runtimeDependency + ('runtimeClasspath') instead of modifying respective api/implementation/compileOnly/runtimeOnly configs + + This is needed because api/implementation/compileOnly/runtimeOnly are used in IDE Import and will leak + to dependencies of IDE modules. But they are not needed here, because IDE resolution works inherently + transitively and symbols from associated compilation will be resolved from source sets of associated + compilation itself (moreover, direct dependencies are not equivalent to transitive ones because of + resolution order - e.g. in case of FQNs clash, so it's even harmful) + */ + project.dependencies.add(compileOnlyConfigurationName, project.files(Callable { other.output.classesDirs })) + project.dependencies.add(runtimeOnlyConfigurationName, project.files(Callable { other.output.allOutputs })) + + compileDependencyConfigurationName.addAllDependenciesFromOtherConfigurations( + project, + other.apiConfigurationName, + other.implementationConfigurationName, + other.compileOnlyConfigurationName + ) + + runtimeDependencyConfigurationName?.addAllDependenciesFromOtherConfigurations( + project, + other.apiConfigurationName, + other.implementationConfigurationName, + other.runtimeOnlyConfigurationName + ) + } + private val _associateWith: MutableSet> = mutableSetOf() override val associateWith: List>