[KPM] Replace 'fun interface' in favor of factory functions

This commit is contained in:
sebastian.sellmair
2022-01-21 10:40:54 +01:00
committed by Space
parent c684588ebb
commit 6720742b84
17 changed files with 222 additions and 130 deletions
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.external.createExternalJvmVariant
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
fun KotlinGradleModule.createKotlinAndroidVariant(androidVariant: BaseVariant) {
val androidOutgoingArtifacts = FragmentArtifacts<KotlinJvmVariant> { fragment ->
val androidOutgoingArtifacts = FragmentArtifacts<KotlinJvmVariant> {
variants.create("classes") { variant ->
variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type)
variant.artifact(project.provider { fragment.compilationOutputs.classesDirs.singleFile }) {
@@ -26,14 +26,14 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
)
}
private val testFragment by lazy {
private val dummyFragment by lazy {
KotlinCommonFragmentFactory(kotlin.main).create("testFragment")
}
@Test
fun `test withProvider`() {
val testDefinition = ConfigurationDefinition<KotlinGradleFragment>(
provider = { project.configurations.create("a") }
provider = ConfigurationProvider { project.configurations.create("a") }
).withConfigurationProvider { project.configurations.create("b") }
assertEquals(
@@ -60,14 +60,14 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
val testConfiguration = project.configurations.create("dummy")
val fragmentAttributes1 = FragmentAttributes<KotlinGradleFragment> {
assertSame(testConfiguration.attributes, this)
assertSame(testConfiguration.attributes, attributes)
assertNull(attributes.getAttribute(testAttribute1))
assertNull(attributes.getAttribute(testAttribute2))
attribute(testAttribute1, "value1")
}
val fragmentAttributes2 = FragmentAttributes<KotlinGradleFragment> {
assertSame(testConfiguration.attributes, this)
assertSame(testConfiguration.attributes, attributes)
assertEquals(attributes.getAttribute(testAttribute1), "value1")
assertNull(attributes.getAttribute(testAttribute2))
attribute(testAttribute2, "value2")
@@ -81,7 +81,7 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
listOf(fragmentAttributes1, fragmentAttributes2), composite.children
)
testConfiguration.attributes.attributes(composite, testFragment)
composite.setAttributes(testConfiguration.attributes, dummyFragment)
assertEquals(
"value1", testConfiguration.attributes.getAttribute(testAttribute1),
@@ -97,7 +97,7 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
@Test
fun `test definition + attributes`() {
val definition = ConfigurationDefinition<KotlinGradleFragment>(
provider = { project.configurations.create("a") }
provider = ConfigurationProvider { project.configurations.create("a") }
)
val attributes1 = FragmentAttributes<KotlinGradleFragment> { }
@@ -131,7 +131,7 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
)
project.configurations.create("dummy").apply {
outgoing.artifacts(composite, testFragment)
composite.addArtifacts(outgoing, dummyFragment)
assertEquals(
project.files("artifact1.jar", "artifact2-a.jar", "artifact2-b.jar").toSet(),
outgoing.artifacts.files.toSet()
@@ -142,7 +142,7 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
@Test
fun `test definition + artifacts`() {
val definition = ConfigurationDefinition<KotlinGradleFragment>(
provider = { throw NotImplementedError() }
provider = ConfigurationProvider { throw NotImplementedError() }
)
val artifacts1 = FragmentArtifacts<KotlinGradleFragment> {}
@@ -174,7 +174,7 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
listOf(capabilities1, capabilities2), composite.children
)
val dummyContext = object : KotlinGradleFragmentConfigurationCapabilities.Context {
val testCapabilitiesContainer = object : KotlinGradleFragmentConfigurationCapabilities.CapabilitiesContainer {
val setCapabilities = mutableListOf<Any>()
override fun capability(notation: Any) {
setCapabilities.add(notation)
@@ -184,9 +184,10 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
}
dummyContext.capabilities(composite, testFragment)
composite.setCapabilities(testCapabilitiesContainer, dummyFragment)
assertEquals(
listOf<Any>("capability1", "capability2"), dummyContext.setCapabilities,
listOf<Any>("capability1", "capability2"), testCapabilitiesContainer.setCapabilities,
"Expected 'dummyContext' to receive all capabilities"
)
}
@@ -194,7 +195,7 @@ class KotlinFragmentConfigurationDefinitionTest : AbstractKpmExtensionTest() {
@Test
fun `test definition + capability`() {
val definition = ConfigurationDefinition<KotlinGradleFragment>(
provider = { throw NotImplementedError() }
provider = ConfigurationProvider { throw NotImplementedError() }
)
val capabilities1 = FragmentCapabilities<KotlinGradleFragment> {}
@@ -87,8 +87,8 @@ class KotlinJvmVariantFactoryTest : AbstractKpmExtensionTest() {
fun `test custom configure compileDependenciesConfiguration`() {
val variant = KotlinJvmVariantFactory(
kotlin.main, KotlinJvmVariantConfig(
compileDependencies = DefaultKotlinCompileDependenciesDefinition + FragmentAttributes { fragment ->
assertSame(fragment.compileDependenciesConfiguration.attributes, this)
compileDependencies = DefaultKotlinCompileDependenciesDefinition + FragmentAttributes {
assertSame(fragment.compileDependenciesConfiguration.attributes, attributes)
attribute(testAttribute, "compileDependencies")
}
)
@@ -103,8 +103,8 @@ class KotlinJvmVariantFactoryTest : AbstractKpmExtensionTest() {
fun `test custom configure runtimeDependenciesConfiguration`() {
val variant = KotlinJvmVariantFactory(
kotlin.main, KotlinJvmVariantConfig(
runtimeDependencies = DefaultKotlinRuntimeDependenciesDefinition + FragmentAttributes { fragment ->
assertSame(fragment.runtimeDependenciesConfiguration.attributes, this)
runtimeDependencies = DefaultKotlinRuntimeDependenciesDefinition + FragmentAttributes {
assertSame(fragment.runtimeDependenciesConfiguration.attributes, attributes)
attribute(testAttribute, "runtimeDependencies")
}
)
@@ -119,8 +119,8 @@ class KotlinJvmVariantFactoryTest : AbstractKpmExtensionTest() {
fun `test custom configure apiElementsConfiguration`() {
val variant = KotlinJvmVariantFactory(
kotlin.main, KotlinJvmVariantConfig(
apiElements = DefaultKotlinApiElementsDefinition + FragmentAttributes { fragment ->
assertSame(fragment.apiElementsConfiguration.attributes, this)
apiElements = DefaultKotlinApiElementsDefinition + FragmentAttributes {
assertSame(fragment.apiElementsConfiguration.attributes, attributes)
attribute(testAttribute, "apiElements")
}
)
@@ -135,8 +135,8 @@ class KotlinJvmVariantFactoryTest : AbstractKpmExtensionTest() {
fun `test custom configure runtimeElementsConfiguration`() {
val variant = KotlinJvmVariantFactory(
kotlin.main, KotlinJvmVariantConfig(
runtimeElements = DefaultKotlinRuntimeElementsDefinition + FragmentAttributes { fragment ->
assertSame(fragment.runtimeElementsConfiguration.attributes, this)
runtimeElements = DefaultKotlinRuntimeElementsDefinition + FragmentAttributes {
assertSame(fragment.runtimeElementsConfiguration.attributes, attributes)
attribute(testAttribute, "runtimeElements")
}
)
@@ -10,7 +10,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.gradle.api.attributes.java.TargetJvmEnvironment
import org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE
import org.gradle.kotlin.dsl.named
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
@@ -21,34 +20,34 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.producerRuntimeUsage
import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
val KotlinFragmentPlatformAttributes = FragmentAttributes<KotlinGradleVariant> { fragment ->
val KotlinFragmentPlatformAttributes = FragmentAttributes<KotlinGradleVariant> {
if (isGradleVersionAtLeast(7, 0) && fragment.platformType == KotlinPlatformType.jvm) {
attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, fragment.project.objects.named(TargetJvmEnvironment.STANDARD_JVM))
namedAttribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, TargetJvmEnvironment.STANDARD_JVM)
}
attribute(KotlinPlatformType.attribute, fragment.platformType)
}
val KotlinFragmentConsumerApiUsageAttribute = FragmentAttributes<KotlinGradleVariant> { fragment ->
attribute(USAGE_ATTRIBUTE, consumerApiUsage(fragment.project, fragment.platformType))
val KotlinFragmentConsumerApiUsageAttribute = FragmentAttributes<KotlinGradleVariant> {
attribute(USAGE_ATTRIBUTE, consumerApiUsage(project, fragment.platformType))
}
val KotlinFragmentProducerApiUsageAttribute = FragmentAttributes<KotlinGradleVariant> { fragment ->
val KotlinFragmentProducerApiUsageAttribute = FragmentAttributes<KotlinGradleVariant> {
attribute(USAGE_ATTRIBUTE, producerApiUsage(fragment.project, fragment.platformType))
}
val KotlinFragmentConsumerRuntimeUsageAttribute = FragmentAttributes<KotlinGradleVariant> { fragment ->
val KotlinFragmentConsumerRuntimeUsageAttribute = FragmentAttributes<KotlinGradleVariant> {
attribute(USAGE_ATTRIBUTE, consumerRuntimeUsage(fragment.project, fragment.platformType))
}
val KotlinFragmentProducerRuntimeUsageAttribute = FragmentAttributes<KotlinGradleVariant> { fragment ->
val KotlinFragmentProducerRuntimeUsageAttribute = FragmentAttributes<KotlinGradleVariant> {
attribute(USAGE_ATTRIBUTE, producerRuntimeUsage(fragment.project, fragment.platformType))
}
val KotlinFragmentMetadataUsageAttribute = FragmentAttributes<KotlinGradleVariant> { fragment ->
val KotlinFragmentMetadataUsageAttribute = FragmentAttributes<KotlinGradleFragment> {
attribute(USAGE_ATTRIBUTE, fragment.project.usageByName(KotlinUsages.KOTLIN_METADATA))
}
val KotlinFragmentKonanTargetAttribute = FragmentAttributes<KotlinNativeVariantInternal> { fragment ->
attribute(KotlinNativeTarget.konanTargetAttribute, fragment.konanTarget.name)
val KotlinFragmentKonanTargetAttribute = FragmentAttributes<KotlinNativeVariantInternal> {
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, fragment.konanTarget.name)
}
@@ -10,70 +10,70 @@ import org.gradle.api.attributes.Category
val DefaultKotlinCompileDependenciesDefinition = KotlinGradleFragmentConfigurationDefinition(
provider = {
provider = ConfigurationProvider {
project.configurations.maybeCreate(disambiguateName("compileDependencies")).apply {
isCanBeConsumed = false
isCanBeResolved = true
}
},
relations = { configuration ->
configuration.extendsFrom(dependencies.transitiveApiConfiguration)
configuration.extendsFrom(dependencies.transitiveImplementationConfiguration)
relations = FragmentConfigurationRelation {
extendsFrom(dependencies.transitiveApiConfiguration)
extendsFrom(dependencies.transitiveImplementationConfiguration)
},
attributes = KotlinFragmentPlatformAttributes + KotlinFragmentConsumerApiUsageAttribute
)
val DefaultKotlinRuntimeDependenciesDefinition = ConfigurationDefinition(
provider = {
provider = ConfigurationProvider {
project.configurations.maybeCreate(disambiguateName("runtimeDependencies")).apply {
isCanBeConsumed = false
isCanBeResolved = true
}
},
attributes = KotlinFragmentPlatformAttributes + KotlinFragmentConsumerRuntimeUsageAttribute,
relations = { configuration ->
configuration.extendsFrom(dependencies.transitiveApiConfiguration)
configuration.extendsFrom(dependencies.transitiveImplementationConfiguration)
relations = FragmentConfigurationRelation {
extendsFrom(dependencies.transitiveApiConfiguration)
extendsFrom(dependencies.transitiveImplementationConfiguration)
}
)
val DefaultKotlinApiElementsDefinition = ConfigurationDefinition(
provider = {
module.project.configurations.maybeCreate(disambiguateName("apiElements")).apply {
provider = ConfigurationProvider {
project.configurations.maybeCreate(disambiguateName("apiElements")).apply {
isCanBeResolved = false
isCanBeConsumed = false
module.ifMadePublic { isCanBeConsumed = true }
}
},
relations = { configuration -> configuration.extendsFrom(dependencies.transitiveApiConfiguration) },
relations = FragmentConfigurationRelation { extendsFrom(dependencies.transitiveApiConfiguration) },
capabilities = KotlinFragmentModuleCapability,
attributes = KotlinFragmentPlatformAttributes + KotlinFragmentProducerApiUsageAttribute + { fragment ->
attributes = KotlinFragmentPlatformAttributes + KotlinFragmentProducerApiUsageAttribute + FragmentAttributes {
attribute(Category.CATEGORY_ATTRIBUTE, fragment.project.objects.named(Category::class.java, Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, fragment.project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
},
)
val DefaultKotlinRuntimeElementsDefinition = ConfigurationDefinition(
provider = {
module.project.configurations.maybeCreate(disambiguateName("runtimeElements")).apply {
provider = ConfigurationProvider {
project.configurations.maybeCreate(disambiguateName("runtimeElements")).apply {
isCanBeResolved = false
isCanBeConsumed = false
module.ifMadePublic { isCanBeConsumed = true }
}
},
relations = { configuration ->
configuration.extendsFrom(dependencies.transitiveApiConfiguration)
configuration.extendsFrom(dependencies.transitiveImplementationConfiguration)
relations = FragmentConfigurationRelation {
extendsFrom(dependencies.transitiveApiConfiguration)
extendsFrom(dependencies.transitiveImplementationConfiguration)
},
attributes = KotlinFragmentPlatformAttributes + KotlinFragmentProducerRuntimeUsageAttribute + { fragment ->
attributes.attribute(Category.CATEGORY_ATTRIBUTE, fragment.project.objects.named(Category::class.java, Category.LIBRARY))
attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, fragment.project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
attributes = KotlinFragmentPlatformAttributes + KotlinFragmentProducerRuntimeUsageAttribute + FragmentAttributes {
attribute(Category.CATEGORY_ATTRIBUTE, fragment.project.objects.named(Category::class.java, Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, fragment.project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
},
capabilities = KotlinFragmentModuleCapability.onlyIfMadePublic()
)
val DefaultKotlinHostSpecificMetadataElementsDefinition = ConfigurationDefinition(
provider = {
provider = ConfigurationProvider {
project.configurations.maybeCreate(disambiguateName("hostSpecificMetadataElements")).apply {
isCanBeResolved = false
isCanBeConsumed = false
@@ -82,4 +82,3 @@ val DefaultKotlinHostSpecificMetadataElementsDefinition = ConfigurationDefinitio
attributes = KotlinFragmentPlatformAttributes + KotlinFragmentKonanTargetAttribute + KotlinFragmentMetadataUsageAttribute,
artifacts = KotlinFragmentHostSpecificMetadataArtifact
)
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
/**
* Registers a [Jar] task with the variant's compilation outputs and attaches this artifact to the given configuration.
*/
val KotlinFragmentCompilationOutputsJarArtifact = FragmentArtifacts<KotlinGradleVariant> { fragment ->
artifact(fragment.project.locateOrRegisterTask<Jar>(fragment.disambiguateName("jar")) {
val KotlinFragmentCompilationOutputsJarArtifact = FragmentArtifacts<KotlinGradleVariant> {
artifact(project.locateOrRegisterTask<Jar>(fragment.disambiguateName("jar")) {
it.from(fragment.compilationOutputs.allOutputs)
it.archiveClassifier.set(dashSeparatedName(fragment.name, fragment.containingModule.moduleClassifier))
})
@@ -19,8 +19,7 @@ import org.jetbrains.kotlin.project.model.refinesClosure
* Will add this jar artifact to the given configuration
*/
val KotlinFragmentHostSpecificMetadataArtifact = FragmentArtifacts<KotlinNativeVariantInternal> artifacts@{ fragment ->
val project = fragment.project
val KotlinFragmentHostSpecificMetadataArtifact = FragmentArtifacts<KotlinNativeVariantInternal> artifacts@{
val hostSpecificMetadataElements = fragment.hostSpecificMetadataElementsConfiguration ?: return@artifacts
val hostSpecificMetadataJar = project.registerTask<Jar>(fragment.disambiguateName("hostSpecificMetadataJar")) { jar ->
@@ -9,7 +9,7 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.capabilities.Capability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability
val KotlinFragmentModuleCapability = FragmentCapabilities<KotlinGradleFragment> { fragment ->
val KotlinFragmentModuleCapability = FragmentCapabilities<KotlinGradleFragment> {
capability(fragment.containingModule.moduleCapability ?: return@FragmentCapabilities)
}
@@ -5,31 +5,47 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.Project
import org.gradle.api.artifacts.ConfigurationPublications
/* Internal abbreviation */
internal typealias FragmentArtifacts<T> = KotlinGradleFragmentConfigurationArtifacts<T>
fun interface KotlinGradleFragmentConfigurationArtifacts<in T : KotlinGradleFragment> {
fun ConfigurationPublications.addArtifacts(fragment: T)
interface KotlinGradleFragmentConfigurationArtifacts<in T : KotlinGradleFragment> {
fun addArtifacts(outgoing: ConfigurationPublications, fragment: T)
companion object {
val None = FragmentArtifacts<KotlinGradleFragment> {}
object None : KotlinGradleFragmentConfigurationArtifacts<KotlinGradleFragment> {
override fun addArtifacts(outgoing: ConfigurationPublications, fragment: KotlinGradleFragment) = Unit
}
}
fun <T : KotlinGradleFragment> ConfigurationPublications.artifacts(
artifacts: FragmentArtifacts<T>, fragment: T
) = with(artifacts) { addArtifacts(fragment) }
class KotlinGradleFragmentConfigurationArtifactsContext<T : KotlinGradleFragment> internal constructor(
internal val outgoing: ConfigurationPublications,
val fragment: T
) : ConfigurationPublications by outgoing {
val project: Project get() = fragment.project
}
@Suppress("FunctionName")
fun <T : KotlinGradleFragment> FragmentArtifacts(
addArtifacts: KotlinGradleFragmentConfigurationArtifactsContext<T>.() -> Unit
): KotlinGradleFragmentConfigurationArtifacts<T> {
return object : KotlinGradleFragmentConfigurationArtifacts<T> {
override fun addArtifacts(outgoing: ConfigurationPublications, fragment: T) {
val context = KotlinGradleFragmentConfigurationArtifactsContext(outgoing, fragment)
context.addArtifacts()
}
}
}
operator fun <T : KotlinGradleFragment> FragmentArtifacts<T>.plus(other: FragmentArtifacts<T>): FragmentArtifacts<T> {
if (this === KotlinGradleFragmentConfigurationArtifacts.None) return other
if (other === KotlinGradleFragmentConfigurationArtifacts.None) return this
if (this is CompositeFragmentArtifacts && other is CompositeFragmentArtifacts) {
return CompositeFragmentArtifacts(this.children + other.children)
}
if (this === FragmentArtifacts.None) return other
if (other === FragmentArtifacts.None) return this
if (this is CompositeFragmentArtifacts) {
return CompositeFragmentArtifacts(this.children + other)
}
@@ -43,7 +59,8 @@ operator fun <T : KotlinGradleFragment> FragmentArtifacts<T>.plus(other: Fragmen
internal class CompositeFragmentArtifacts<in T : KotlinGradleFragment>(val children: List<FragmentArtifacts<T>>) :
FragmentArtifacts<T> {
override fun ConfigurationPublications.addArtifacts(fragment: T) {
children.forEach { child -> artifacts(child, fragment) }
override fun addArtifacts(outgoing: ConfigurationPublications, fragment: T) {
children.forEach { child -> child.addArtifacts(outgoing, fragment) }
}
}
@@ -5,31 +5,58 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.Named
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer
/* Internal abbreviation */
internal typealias FragmentAttributes<T> = KotlinGradleFragmentConfigurationAttributes<T>
fun interface KotlinGradleFragmentConfigurationAttributes<in T : KotlinGradleFragment> {
fun AttributeContainer.setAttributes(fragment: T)
interface KotlinGradleFragmentConfigurationAttributes<in T : KotlinGradleFragment> {
companion object {
val None = FragmentAttributes<KotlinGradleFragment> {}
fun setAttributes(attributes: AttributeContainer, fragment: T)
object None : FragmentAttributes<KotlinGradleFragment> {
override fun setAttributes(attributes: AttributeContainer, fragment: KotlinGradleFragment) = Unit
}
}
fun <T : KotlinGradleFragment> AttributeContainer.attributes(attributes: FragmentAttributes<T>, fragment: T) = with(attributes) {
setAttributes(fragment)
class KotlinGradleFragmentConfigurationAttributesContext<T : KotlinGradleFragment> internal constructor(
internal val attributes: AttributeContainer,
val fragment: T,
) : AttributeContainer by attributes {
val project: Project get() = fragment.project
inline fun <reified T : Named> named(name: String): T = project.objects.named(T::class.java, name)
inline fun <reified T : Named> namedAttribute(key: Attribute<T>, name: String) = apply { attribute(key, named(name)) }
override fun <K : Any> attribute(key: Attribute<K>, value: K): KotlinGradleFragmentConfigurationAttributesContext<T> = apply {
attributes.attribute(key, value)
}
}
@Suppress("FunctionName")
fun <T : KotlinGradleFragment> FragmentAttributes(
setAttributes: KotlinGradleFragmentConfigurationAttributesContext<T>.() -> Unit
): KotlinGradleFragmentConfigurationAttributes<T> {
return object : KotlinGradleFragmentConfigurationAttributes<T> {
override fun setAttributes(attributes: AttributeContainer, fragment: T) {
val context = KotlinGradleFragmentConfigurationAttributesContext(attributes, fragment)
context.setAttributes()
}
}
}
operator fun <T : KotlinGradleFragment> FragmentAttributes<T>.plus(other: FragmentAttributes<T>): FragmentAttributes<T> {
if (this === KotlinGradleFragmentConfigurationAttributes.None) return other
if (other === KotlinGradleFragmentConfigurationAttributes.None) return this
if (this is CompositeFragmentAttributes && other is CompositeFragmentAttributes) {
return CompositeFragmentAttributes(this.children + other.children)
}
if (this === FragmentAttributes.None) return other
if (other === FragmentAttributes.None) return this
if (this is CompositeFragmentAttributes) {
return CompositeFragmentAttributes(this.children + other)
}
@@ -43,7 +70,7 @@ operator fun <T : KotlinGradleFragment> FragmentAttributes<T>.plus(other: Fragme
internal class CompositeFragmentAttributes<in T : KotlinGradleFragment>(val children: List<FragmentAttributes<T>>) :
FragmentAttributes<T> {
override fun AttributeContainer.setAttributes(fragment: T) {
children.forEach { attribute -> attributes(attribute, fragment) }
override fun setAttributes(attributes: AttributeContainer, fragment: T) {
children.forEach { child -> child.setAttributes(attributes, fragment) }
}
}
@@ -3,52 +3,80 @@
* 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.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationPublications
import org.gradle.api.capabilities.Capability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleFragmentConfigurationCapabilities.CapabilitiesContainer
/* Internal abbreviation */
internal typealias FragmentCapabilities<T> = KotlinGradleFragmentConfigurationCapabilities<T>
fun interface KotlinGradleFragmentConfigurationCapabilities<in T : KotlinGradleFragment> {
interface Context {
interface KotlinGradleFragmentConfigurationCapabilities<in T : KotlinGradleFragment> {
interface CapabilitiesContainer {
fun capability(notation: Any)
val capabilities: List<Capability>
}
class ContextImpl internal constructor(
private val configuration: Configuration
) : Context {
override fun capability(notation: Any) = configuration.outgoing.capability(notation)
override val capabilities: List<Capability> get() = configuration.outgoing.capabilities.orEmpty().toList()
}
fun setCapabilities(container: CapabilitiesContainer, fragment: T)
fun Context.setCapabilities(fragment: T)
companion object {
val None = FragmentCapabilities<KotlinGradleFragment> {}
object None : KotlinGradleFragmentConfigurationCapabilities<KotlinGradleFragment> {
override fun setCapabilities(container: CapabilitiesContainer, fragment: KotlinGradleFragment) = Unit
}
}
fun <T : KotlinGradleFragment> KotlinGradleFragmentConfigurationCapabilities<T>.onlyIfMadePublic(): KotlinGradleFragmentConfigurationCapabilities<T> {
return KotlinGradleFragmentConfigurationCapabilities { fragment ->
fragment.containingModule.ifMadePublic { capabilities(this@onlyIfMadePublic, fragment) }
fun <T : KotlinGradleFragment> KotlinGradleFragmentConfigurationCapabilities<T>.setCapabilities(
publications: ConfigurationPublications, fragment: T
) = setCapabilities(CapabilitiesContainer(publications), fragment)
fun CapabilitiesContainer(configuration: ConfigurationPublications): CapabilitiesContainer =
CapabilitiesContainerImpl(configuration)
fun CapabilitiesContainer(configuration: Configuration): CapabilitiesContainer =
CapabilitiesContainerImpl(configuration.outgoing)
private class CapabilitiesContainerImpl(
private val publications: ConfigurationPublications
) : CapabilitiesContainer {
override fun capability(notation: Any) = publications.capability(notation)
override val capabilities: List<Capability> get() = publications.capabilities.orEmpty().toList()
}
class KotlinGradleFragmentConfigurationCapabilitiesContext<T : KotlinGradleFragment> internal constructor(
internal val container: CapabilitiesContainer, val fragment: T
) : CapabilitiesContainer by container {
val project: Project get() = fragment.project
}
fun <T : KotlinGradleFragment> FragmentCapabilities(
setCapabilities: KotlinGradleFragmentConfigurationCapabilitiesContext<T>.() -> Unit
): KotlinGradleFragmentConfigurationCapabilities<T> = object : KotlinGradleFragmentConfigurationCapabilities<T> {
override fun setCapabilities(container: CapabilitiesContainer, fragment: T) {
val context = KotlinGradleFragmentConfigurationCapabilitiesContext(container, fragment)
context.setCapabilities()
}
}
fun <T : KotlinGradleFragment> KotlinGradleFragmentConfigurationCapabilities.Context.capabilities(
capabilities: KotlinGradleFragmentConfigurationCapabilities<T>, fragment: T
) = with(capabilities) { setCapabilities(fragment) }
fun <T : KotlinGradleFragment> KotlinGradleFragmentConfigurationCapabilities<T>.onlyIfMadePublic():
KotlinGradleFragmentConfigurationCapabilities<T> {
val decorated = this
return FragmentCapabilities {
fragment.containingModule.ifMadePublic { decorated.setCapabilities(this, fragment) }
}
}
operator fun <T : KotlinGradleFragment> FragmentCapabilities<T>.plus(other: FragmentCapabilities<T>): FragmentCapabilities<T> {
if (this === KotlinGradleFragmentConfigurationCapabilities.None) return other
if (other === KotlinGradleFragmentConfigurationCapabilities.None) return this
if (this is CompositeFragmentCapabilities && other is CompositeFragmentCapabilities) {
return CompositeFragmentCapabilities(this.children + other.children)
}
if (this === FragmentCapabilities.None) return other
if (other === FragmentCapabilities.None) return this
if (this is CompositeFragmentCapabilities) {
return CompositeFragmentCapabilities(this.children + other)
}
@@ -62,7 +90,7 @@ operator fun <T : KotlinGradleFragment> FragmentCapabilities<T>.plus(other: Frag
internal class CompositeFragmentCapabilities<in T : KotlinGradleFragment>(val children: List<FragmentCapabilities<T>>) :
FragmentCapabilities<T> {
override fun KotlinGradleFragmentConfigurationCapabilities.Context.setCapabilities(fragment: T) {
children.forEach { capability -> capabilities(capability, fragment) }
override fun setCapabilities(container: CapabilitiesContainer, fragment: T) {
children.forEach { child -> child.setCapabilities(container, fragment) }
}
}
@@ -37,7 +37,7 @@ internal class KotlinGradleFragmentConfigurationContextImpl(
fun <T : KotlinGradleFragment> KotlinGradleFragmentConfigurationDefinition<T>.withConfigurationProvider(
provider: KotlinGradleFragmentConfigurationContext.() -> Configuration
) = copy(provider = provider)
) = copy(provider = ConfigurationProvider(provider))
operator fun <T : KotlinGradleFragment> KotlinGradleFragmentConfigurationDefinition<T>.plus(other: FragmentAttributes<T>):
KotlinGradleFragmentConfigurationDefinition<T> = copy(attributes = attributes + other)
@@ -3,14 +3,17 @@
* 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
fun interface KotlinGradleFragmentConfigurationProvider {
fun KotlinGradleFragmentConfigurationContext.getConfiguration(): Configuration
interface KotlinGradleFragmentConfigurationProvider {
fun getConfiguration(context: KotlinGradleFragmentConfigurationContext): Configuration
}
internal fun KotlinGradleFragmentConfigurationProvider.getConfiguration(context: KotlinGradleFragmentConfigurationContext): Configuration {
return with(context) { getConfiguration() }
fun ConfigurationProvider(provider: KotlinGradleFragmentConfigurationContext.() -> Configuration):
KotlinGradleFragmentConfigurationProvider = object : KotlinGradleFragmentConfigurationProvider {
override fun getConfiguration(context: KotlinGradleFragmentConfigurationContext): Configuration = context.provider()
}
@@ -3,17 +3,37 @@
* 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.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
/* Internal abbreviation */
internal typealias FragmentRelation = KotlinGradleFragmentConfigurationRelation
internal typealias FragmentConfigurationRelation = KotlinGradleFragmentConfigurationRelation
fun interface KotlinGradleFragmentConfigurationRelation {
fun KotlinGradleFragmentConfigurationContext.setupExtendsFromRelations(configuration: Configuration)
interface KotlinGradleFragmentConfigurationRelation {
fun setExtendsFrom(configuration: Configuration, context: KotlinGradleFragmentConfigurationContext)
companion object {
val None = FragmentRelation {}
object None : KotlinGradleFragmentConfigurationRelation {
override fun setExtendsFrom(configuration: Configuration, context: KotlinGradleFragmentConfigurationContext) = Unit
}
}
class KotlinGradleFragmentConfigurationRelationContext internal constructor(
val configuration: Configuration,
context: KotlinGradleFragmentConfigurationContext
) : KotlinGradleFragmentConfigurationContext by context {
fun extendsFrom(configuration: Configuration) = this.configuration.extendsFrom(configuration)
fun extendsFrom(configuration: String) = project.addExtendsFromRelation(this.configuration.name, configuration)
}
fun FragmentConfigurationRelation(
setExtendsFrom: KotlinGradleFragmentConfigurationRelationContext.() -> Unit
): KotlinGradleFragmentConfigurationRelation = object : KotlinGradleFragmentConfigurationRelation {
override fun setExtendsFrom(configuration: Configuration, context: KotlinGradleFragmentConfigurationContext) {
val relationContext = KotlinGradleFragmentConfigurationRelationContext(configuration, context)
relationContext.setExtendsFrom()
}
}
@@ -51,12 +51,9 @@ class KotlinGradleFragmentFactory<T : KotlinGradleFragment>(
}
internal fun <T : KotlinGradleFragment> Configuration.configure(
definition: KotlinGradleFragmentConfigurationDefinition<T>,
fragment: T
definition: KotlinGradleFragmentConfigurationDefinition<T>, fragment: T
) {
attributes.attributes(definition.attributes, fragment)
outgoing.artifacts(definition.artifacts, fragment)
KotlinGradleFragmentConfigurationCapabilities.ContextImpl(this)
.capabilities(definition.capabilities, fragment)
definition.attributes.setAttributes(attributes, fragment)
definition.artifacts.addArtifacts(outgoing, fragment)
definition.capabilities.setCapabilities(outgoing, fragment)
}
@@ -54,23 +54,25 @@ class KotlinJvmVariantInstantiator internal constructor(
override fun create(name: String): KotlinJvmVariant {
val names = FragmentNameDisambiguation(module, name)
val context = KotlinGradleFragmentConfigurationContextImpl(module, config.dependenciesConfigurationFactory.create(module, names), names)
val context = KotlinGradleFragmentConfigurationContextImpl(
module, config.dependenciesConfigurationFactory.create(module, names), names
)
return KotlinJvmVariant(
containingModule = module,
fragmentName = name,
dependencyConfigurations = context.dependencies,
compileDependenciesConfiguration = config.compileDependencies.provider.getConfiguration(context).also { configuration ->
config.compileDependencies.relations.run { context.setupExtendsFromRelations(configuration) }
config.compileDependencies.relations.setExtendsFrom(configuration, context)
},
runtimeDependenciesConfiguration = config.runtimeDependencies.provider.getConfiguration(context).also { configuration ->
config.runtimeDependencies.relations.run { context.setupExtendsFromRelations(configuration) }
config.runtimeElements.relations.setExtendsFrom(configuration, context)
},
apiElementsConfiguration = config.apiElements.provider.getConfiguration(context).also { configuration ->
config.apiElements.relations.run { context.setupExtendsFromRelations(configuration) }
config.apiElements.relations.setExtendsFrom(configuration, context)
},
runtimeElementsConfiguration = config.runtimeElements.provider.getConfiguration(context).also { configuration ->
config.runtimeElements.relations.run { context.setupExtendsFromRelations(configuration) }
config.runtimeElements.relations.setExtendsFrom(configuration, context)
}
)
}
@@ -61,14 +61,14 @@ class KotlinNativeVariantInstantiator<T : KotlinNativeVariantInternal>(
fragmentName = name,
dependencyConfigurations = dependencies,
compileDependencyConfiguration = config.compileDependencies.provider.getConfiguration(context).also { configuration ->
config.compileDependencies.relations.run { context.setupExtendsFromRelations(configuration) }
config.compileDependencies.relations.setExtendsFrom(configuration, context)
},
apiElementsConfiguration = config.apiElements.provider.getConfiguration(context).also { configuration ->
config.apiElements.relations.run { context.setupExtendsFromRelations(configuration) }
config.apiElements.relations.setExtendsFrom(configuration, context)
},
hostSpecificMetadataElementsConfiguration =
config.hostSpecificMetadataElements.provider.getConfiguration(context).also { configuration ->
config.hostSpecificMetadataElements.relations.run { context.setupExtendsFromRelations(configuration) }
config.hostSpecificMetadataElements.relations.setExtendsFrom(configuration, context)
}
)
}