diff --git a/.idea/dictionaries/sebastiansellmair.xml b/.idea/dictionaries/sebastiansellmair.xml index ef613c08528..805e5bf1e9e 100644 --- a/.idea/dictionaries/sebastiansellmair.xml +++ b/.idea/dictionaries/sebastiansellmair.xml @@ -2,6 +2,7 @@ cinterops + instantiator interops klibrary diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinDependencyConfigurations.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinDependencyConfigurations.kt new file mode 100644 index 00000000000..519e27663a0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinDependencyConfigurations.kt @@ -0,0 +1,49 @@ +/* + * 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.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration + +interface KotlinDependencyConfigurations { + val apiConfiguration: NamedDomainObjectProvider + val implementationConfiguration: NamedDomainObjectProvider + val compileOnlyConfiguration: NamedDomainObjectProvider + val runtimeOnlyConfiguration: NamedDomainObjectProvider + + /** This configuration includes the dependencies from the refines-parents */ + val transitiveApiConfiguration: NamedDomainObjectProvider + + /** This configuration includes the dependencies from the refines-parents */ + val transitiveImplementationConfiguration: NamedDomainObjectProvider + + private class Impl( + override val apiConfiguration: NamedDomainObjectProvider, + override val implementationConfiguration: NamedDomainObjectProvider, + override val compileOnlyConfiguration: NamedDomainObjectProvider, + override val runtimeOnlyConfiguration: NamedDomainObjectProvider, + override val transitiveApiConfiguration: NamedDomainObjectProvider, + override val transitiveImplementationConfiguration: NamedDomainObjectProvider + ) : KotlinDependencyConfigurations + + companion object { + fun create( + apiConfiguration: NamedDomainObjectProvider, + implementationConfiguration: NamedDomainObjectProvider, + compileOnlyConfiguration: NamedDomainObjectProvider, + runtimeOnlyConfiguration: NamedDomainObjectProvider, + transitiveApiConfiguration: NamedDomainObjectProvider, + transitiveImplementationConfiguration: NamedDomainObjectProvider + ): KotlinDependencyConfigurations = Impl( + apiConfiguration = apiConfiguration, + implementationConfiguration = implementationConfiguration, + compileOnlyConfiguration = compileOnlyConfiguration, + runtimeOnlyConfiguration = runtimeOnlyConfiguration, + transitiveApiConfiguration = transitiveApiConfiguration, + transitiveImplementationConfiguration = transitiveImplementationConfiguration + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt index 8da9b884bf1..5b95a9c1a3c 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder import org.jetbrains.kotlin.project.model.KotlinModuleFragment import org.jetbrains.kotlin.project.model.refinesClosure -interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, Named { +interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, KotlinDependencyConfigurations, Named { override val kotlinSourceRoots: SourceDirectorySet override val containingModule: KotlinGradleModule @@ -38,16 +38,22 @@ interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, Na const val COMMON_FRAGMENT_NAME = "common" } - /** This configuration includes the dependencies from the refines-parents */ - val transitiveApiConfigurationName: String + override val apiConfigurationName: String + get() = apiConfiguration.name - /** This configuration includes the dependencies from the refines-parents */ - val transitiveImplementationConfigurationName: String + override val implementationConfigurationName: String + get() = implementationConfiguration.name + + override val compileOnlyConfigurationName: String + get() = compileOnlyConfiguration.name + + override val runtimeOnlyConfigurationName: String + get() = runtimeOnlyConfiguration.name override val relatedConfigurationNames: List get() = super.relatedConfigurationNames + // TODO: resolvable metadata configurations? - listOf(transitiveApiConfigurationName, transitiveImplementationConfigurationName) + listOf(transitiveApiConfiguration.name, transitiveImplementationConfiguration.name) } val KotlinGradleFragment.refinesClosure: Set diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleVariant.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleVariant.kt index d22ba16c5e3..7508ada5d0e 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleVariant.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleVariant.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.FileCollection import org.gradle.api.publish.maven.MavenPublication -import org.gradle.api.tasks.TaskProvider -import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.project.model.KotlinModuleVariant @@ -18,7 +18,7 @@ interface KotlinGradleVariant : KotlinGradleFragment, KotlinModuleVariant { val platformType: KotlinPlatformType // TODO generalize with KotlinCompilation? - val compileDependencyConfigurationName: String + val compileDependenciesConfiguration: NamedDomainObjectProvider var compileDependencyFiles: FileCollection @@ -29,30 +29,28 @@ interface KotlinGradleVariant : KotlinGradleFragment, KotlinModuleVariant { val sourceArchiveTaskName: String // TODO generalize exposing outputs: what if a variant has more than one such configurations or none? - val apiElementsConfigurationName: String + val apiElementsConfiguration: NamedDomainObjectProvider val gradleVariantNames: Set } interface KotlinGradleVariantWithRuntime : KotlinGradleVariant { // TODO deduplicate with KotlinCompilation? - val runtimeDependencyConfigurationName: String + val runtimeDependenciesConfiguration: NamedDomainObjectProvider var runtimeDependencyFiles: FileCollection val runtimeFiles: ConfigurableFileCollection // TODO generalize exposing outputs: what if a variant has more than one such configurations or none? - val runtimeElementsConfigurationName: String + val runtimeElementsConfiguration: NamedDomainObjectProvider } interface KotlinNativeVariant : KotlinGradleVariant { override val platformType: KotlinPlatformType get() = KotlinPlatformType.native - /** A configuration name for the metadata of the host-specific fragments which this variant includes, - * if applies to this Native variant; null otherwise */ - val hostSpecificMetadataElementsConfigurationName: String? + val hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? var enableEndorsedLibraries: Boolean } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt index 9c96ae69d3d..e528be19dc0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt @@ -48,7 +48,7 @@ internal fun customizeKotlinDependencies(project: Project) { } private fun configureDefaultVersionsResolutionStrategy(project: Project) { - project.configurations.all { configuration -> + project.configurations.configureEach { configuration -> // Use the API introduced in Gradle 4.4 to modify the dependencies directly before they are resolved: configuration.withDependencies { dependencySet -> val coreLibrariesVersion = project.topLevelExtension.coreLibrariesVersion 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 644078de336..249b6962e58 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 @@ -334,7 +334,7 @@ class GradleModuleVariantResolver : ModuleVariantResolver { project.configurations.getByName(compilation.compileDependencyConfigurationName) } is KotlinPm20ProjectExtension -> { - (requestingVariant as KotlinGradleVariant).compileDependencyConfiguration + (requestingVariant as KotlinGradleVariant).compileDependenciesConfiguration.get() } else -> error("could not find the compile dependencies configuration for variant $requestingVariant") } @@ -347,4 +347,4 @@ class GradleModuleVariantResolver : ModuleVariantResolver { } } } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/FragmentGranularMetadataResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/FragmentGranularMetadataResolver.kt index 28116d7a2fa..401689924ab 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/FragmentGranularMetadataResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/FragmentGranularMetadataResolver.kt @@ -161,7 +161,7 @@ internal class FragmentGranularMetadataResolver( // resolve the dependencies of that variant getting the host-specific metadata artifact relevantVariantResolution?.let { resolution -> val configurationResolvingPlatformVariant = - (resolution.requestingVariant as KotlinGradleVariant).compileDependencyConfiguration + (resolution.requestingVariant as KotlinGradleVariant).compileDependenciesConfiguration.get() val hostSpecificArtifact = ResolvedMppVariantsProvider.get(project) .getHostSpecificMetadataArtifactByRootModule( dependencyModule.moduleIdentifier, 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 d2cecaf14b2..e9fe2de1e6d 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 @@ -5,7 +5,10 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 -import org.gradle.api.* +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.Plugin +import org.gradle.api.Project import org.gradle.api.component.SoftwareComponentFactory import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.publish.PublishingExtension @@ -17,7 +20,6 @@ import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier import javax.inject.Inject -import kotlin.reflect.KClass abstract class KotlinPm20GradlePlugin @Inject constructor( @Inject private val softwareComponentFactory: SoftwareComponentFactory @@ -42,22 +44,20 @@ abstract class KotlinPm20GradlePlugin @Inject constructor( KotlinJvmVariantFactory(module) ) - fun registerNativeVariantFactory(variantClass: KClass) { - module.fragments.registerFactory( - variantClass.java, - KotlinNativeVariantFactory(module, variantClass) - ) - } + fun registerNativeVariantFactory( + constructor: KotlinNativeVariantConstructor + ) = module.fragments.registerFactory( + constructor.variantClass, KotlinNativeVariantFactory(KotlinNativeVariantInstantiator(module, constructor)) + ) + listOf( // FIXME codegen, add missing native targets - KotlinLinuxX64Variant::class, - KotlinMacosX64Variant::class, - KotlinMacosArm64Variant::class, - KotlinIosX64Variant::class, - KotlinIosArm64Variant::class - ).forEach { variantClass -> - registerNativeVariantFactory(variantClass) - } + KotlinLinuxX64Variant.constructor, + KotlinMacosX64Variant.constructor, + KotlinMacosArm64Variant.constructor, + KotlinIosX64Variant.constructor, + KotlinIosArm64Variant.constructor + ).forEach { constructor -> registerNativeVariantFactory(constructor) } } } @@ -198,4 +198,4 @@ open class KotlinFragmentSlice( fun inModule(module: KotlinGradleModule, configure: T.() -> Unit) { getOrCreateFragment(module).configure() } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCommonFragmentFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCommonFragmentFactory.kt new file mode 100644 index 00000000000..ab4eaf36ef1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCommonFragmentFactory.kt @@ -0,0 +1,43 @@ +/* + * 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 + +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation + +typealias KotlinCommonFragmentFactory = KotlinGradleFragmentFactory + +fun KotlinCommonFragmentFactory(module: KotlinGradleModule): KotlinCommonFragmentFactory = + KotlinCommonFragmentFactory(KotlinCommonFragmentInstantiator(module)) + +fun KotlinCommonFragmentFactory( + commonFragmentInstantiator: KotlinCommonFragmentInstantiator, + commonFragmentConfigurator: KotlinCommonFragmentConfigurator = KotlinCommonFragmentConfigurator() +): KotlinGradleFragmentFactory = KotlinGradleFragmentFactory( + fragmentInstantiator = commonFragmentInstantiator, + fragmentConfigurator = commonFragmentConfigurator +) + +class KotlinCommonFragmentInstantiator( + private val module: KotlinGradleModule, + private val dependencyConfigurationsFactory: KotlinDependencyConfigurationsFactory = + DefaultKotlinDependencyConfigurationsFactory +) : KotlinGradleFragmentFactory.FragmentInstantiator { + override fun create(name: String): KotlinGradleFragmentInternal { + val names = FragmentNameDisambiguation(module, name) + return KotlinGradleFragmentInternal(module, name, dependencyConfigurationsFactory.create(module, names)) + } +} + +class KotlinCommonFragmentConfigurator( + private val sourceDirectoriesSetup: KotlinSourceDirectoriesConfigurator = + DefaultKotlinSourceDirectoriesConfigurator +) : KotlinGradleFragmentFactory.FragmentConfigurator { + override fun configure(fragment: KotlinGradleFragmentInternal) { + sourceDirectoriesSetup.configure(fragment) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationConfigurator.kt new file mode 100644 index 00000000000..13fadfa444d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationConfigurator.kt @@ -0,0 +1,49 @@ +/* + * 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.artifacts.Configuration +import org.gradle.api.tasks.TaskProvider +import org.gradle.jvm.tasks.Jar +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName +import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask +import org.jetbrains.kotlin.gradle.utils.dashSeparatedName + +interface KotlinCompileTaskConfigurator { + fun registerCompileTasks(variant: T): TaskProvider<*> +} + +object KotlinJvmCompileTaskConfigurator : KotlinCompileTaskConfigurator { + override fun registerCompileTasks(variant: KotlinJvmVariant): TaskProvider<*> { + val compilationData = variant.compilationData + LifecycleTasksManager(variant.project).registerClassesTask(compilationData) + return KotlinCompilationTaskConfigurator(variant.project).createKotlinJvmCompilationTask(variant, compilationData) + } +} + +object KotlinNativeCompileTaskConfigurator : KotlinCompileTaskConfigurator { + override fun registerCompileTasks(variant: KotlinNativeVariantInternal): TaskProvider<*> { + val compilationData = variant.compilationData + LifecycleTasksManager(variant.project).registerClassesTask(compilationData) + return KotlinCompilationTaskConfigurator(variant.project).createKotlinNativeCompilationTask(variant, compilationData) + } +} + +// TODO NOW: Find place +object KotlinFragmentJarArtifactElementsConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + val project = fragment.project + val module = fragment.containingModule + val jarTaskName = fragment.disambiguateName("jar") + val jarTask = project.locateOrRegisterTask(jarTaskName) { + it.from(fragment.compilationOutputs.allOutputs) + it.archiveClassifier.set(dashSeparatedName(fragment.name, module.moduleClassifier)) + } + project.artifacts.add(configuration.name, jarTask) + } +} + + 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 9af21f02813..4dfd17e94ec 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 @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.pm20Extension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.isMain +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.project.model.refinesClosure @@ -45,4 +46,4 @@ interface KotlinVariantCompilationDataInternal : Kotlin fun KotlinCompilationData<*>.isMainCompilationData(): Boolean = when (this) { is KotlinCompilation<*> -> isMain() else -> compilationPurpose == KotlinGradleModule.MAIN_MODULE_NAME -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinDependencyConfigurationsFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinDependencyConfigurationsFactory.kt new file mode 100644 index 00000000000..634f5de293c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinDependencyConfigurationsFactory.kt @@ -0,0 +1,54 @@ +/* + * 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.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister +import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation +import org.jetbrains.kotlin.gradle.utils.extendsFrom + +interface KotlinDependencyConfigurationsFactory { + fun create(module: KotlinGradleModule, names: FragmentNameDisambiguation): KotlinDependencyConfigurations +} + +object DefaultKotlinDependencyConfigurationsFactory : KotlinDependencyConfigurationsFactory { + + override fun create(module: KotlinGradleModule, names: FragmentNameDisambiguation): KotlinDependencyConfigurations { + val configurations = module.project.configurations + val apiConfiguration = configurations.locateOrRegister(names.disambiguateName("api")) + val implementationConfiguration = configurations.locateOrRegister(names.disambiguateName("implementation")) + val compileOnlyConfiguration = configurations.locateOrRegister(names.disambiguateName("compileOnly")) + val runtimeOnlyConfiguration = configurations.locateOrRegister(names.disambiguateName("runtimeOnly")) + val transitiveApiConfiguration = configurations.locateOrRegister(names.disambiguateName("transitiveApi")) + val transitiveImplementationConfiguration = configurations.locateOrRegister(names.disambiguateName("transitiveImplementation")) + + listOf( + apiConfiguration, + implementationConfiguration, + compileOnlyConfiguration, + runtimeOnlyConfiguration, + transitiveApiConfiguration, + transitiveImplementationConfiguration + ).forEach { configurationProvider -> + configurationProvider.configure { configuration -> + configuration.isCanBeConsumed = false + configuration.isCanBeResolved = false + } + } + + transitiveApiConfiguration.extendsFrom(apiConfiguration) + transitiveImplementationConfiguration.extendsFrom(implementationConfiguration) + + return KotlinDependencyConfigurations.create( + apiConfiguration = apiConfiguration, + implementationConfiguration = implementationConfiguration, + compileOnlyConfiguration = compileOnlyConfiguration, + runtimeOnlyConfiguration = runtimeOnlyConfiguration, + transitiveApiConfiguration = transitiveApiConfiguration, + transitiveImplementationConfiguration = transitiveImplementationConfiguration + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentConfigurationInstantiator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentConfigurationInstantiator.kt new file mode 100644 index 00000000000..919175c31a0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentConfigurationInstantiator.kt @@ -0,0 +1,18 @@ +/* + * 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.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation + +interface KotlinFragmentConfigurationInstantiator { + fun locateOrRegister( + module: KotlinGradleModule, + names: FragmentNameDisambiguation, + dependencies: KotlinDependencyConfigurations + ): NamedDomainObjectProvider +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentConfigurationsConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentConfigurationsConfigurator.kt new file mode 100644 index 00000000000..5c113db898a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentConfigurationsConfigurator.kt @@ -0,0 +1,110 @@ +/* + * 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.consumerApiUsage +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.consumerRuntimeUsage +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.producerApiUsage +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.producerRuntimeUsage +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability +import org.jetbrains.kotlin.gradle.plugin.usageByName + +fun interface KotlinFragmentConfigurationsConfigurator { + fun configure(fragment: T, configuration: Configuration) +} + +object KotlinFragmentPlatformAttributesConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType) + } +} + +object KotlinFragmentConsumerApiUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + configuration.attributes.attribute(USAGE_ATTRIBUTE, consumerApiUsage(fragment.project, fragment.platformType)) + } +} + +object KotlinFragmentProducerApiUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + configuration.attributes.attribute(USAGE_ATTRIBUTE, producerApiUsage(fragment.project, fragment.platformType)) + } +} + +object KotlinFragmentConsumerRuntimeUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + configuration.attributes.attribute(USAGE_ATTRIBUTE, consumerRuntimeUsage(fragment.project, fragment.platformType)) + } +} + +object KotlinFragmentProducerRuntimeUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + configuration.attributes.attribute(USAGE_ATTRIBUTE, producerRuntimeUsage(fragment.project, fragment.platformType)) + } +} + +object KotlinFragmentMetadataUsageAttributeConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + configuration.attributes.attribute(USAGE_ATTRIBUTE, fragment.project.usageByName(KotlinUsages.KOTLIN_METADATA)) + } +} + +object KonanTargetAttributesConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinNativeVariantInternal, configuration: Configuration) { + configuration.attributes.attribute(KotlinNativeTarget.konanTargetAttribute, fragment.konanTarget.name) + } +} + +object KotlinFragmentModuleCapabilityConfigurator : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) { + setModuleCapability(configuration, fragment.containingModule) + } + + internal fun setModuleCapability(configuration: Configuration, module: KotlinGradleModule) { + if (module.moduleClassifier != null) { + configuration.outgoing.capability(ComputedCapability.fromModule(module)) + } + } +} + +operator fun KotlinFragmentConfigurationsConfigurator.plus( + other: KotlinFragmentConfigurationsConfigurator +): KotlinFragmentConfigurationsConfigurator { + if (this is CompositeKotlinFragmentConfigurationsConfigurator && other is CompositeKotlinFragmentConfigurationsConfigurator) { + return CompositeKotlinFragmentConfigurationsConfigurator(this.setups + other.setups) + } + + if (this is CompositeKotlinFragmentConfigurationsConfigurator) { + return CompositeKotlinFragmentConfigurationsConfigurator(this.setups + other) + } + + if (other is CompositeKotlinFragmentConfigurationsConfigurator) { + return CompositeKotlinFragmentConfigurationsConfigurator(listOf(this) + other.setups) + } + + return CompositeKotlinFragmentConfigurationsConfigurator(listOf(this, other)) +} + +fun KotlinConfigurationsConfigurator( + vararg configurators: KotlinFragmentConfigurationsConfigurator +): KotlinFragmentConfigurationsConfigurator { + return CompositeKotlinFragmentConfigurationsConfigurator(configurators.toList()) +} + +private class CompositeKotlinFragmentConfigurationsConfigurator( + val setups: List> +) : KotlinFragmentConfigurationsConfigurator { + override fun configure(fragment: T, configuration: Configuration) { + setups.forEach { setup -> setup.configure(fragment, configuration) } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt index 6265bda8302..7cde9c1d778 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.sources.FragmentConsistencyChecker import org.jetbrains.kotlin.gradle.plugin.sources.FragmentConsistencyChecks import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated import org.jetbrains.kotlin.project.model.KotlinModuleDependency import org.jetbrains.kotlin.project.model.KotlinModuleFragment @@ -27,11 +26,12 @@ import org.jetbrains.kotlin.project.model.refinesClosure import javax.inject.Inject open class KotlinGradleFragmentInternal @Inject constructor( - override val containingModule: KotlinGradleModule, - override val fragmentName: String -) : KotlinGradleFragment { + final override val containingModule: KotlinGradleModule, + final override val fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations +) : KotlinGradleFragment, KotlinDependencyConfigurations by dependencyConfigurations { - override fun getName(): String = fragmentName + final override fun getName(): String = fragmentName final override val project: Project // overriding with final to avoid warnings get() = super.project @@ -49,12 +49,14 @@ open class KotlinGradleFragmentInternal @Inject constructor( override fun refines(other: NamedDomainObjectProvider) { _directRefinesDependencies.add(other) other.configure { checkCanRefine(it) } - listOf( - KotlinGradleFragment::transitiveApiConfigurationName, - KotlinGradleFragment::transitiveImplementationConfigurationName - ).forEach { getConfiguration -> - project.addExtendsFromRelation(getConfiguration(this), getConfiguration(other.get())) // todo eager instantiation; fix? - } + + project.addExtendsFromRelation( + this.transitiveApiConfiguration.name, other.get().transitiveApiConfiguration.name + ) + + project.addExtendsFromRelation( + this.transitiveImplementationConfiguration.name, other.get().transitiveImplementationConfiguration.name + ) project.runProjectConfigurationHealthCheckWhenEvaluated { kotlinGradleFragmentConsistencyChecker.runAllChecks(this@KotlinGradleFragmentInternal, other.get()) @@ -71,6 +73,7 @@ open class KotlinGradleFragmentInternal @Inject constructor( override fun dependencies(configureClosure: Closure) = dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) } + /* override val apiConfigurationName: String get() = disambiguateName("api") @@ -83,6 +86,8 @@ open class KotlinGradleFragmentInternal @Inject constructor( override val runtimeOnlyConfigurationName: String get() = disambiguateName("runtimeOnly") + */ + private val _directRefinesDependencies = mutableSetOf>() override val directRefinesDependencies: Iterable @@ -96,18 +101,9 @@ open class KotlinGradleFragmentInternal @Inject constructor( "$fragmentName.kotlin", "Kotlin sources for fragment $fragmentName" ) - override val transitiveApiConfigurationName: String - get() = disambiguateName("transitiveApi") - - override val transitiveImplementationConfigurationName: String - get() = disambiguateName("transitiveImplementation") - override fun toString(): String = "fragment $fragmentName in $containingModule" } -internal fun KotlinModuleFragment.disambiguateName(simpleName: String) = - lowerCamelCaseName(fragmentName, containingModule.moduleIdentifier.moduleClassifier ?: KotlinGradleModule.MAIN_MODULE_NAME, simpleName) - val KotlinGradleFragment.refinesClosure: Set get() = (this as KotlinModuleFragment).refinesClosure.map { it as KotlinGradleFragment }.toSet() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragmentFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragmentFactory.kt new file mode 100644 index 00000000000..361f3c3d594 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragmentFactory.kt @@ -0,0 +1,26 @@ +/* + * 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.NamedDomainObjectFactory + +class KotlinGradleFragmentFactory( + private val fragmentInstantiator: FragmentInstantiator, + private val fragmentConfigurator: FragmentConfigurator +) : NamedDomainObjectFactory { + + interface FragmentInstantiator { + fun create(name: String): T + } + + interface FragmentConfigurator { + fun configure(fragment: T) + } + + override fun create(name: String): T { + return fragmentInstantiator.create(name).apply(fragmentConfigurator::configure) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModuleFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModuleFactory.kt index 21e377bb08f..04a078820bf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModuleFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModuleFactory.kt @@ -42,6 +42,6 @@ open class KotlinGradleModuleFactory(private val project: Project) : NamedDomain } protected open fun registerFragmentFactory(module: KotlinGradleModule) { - module.fragments.registerFactory(KotlinGradleFragment::class.java, CommonGradleFragmentFactory(module)) + module.fragments.registerFactory(KotlinGradleFragment::class.java, KotlinCommonFragmentFactory(module)) } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinHostSpecificMetadataArtifactConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinHostSpecificMetadataArtifactConfigurator.kt new file mode 100644 index 00000000000..acc729a3ca8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinHostSpecificMetadataArtifactConfigurator.kt @@ -0,0 +1,46 @@ +/* + * 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.artifacts.Dependency +import org.gradle.jvm.tasks.Jar +import org.jetbrains.kotlin.gradle.dsl.pm20Extension +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName +import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives +import org.jetbrains.kotlin.gradle.tasks.registerTask +import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION +import org.jetbrains.kotlin.project.model.refinesClosure + +object KotlinHostSpecificMetadataArtifactConfigurator : + KotlinGradleFragmentFactory.FragmentConfigurator { + override fun configure(fragment: KotlinNativeVariantInternal) { + val project = fragment.project + val hostSpecificMetadataElements = fragment.hostSpecificMetadataElementsConfiguration ?: return + + val hostSpecificMetadataJar = project.registerTask(fragment.disambiguateName("hostSpecificMetadataJar")) { jar -> + jar.archiveClassifier.set("metadata") + jar.archiveAppendix.set(fragment.disambiguateName("")) + project.pm20Extension.metadataCompilationRegistryByModuleId.getValue(fragment.containingModule.moduleIdentifier) + .withAll { metadataCompilation -> + val metadataFragment = metadataCompilation.fragment + if (metadataCompilation is KotlinNativeFragmentMetadataCompilationData) { + jar.from(project.files(project.provider { + if (metadataFragment in fragment.refinesClosure && metadataFragment.isNativeHostSpecific()) + project.filesWithUnpackedArchives(metadataCompilation.output.allOutputs, setOf(KLIB_FILE_EXTENSION)) + else emptyList() + })) { spec -> spec.into(metadataFragment.name) } + } + } + } + + hostSpecificMetadataElements.configure { configuration -> + project.artifacts.add(configuration.name, hostSpecificMetadataJar) + configuration.dependencies.addAllLater(project.objects.listProperty(Dependency::class.java).apply { + set(project.provider { fragment.apiElementsConfiguration.get().allDependencies }) + }) + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt index 1d156e298c4..0cf2b780862 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt @@ -5,14 +5,31 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration import org.gradle.api.plugins.BasePluginConvention import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl -import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName -open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) : - KotlinGradlePublishedVariantWithRuntime(containingModule, fragmentName) { +open class KotlinJvmVariant( + containingModule: KotlinGradleModule, + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependenciesConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + runtimeDependenciesConfiguration: NamedDomainObjectProvider, + runtimeElementsConfiguration: NamedDomainObjectProvider +) : KotlinGradlePublishedVariantWithRuntime( + containingModule = containingModule, + fragmentName = fragmentName, + dependencyConfigurations = dependencyConfigurations, + compileDependencyConfiguration = compileDependenciesConfiguration, + apiElementsConfiguration = apiElementsConfiguration, + runtimeDependencyConfiguration = runtimeDependenciesConfiguration, + runtimeElementsConfiguration = runtimeElementsConfiguration +) { override val compilationData: KotlinJvmVariantCompilationData by lazy { KotlinJvmVariantCompilationData(this) } override val platformType: KotlinPlatformType diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariantFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariantFactory.kt index 8b96bdb7a14..74b313ef827 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariantFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariantFactory.kt @@ -3,44 +3,109 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +@file:Suppress("FunctionName") + package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 -import org.gradle.api.tasks.TaskProvider -import org.gradle.jvm.tasks.Jar -import org.gradle.language.base.plugins.LifecycleBasePlugin -import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor -import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion -import org.jetbrains.kotlin.gradle.plugin.mpp.addCommonSourcesToKotlinCompileTask -import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask -import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask -import org.jetbrains.kotlin.gradle.utils.dashSeparatedName +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.configuration.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation -open class KotlinJvmVariantFactory(module: KotlinGradleModule) : - AbstractKotlinGradleRuntimePublishedVariantFactory(module) { - override fun instantiateFragment(name: String) = KotlinJvmVariant(module, name) +typealias KotlinJvmVariantFactory = KotlinGradleFragmentFactory - // FIXME expose the JAR with the artifacts API - private fun getOrCreateJarTask(fragment: KotlinJvmVariant): TaskProvider { - val jarTaskName = fragment.disambiguateName("jar") - return project.locateOrRegisterTask(jarTaskName) { - it.from(fragment.compilationOutputs.allOutputs) - it.archiveClassifier.set(dashSeparatedName(fragment.name, module.moduleClassifier)) - } - } +fun KotlinJvmVariantFactory(module: KotlinGradleModule): KotlinJvmVariantFactory = + KotlinJvmVariantFactory(KotlinJvmVariantInstantiator(module)) - override fun createElementsConfigurations(fragment: KotlinJvmVariant) { - super.createElementsConfigurations(fragment) - listOf(fragment.apiElementsConfigurationName, fragment.runtimeElementsConfigurationName).forEach { - project.artifacts.add(it, getOrCreateJarTask(fragment)) - } - } +fun KotlinJvmVariantFactory( + jvmVariantInstantiator: KotlinJvmVariantInstantiator, + jvmVariantConfigurator: KotlinJvmVariantConfigurator = KotlinJvmVariantConfigurator() +): KotlinJvmVariantFactory = KotlinGradleFragmentFactory( + fragmentInstantiator = jvmVariantInstantiator, + fragmentConfigurator = jvmVariantConfigurator +) - override fun configureKotlinCompilation(fragment: KotlinJvmVariant) { - val compilationData = fragment.compilationData - LifecycleTasksManager(project).registerClassesTask(compilationData) - KotlinCompilationTaskConfigurator(project).createKotlinJvmCompilationTask(fragment, compilationData) +class KotlinJvmVariantInstantiator( + private val module: KotlinGradleModule, + + private val dependenciesConfigurationFactory: KotlinDependencyConfigurationsFactory = + DefaultKotlinDependencyConfigurationsFactory, + + private val compileDependenciesConfigurationInstantiator: KotlinCompileDependenciesConfigurationInstantiator = + DefaultKotlinCompileDependenciesConfigurationInstantiator, + + private val apiElementsConfigurationInstantiator: KotlinApiElementsConfigurationInstantiator = + DefaultKotlinApiElementsConfigurationInstantiator, + + private val runtimeDependenciesConfigurationInstantiator: KotlinRuntimeDependenciesConfigurationInstantiator = + DefaultKotlinRuntimeDependenciesConfigurationInstantiator, + + private val runtimeElementsConfigurationInstantiator: KotlinRuntimeElementsConfigurationFactory = + DefaultKotlinRuntimeElementsConfigurationInstantiator, + + ) : KotlinGradleFragmentFactory.FragmentInstantiator { + + override fun create(name: String): KotlinJvmVariant { + val names = FragmentNameDisambiguation(module, name) + val dependencies = dependenciesConfigurationFactory.create(module, names) + return KotlinJvmVariant( + containingModule = module, + fragmentName = name, + dependencyConfigurations = dependencies, + compileDependenciesConfiguration = compileDependenciesConfigurationInstantiator.locateOrRegister(module, names, dependencies), + apiElementsConfiguration = apiElementsConfigurationInstantiator.locateOrRegister(module, names, dependencies), + runtimeDependenciesConfiguration = runtimeDependenciesConfigurationInstantiator.locateOrRegister(module, names, dependencies), + runtimeElementsConfiguration = runtimeElementsConfigurationInstantiator.locateOrRegister(module, names, dependencies) + ) } } -//endregion Variant \ No newline at end of file +class KotlinJvmVariantConfigurator( + private val compileTaskConfigurator: KotlinCompileTaskConfigurator = + KotlinJvmCompileTaskConfigurator, + + private val sourceArchiveTaskConfigurator: KotlinSourceArchiveTaskConfigurator = + DefaultKotlinSourceArchiveTaskConfigurator, + + private val sourceDirectoriesConfigurator: KotlinSourceDirectoriesConfigurator = + DefaultKotlinSourceDirectoriesConfigurator, + + private val compileDependenciesConfigurator: KotlinFragmentConfigurationsConfigurator = + DefaultKotlinCompileDependenciesConfigurator, + + private val runtimeDependenciesConfigurator: KotlinFragmentConfigurationsConfigurator = + DefaultKotlinRuntimeDependenciesConfigurator, + + private val apiElementsConfigurator: KotlinFragmentConfigurationsConfigurator = + DefaultKotlinApiElementsConfigurator, + + private val runtimeElementsConfigurator: KotlinFragmentConfigurationsConfigurator = + DefaultKotlinRuntimeElementsConfigurator, + + private val publicationConfigurator: KotlinPublicationConfigurator = + KotlinPublicationConfigurator.SingleVariantPublication + +) : KotlinGradleFragmentFactory.FragmentConfigurator { + + override fun configure(fragment: KotlinJvmVariant) { + fragment.compileDependenciesConfiguration.configure { configuration -> + compileDependenciesConfigurator.configure(fragment, configuration) + } + + fragment.runtimeDependenciesConfiguration.configure { configuration -> + runtimeDependenciesConfigurator.configure(fragment, configuration) + } + + fragment.apiElementsConfiguration.configure { configuration -> + apiElementsConfigurator.configure(fragment, configuration) + } + + fragment.runtimeElementsConfiguration.configure { configuration -> + runtimeElementsConfigurator.configure(fragment, configuration) + } + + sourceDirectoriesConfigurator.configure(fragment) + + compileTaskConfigurator.registerCompileTasks(fragment) + sourceArchiveTaskConfigurator.registerSourceArchiveTask(fragment) + publicationConfigurator.configure(fragment) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt index 8e42c5a8966..cb106165945 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl import org.jetbrains.kotlin.gradle.dsl.pm20Extension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider import org.jetbrains.kotlin.gradle.targets.metadata.createMetadataDependencyTransformationClasspath import org.jetbrains.kotlin.gradle.utils.getValue diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt index c74e49d9828..94614d1edb3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt @@ -5,12 +5,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 -import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.NamedDomainObjectProvider import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings import org.jetbrains.kotlin.gradle.plugin.mpp.NativeCompileOptions -import org.jetbrains.kotlin.gradle.plugin.mpp.isHostSpecificKonanTargetsSet import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName import org.jetbrains.kotlin.konan.target.KonanTarget import javax.inject.Inject @@ -18,18 +18,25 @@ import javax.inject.Inject abstract class KotlinNativeVariantInternal( containingModule: KotlinGradleModule, fragmentName: String, - val konanTarget: KonanTarget + val konanTarget: KonanTarget, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + final override val hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? ) : KotlinNativeVariant, - KotlinGradleVariantInternal(containingModule, fragmentName), + KotlinGradleVariantInternal( + containingModule = containingModule, + fragmentName = fragmentName, + dependencyConfigurations = dependencyConfigurations, + compileDependenciesConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration + ), SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder(containingModule, fragmentName) { - final override val hostSpecificMetadataElementsConfigurationName: String? - get() = disambiguateName("hostSpecificMetadataElements").takeIf { includesHostSpecificMetadata } - override var enableEndorsedLibraries: Boolean = false override val gradleVariantNames: Set - get() = listOf(apiElementsConfigurationName).flatMap { listOf(it, publishedConfigurationName(it)) }.toSet() + get() = listOf(apiElementsConfiguration.name).flatMap { listOf(it, publishedConfigurationName(it)) }.toSet() val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> DefaultCInteropSettings(project, cinteropName, compilationData) @@ -38,24 +45,149 @@ abstract class KotlinNativeVariantInternal( override val compilationData by lazy { KotlinNativeVariantCompilationData(this) } } -internal val KotlinNativeVariantInternal.includesHostSpecificMetadata: Boolean - get() = isHostSpecificKonanTargetsSet(setOf(konanTarget)) +class KotlinNativeVariantConstructor( + val konanTarget: KonanTarget, + val variantClass: Class, + private val constructor: ( + containingModule: KotlinGradleModule, + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? + ) -> T +) { + operator fun invoke( + containingModule: KotlinGradleModule, + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? + ): T = constructor( + containingModule, fragmentName, + dependencyConfigurations, + compileDependencyConfiguration, + apiElementsConfiguration, + hostSpecificMetadataElementsConfiguration + ) +} // FIXME codegen -open class KotlinLinuxX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) : - KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.LINUX_X64) +open class KotlinLinuxX64Variant @Inject constructor( + containingModule: KotlinGradleModule, + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? +) : KotlinNativeVariantInternal( + containingModule = containingModule, + fragmentName = fragmentName, + konanTarget = KonanTarget.LINUX_X64, + dependencyConfigurations = dependencyConfigurations, + compileDependencyConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration, + hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration +) { + companion object { + val constructor = KotlinNativeVariantConstructor( + KonanTarget.LINUX_X64, KotlinLinuxX64Variant::class.java, ::KotlinLinuxX64Variant + ) + } +} -open class KotlinMacosX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) : - KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.MACOS_X64) +open class KotlinMacosX64Variant @Inject constructor( + containingModule: KotlinGradleModule, + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? +) : KotlinNativeVariantInternal( + containingModule = containingModule, + fragmentName = fragmentName, + konanTarget = KonanTarget.MACOS_X64, + dependencyConfigurations = dependencyConfigurations, + compileDependencyConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration, + hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration +) { + companion object { + val constructor = KotlinNativeVariantConstructor( + KonanTarget.MACOS_X64, KotlinMacosX64Variant::class.java, ::KotlinMacosX64Variant + ) + } +} -open class KotlinMacosArm64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) : - KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.MACOS_ARM64) +open class KotlinMacosArm64Variant @Inject constructor( + containingModule: KotlinGradleModule, fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? +) : KotlinNativeVariantInternal( + containingModule = containingModule, + fragmentName = fragmentName, + konanTarget = KonanTarget.MACOS_ARM64, + dependencyConfigurations = dependencyConfigurations, + compileDependencyConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration, + hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration +) { + companion object { + val constructor = KotlinNativeVariantConstructor( + KonanTarget.MACOS_ARM64, KotlinMacosArm64Variant::class.java, ::KotlinMacosArm64Variant + ) + } +} -open class KotlinIosX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) : - KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.IOS_X64) +open class KotlinIosX64Variant @Inject constructor( + containingModule: KotlinGradleModule, + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? +) : KotlinNativeVariantInternal( + containingModule = containingModule, + fragmentName = fragmentName, + konanTarget = KonanTarget.IOS_X64, + dependencyConfigurations = dependencyConfigurations, + compileDependencyConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration, + hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration +) { + companion object { + val constructor = KotlinNativeVariantConstructor( + KonanTarget.IOS_X64, KotlinIosX64Variant::class.java, ::KotlinIosX64Variant + ) + } +} + +open class KotlinIosArm64Variant @Inject constructor( + containingModule: KotlinGradleModule, + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider? +) : KotlinNativeVariantInternal( + containingModule = containingModule, + fragmentName = fragmentName, + konanTarget = KonanTarget.IOS_ARM64, + dependencyConfigurations = dependencyConfigurations, + compileDependencyConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration, + hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration +) { + companion object { + val constructor = KotlinNativeVariantConstructor( + KonanTarget.IOS_ARM64, KotlinIosArm64Variant::class.java, ::KotlinIosArm64Variant + ) + } +} -open class KotlinIosArm64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) : - KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.IOS_ARM64) interface KotlinNativeCompilationData : KotlinCompilationData { val konanTarget: KonanTarget diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt index 88d89205be9..d31125d015a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt @@ -3,87 +3,98 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +@file:Suppress("FunctionName") + package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 -import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.Dependency -import org.gradle.api.attributes.Usage -import org.gradle.jvm.tasks.Jar -import org.jetbrains.kotlin.gradle.dsl.pm20Extension -import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator -import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages -import org.jetbrains.kotlin.gradle.plugin.usageByName -import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives -import org.jetbrains.kotlin.gradle.tasks.registerTask -import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION -import org.jetbrains.kotlin.project.model.refinesClosure -import kotlin.reflect.KClass +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.configuration.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation -open class KotlinNativeVariantFactory( - module: KotlinGradleModule, - val variantClass: KClass -) : - AbstractKotlinGradleVariantFactory(module) { +fun KotlinNativeVariantFactory( + nativeVariantInstantiator: KotlinNativeVariantInstantiator, + nativeVariantConfigurator: KotlinNativeVariantConfigurator = KotlinNativeVariantConfigurator() +) = KotlinGradleFragmentFactory( + fragmentInstantiator = nativeVariantInstantiator, + fragmentConfigurator = nativeVariantConfigurator +) - override fun instantiateFragment(name: String): T = - module.project.objects.newInstance(variantClass.java, module, name) +class KotlinNativeVariantInstantiator( + private val module: KotlinGradleModule, - override fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) { - super.setPlatformAttributesInConfiguration(fragment, configuration) - configuration.attributes.attribute(KotlinNativeTarget.konanTargetAttribute, fragment.konanTarget.name) + private val kotlinNativeVariantConstructor: KotlinNativeVariantConstructor, + + private val dependenciesConfigurationFactory: KotlinDependencyConfigurationsFactory = + DefaultKotlinDependencyConfigurationsFactory, + + private val compileDependenciesConfigurationInstantiator: KotlinCompileDependenciesConfigurationInstantiator = + DefaultKotlinCompileDependenciesConfigurationInstantiator, + + private val apiElementsConfigurationInstantiator: KotlinApiElementsConfigurationInstantiator = + DefaultKotlinApiElementsConfigurationInstantiator, + + private val hostSpecificMetadataElementsConfigurationInstantiator: KotlinHostSpecificMetadataElementsConfigurationInstantiator? = + DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator(kotlinNativeVariantConstructor.konanTarget) + +) : KotlinGradleFragmentFactory.FragmentInstantiator { + + override fun create(name: String): T { + val names = FragmentNameDisambiguation(module, name) + val dependencies = dependenciesConfigurationFactory.create(module, names) + return kotlinNativeVariantConstructor.invoke( + containingModule = module, + fragmentName = name, + dependencyConfigurations = dependencies, + compileDependencyConfiguration = compileDependenciesConfigurationInstantiator.locateOrRegister(module, names, dependencies), + apiElementsConfiguration = apiElementsConfigurationInstantiator.locateOrRegister(module, names, dependencies), + hostSpecificMetadataElementsConfiguration = + hostSpecificMetadataElementsConfigurationInstantiator?.locateOrRegister(module, names, dependencies) + ) } +} - override fun create(name: String): T = - super.create(name).also { result -> - configureHostSpecificMetadata(result) - configureVariantPublishing(result) +class KotlinNativeVariantConfigurator( + private val compileTaskConfigurator: KotlinCompileTaskConfigurator = + KotlinNativeCompileTaskConfigurator, + + private val sourceArchiveTaskConfigurator: KotlinSourceArchiveTaskConfigurator = + DefaultKotlinSourceArchiveTaskConfigurator, + + private val sourceDirectoriesConfigurator: KotlinSourceDirectoriesConfigurator = + DefaultKotlinSourceDirectoriesConfigurator, + + private val compileDependenciesConfigurator: KotlinFragmentConfigurationsConfigurator = + DefaultKotlinCompileDependenciesConfigurator + KonanTargetAttributesConfigurator, + + private val apiElementsConfigurator: KotlinFragmentConfigurationsConfigurator = + DefaultKotlinApiElementsConfigurator + KonanTargetAttributesConfigurator, + + private val hostSpecificMetadataElementsConfigurator: KotlinFragmentConfigurationsConfigurator = + DefaultHostSpecificMetadataElementsConfigurator, + + private val hostSpecificMetadataArtifactConfigurator: KotlinGradleFragmentFactory.FragmentConfigurator = + KotlinHostSpecificMetadataArtifactConfigurator, + + private val publicationConfigurator: KotlinPublicationConfigurator = + KotlinPublicationConfigurator.NativeVariantPublication +) : KotlinGradleFragmentFactory.FragmentConfigurator { + + override fun configure(fragment: T) { + fragment.compileDependenciesConfiguration.configure { configuration -> + compileDependenciesConfigurator.configure(fragment, configuration) } - override fun configureKotlinCompilation(fragment: T) { - val compilationData = fragment.compilationData - LifecycleTasksManager(project).registerClassesTask(compilationData) - KotlinCompilationTaskConfigurator(project).createKotlinNativeCompilationTask(fragment, compilationData) - } - - private fun configureHostSpecificMetadata(variant: T) { - val hostSpecificConfigurationNameIfEnabled = variant.hostSpecificMetadataElementsConfigurationName - ?: return - - val hostSpecificMetadataJar = project.registerTask(variant.disambiguateName("hostSpecificMetadataJar")) { jar -> - jar.archiveClassifier.set("metadata") - jar.archiveAppendix.set(variant.disambiguateName("")) - project.pm20Extension.metadataCompilationRegistryByModuleId.getValue(variant.containingModule.moduleIdentifier) - .withAll { metadataCompilation -> - val fragment = metadataCompilation.fragment - if (metadataCompilation is KotlinNativeFragmentMetadataCompilationData) { - jar.from(project.files(project.provider { - if (fragment in variant.refinesClosure && fragment.isNativeHostSpecific()) - project.filesWithUnpackedArchives(metadataCompilation.output.allOutputs, setOf(KLIB_FILE_EXTENSION)) - else emptyList() - })) { spec -> spec.into(fragment.name) } - } - } + fragment.apiElementsConfiguration.configure { configuration -> + apiElementsConfigurator.configure(fragment, configuration) } - val apiElements = project.configurations.getByName(variant.apiElementsConfigurationName) - project.configurations.create(hostSpecificConfigurationNameIfEnabled).apply { - isCanBeResolved = false - isCanBeConsumed = false - setPlatformAttributesAndMetadataUsage(variant) - project.artifacts.add(name, hostSpecificMetadataJar) - dependencies.addAllLater(project.objects.listProperty(Dependency::class.java).apply { - set(project.provider { apiElements.allDependencies }) - }) + + fragment.hostSpecificMetadataElementsConfiguration?.configure { configuration -> + hostSpecificMetadataElementsConfigurator.configure(fragment, configuration) } - } - open fun configureVariantPublishing(variant: T) { - VariantPublishingConfigurator.get(project).configureNativeVariantPublication(variant) + hostSpecificMetadataArtifactConfigurator.configure(fragment) + sourceDirectoriesConfigurator.configure(fragment) + compileTaskConfigurator.registerCompileTasks(fragment) + sourceArchiveTaskConfigurator.registerSourceArchiveTask(fragment) + publicationConfigurator.configure(fragment) } - - private fun Configuration.setPlatformAttributesAndMetadataUsage(variant: T) { - configureApiElementsConfiguration(variant, this) // then override the Usage attribute - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) - } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinPublicationConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinPublicationConfigurator.kt new file mode 100644 index 00000000000..2bb9e7a31e3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinPublicationConfigurator.kt @@ -0,0 +1,25 @@ +/* + * 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 + +interface KotlinPublicationConfigurator : KotlinGradleFragmentFactory.FragmentConfigurator { + + object NoPublication : KotlinPublicationConfigurator { + override fun configure(fragment: KotlinGradleVariant) = Unit + } + + object SingleVariantPublication : KotlinPublicationConfigurator { + override fun configure(fragment: KotlinGradlePublishedVariantWithRuntime) { + VariantPublishingConfigurator.get(fragment.project).configureSingleVariantPublication(fragment) + } + } + + object NativeVariantPublication : KotlinPublicationConfigurator { + override fun configure(fragment: KotlinNativeVariantInternal) { + VariantPublishingConfigurator.get(fragment.project).configureNativeVariantPublication(fragment) + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinSourceArchiveTaskConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinSourceArchiveTaskConfigurator.kt new file mode 100644 index 00000000000..99a1df098a8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinSourceArchiveTaskConfigurator.kt @@ -0,0 +1,27 @@ +/* + * 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.tasks.TaskProvider +import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTaskNamed + +interface KotlinSourceArchiveTaskConfigurator { + fun registerSourceArchiveTask(variant: T): TaskProvider<*>? +} + +object DefaultKotlinSourceArchiveTaskConfigurator : KotlinSourceArchiveTaskConfigurator { + override fun registerSourceArchiveTask(variant: KotlinGradleVariant): TaskProvider<*> { + return sourcesJarTaskNamed( + taskName = variant.sourceArchiveTaskName, + project = variant.project, + sourceSets = lazy { + FragmentSourcesProvider().getSourcesFromRefinesClosureAsMap(variant) + .entries.associate { it.key.fragmentName to it.value.get() } + }, + artifactNameAppendix = variant.name + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinSourceDirectoriesConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinSourceDirectoriesConfigurator.kt new file mode 100644 index 00000000000..d33498d8bbc --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinSourceDirectoriesConfigurator.kt @@ -0,0 +1,29 @@ +/* + * 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.Project +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import java.io.File + +interface KotlinSourceDirectoriesConfigurator: KotlinGradleFragmentFactory.FragmentConfigurator + +object DefaultKotlinSourceDirectoriesConfigurator : KotlinSourceDirectoriesConfigurator { + override fun configure(fragment: KotlinGradleFragment) { + fragment.kotlinSourceRoots.srcDir( + defaultSourceFolder( + project = fragment.project, + moduleName = fragment.containingModule.name, + fragmentName = fragment.fragmentName, + type = "kotlin" + ) + ) + } + + fun defaultSourceFolder(project: Project, moduleName: String, fragmentName: String, type: String): File { + return project.file("src/${lowerCamelCaseName(fragmentName, moduleName)}/$type") + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/TransformKotlinGranularMetadataForFragment.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/TransformKotlinGranularMetadataForFragment.kt index 4c0fd333bac..24d8e96a143 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/TransformKotlinGranularMetadataForFragment.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/TransformKotlinGranularMetadataForFragment.kt @@ -10,6 +10,7 @@ import org.gradle.api.file.FileCollection import org.gradle.api.tasks.* import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution import org.jetbrains.kotlin.gradle.plugin.mpp.getAllCompiledSourceSetMetadata +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider import org.jetbrains.kotlin.gradle.utils.getValue import java.io.File @@ -53,7 +54,7 @@ internal open class TransformKotlinGranularMetadataForFragment val participatingFragments = fragment.refinesClosure val participatingCompilations = participatingFragments.flatMap { it.containingModule.variantsContainingFragment(it) } participatingCompilations.associate { variant -> - variant.fragmentName to project.configurations.getByName(variant.compileDependencyConfigurationName) + variant.fragmentName to variant.compileDependenciesConfiguration.get() .allDependencies.map { listOf(it.group, it.name, it.version) }.toSet() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariantFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariantFactories.kt deleted file mode 100644 index 618d8091da5..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariantFactories.kt +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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.artifacts.Configuration -import org.gradle.api.attributes.Bundling -import org.gradle.api.attributes.Category -import org.gradle.api.attributes.Usage -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability -import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTaskNamed -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation - -abstract class AbstractKotlinGradleVariantFactory( - module: KotlinGradleModule -) : AbstractKotlinGradleFragmentFactory(module) { - - override fun create(name: String): T = - super.create(name).also { fragment -> - createSourcesArchiveTask(fragment) - createElementsConfigurations(fragment) - configureKotlinCompilation(fragment) - // TODO configure resources processing - } - - protected open fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) { - configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType) - } - - open fun configureCompileResolvableConfiguration(fragment: T, configuration: Configuration) { - setPlatformAttributesInConfiguration(fragment, configuration) - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(project, fragment.platformType)) - } - - open fun configureApiElementsConfiguration(fragment: T, configuration: Configuration) { - setPlatformAttributesInConfiguration(fragment, configuration) - configuration.attributes.apply { - attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(project, fragment.platformType)) - attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category::class.java, Category.LIBRARY)) - attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling::class.java, Bundling.EXTERNAL)) - } - } - - abstract fun configureKotlinCompilation(fragment: T) - - open fun createSourcesArchiveTask(fragment: T) { - sourcesJarTaskNamed( - fragment.sourceArchiveTaskName, - project, - lazy { FragmentSourcesProvider().getSourcesFromRefinesClosureAsMap(fragment).entries.associate { it.key.fragmentName to it.value.get() } }, - fragment.name - ) - } - - override fun createDependencyConfigurations(fragment: T) { - super.createDependencyConfigurations(fragment) - - fragment.compileDependencyFiles = project.configurations.create(fragment.compileDependencyConfigurationName).apply { - isCanBeConsumed = false - isCanBeResolved = true - configureCompileResolvableConfiguration(fragment, this@apply) - project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName) - project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName) - } - // FIXME runtime classpath if supported - } - - open fun createElementsConfigurations(fragment: T) { - project.configurations.maybeCreate(fragment.apiElementsConfigurationName).apply { - isCanBeResolved = false - isCanBeConsumed = false - module.ifMadePublic { - isCanBeConsumed = true - } - setModuleCapability(this, fragment.containingModule) - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(project, fragment.platformType)) - extendsFrom(project.configurations.getByName(fragment.transitiveApiConfigurationName)) - // FIXME + compileOnly - configureApiElementsConfiguration(fragment, this@apply) - } - } -} - -abstract class AbstractKotlinGradleVariantWithRuntimeFactory(module: KotlinGradleModule) : - AbstractKotlinGradleVariantFactory(module) { - - open fun configureRuntimeResolvableConfiguration(fragment: T, configuration: Configuration) { - setPlatformAttributesInConfiguration(fragment, configuration) - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(project, fragment.platformType)) - } - - open fun configureRuntimeElementsConfiguration(fragment: T, configuration: Configuration) { - setPlatformAttributesInConfiguration(fragment, configuration) - configuration.attributes.apply { - attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(project, fragment.platformType)) - attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category::class.java, Category.LIBRARY)) - attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling::class.java, Bundling.EXTERNAL)) - } - } - - override fun createDependencyConfigurations(fragment: T) { - super.createDependencyConfigurations(fragment) - - fragment.runtimeDependencyFiles = project.configurations.create(fragment.runtimeDependencyConfigurationName).apply { - isCanBeConsumed = false - isCanBeResolved = true - configureRuntimeResolvableConfiguration(fragment, this@apply) - project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName) - project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName) - } - } - - override fun createElementsConfigurations(fragment: T) { - super.createElementsConfigurations(fragment) - - project.configurations.maybeCreate(fragment.runtimeElementsConfigurationName).apply { - isCanBeResolved = false - isCanBeConsumed = false - module.ifMadePublic { - isCanBeConsumed = true - setModuleCapability(this, fragment.containingModule) - } - configureRuntimeElementsConfiguration(fragment, this@apply) - extendsFrom(project.configurations.getByName(fragment.transitiveApiConfigurationName)) - extendsFrom(project.configurations.getByName(fragment.transitiveImplementationConfigurationName)) - // FIXME + runtimeOnly - } - } -} - -abstract class AbstractKotlinGradleRuntimePublishedVariantFactory(module: KotlinGradleModule) : - AbstractKotlinGradleVariantWithRuntimeFactory(module) { - - override fun create(name: String): T { - val result = super.create(name) - configureVariantPublishing(result) - return result - } - - open fun configureVariantPublishing(variant: T) { - VariantPublishingConfigurator.get(project).configureSingleVariantPublication(variant) - } -} - -internal fun setModuleCapability(configuration: Configuration, module: KotlinGradleModule) { - if (module.moduleClassifier != null) { - configuration.outgoing.capability(ComputedCapability.fromModule(module)) - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt index 197f7063b33..83e12c2808d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt @@ -5,81 +5,69 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 -import org.gradle.api.Project +import org.gradle.api.NamedDomainObjectProvider import org.gradle.api.artifacts.Configuration import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.FileCollection import org.gradle.api.publish.maven.MavenPublication -import org.gradle.api.tasks.TaskProvider -import org.gradle.api.tasks.bundling.AbstractArchiveTask -import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput import org.jetbrains.kotlin.gradle.plugin.mpp.MavenPublicationCoordinatesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName -import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.project.model.KotlinAttributeKey import org.jetbrains.kotlin.project.model.KotlinPlatformTypeAttribute abstract class KotlinGradleVariantInternal( containingModule: KotlinGradleModule, - override val fragmentName: String -) : KotlinGradleFragmentInternal(containingModule, fragmentName), KotlinGradleVariant { + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + final override val compileDependenciesConfiguration: NamedDomainObjectProvider, + final override val apiElementsConfiguration: NamedDomainObjectProvider +) : KotlinGradleFragmentInternal( + containingModule, fragmentName, dependencyConfigurations +), KotlinGradleVariant { override val variantAttributes: Map get() = mapOf(KotlinPlatformTypeAttribute to kotlinPlatformTypeAttributeFromPlatform(platformType)) // TODO user attributes - // TODO generalize with KotlinCompilation? - override val compileDependencyConfigurationName: String - get() = disambiguateName("CompileDependencies") - - override lateinit var compileDependencyFiles: FileCollection + override var compileDependencyFiles: FileCollection = project.files({ compileDependenciesConfiguration.get() }) internal abstract val compilationData: KotlinVariantCompilationDataInternal<*> // TODO rewrite using our own artifacts API? - override val compilationOutputs: KotlinCompilationOutput = - DefaultKotlinCompilationOutput( - project, - project.provider { project.buildDir.resolve("processedResources/${containingModule.name}/${fragmentName}") } - ) + override val compilationOutputs: KotlinCompilationOutput = DefaultKotlinCompilationOutput( + project, project.provider { project.buildDir.resolve("processedResources/${containingModule.name}/${fragmentName}") } + ) // TODO rewrite using our own artifacts API override val sourceArchiveTaskName: String get() = defaultSourceArtifactTaskName - // TODO generalize exposing outputs: what if a variant has more than one such configurations or none? - override val apiElementsConfigurationName: String - get() = disambiguateName("apiElements") - override fun toString(): String = "variant $fragmentName in $containingModule" } -internal val KotlinGradleVariant.compileDependencyConfiguration: Configuration - get() = containingModule.project.configurations.getByName(compileDependencyConfigurationName) - class DefaultSingleMavenPublishedModuleHolder( - private var module: KotlinGradleModule, - override val defaultPublishedModuleSuffix: String? + private var module: KotlinGradleModule, override val defaultPublishedModuleSuffix: String? ) : SingleMavenPublishedModuleHolder { private val project get() = module.project private var assignedMavenPublication: MavenPublication? = null override fun assignMavenPublication(publication: MavenPublication) { - if (assignedMavenPublication != null) - error("already assigned publication $publication") + if (assignedMavenPublication != null) error("already assigned publication $publication") assignedMavenPublication = publication } - override val publishedMavenModuleCoordinates: PublishedModuleCoordinatesProvider = - MavenPublicationCoordinatesProvider( - project, - { assignedMavenPublication }, - defaultPublishedModuleSuffix, - capabilities = listOfNotNull(ComputedCapability.capabilityStringFromModule(module)) - ) + override val publishedMavenModuleCoordinates: PublishedModuleCoordinatesProvider = MavenPublicationCoordinatesProvider( + project, + { assignedMavenPublication }, + defaultPublishedModuleSuffix, + capabilities = listOfNotNull(ComputedCapability.capabilityStringFromModule(module)) + ) } private fun kotlinPlatformTypeAttributeFromPlatform(platformType: KotlinPlatformType) = platformType.name @@ -90,39 +78,50 @@ internal val KotlinGradleVariant.defaultSourceArtifactTaskName: String abstract class KotlinGradleVariantWithRuntimeInternal( containingModule: KotlinGradleModule, - fragmentName: String -) : KotlinGradleVariantInternal(containingModule, fragmentName), KotlinGradleVariantWithRuntime { + fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + final override val runtimeDependenciesConfiguration: NamedDomainObjectProvider, + final override val runtimeElementsConfiguration: NamedDomainObjectProvider +) : KotlinGradleVariantInternal( + containingModule = containingModule, + fragmentName = fragmentName, + dependencyConfigurations = dependencyConfigurations, + compileDependenciesConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration +), KotlinGradleVariantWithRuntime { // TODO deduplicate with KotlinCompilation? - override val runtimeDependencyConfigurationName: String - get() = disambiguateName("RuntimeDependencies") - override lateinit var runtimeDependencyFiles: FileCollection + override var runtimeDependencyFiles: FileCollection = project.files(runtimeDependenciesConfiguration) - override val runtimeFiles: ConfigurableFileCollection = project.files( - listOf( - { compilationOutputs.allOutputs }, - { runtimeDependencyFiles } - ) - ) - - // TODO generalize exposing outputs: what if a variant has more than one such configurations or none? - override val runtimeElementsConfigurationName: String - get() = disambiguateName("runtimeElements") + override val runtimeFiles: ConfigurableFileCollection = + project.files(listOf({ compilationOutputs.allOutputs }, { runtimeDependencyFiles })) } private fun defaultModuleSuffix(module: KotlinGradleModule, variantName: String): String = dashSeparatedName(variantName, module.moduleClassifier) -abstract class KotlinGradlePublishedVariantWithRuntime(containingModule: KotlinGradleModule, fragmentName: String) : - KotlinGradleVariantWithRuntimeInternal(containingModule, fragmentName), - SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder( - containingModule, - defaultModuleSuffix(containingModule, fragmentName) - ) { - +abstract class KotlinGradlePublishedVariantWithRuntime( + containingModule: KotlinGradleModule, fragmentName: String, + dependencyConfigurations: KotlinDependencyConfigurations, + compileDependencyConfiguration: NamedDomainObjectProvider, + apiElementsConfiguration: NamedDomainObjectProvider, + runtimeDependencyConfiguration: NamedDomainObjectProvider, + runtimeElementsConfiguration: NamedDomainObjectProvider +) : KotlinGradleVariantWithRuntimeInternal( + containingModule = containingModule, + fragmentName = fragmentName, + dependencyConfigurations = dependencyConfigurations, + compileDependencyConfiguration = compileDependencyConfiguration, + apiElementsConfiguration = apiElementsConfiguration, + runtimeDependenciesConfiguration = runtimeDependencyConfiguration, + runtimeElementsConfiguration = runtimeElementsConfiguration +), SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder( + containingModule, defaultModuleSuffix(containingModule, fragmentName) +) { override val gradleVariantNames: Set - get() = - listOf(apiElementsConfigurationName, runtimeElementsConfigurationName).flatMapTo(mutableSetOf()) { - listOf(it, publishedConfigurationName(it)) - } -} \ No newline at end of file + get() = listOf(apiElementsConfiguration.name, runtimeElementsConfiguration.name).flatMapTo(mutableSetOf()) { + listOf(it, publishedConfigurationName(it)) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinApiElements.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinApiElements.kt new file mode 100644 index 00000000000..648c4780406 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinApiElements.kt @@ -0,0 +1,40 @@ +/* + * 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.configuration + +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Bundling +import org.gradle.api.attributes.Category +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister + +interface KotlinApiElementsConfigurationInstantiator : KotlinFragmentConfigurationInstantiator + +object DefaultKotlinApiElementsConfigurationInstantiator : KotlinApiElementsConfigurationInstantiator { + override fun locateOrRegister( + module: KotlinGradleModule, + names: FragmentNameDisambiguation, + dependencies: KotlinDependencyConfigurations + ): NamedDomainObjectProvider { + return module.project.configurations.locateOrRegister(names.disambiguateName("apiElements")) { + isCanBeResolved = false + isCanBeConsumed = false + extendsFrom(dependencies.transitiveApiConfiguration.get()) + module.ifMadePublic { isCanBeConsumed = true } + + attributes.attribute(Category.CATEGORY_ATTRIBUTE, module.project.objects.named(Category::class.java, Category.LIBRARY)) + attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, module.project.objects.named(Bundling::class.java, Bundling.EXTERNAL)) + } + } +} + +val DefaultKotlinApiElementsConfigurator = KotlinConfigurationsConfigurator( + KotlinFragmentPlatformAttributesConfigurator, + KotlinFragmentModuleCapabilityConfigurator, + KotlinFragmentProducerApiUsageAttributesConfigurator +) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinCompileDependencies.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinCompileDependencies.kt new file mode 100644 index 00000000000..597fe1be3f3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinCompileDependencies.kt @@ -0,0 +1,35 @@ +/* + * 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.configuration + +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister +import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation + + +interface KotlinCompileDependenciesConfigurationInstantiator : KotlinFragmentConfigurationInstantiator + +object DefaultKotlinCompileDependenciesConfigurationInstantiator : KotlinCompileDependenciesConfigurationInstantiator { + override fun locateOrRegister( + module: KotlinGradleModule, + names: FragmentNameDisambiguation, + dependencies: KotlinDependencyConfigurations + ): NamedDomainObjectProvider { + return module.project.configurations.locateOrRegister(names.disambiguateName("compileDependencies")) { + isCanBeConsumed = false + isCanBeResolved = true + module.project.addExtendsFromRelation(name, dependencies.transitiveApiConfiguration.name) + module.project.addExtendsFromRelation(name, dependencies.transitiveImplementationConfiguration.name) + } + } +} + +val DefaultKotlinCompileDependenciesConfigurator = KotlinConfigurationsConfigurator( + KotlinFragmentPlatformAttributesConfigurator, KotlinFragmentConsumerApiUsageAttributesConfigurator +) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinHostSpecificMetadataElements.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinHostSpecificMetadataElements.kt new file mode 100644 index 00000000000..66fe3d5d651 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinHostSpecificMetadataElements.kt @@ -0,0 +1,41 @@ +/* + * 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.plugin.mpp.pm20.configuration + +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration +import org.jetbrains.kotlin.gradle.plugin.mpp.isHostSpecificKonanTargetsSet +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister +import org.jetbrains.kotlin.konan.target.KonanTarget + +interface KotlinHostSpecificMetadataElementsConfigurationInstantiator : KotlinFragmentConfigurationInstantiator + +fun DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator( + konanTarget: KonanTarget +): KotlinHostSpecificMetadataElementsConfigurationInstantiator? = if (isHostSpecificKonanTargetsSet(setOf(konanTarget))) + DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator else null + +private object DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator : + KotlinHostSpecificMetadataElementsConfigurationInstantiator { + override fun locateOrRegister( + module: KotlinGradleModule, names: FragmentNameDisambiguation, dependencies: KotlinDependencyConfigurations + ): NamedDomainObjectProvider { + return module.project.configurations.locateOrRegister(names.disambiguateName("hostSpecificMetadataElements")) { + isCanBeResolved = false + isCanBeConsumed = false + } + } +} + +val DefaultHostSpecificMetadataElementsConfigurator = KotlinConfigurationsConfigurator( + KotlinFragmentPlatformAttributesConfigurator, + KonanTargetAttributesConfigurator, + KotlinFragmentMetadataUsageAttributeConfigurator +) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinRuntimeDependencies.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinRuntimeDependencies.kt new file mode 100644 index 00000000000..1238f6708d1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinRuntimeDependencies.kt @@ -0,0 +1,35 @@ +/* + * 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.configuration + +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister +import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation + +interface KotlinRuntimeDependenciesConfigurationInstantiator : KotlinFragmentConfigurationInstantiator + +object DefaultKotlinRuntimeDependenciesConfigurationInstantiator : KotlinRuntimeDependenciesConfigurationInstantiator { + override fun locateOrRegister( + module: KotlinGradleModule, + names: FragmentNameDisambiguation, + dependencies: KotlinDependencyConfigurations + ): NamedDomainObjectProvider { + return module.project.configurations.locateOrRegister(names.disambiguateName("runtimeDependencies")) { + isCanBeConsumed = false + isCanBeResolved = true + module.project.addExtendsFromRelation(name, dependencies.transitiveApiConfiguration.name) + module.project.addExtendsFromRelation(name, dependencies.transitiveImplementationConfiguration.name) + } + } +} + +val DefaultKotlinRuntimeDependenciesConfigurator = KotlinConfigurationsConfigurator( + KotlinFragmentPlatformAttributesConfigurator, + KotlinFragmentConsumerRuntimeUsageAttributesConfigurator +) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinRuntimeElements.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinRuntimeElements.kt new file mode 100644 index 00000000000..476b8949c2c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/configuration/KotlinRuntimeElements.kt @@ -0,0 +1,45 @@ +/* + * 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.configuration + +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Bundling +import org.gradle.api.attributes.Category +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinFragmentModuleCapabilityConfigurator.setModuleCapability +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister + +interface KotlinRuntimeElementsConfigurationFactory : KotlinFragmentConfigurationInstantiator + +object DefaultKotlinRuntimeElementsConfigurationInstantiator : KotlinRuntimeElementsConfigurationFactory { + override fun locateOrRegister( + module: KotlinGradleModule, + names: FragmentNameDisambiguation, + dependencies: KotlinDependencyConfigurations + ): NamedDomainObjectProvider { + return module.project.configurations.locateOrRegister(names.disambiguateName("runtimeElements")) { + isCanBeResolved = false + isCanBeConsumed = false + + attributes.attribute(Category.CATEGORY_ATTRIBUTE, module.project.objects.named(Category::class.java, Category.LIBRARY)) + attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, module.project.objects.named(Bundling::class.java, Bundling.EXTERNAL)) + + extendsFrom(dependencies.transitiveApiConfiguration.get()) + extendsFrom(dependencies.transitiveImplementationConfiguration.get()) + module.ifMadePublic { + isCanBeConsumed = true + setModuleCapability(this, module) + } + } + } +} + +val DefaultKotlinRuntimeElementsConfigurator = KotlinConfigurationsConfigurator( + KotlinFragmentPlatformAttributesConfigurator, + KotlinFragmentProducerRuntimeUsageAttributesConfigurator +) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentFactories.kt deleted file mode 100644 index 476cfef5c0d..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentFactories.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.NamedDomainObjectFactory -import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.project.model.KotlinModuleFragment -import java.io.File - -abstract class AbstractKotlinGradleFragmentFactory( - protected val module: KotlinGradleModule -) : NamedDomainObjectFactory { - - protected val project: Project - get() = module.project - - abstract fun instantiateFragment(name: String): T - - override fun create(name: String): T = - instantiateFragment(name).apply { - createDependencyConfigurations(this) - addDefaultSourceDirectories(this) - } - - protected open fun createDependencyConfigurations(fragment: T) { - with(project.configurations) { - fragment.relatedConfigurationNames.forEach { configurationName -> - maybeCreate(configurationName).apply { - // FIXME add metadata configurations or API for IDE import? - if (!configurationName.endsWith(METADATA_CONFIGURATION_NAME_SUFFIX)) { - isCanBeResolved = false - } - isCanBeConsumed = false - } - } - listOf( - fragment.apiConfigurationName to fragment.transitiveApiConfigurationName, - fragment.implementationConfigurationName to fragment.transitiveImplementationConfigurationName - ).forEach { (configuration, transitiveConfiguration) -> - project.addExtendsFromRelation(transitiveConfiguration, configuration) - } - } - } - - protected open fun addDefaultSourceDirectories(fragment: KotlinGradleFragment) { - fragment.kotlinSourceRoots.srcDir(defaultSourceFolder(project, module.name, fragment.fragmentName, "kotlin")) - // TODO handle resources - } - - companion object { - fun defaultSourceFolder(project: Project, moduleName: String, fragmentName: String, type: String): File { - return project.file("src/${lowerCamelCaseName(fragmentName, moduleName)}/$type") - } - } -} - -class CommonGradleFragmentFactory(module: KotlinGradleModule) : AbstractKotlinGradleFragmentFactory(module) { - override fun instantiateFragment(name: String): KotlinGradleFragmentInternal = - project.objects.newInstance(KotlinGradleFragmentInternal::class.java, module, name) -} \ 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 5ef7f7f8106..3093be87e20 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 @@ -14,7 +14,9 @@ import org.jetbrains.kotlin.gradle.dsl.pm20Extension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.KotlinCommonSourceSetProcessor import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinFragmentModuleCapabilityConfigurator.setModuleCapability import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName import org.jetbrains.kotlin.gradle.targets.metadata.createGenerateProjectStructureMetadataTask import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives import org.jetbrains.kotlin.gradle.tasks.* diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/KotlinFragmentNameDisambiguation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/KotlinFragmentNameDisambiguation.kt new file mode 100644 index 00000000000..2f28376cb91 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/KotlinFragmentNameDisambiguation.kt @@ -0,0 +1,40 @@ +/* + * 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util + +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import org.jetbrains.kotlin.project.model.KotlinModule +import org.jetbrains.kotlin.project.model.KotlinModuleFragment + +internal typealias FragmentNameDisambiguation = KotlinFragmentNameDisambiguation + +internal fun FragmentNameDisambiguation(module: KotlinModule, fragmentName: String): FragmentNameDisambiguation { + return DefaultKotlinFragmentNameDisambiguation(module, fragmentName) +} + +interface KotlinFragmentNameDisambiguation { + fun disambiguateName(simpleName: String): String +} + +private class DefaultKotlinFragmentNameDisambiguation( + private val module: KotlinModule, + private val fragmentName: String +) : KotlinFragmentNameDisambiguation { + override fun disambiguateName(simpleName: String): String { + return KotlinModuleFragment.disambiguateName(module, fragmentName, simpleName) + } +} + +internal fun KotlinModuleFragment.disambiguateName(simpleName: String) = + KotlinModuleFragment.disambiguateName(containingModule, fragmentName, simpleName) + +internal fun KotlinModuleFragment.Companion.disambiguateName(module: KotlinModule, fragmentName: String, simpleName: String) = + lowerCamelCaseName(fragmentName, module.moduleIdentifier.moduleClassifier ?: KotlinGradleModule.MAIN_MODULE_NAME, simpleName) + + diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/locateOrRegister.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/locateOrRegister.kt new file mode 100644 index 00000000000..f89b7dc7fb5 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/locateOrRegister.kt @@ -0,0 +1,14 @@ +/* + * 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.util + +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.NamedDomainObjectProvider + +fun NamedDomainObjectContainer.locateOrRegister(name: String, configure: T.() -> Unit = {}): NamedDomainObjectProvider { + return if (name in names) named(name, configure) + else register(name, configure) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/variantPublishing.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/variantPublishing.kt index 60e0f328659..7181f0f2f89 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/variantPublishing.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/variantPublishing.kt @@ -17,7 +17,9 @@ import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinFragmentModuleCapabilityConfigurator.setModuleCapability import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName import org.jetbrains.kotlin.gradle.plugin.usageByName import org.jetbrains.kotlin.gradle.tasks.withType @@ -26,14 +28,14 @@ import javax.inject.Inject fun VariantPublishingConfigurator.configureNativeVariantPublication(variant: KotlinNativeVariantInternal) { val publishConfigurations = listOfNotNull( - variant.apiElementsConfigurationName, - variant.hostSpecificMetadataElementsConfigurationName // host-specific metadata may be absent + variant.apiElementsConfiguration.name, + variant.hostSpecificMetadataElementsConfiguration?.name // host-specific metadata may be absent ) configurePublishing(variant, variant, publishConfigurations) } fun VariantPublishingConfigurator.configureSingleVariantPublication(variant: KotlinGradlePublishedVariantWithRuntime) { - val publishConfigurations = listOf(variant.apiElementsConfigurationName, variant.runtimeElementsConfigurationName) + val publishConfigurations = listOf(variant.apiElementsConfiguration.name, variant.runtimeElementsConfiguration.name) configurePublishing(variant, variant, publishConfigurations) } @@ -50,8 +52,8 @@ open class VariantPublishingConfigurator @Inject constructor( open fun inferMavenScopes(variant: KotlinGradleVariant, configurationNames: Iterable): Map = configurationNames.associateWith { configurationName -> when { - configurationName == variant.apiElementsConfigurationName -> "compile" - variant is KotlinGradleVariantWithRuntime && configurationName == variant.runtimeElementsConfigurationName -> "runtime" + configurationName == variant.apiElementsConfiguration.name -> "compile" + variant is KotlinGradleVariantWithRuntime && configurationName == variant.runtimeElementsConfiguration.name -> "runtime" else -> null } } @@ -201,4 +203,4 @@ open class DocumentationVariantConfigurator { ComputedCapability.fromModuleOrNull(variant.containingModule) ) } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt index 1d0219b0e2d..a7f64a3ebf5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt @@ -50,7 +50,7 @@ class AndroidExtensionsSubpluginIndicator @Inject internal constructor(private v private fun addAndroidExtensionsRuntime(project: Project) { val kotlinPluginVersion = project.getKotlinPluginVersion() - project.configurations.all { configuration -> + project.configurations.configureEach all@{ configuration -> val name = configuration.name if (name != "implementation" && name != "compile") return@all @@ -303,4 +303,4 @@ class AndroidSubplugin : kotlinCompilation: KotlinCompilation? ): List = emptyList() //endregion -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt index 4e1d608ed5d..e390f54f491 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeVariantCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.disambiguateName +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import java.io.File @@ -142,4 +143,4 @@ private fun KotlinNativeCompilationData<*>.disambiguateName(simpleName: String): this.compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, simpleName ) -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt index 05499e085c1..1d6f85655a9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt @@ -539,7 +539,7 @@ open class KotlinNativeTargetConfigurator : AbstractKotl private val KotlinNativeCompilationData<*>.apiElementsConfigurationName: String get() = when (val dataOwner = owner) { - is KotlinGradleVariant -> dataOwner.apiElementsConfigurationName + is KotlinGradleVariant -> dataOwner.apiElementsConfiguration.name is KotlinTarget -> dataOwner.apiElementsConfigurationName else -> error("unexpected owner of $this") } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt index 903a26f80ef..6102187342a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt @@ -5,8 +5,9 @@ package org.jetbrains.kotlin.gradle.utils +import org.gradle.api.NamedDomainObjectProvider import org.gradle.api.Project -import java.lang.RuntimeException +import org.gradle.api.artifacts.Configuration fun Project.addExtendsFromRelation(extendingConfigurationName: String, extendsFromConfigurationName: String, forced: Boolean = true) { if (extendingConfigurationName == extendsFromConfigurationName) return @@ -16,4 +17,9 @@ fun Project.addExtendsFromRelation(extendingConfigurationName: String, extendsFr else return extending.extendsFrom(configurations.getByName(extendsFromConfigurationName)) -} \ No newline at end of file +} + +fun NamedDomainObjectProvider.extendsFrom(other: NamedDomainObjectProvider) { + if (name == other.name) return + configure { extending -> extending.extendsFrom(other.get()) } +} diff --git a/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt b/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt index 219506a8997..b07bc492fd2 100644 --- a/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt +++ b/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt @@ -21,6 +21,8 @@ interface KotlinModuleFragment { // TODO: should this be source roots or source files? val kotlinSourceRoots: Iterable + + companion object } interface KotlinModuleVariant : KotlinModuleFragment { @@ -72,4 +74,4 @@ class BasicKotlinModuleVariant( ), KotlinModuleVariant { override val variantAttributes: MutableMap = mutableMapOf() override fun toString(): String = "variant $fragmentName" -} \ No newline at end of file +}