From 8c1c687e923775c0670b86d44e299889ba8b4a7e Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Fri, 23 Aug 2019 16:23:01 +0300 Subject: [PATCH] Implement associate compilations, KT-34009 Partial implementation of the associate compilations proposal. A compilation can now contain links to other compilation that it compiles against. This links will replace ad-hoc inter-compilation dependencies. Issue #KT-34009 Fixed --- .../kotlin/gradle/plugin/KotlinCompilation.kt | 4 ++ .../kotlin/gradle/plugin/KotlinPlugin.kt | 10 +++++ .../gradle/plugin/KotlinTargetConfigurator.kt | 5 ++- .../gradle/plugin/mpp/kotlinCompilations.kt | 42 +++++++++++++++++++ .../targets/jvm/KotlinWithJavaCompilation.kt | 7 ++++ 5 files changed, 66 insertions(+), 2 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 8ab6e699b53..453d5eb89ad 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 @@ -67,6 +67,10 @@ interface KotlinCompilation : Named, HasAttributes, fun source(sourceSet: KotlinSourceSet) + fun associateWith(other: KotlinCompilation<*>) + + val associateWith: Set> + override fun getName(): String = compilationName override val relatedConfigurationNames: List diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index e36cc71136a..5d938b3b7a6 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -476,6 +476,10 @@ internal abstract class AbstractKotlinPlugin( kotlinCompilation.source(kotlinSourceSet) } + kotlinTarget.compilations.run { + getByName(KotlinCompilation.TEST_COMPILATION_NAME).associateWith(getByName(KotlinCompilation.MAIN_COMPILATION_NAME)) + } + // Since the 'java' plugin (as opposed to 'java-library') doesn't known anything about the 'api' configurations, // add the API dependencies of the main compilation directly to the 'apiElements' configuration, so that the 'api' dependencies // are properly published with the 'compile' scope (KT-28355): @@ -939,6 +943,12 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool ) { val javaTask = getJavaTask(variantData) ?: return + getTestedVariantData(variantData)?.let { testedVariant -> + val testedVariantName = getVariantName(testedVariant) + val testedCompilation = compilation.target.compilations.getByName(testedVariantName) + compilation.associateWith(testedCompilation) + } + val kotlinTask = compilation.compileKotlinTask configureSources(kotlinTask, variantData, compilation) wireKotlinTasks(project, compilation, androidPlugin, androidExt, variantData, javaTask, kotlinTask) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt index 1840432acdd..d6c3496aaeb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt @@ -81,10 +81,11 @@ abstract class AbstractKotlinTargetConfigurator if (createTestCompilation) { target.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME).apply { - compileDependencyFiles += main.output.allOutputs + associateWith(main) if (this is KotlinCompilationToRunnableFiles) { - runtimeDependencyFiles += project.files(output.allOutputs, main.output.allOutputs) + // TODO: fix inconsistency? KT-27272 + runtimeDependencyFiles += project.files(output.allOutputs) } } } 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 fbb95b17630..9a2817c8133 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 @@ -199,8 +199,50 @@ abstract class AbstractKotlinCompilation( val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName" return filterModuleName("$baseName$suffix") } + + override fun associateWith(other: KotlinCompilation<*>) { + require(other.target == target) { "Only associations between compilations of a single target are supported" } + other as AbstractKotlinCompilation<*> + + _associateWith += other + + addAssociateCompilationDependencies(other) + } + + protected open fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) { + target.project.dependencies.run { + val project = target.project + + add( + compileDependencyConfigurationName, + project.files(Callable { other.output.classesDirs }, Callable { other.compileDependencyFiles }) + ) + + if (this@AbstractKotlinCompilation is KotlinCompilationToRunnableFiles<*>) { + add(runtimeDependencyConfigurationName, project.files(Callable { other.output.allOutputs })) + if (other is KotlinCompilationToRunnableFiles<*>) { + add(runtimeDependencyConfigurationName, project.files(Callable { other.runtimeDependencyFiles })) + } + } + } + } + + private val _associateWith: MutableSet> = mutableSetOf() + + override val associateWith: Set> + get() = Collections.unmodifiableSet(_associateWith) } + internal val KotlinCompilation<*>.associateWithTransitiveClosure: Iterable> + get() = mutableSetOf>().apply { + fun visit(other: KotlinCompilation<*>) { + if (add(other)) { + other.associateWith.forEach(::visit) + } + } + associateWith.forEach(::visit) + } + abstract class AbstractKotlinCompilationToRunnableFiles( target: KotlinTarget, name: String diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaCompilation.kt index 9ea82d916fc..4973eac7a49 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinWithJavaCompilation.kt @@ -9,6 +9,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.file.FileCollection import org.gradle.api.tasks.SourceSet import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile @@ -57,6 +58,12 @@ import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile javaSourceSet.compileClasspath = value } + override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) { + if (name != SourceSet.TEST_SOURCE_SET_NAME || other.name != SourceSet.MAIN_SOURCE_SET_NAME) { + super.addAssociateCompilationDependencies(other) + } // otherwise, do nothing: the Java Gradle plugin adds these dependencies for us, we don't need to add them to the classpath + } + fun source(javaSourceSet: SourceSet) { with(target.project) { afterEvaluate {