[Gradle] KotlinCompilation: Remove .ownModuleName vs .moduleName duplication

This mechanism is simply not necessary anymore.
Just using the 'ownModuleName' as the value of 'moduleName' is
sufficient.

^KT-54312 Verification Pending
This commit is contained in:
Sebastian Sellmair
2022-10-26 10:25:46 +02:00
committed by Space Team
parent 02df7a7d4c
commit b3d82c74fe
19 changed files with 21 additions and 229 deletions
@@ -1368,7 +1368,6 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/pm20/Grad
public abstract fun getKotlinSourceDirectoriesByFragmentName ()Ljava/util/Map;
public abstract fun getLanguageSettings ()Lorg/jetbrains/kotlin/project/model/LanguageSettings;
public abstract fun getOutput ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinCompilationOutput;
public abstract fun getOwnModuleName ()Ljava/lang/String;
public abstract fun getOwner ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmVariant;
public abstract fun getPlatformType ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinPlatformType;
public abstract fun getProject ()Lorg/gradle/api/Project;
@@ -1418,7 +1417,6 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/pm20/Kotl
public abstract fun getLanguageSettings ()Lorg/jetbrains/kotlin/project/model/LanguageSettings;
public abstract fun getModuleName ()Ljava/lang/String;
public abstract fun getOutput ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinCompilationOutput;
public abstract fun getOwnModuleName ()Ljava/lang/String;
public abstract fun getOwner ()Ljava/lang/Object;
public abstract fun getPlatformType ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinPlatformType;
public abstract fun getProject ()Lorg/gradle/api/Project;
@@ -115,6 +115,7 @@ interface KotlinCompilation<out T : KotlinCommonOptionsDeprecated> : Named,
override val relatedConfigurationNames: List<String>
get() = super.relatedConfigurationNames + compileDependencyConfigurationName
@Deprecated("Scheduled for removal with Kotlin 1.9. Use compilerOptions instead")
val moduleName: String
val disambiguatedName
@@ -43,6 +43,4 @@ interface GradleKpmVariantCompilationData<T : KotlinCommonOptionsDeprecated> : K
override val platformType: KotlinPlatformType
get() = owner.platformType
override val ownModuleName: String
}
@@ -34,7 +34,6 @@ interface KotlinCompilationData<T : KotlinCommonOptionsDeprecated> {
val platformType: KotlinPlatformType
val moduleName: String
val ownModuleName: String
@Deprecated(
message = "Replaced with compilerOptions.options",
@@ -1769,7 +1769,7 @@ class NewMultiplatformIT : BaseGradleIT() {
"Hello.internalFun\$new_mpp_associate_compilations",
"HelloTest.internalTestFun\$new_mpp_associate_compilations"
)
assertFileExists("build/classes/kotlin/jvm/integrationTest/META-INF/new-mpp-associate-compilations.kotlin_module")
assertFileExists("build/classes/kotlin/jvm/integrationTest/META-INF/new-mpp-associate-compilations_integrationTest.kotlin_module")
// JS:
assertFileExists(
@@ -24,7 +24,6 @@ internal sealed class KotlinCompilationProjection {
abstract val platformType: KotlinPlatformType
abstract val targetDisambiguationClassifier: String?
abstract val compilationName: String
abstract val ownModuleName: String
abstract val moduleName: String
abstract val compilerOptions: HasCompilerOptions<*>
abstract val compileKotlinTaskName: String
@@ -52,11 +51,9 @@ internal sealed class KotlinCompilationProjection {
override val compilationName: String
get() = origin.compilationName
override val ownModuleName: String
get() = origin.internal.compilationModule.ownModuleName.get()
@Suppress("DEPRECATION")
override val moduleName: String
get() = origin.internal.moduleName
get() = origin.moduleName
override val compilerOptions: HasCompilerOptions<*>
get() = origin.compilerOptions
@@ -102,8 +99,6 @@ internal sealed class KotlinCompilationProjection {
override val compilationName: String
get() = origin.compilationPurpose
override val ownModuleName: String
get() = origin.ownModuleName
override val moduleName: String
get() = origin.moduleName
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationConfigurationsContainer
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager
import org.jetbrains.kotlin.gradle.utils.ObservableSet
import org.jetbrains.kotlin.tooling.core.MutableExtras
@@ -22,7 +21,6 @@ internal interface InternalKotlinCompilation<out T : KotlinCommonOptions> : Kotl
val configurations: KotlinCompilationConfigurationsContainer
val friendPaths: Iterable<FileCollection>
val compilationModule: KotlinCompilationModuleManager.CompilationModule
val processResourcesTaskName: String?
}
@@ -20,7 +20,6 @@ internal fun interface KotlinCompilationAssociator {
internal object DefaultKotlinCompilationAssociator : KotlinCompilationAssociator {
override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) {
target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule)
val project = target.project
/*
@@ -54,7 +53,6 @@ internal object DefaultKotlinCompilationAssociator : KotlinCompilationAssociator
internal object NativeKotlinCompilationAssociator : KotlinCompilationAssociator {
override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) {
target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule)
first.compileDependencyFiles +=
second.output.classesDirs + target.project.filesProvider { second.compileDependencyFiles }
@@ -67,8 +65,6 @@ internal object NativeKotlinCompilationAssociator : KotlinCompilationAssociator
internal object JvmKotlinCompilationAssociator : KotlinCompilationAssociator {
override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) {
target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule)
/* Main to Test association handled already by java plugin */
if (target is KotlinJvmTarget && target.withJavaEnabled && first.isMain() && second.isTest()) {
return
@@ -87,7 +83,6 @@ internal object JvmKotlinCompilationAssociator : KotlinCompilationAssociator {
*/
internal object AndroidKotlinCompilationAssociator : KotlinCompilationAssociator {
override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) {
target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule)
first.compileDependencyConfigurationName.addAllDependenciesFromOtherConfigurations(
target.project,
second.apiConfigurationName,
@@ -17,7 +17,9 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.HierarchyAttributeContainer
import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.utils.ObservableSet
@@ -34,7 +36,7 @@ internal class KotlinCompilationImpl @Inject constructor(
data class Params(
val target: KotlinTarget,
val compilationModule: KotlinCompilationModuleManager.CompilationModule,
val compilationName: String,
val sourceSets: KotlinCompilationSourceSetsContainer,
val dependencyConfigurations: KotlinCompilationConfigurationsContainer,
val compilationTaskNames: KotlinCompilationTaskNamesContainer,
@@ -65,7 +67,7 @@ internal class KotlinCompilationImpl @Inject constructor(
get() = params.dependencyConfigurations
override val compilationName: String
get() = params.compilationModule.compilationName
get() = params.compilationName
override val output: KotlinCompilationOutput
get() = params.output
@@ -149,11 +151,13 @@ internal class KotlinCompilationImpl @Inject constructor(
//region Compiler Module Management
override val compilationModule: KotlinCompilationModuleManager.CompilationModule
get() = params.compilationModule
@Suppress("OVERRIDE_DEPRECATION")
override val moduleName: String
get() = project.kotlinCompilationModuleManager.getModuleLeader(compilationModule).ownModuleName.get()
get() {
val baseName = target.project.archivesName.orNull ?: target.project.name
val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName"
return filterModuleName("$baseName$suffix")
}
//endregion
@@ -210,7 +214,6 @@ internal class KotlinCompilationImpl @Inject constructor(
override fun associateWith(other: KotlinCompilation<*>) {
require(other.target == target) { "Only associations between compilations of a single target are supported" }
if (!associateWithImpl.add(other)) return
project.kotlinCompilationModuleManager.unionModules(this.compilationModule, other.internal.compilationModule)
params.compilationAssociator.associate(target, this, other.internal)
}
@@ -1,62 +0,0 @@
/*
* Copyright 2010-2022 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.plugin.mpp.compilationImpl
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule
import org.jetbrains.kotlin.gradle.utils.getOrPut
import org.jetbrains.kotlin.tooling.core.withLinearClosure
/**
* This is a disjoint-set union-like approach to having a module name that is equal across associated compilations, as the compiler
* now requires that to properly compile internal calls to friend classes. Associating a compilation with another one leads to their
* disjoint sets being united, so their module names become equal, taken from the new leader compilation.
*/
internal interface KotlinCompilationModuleManager {
class CompilationModule(val compilationName: String, val ownModuleName: Provider<String>, val type: Type) {
enum class Type {
Main, /* Including tests */ Auxiliary
}
}
fun unionModules(first: CompilationModule, second: CompilationModule)
fun getModuleLeader(compilation: CompilationModule): CompilationModule
}
internal val Project.kotlinCompilationModuleManager: KotlinCompilationModuleManager
get() = extensions.extraProperties.getOrPut(KotlinCompilationModuleManager::class.java.name) {
DefaultKotlinCompilationModuleManager()
}
private class DefaultKotlinCompilationModuleManager : KotlinCompilationModuleManager {
private val leadingReferenceMap = mutableMapOf</*Follower compilationName*/String, /*Leader*/CompilationModule>()
override fun getModuleLeader(compilation: CompilationModule): CompilationModule {
return compilation.withLinearClosure { next -> leadingReferenceMap[next.compilationName] }.last()
}
override fun unionModules(first: CompilationModule, second: CompilationModule) {
val firstLeader = getModuleLeader(first)
val secondLeader = getModuleLeader(second)
if (firstLeader == secondLeader) return
val newLeaderCandidates = listOf(firstLeader, secondLeader)
/*
heuristically choose the new leader: choose `main` when possible, don't choose `*test*` when there's an alternative,
if that didn't work, choose the first name lexicographically
*/
val newLeader = newLeaderCandidates.singleOrNull { it.type == CompilationModule.Type.Main }
?: newLeaderCandidates.singleOrNull { it.compilationName.contains("main", true) }
?: newLeaderCandidates.singleOrNull { !it.compilationName.contains("test", true) }
?: checkNotNull(newLeaderCandidates.minByOrNull { it.compilationName })
setOf(first, second, firstLeader, secondLeader).forEach { compilationInfo ->
leadingReferenceMap[compilationInfo.compilationName] = newLeader
}
}
}
@@ -1,27 +0,0 @@
/*
* Copyright 2010-2022 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.plugin.mpp.compilationImpl.factory
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager
import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
internal object DefaultCompilationModuleFactory : KotlinCompilationImplFactory.CompilationModuleFactory {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationModuleManager.CompilationModule =
KotlinCompilationModuleManager.CompilationModule(
compilationName = compilationName,
ownModuleName = target.project.provider {
val baseName = target.project.archivesName.orNull
?: target.project.name
val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName"
filterModuleName("$baseName$suffix")
},
type = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) KotlinCompilationModuleManager.CompilationModule.Type.Main
else KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary
)
}
@@ -11,16 +11,12 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.DecoratedKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.*
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule
import org.jetbrains.kotlin.gradle.plugin.mpp.decoratedInstance
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
internal class KotlinCompilationImplFactory(
private val compilerOptionsFactory: KotlinCompilerOptionsFactory,
private val compilationModuleFactory: CompilationModuleFactory =
DefaultCompilationModuleFactory,
private val compilationSourceSetsContainerFactory: KotlinCompilationSourceSetsContainerFactory =
DefaultKotlinCompilationSourceSetsContainerFactory(),
@@ -51,9 +47,6 @@ internal class KotlinCompilationImplFactory(
private val postConfigureAction: PostConfigure =
DefaultKotlinCompilationPostConfigure
) {
fun interface CompilationModuleFactory {
fun create(target: KotlinTarget, compilationName: String): CompilationModule
}
fun interface KotlinCompilationSourceSetsContainerFactory {
fun create(target: KotlinTarget, compilationName: String): KotlinCompilationSourceSetsContainer
@@ -102,7 +95,7 @@ internal class KotlinCompilationImplFactory(
val compilation = KotlinCompilationImpl(
KotlinCompilationImpl.Params(
target = target,
compilationModule = compilationModuleFactory.create(target, compilationName),
compilationName = compilationName,
sourceSets = compilationSourceSetsContainerFactory.create(target, compilationName),
dependencyConfigurations = compilationDependencyConfigurationsFactory.create(target, compilationName),
compilationTaskNames = compilationTaskNamesContainerFactory.create(target, compilationName),
@@ -9,10 +9,7 @@ import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KpmGradleModuleVariantResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.allDependencyModules
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.utils.filesProvider
@@ -53,11 +50,6 @@ interface GradleKpmVariantCompilationDataInternal<T : KotlinCommonOptions> : Gra
}
override val moduleName: String
get() = // TODO accurate module names that don't rely on all variants having a main counterpart
owner.containingModule.project.pm20Extension.modules
.getByName(GradleKpmModule.MAIN_MODULE_NAME).variants.findByName(owner.name)?.ownModuleName() ?: ownModuleName
override val ownModuleName: String
get() = owner.ownModuleName()
private fun resolveFriendVariants(): Iterable<GradleKpmVariant> {
@@ -91,8 +91,6 @@ internal abstract class AbstractKotlinFragmentMetadataCompilationData<T : Kotlin
return filterModuleName("$baseName$suffix")
}
override val ownModuleName: String
get() = moduleName
override val friendPaths: Iterable<FileCollection>
get() = metadataCompilationRegistry.run {
@@ -285,6 +285,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
internal open fun isIncrementalCompilationEnabled(): Boolean =
incremental
@Deprecated("Scheduled for removal with Kotlin 1.9", ReplaceWith("moduleName"))
@get:Input
abstract val ownModuleName: Property<String>
@@ -99,7 +99,8 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
)
}
task.moduleName.set(providers.provider { compilationProjection.moduleName })
task.ownModuleName.set(project.provider { compilationProjection.ownModuleName })
@Suppress("DEPRECATION")
task.ownModuleName.set(project.provider { compilationProjection.moduleName })
task.sourceSetName.value(providers.provider { compilationProjection.compilationName })
task.multiPlatformEnabled.value(
providers.provider {
@@ -29,9 +29,7 @@ internal open class BaseKotlin2JsCompileConfig<TASK : Kotlin2JsCompile>(
configureAdditionalFreeCompilerArguments(task, compilation)
task.compilerOptions.moduleName.convention(
compilation.ownModuleName
)
task.compilerOptions.moduleName.convention(compilation.moduleName)
@Suppress("DEPRECATION")
task.outputFileProperty.value(
@@ -76,10 +76,10 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
task.associatedJavaCompileTaskName.value(javaTaskProvider.name)
}
@Suppress("DEPRECATION")
task.ownModuleName.value(
providers.provider {
@Suppress("DEPRECATION")
task.parentKotlinOptions.orNull?.moduleName ?: compilationProjection.ownModuleName
task.parentKotlinOptions.orNull?.moduleName ?: compilationProjection.moduleName
})
}
}
@@ -1,89 +0,0 @@
/*
* Copyright 2010-2022 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
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.kotlinCompilationModuleManager
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
import org.junit.Test
import kotlin.test.assertEquals
class KotlinCompilationsModuleGroupsTest {
private val project = buildProjectWithMPP()
private val kotlin = project.multiplatformExtension
private val instance: KotlinCompilationModuleManager = project.kotlinCompilationModuleManager
private fun compilation(name: String): InternalKotlinCompilation<*> =
kotlin.jvm().compilations.maybeCreate(name)
private fun KotlinCompilationModuleManager.unionModules(first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) {
unionModules(first.compilationModule, second.compilationModule)
}
@Test
fun testIdentityAsModuleLeaderForNewCompilation() {
val a = compilation("a")
assertEquals(a.internal.compilationModule, instance.getModuleLeader(a.compilationModule))
}
private fun assertLeader(leader: InternalKotlinCompilation<*>, vararg ofCompilations: InternalKotlinCompilation<*>) {
val leadersForModules = ofCompilations.map { instance.getModuleLeader(it.compilationModule) }
assertEquals(leadersForModules.map { leader.compilationModule }, leadersForModules)
}
@Test
fun testModulesMerged() {
val (a, b, c, d) = listOf("a", "b", "c", "d").map(this::compilation)
// Union all but one:
instance.unionModules(b, c)
instance.unionModules(a, b)
assertLeader(a, a, b, c)
assertLeader(d, d)
}
@Test
fun testMainPreferredAsLeader() {
val (aMain, aTest) = listOf("aMain", "aTest").map(this::compilation)
val (zMain, yTest) = listOf("zMain", "yTest").map(this::compilation)
val (xMain, xBenchmark, xTest) = listOf("xMain", "xBenchmark", "xTest").map(this::compilation)
instance.unionModules(aMain, aTest)
assertLeader(aMain, aMain, aTest)
instance.unionModules(yTest, zMain)
assertLeader(zMain, zMain, yTest)
instance.unionModules(xBenchmark, xTest)
instance.unionModules(xBenchmark, xMain)
assertLeader(xMain, xMain, xBenchmark, xTest)
}
@Test
fun testNonTestPreferredAsLeader() {
val (aBenchmark, aPerformanceTest, aTest) = listOf("aBenchmark", "aPerformanceTest", "aTest").map(this::compilation)
instance.unionModules(aPerformanceTest, aTest)
instance.unionModules(aTest, aBenchmark)
assertLeader(aBenchmark, aBenchmark, aPerformanceTest, aTest)
}
@Test
fun unionModuleWithSelf() {
val compilation = compilation("compilation")
instance.unionModules(compilation, compilation)
assertLeader(compilation, compilation)
}
@Test
fun testUnionModulesTwice() {
val (a, b) = listOf("a", "b").map(this::compilation)
instance.unionModules(a, b)
instance.unionModules(a, b)
assertLeader(a, a, b)
}
}