diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt index f9f9e601095..e96b0e5d327 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsSingleTargetPreset import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.DefaultKpmGradleProjectModelContainer import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModuleFactory import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension @@ -118,8 +119,11 @@ open class KotlinProjectExtension @Inject constructor(project: Project) : Kotlin DslObject(this).extensions.add("sourceSets", value) } - internal val kpmModules: NamedDomainObjectContainer = - project.objects.domainObjectContainer(KotlinGradleModule::class.java, KotlinGradleModuleFactory(project)) + internal val kpmModelContainer by lazy { + if (PropertiesProvider(project).experimentalKpmModelMapping) { + DefaultKpmGradleProjectModelContainer.create(project) + } else error("Model mapping is not enabled.") + } } abstract class KotlinSingleTargetExtension(project: Project) : KotlinProjectExtension(project) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/IdeFragmentDependencyResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/IdeFragmentDependencyResolver.kt index 637b875d17e..426a919da57 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/IdeFragmentDependencyResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/IdeFragmentDependencyResolver.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.getSourceSetCompiledMetadata import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.FragmentGranularMetadataResolverFactory import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleFragment import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule.Companion.moduleName +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.kpmModules import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toModuleDependency import org.jetbrains.kotlin.gradle.plugin.sources.SourceSetMetadataStorageForIde import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier @@ -49,7 +50,7 @@ private class IdeFragmentDependencyResolverImpl( private val fragmentGranularMetadataResolverFactory: FragmentGranularMetadataResolverFactory ) : IdeFragmentDependencyResolver { override fun resolveDependencies(moduleName: String, fragmentName: String): List { - val fragment = project.pm20Extension.modules.getByName(moduleName).fragments.getByName(fragmentName) + val fragment = project.kpmModules.getByName(moduleName).fragments.getByName(fragmentName) val fragmentGranularMetadataResolver = fragmentGranularMetadataResolverFactory.getOrCreate(fragment) return fragmentGranularMetadataResolver.resolutions.flatMap { resolution -> resolveDependenciesForIde(fragment, resolution) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt index 6f43e611181..ed0785bbae4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt @@ -121,7 +121,7 @@ private fun detectModules(targets: Iterable, sourceSets: Iterable< @Suppress("unused") class GradleProjectModuleBuilder(private val addInferredSourceSetVisibilityAsExplicit: Boolean) { - private fun getModulesFromPm20Project(project: Project) = project.pm20Extension.modules.toList() + private fun getModulesFromPm20Project(project: Project) = project.kpmModules.toList() fun buildModulesFromProject(project: Project): List { if (project.topLevelExtension is KotlinPm20ProjectExtension) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt index eab7077670c..e9ce0b7d6ae 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt @@ -119,19 +119,13 @@ abstract class KotlinPm20GradlePlugin @Inject constructor( fun rootPublicationComponentName(module: KotlinGradleModule) = module.disambiguateName("root") -internal val Project.kpmModules: NamedDomainObjectContainer - get() = when (val ext = project.topLevelExtensionOrNull) { - is KotlinPm20ProjectExtension -> ext.modules - is KotlinProjectExtension -> ext.kpmModules - else -> error("can't find Kotlin KPM modules in $project") - } +open class KotlinPm20ProjectExtension(project: Project) : + KotlinTopLevelExtension(project) { -open class KotlinPm20ProjectExtension(project: Project) : KotlinTopLevelExtension(project) { - val modules: NamedDomainObjectContainer = - project.objects.domainObjectContainer( - KotlinGradleModule::class.java, - KotlinGradleModuleFactory(project) - ) + internal val kpmModelContainer = DefaultKpmGradleProjectModelContainer.create(project) + + val modules: NamedDomainObjectContainer + get() = project.kpmModules @Suppress("unused") // DSL function fun mainAndTest(configure: KotlinGradleModule.() -> Unit) { @@ -148,11 +142,6 @@ open class KotlinPm20ProjectExtension(project: Project) : KotlinTopLevelExtensio fun main(configure: KotlinGradleModule.() -> Unit = { }) = main.apply(configure) fun test(configure: KotlinGradleModule.() -> Unit = { }) = test.apply(configure) - internal val metadataCompilationRegistryByModuleId: MutableMap = - mutableMapOf() - - internal var rootPublication: MavenPublication? = null - @PublishedApi @JvmName("isAllowCommonizer") internal fun isAllowCommonizerForIde(@Suppress("UNUSED_PARAMETER") project: Project): Boolean = false diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationData.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationData.kt index 4dfd17e94ec..42e1805a8e0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationData.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationData.kt @@ -31,12 +31,12 @@ interface KotlinVariantCompilationDataInternal : Kotlin get() { // FIXME support compiling against the artifact task outputs // TODO note for Android: see the friend artifacts code in KotlinAndroidCompilation - return owner.containingModule.project.pm20Extension.modules.flatMap { it.variants.map { it.compilationOutputs.classesDirs } } + return owner.containingModule.project.kpmModules.flatMap { it.variants.map { it.compilationOutputs.classesDirs } } } 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 + owner.containingModule.project.kpmModules .getByName(KotlinGradleModule.MAIN_MODULE_NAME).variants.findByName(owner.name)?.ownModuleName() ?: ownModuleName override val ownModuleName: String diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentHostSpecificMetadataArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentHostSpecificMetadataArtifact.kt index 8cf34c03686..93a0894bfbf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentHostSpecificMetadataArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentHostSpecificMetadataArtifact.kt @@ -25,7 +25,7 @@ val KotlinFragmentHostSpecificMetadataArtifact = FragmentArtifacts(fragment.disambiguateName("hostSpecificMetadataJar")) { jar -> jar.archiveClassifier.set("metadata") jar.archiveAppendix.set(fragment.disambiguateName("")) - project.pm20Extension.metadataCompilationRegistryByModuleId.getValue(fragment.containingModule.moduleIdentifier) + project.metadataCompilationRegistryByModuleId.getValue(fragment.containingModule.moduleIdentifier) .withAll { metadataCompilation -> val metadataFragment = metadataCompilation.fragment if (metadataCompilation is KotlinNativeFragmentMetadataCompilationData) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KpmProjectModelContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KpmProjectModelContainer.kt new file mode 100644 index 00000000000..3e3974b04e6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KpmProjectModelContainer.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2021 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.pm20 + +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.api.publish.maven.MavenPublication +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.jetbrains.kotlin.gradle.dsl.topLevelExtensionOrNull +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier + +internal interface KpmGradleProjectModelContainer { + val modules: NamedDomainObjectContainer + val metadataCompilationRegistryByModuleId: MutableMap + val rootPublication: MavenPublication? +} + +internal val Project.kpmModelContainer: KpmGradleProjectModelContainer + get() = kpmModelContainerOrNull ?: error("Couldn't find KPM container for $project") + +internal val Project.kpmModelContainerOrNull: KpmGradleProjectModelContainer? + get() = when (val ext = project.topLevelExtensionOrNull) { + is KotlinPm20ProjectExtension -> ext.kpmModelContainer + is KotlinProjectExtension -> if (PropertiesProvider(project).experimentalKpmModelMapping) ext.kpmModelContainer else null + else -> null + } + +internal val Project.hasKpmModel: Boolean + get() = kpmModelContainerOrNull != null + +internal val Project.kpmModules: NamedDomainObjectContainer + get() = kpmModelContainer.modules + +internal val Project.metadataCompilationRegistryByModuleId: MutableMap + get() = kpmModelContainer.metadataCompilationRegistryByModuleId + +internal class DefaultKpmGradleProjectModelContainer( + override val modules: NamedDomainObjectContainer, + override val metadataCompilationRegistryByModuleId: MutableMap, +) : KpmGradleProjectModelContainer { + override var rootPublication: MavenPublication? = null + + companion object { + fun create(project: Project): DefaultKpmGradleProjectModelContainer { + return DefaultKpmGradleProjectModelContainer(createKpmModulesContainer(project), mutableMapOf()) + } + + private fun createKpmModulesContainer(project: Project): NamedDomainObjectContainer = + project.objects.domainObjectContainer( + KotlinGradleModule::class.java, + KotlinGradleModuleFactory(project) + ) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt index 20029fe8f0e..f76989e8a8b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt @@ -34,7 +34,7 @@ internal fun configureMetadataResolutionAndBuild(module: KotlinGradleModule) { createResolvableMetadataConfigurationForModule(module) val metadataCompilationRegistry = MetadataCompilationRegistry() - project.pm20Extension.metadataCompilationRegistryByModuleId[module.moduleIdentifier] = + project.metadataCompilationRegistryByModuleId[module.moduleIdentifier] = metadataCompilationRegistry configureMetadataCompilationsAndCreateRegistry(module, metadataCompilationRegistry) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/FragmentMappedKotlinSourceSetFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/FragmentMappedKotlinSourceSetFactory.kt index 14b2aef350c..0c230d43046 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/FragmentMappedKotlinSourceSetFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/FragmentMappedKotlinSourceSetFactory.kt @@ -9,6 +9,7 @@ import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.kpmModules class FragmentMappedKotlinSourceSetFactory constructor(private val project: Project) : NamedDomainObjectFactory { @@ -17,7 +18,7 @@ class FragmentMappedKotlinSourceSetFactory constructor(private val project: Proj val locator = SourceSetMappedFragmentLocator.get(project) val location = locator.locateFragmentForSourceSet(project, name) ?: error("Couldn't map the source set name $name to KPM fragment") val (moduleName, fragmentName) = location - val modules = project.multiplatformExtension.kpmModules + val modules = project.kpmModules val fragment = modules.maybeCreate(moduleName).fragments.maybeCreate(fragmentName) /** TODO setup JS-specific attributes similar to [org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory]*/ return FragmentMappedKotlinSourceSet(project, fragment) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/SourceSetMappedFragmentLocator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/SourceSetMappedFragmentLocator.kt index 7bfb8a97949..c5836a3f1d5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/SourceSetMappedFragmentLocator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/kpm/SourceSetMappedFragmentLocator.kt @@ -9,6 +9,7 @@ import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.dsl.pm20Extension import org.jetbrains.kotlin.gradle.dsl.topLevelExtensionOrNull +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.kpmModules interface SourceSetMappedFragmentLocator { data class FragmentLocation(val moduleName: String, val fragmentName: String) { @@ -37,7 +38,7 @@ private class MultiplatformSourceSetMappedFragmentLocator : SourceSetMappedFragm } val candidateModuleNames = (1..camelCaseParts.size).asSequence().map { camelCaseParts.takeLast(it).joinToString("").decapitalize() } val moduleName = - candidateModuleNames.firstOrNull { project.kotlinExtension.kpmModules.findByName(it) != null } ?: candidateModuleNames.first() + candidateModuleNames.firstOrNull { project.kpmModules.findByName(it) != null } ?: candidateModuleNames.first() val fragmentName = sourceSetName.dropLast(moduleName.length) return SourceSetMappedFragmentLocator.FragmentLocation(moduleName, fragmentName)