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
This commit is contained in:
Sergey Igushkin
2019-08-23 16:23:01 +03:00
parent bb6f406be4
commit 8c1c687e92
5 changed files with 66 additions and 2 deletions
@@ -67,6 +67,10 @@ interface KotlinCompilation<out T : KotlinCommonOptions> : Named, HasAttributes,
fun source(sourceSet: KotlinSourceSet)
fun associateWith(other: KotlinCompilation<*>)
val associateWith: Set<KotlinCompilation<*>>
override fun getName(): String = compilationName
override val relatedConfigurationNames: List<String>
@@ -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)
@@ -81,10 +81,11 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
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)
}
}
}
@@ -199,8 +199,50 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
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<AbstractKotlinCompilation<*>> = mutableSetOf()
override val associateWith: Set<KotlinCompilation<*>>
get() = Collections.unmodifiableSet(_associateWith)
}
internal val KotlinCompilation<*>.associateWithTransitiveClosure: Iterable<KotlinCompilation<*>>
get() = mutableSetOf<KotlinCompilation<*>>().apply {
fun visit(other: KotlinCompilation<*>) {
if (add(other)) {
other.associateWith.forEach(::visit)
}
}
associateWith.forEach(::visit)
}
abstract class AbstractKotlinCompilationToRunnableFiles<T : KotlinCommonOptions>(
target: KotlinTarget,
name: String
@@ -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 {