diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinTarget.kt index 66c53d29d3d..2f406213727 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinTarget.kt @@ -8,24 +8,17 @@ import org.gradle.api.Action import org.gradle.api.DomainObjectSet import org.gradle.api.Project import org.gradle.api.artifacts.ConfigurablePublishArtifact -import org.gradle.api.attributes.* -import org.gradle.api.component.ComponentWithCoordinates -import org.gradle.api.component.ComponentWithVariants -import org.gradle.api.component.SoftwareComponent -import org.gradle.api.component.SoftwareComponentFactory -import org.gradle.api.internal.component.SoftwareComponentInternal -import org.gradle.api.internal.component.UsageContext -import org.gradle.api.internal.project.ProjectInternal +import org.gradle.api.attributes.AttributeContainer import org.gradle.api.publish.maven.MavenPublication +import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.PRESETS_API_IS_DEPRECATED_MESSAGE -import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.* -import org.jetbrains.kotlin.gradle.utils.dashSeparatedName -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.COMPILE +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.RUNTIME +import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.tooling.core.MutableExtras import org.jetbrains.kotlin.tooling.core.mutableExtrasOf import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly @@ -34,7 +27,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull internal const val PRIMARY_SINGLE_COMPONENT_NAME = "kotlin" abstract class AbstractKotlinTarget( - final override val project: Project + final override val project: Project, ) : InternalKotlinTarget { final override val extras: MutableExtras = mutableExtrasOf() @@ -96,8 +89,13 @@ abstract class AbstractKotlinTarget( setOf(result) } - override val components: Set by lazy { - project.buildAdhocComponentsFromKotlinVariants(kotlinComponents) + + /** + * Returns, potentially not configured (e.g. without some usages), Gradle SoftwareComponent's for this target + * For final version of components use [awaitComponents] + */ + override val components: Set by lazy { + kotlinComponents.map { kotlinComponent -> KotlinTargetSoftwareComponent(this, kotlinComponent) }.toSet() } protected open fun createKotlinVariant( @@ -190,69 +188,6 @@ abstract class AbstractKotlinTarget( internal set } -private val publishedConfigurationNameSuffix = "-published" - -internal fun publishedConfigurationName(originalVariantName: String) = originalVariantName + publishedConfigurationNameSuffix -internal fun originalVariantNameFromPublished(publishedConfigurationName: String): String? = - publishedConfigurationName.takeIf { it.endsWith(publishedConfigurationNameSuffix) }?.removeSuffix(publishedConfigurationNameSuffix) - internal fun KotlinTarget.disambiguateName(simpleName: String) = lowerCamelCaseName(targetName, simpleName) -internal fun javaApiUsageForMavenScoping() = "java-api-jars" - -internal fun Project.buildAdhocComponentsFromKotlinVariants(kotlinVariants: Set): Set { - val softwareComponentFactoryClass = SoftwareComponentFactory::class.java - // TODO replace internal API access with injection (not possible until we have this class on the compile classpath) - val softwareComponentFactory = (project as ProjectInternal).services.get(softwareComponentFactoryClass) - - return kotlinVariants.map { kotlinVariant -> - val adhocVariant = softwareComponentFactory.adhoc(kotlinVariant.name) - - project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseCompilations) { - (kotlinVariant as SoftwareComponentInternal).usages.filterIsInstance().forEach { kotlinUsageContext -> - val publishedConfigurationName = publishedConfigurationName(kotlinUsageContext.name) - val configuration = project.configurations.findByName(publishedConfigurationName) - ?: project.configurations.create(publishedConfigurationName).also { configuration -> - configuration.isCanBeConsumed = false - configuration.isCanBeResolved = false - configuration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName)) - configuration.artifacts.addAll(kotlinUsageContext.artifacts) - - val attributes = kotlinUsageContext.attributes - attributes.keySet().forEach { - // capture type parameter T - fun copyAttribute(key: Attribute, from: AttributeContainer, to: AttributeContainer) { - to.attribute(key, from.getAttribute(key)!!) - } - copyAttribute(it, attributes, configuration.attributes) - } - } - - adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails -> - val mavenScope = kotlinUsageContext.mavenScope - if (mavenScope != null) { - val mavenScopeString = when (mavenScope) { - COMPILE -> "compile" - RUNTIME -> "runtime" - } - configurationVariantDetails.mapToMavenScope(mavenScopeString) - } - } - } - } - - adhocVariant as SoftwareComponent - - object : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal { - override fun getCoordinates() = - (kotlinVariant as? ComponentWithCoordinates)?.coordinates ?: error("kotlinVariant is not ComponentWithCoordinates") - - override fun getVariants(): Set = - (kotlinVariant as? KotlinVariantWithMetadataVariant)?.variants.orEmpty() - - override fun getName(): String = adhocVariant.name - override fun getUsages(): MutableSet = (adhocVariant as SoftwareComponentInternal).usages - } - }.toSet() -} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinTarget.kt index 58b147333b4..29d035139bb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinTarget.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.publish.maven.MavenPublication +import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent import org.jetbrains.kotlin.tooling.core.HasMutableExtras @@ -13,6 +15,9 @@ import org.jetbrains.kotlin.tooling.core.HasMutableExtras internal interface InternalKotlinTarget : KotlinTarget, HasMutableExtras { var isSourcesPublishable: Boolean val kotlinComponents: Set + + @InternalKotlinGradlePluginApi + override val components: Set fun onPublicationCreated(publication: MavenPublication) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinTargetComponent.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinTargetComponent.kt new file mode 100644 index 00000000000..132fd4bc584 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinTargetComponent.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2023 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 + +import org.gradle.api.internal.component.SoftwareComponentInternal +import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent + +/** + * Enforced 'internal' common supertype for all [KotlinTargetComponent] implementations. + */ +@InternalKotlinGradlePluginApi +abstract class InternalKotlinTargetComponent : KotlinTargetComponent, SoftwareComponentInternal { + abstract override fun getUsages(): Set +} + +internal val KotlinTargetComponent.internal: InternalKotlinTargetComponent + get() = this as InternalKotlinTargetComponent \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinTargetSoftwareComponent.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinTargetSoftwareComponent.kt new file mode 100644 index 00000000000..3c666afdba0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinTargetSoftwareComponent.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2023 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 + +import org.gradle.api.component.ComponentWithCoordinates +import org.gradle.api.component.ComponentWithVariants +import org.gradle.api.internal.component.SoftwareComponentInternal +import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetSoftwareComponent + +/** + * Common supertype for + * - [KotlinTargetSoftwareComponentImpl]: internal targets + * - [ExternalKotlinTargetSoftwareComponent]: external targets + */ +@InternalKotlinGradlePluginApi +abstract class KotlinTargetSoftwareComponent : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinTargetSoftwareComponentImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinTargetSoftwareComponentImpl.kt new file mode 100644 index 00000000000..6fd33676b6d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinTargetSoftwareComponentImpl.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2010-2023 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 + +import org.gradle.api.Project +import org.gradle.api.component.AdhocComponentWithVariants +import org.gradle.api.component.ComponentWithCoordinates +import org.gradle.api.component.SoftwareComponent +import org.gradle.api.component.SoftwareComponentFactory +import org.gradle.api.internal.component.SoftwareComponentInternal +import org.gradle.api.internal.component.UsageContext +import org.gradle.api.internal.project.ProjectInternal +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent +import org.jetbrains.kotlin.gradle.plugin.launchInStage +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes +import org.jetbrains.kotlin.tooling.core.UnsafeApi + +internal fun KotlinTargetSoftwareComponent( + target: AbstractKotlinTarget, + kotlinComponent: KotlinTargetComponent, +): KotlinTargetSoftwareComponent { + val softwareComponentFactory = (target.project as ProjectInternal).services.get(SoftwareComponentFactory::class.java) + val adhocVariant = softwareComponentFactory.adhoc(kotlinComponent.name) + + /* Launch configuration */ + target.project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseCompilations) { + kotlinComponent.internal.usages.forEach { kotlinUsageContext -> + /* Explicitly typing 'Project' to avoid smart cast from 'target.project as ProjectInternal' */ + val project: Project = target.project + val publishedConfigurationName = publishedConfigurationName(kotlinUsageContext.name) + val configuration = project.configurations.findByName(publishedConfigurationName) + ?: project.configurations.create(publishedConfigurationName).also { publishedConfiguration -> + publishedConfiguration.isCanBeConsumed = false + publishedConfiguration.isCanBeResolved = false + publishedConfiguration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName)) + publishedConfiguration.artifacts.addAll(kotlinUsageContext.artifacts) + copyAttributes(from = kotlinUsageContext.attributes, to = publishedConfiguration.attributes) + } + + adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails -> + val mavenScope = kotlinUsageContext.mavenScope + if (mavenScope != null) { + val mavenScopeString = when (mavenScope) { + KotlinUsageContext.MavenScope.COMPILE -> "compile" + KotlinUsageContext.MavenScope.RUNTIME -> "runtime" + } + configurationVariantDetails.mapToMavenScope(mavenScopeString) + } + } + } + } + + @OptIn(UnsafeApi::class) + return KotlinTargetSoftwareComponentImpl(adhocVariant, kotlinComponent) +} + + +/* Smaller Utils functions */ + +private val publishedConfigurationNameSuffix = "-published" + +internal fun originalVariantNameFromPublished(publishedConfigurationName: String): String? = + publishedConfigurationName.takeIf { it.endsWith(publishedConfigurationNameSuffix) }?.removeSuffix(publishedConfigurationNameSuffix) + +internal fun publishedConfigurationName(originalVariantName: String) = originalVariantName + publishedConfigurationNameSuffix + +/* KotlinTargetSoftwareComponent Implementation */ + +internal class KotlinTargetSoftwareComponentImpl @UnsafeApi constructor( + private val adhocComponent: AdhocComponentWithVariants, + private val kotlinComponent: KotlinTargetComponent, +) : KotlinTargetSoftwareComponent() { + + override fun getCoordinates() = + (kotlinComponent as? ComponentWithCoordinates)?.coordinates ?: error("kotlinComponent is not ComponentWithCoordinates") + + override fun getVariants(): Set = + (kotlinComponent as? KotlinVariantWithMetadataVariant)?.variants.orEmpty() + + override fun getName(): String = adhocComponent.name + override fun getUsages(): MutableSet = (adhocComponent as SoftwareComponentInternal).usages +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetComponent.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetComponent.kt index 8aa321ec113..ee799f0d565 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetComponent.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetComponent.kt @@ -10,16 +10,17 @@ import org.gradle.api.artifacts.PublishArtifact import org.gradle.api.component.ComponentWithCoordinates import org.gradle.api.publish.maven.MavenPublication import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinTarget -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetComponentWithPublication +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.COMPILE +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.RUNTIME import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetComponent.TargetProvider -import org.jetbrains.kotlin.gradle.plugin.mpp.getCoordinatesFromPublicationDelegateAndProject import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly internal class ExternalKotlinTargetComponent( - val targetProvider: TargetProvider -) : KotlinTargetComponentWithPublication, ComponentWithCoordinates { + val targetProvider: TargetProvider, +) : InternalKotlinTargetComponent(), KotlinTargetComponentWithPublication, ComponentWithCoordinates { /* Target creation requires this component. We will provide the target once it is required @@ -37,7 +38,7 @@ internal class ExternalKotlinTargetComponent( /* Required for getting correct coordinates */ override var publicationDelegate: MavenPublication? = null - override val target: KotlinTarget by lazy { targetProvider() } + override val target: DecoratedExternalKotlinTarget by lazy { targetProvider() } override val publishable: Boolean get() = target.publishable @@ -60,4 +61,23 @@ internal class ExternalKotlinTargetComponent( override fun getCoordinates(): ModuleVersionIdentifier = getCoordinatesFromPublicationDelegateAndProject(publicationDelegate, target.project, null) + + private val _usages: Set by lazy { + val compilation = target.compilations.findByName(KotlinCompilation.MAIN_COMPILATION_NAME) + ?: error("Missing conventional '${KotlinCompilation.MAIN_COMPILATION_NAME}' compilation in '$target'") + + setOf( + DefaultKotlinUsageContext(compilation, COMPILE, target.apiElementsPublishedConfiguration.name), + DefaultKotlinUsageContext(compilation, RUNTIME, target.runtimeElementsPublishedConfiguration.name), + DefaultKotlinUsageContext( + compilation = compilation, + mavenScope = null, + dependencyConfigurationName = target.sourcesElementsPublishedConfiguration.name, + includeIntoProjectStructureMetadata = false, + publishOnlyIf = { target.isSourcesPublishable } + ) + ) + } + + override fun getUsages(): Set = _usages.filter { it.publishOnlyIf.predicate() }.toSet() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetSoftwareComponent.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetSoftwareComponent.kt index fdbd2cf9f4b..93942c6e193 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetSoftwareComponent.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetSoftwareComponent.kt @@ -1,13 +1,11 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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.external import org.gradle.api.artifacts.ModuleVersionIdentifier -import org.gradle.api.component.ComponentWithCoordinates -import org.gradle.api.component.ComponentWithVariants import org.gradle.api.component.SoftwareComponent import org.gradle.api.component.SoftwareComponentFactory import org.gradle.api.internal.component.SoftwareComponentInternal @@ -15,8 +13,11 @@ import org.gradle.api.internal.component.UsageContext import org.gradle.api.internal.project.ProjectInternal import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.launch +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetSoftwareComponent import org.jetbrains.kotlin.tooling.core.UnsafeApi + internal fun ExternalKotlinTargetSoftwareComponent( target: ExternalKotlinTargetImpl, ): ExternalKotlinTargetSoftwareComponent { @@ -39,7 +40,7 @@ internal fun ExternalKotlinTargetSoftwareComponent( return ExternalKotlinTargetSoftwareComponent( target.project.multiplatformExtension, adhocSoftwareComponent as SoftwareComponentInternal, - target.kotlinTargetComponent + target.kotlinTargetComponent, ) } @@ -47,7 +48,8 @@ internal class ExternalKotlinTargetSoftwareComponent @UnsafeApi constructor( private val multiplatformExtension: KotlinMultiplatformExtension, private val adhocSoftwareComponent: SoftwareComponentInternal, private val kotlinTargetComponent: ExternalKotlinTargetComponent, -) : ComponentWithCoordinates, ComponentWithVariants, SoftwareComponentInternal { +) : KotlinTargetSoftwareComponent() { + override fun getName(): String = adhocSoftwareComponent.name override fun getUsages(): Set = adhocSoftwareComponent.usages override fun getVariants(): Set = multiplatformExtension.metadata().components diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinVariants.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinVariants.kt index 1cf205843ba..002a4f96d0e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinVariants.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinVariants.kt @@ -59,7 +59,7 @@ private interface KotlinTargetComponentWithCoordinatesAndPublication : open class KotlinVariant( val producingCompilation: KotlinCompilation<*>, private val usages: Set -) : KotlinTargetComponentWithPublication, SoftwareComponentInternal { +) : InternalKotlinTargetComponent(), KotlinTargetComponentWithPublication { var componentName: String? = null var artifactTargetName: String = target.targetName @@ -112,7 +112,7 @@ class JointAndroidKotlinTargetComponent( override val target: KotlinAndroidTarget, private val nestedVariants: Set, val flavorNames: List -) : KotlinTargetComponentWithCoordinatesAndPublication, SoftwareComponentInternal { +) : InternalKotlinTargetComponent(), KotlinTargetComponentWithCoordinatesAndPublication { override fun getUsages(): Set = nestedVariants.filter { it.publishable }.flatMap { it.usages }.toSet() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index 16b0ae26fe2..ced3d3e8704 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -12,7 +12,6 @@ import org.gradle.api.attributes.Category import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE import org.gradle.api.file.FileCollection -import org.gradle.api.internal.component.SoftwareComponentInternal import org.gradle.api.plugins.BasePlugin import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.Jar @@ -189,7 +188,7 @@ class KotlinMetadataTargetConfigurator : private fun createMetadataCompilationsForCommonSourceSets( target: KotlinMetadataTarget, - allMetadataJar: TaskProvider + allMetadataJar: TaskProvider, ) = target.project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseDsl) { withRestrictedStages(KotlinPluginLifecycle.Stage.upTo(KotlinPluginLifecycle.Stage.FinaliseCompilations)) { // Do this after all targets are configured by the user build script @@ -255,7 +254,7 @@ class KotlinMetadataTargetConfigurator : } private fun exportDependenciesForPublishing( - compilation: KotlinCompilation<*> + compilation: KotlinCompilation<*>, ) { val sourceSet = compilation.defaultSourceSet val isSharedNativeCompilation = compilation is KotlinSharedNativeCompilation @@ -295,7 +294,7 @@ class KotlinMetadataTargetConfigurator : target: KotlinMetadataTarget, sourceSet: KotlinSourceSet, allMetadataJar: TaskProvider, - isHostSpecific: Boolean + isHostSpecific: Boolean, ): KotlinCompilation<*> { val project = target.project @@ -392,7 +391,7 @@ class KotlinMetadataTargetConfigurator : } internal class NativeSharedCompilationProcessor( - private val compilation: KotlinSharedNativeCompilation + private val compilation: KotlinSharedNativeCompilation, ) : KotlinCompilationProcessor(KotlinCompilationInfo(compilation)) { override val kotlinTask: TaskProvider = @@ -472,18 +471,14 @@ internal suspend fun getCommonSourceSetsForMetadataCompilation(project: Project) internal suspend fun getPublishedPlatformCompilations(project: Project): Map> { val result = mutableMapOf>() - project.multiplatformExtension.awaitTargets().withType(AbstractKotlinTarget::class.java).forEach { target -> + project.multiplatformExtension.awaitTargets().withType(InternalKotlinTarget::class.java).forEach { target -> if (target.platformType == KotlinPlatformType.common) return@forEach target.kotlinComponents - .filterIsInstance() - .forEach { component -> - component.usages - .filterIsInstance() - .filter { it.includeIntoProjectStructureMetadata } - .forEach { usage -> result[usage] = usage.compilation } - } + .flatMap { component -> component.internal.usages } + .filter { it.includeIntoProjectStructureMetadata } + .forEach { usage -> result[usage] = usage.compilation } } return result diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/InternalKotlinTargetComponentTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/InternalKotlinTargetComponentTest.kt new file mode 100644 index 00000000000..7333ba7feac --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/InternalKotlinTargetComponentTest.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2023 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.unitTests + +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent +import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinTargetComponent +import org.jetbrains.kotlin.gradle.util.assertAllImplementationsAlsoImplement +import kotlin.test.Test + +class InternalKotlinTargetComponentTest { + @Test + fun `test - all implementations of KotlinTargetComponent - implement InternalKotlinTargetComponent`() { + assertAllImplementationsAlsoImplement(KotlinTargetComponent::class, InternalKotlinTargetComponent::class) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt index 1e1ffb09922..9769e1dc795 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/MppPublicationTest.kt @@ -124,7 +124,7 @@ class MppPublicationTest { for ((targetName, sourceElements) in sourcesElements) { assertTrue( - message = "Sources Elements of target $targetName doesn't have 'userAttribute'" + message = "$sourceElements of target $targetName doesn't have 'userAttribute'" ) { sourceElements.attributes.toMapOfStrings().containsKey("userAttribute") } } } @@ -143,6 +143,7 @@ class MppPublicationTest { @Test fun `sourcesJar task should be available during configuration time`() { kotlin.linuxX64("linux") + project.evaluate() val sourcesJars = listOf( "sourcesJar", // sources of common source sets i.e. root module @@ -187,6 +188,7 @@ class MppPublicationTest { fun `test that sourcesJar tasks still exist even if sources should not be published`() { kotlin.linuxX64("linux") kotlin.withSourcesJar(publish = false) + project.evaluate() val sourcesJars = listOf( "sourcesJar", // sources of common source sets i.e. root module diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt index b669cf66820..9272495e3fa 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ProjectCompilerOptionsTests.kt @@ -190,7 +190,7 @@ class ProjectCompilerOptionsTests { } } - assertEquals(true, project.kotlinJvmTask("compileFakeKotlinFake").compilerOptions.javaParameters.get()) + assertEquals(true, project.kotlinJvmTask("compileKotlinFake").compilerOptions.javaParameters.get()) assertEquals(true, project.kotlinJvmTask("compileTestKotlinFake").compilerOptions.javaParameters.get()) } @@ -199,7 +199,7 @@ class ProjectCompilerOptionsTests { val project = buildProjectWithMPP() project.runLifecycleAwareTest { tasks.withType().configureEach { - if (it.name == "compileFakeKotlinFake") { + if (it.name == "compileKotlinFake") { it.compilerOptions.javaParameters.set(false) } } @@ -215,7 +215,7 @@ class ProjectCompilerOptionsTests { } } - assertEquals(false, project.kotlinJvmTask("compileFakeKotlinFake").compilerOptions.javaParameters.get()) + assertEquals(false, project.kotlinJvmTask("compileKotlinFake").compilerOptions.javaParameters.get()) assertEquals(true, project.kotlinJvmTask("compileTestKotlinFake").compilerOptions.javaParameters.get()) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/externalTargetApiUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/externalTargetApiUtils.kt index 1582017a968..6f9ed6729a9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/externalTargetApiUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/externalTargetApiUtils.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.util import org.gradle.api.NamedDomainObjectContainer import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.mpp.external.* import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.CompilationFactory @@ -18,6 +19,7 @@ class FakeCompilation(delegate: Delegate) : DecoratedExternalKotlinCompilation(d override val compilerOptions: HasCompilerOptions get() = super.compilerOptions as HasCompilerOptions } + class FakeTarget(delegate: Delegate) : DecoratedExternalKotlinTarget(delegate) { @Suppress("UNCHECKED_CAST") @@ -40,7 +42,7 @@ fun ExternalKotlinTargetDescriptorBuilder.defaults() { fun ExternalKotlinCompilationDescriptorBuilder.defaults( kotlin: KotlinMultiplatformExtension, - name: String = "fake" + name: String = KotlinCompilation.MAIN_COMPILATION_NAME, ) { compilationName = name compilationFactory = CompilationFactory(::FakeCompilation)