From dbd77fc785474065ed152e84d8218d085e9df8ea Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Thu, 21 Dec 2023 22:18:33 +0100 Subject: [PATCH] [Gradle] Fix eager task realization due to attributes querying Gradle 8.3+ starts triggering JVM eager tasks creating via eagerly configured attributes that we copy over from the Gradle JVM plugin for Kotlin compilation. The fix is to migrate to '.attributeProvider()' API to configure the attribute. ^KT-60664 In Progress --- .../kotlin/gradle/ConfigurationAvoidanceIT.kt | 4 +- .../kotlin/gradle/KotlinGradlePluginIT.kt | 46 ++++++++----- .../gradle/android/AndroidTargetPrototype.kt | 66 +++++++++++++++---- .../android/createAndroidCompilation.kt | 20 ++++-- .../compilerRunner/GradleCliCommonizer.kt | 11 ++-- ...tlinLegacyCompatibilityMetadataArtifact.kt | 5 +- .../artifacts/KotlinMetadataArtifact.kt | 5 +- ...otlinNativeHostSpecificMetadataArtifact.kt | 13 +++- .../artifacts/KotlinNativeKlibArtifact.kt | 5 +- .../gradle/artifacts/KotlinTargetArtifact.kt | 5 +- .../kapt/Kapt3KotlinGradleSubplugin.kt | 2 +- .../gradle/plugin/AbstractKotlinPlugin.kt | 9 +-- .../gradle/plugin/KotlinPluginWrapper.kt | 5 ++ .../gradle/plugin/KotlinTargetConfigurator.kt | 31 ++++----- ...JvmAndAndroidPlatformDependencyResolver.kt | 10 +-- ...deJvmAndAndroidSourceDependencyResolver.kt | 9 ++- .../internal/AttributesConfigurationHelper.kt | 55 ++++++++++++++++ .../plugin/mpp/HierarchyAttributeContainer.kt | 4 +- .../plugin/mpp/KotlinSoftwareComponent.kt | 12 ++-- .../mpp/KotlinTargetSoftwareComponentImpl.kt | 11 +++- .../kotlin/gradle/plugin/mpp/Publishing.kt | 8 +-- .../plugin/mpp/applyUserDefinedAttributes.kt | 21 ++++-- ...lationDependencyConfigurationsFactories.kt | 19 +++--- .../external/createExternalKotlinTarget.kt | 8 +-- .../mpp/resolvableMetadataConfiguration.kt | 9 ++- .../plugin/sources/KotlinSourceSetFactory.kt | 9 +-- .../internal/ScriptingGradleSubplugin.kt | 11 ++-- .../CreateTargetConfigurationsSideEffect.kt | 13 ++-- .../targets/android/AndroidProjectHandler.kt | 7 +- .../targets/android/KotlinAndroidTarget.kt | 3 +- .../resolver/KotlinCompilationNpmResolver.kt | 12 ++-- .../gradle/targets/jvm/KotlinJvmTarget.kt | 2 +- .../ConfigureFrameworkExportSideEffect.kt | 7 +- .../targets/native/KotlinNativeTarget.kt | 3 +- .../gradle/targets/native/NativeBinaries.kt | 6 +- .../native/configureBinaryFrameworks.kt | 14 ++-- ...CInteropCommonizerArtifactTypeAttribute.kt | 9 +-- .../CInteropCommonizerConfigurations.kt | 13 ++-- .../native/internal/CInteropConfigurations.kt | 19 +++--- .../targets/native/tasks/KotlinNativeLink.kt | 4 +- .../native/tasks/artifact/KotlinArtifact.kt | 14 ++-- .../gradle/tasks/configuration/KaptConfig.kt | 11 ++-- .../configuration/KotlinCompileConfig.kt | 11 ++-- .../utils/gradleAttributesContainerUtils.kt | 51 +++++++++++--- .../gradle/utils/gradleConfigurationUtils.kt | 10 +-- .../BinaryFrameworksCustomAttributesTest.kt | 4 +- .../KT56143CinteropConfigurationAttributes.kt | 8 +-- ...eropCommonizerArtifactTypeAttributeTest.kt | 15 +++-- .../unitTests/ExternalKotlinTargetApiTests.kt | 6 +- .../IdeaKotlinBinaryAttributesFactoryTest.kt | 10 ++- .../kotlin/gradle/plugin/PluginWrappers.kt | 2 +- .../AttributesConfigurationHelperG70.kt | 26 ++++++++ .../kotlin/gradle/plugin/PluginWrappers.kt | 2 +- .../AttributesConfigurationHelperG71.kt | 26 ++++++++ .../kotlin/gradle/plugin/PluginWrappers.kt | 2 + .../AttributesConfigurationHelperG74.kt | 35 ++++++++++ .../kotlin/gradle/plugin/PluginWrappers.kt | 1 + .../AttributesConfigurationHelperG6.kt | 26 ++++++++ 58 files changed, 563 insertions(+), 222 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelper.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG70.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG71.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG74.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG6.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationAvoidanceIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationAvoidanceIT.kt index 8413b0213c6..360df26bc69 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationAvoidanceIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationAvoidanceIT.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.gradle -import org.gradle.api.logging.configuration.WarningMode import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.DisplayName @@ -27,7 +26,8 @@ class ConfigurationAvoidanceIT : KGPBaseTest() { @JvmGradlePluginTests @GradleTestVersions( - additionalVersions = [TestVersions.Gradle.G_7_3] + additionalVersions = [TestVersions.Gradle.G_7_3], + maxVersion = TestVersions.Gradle.G_8_3 ) @DisplayName("KGP/Jvm does not eagerly configure any tasks") @GradleTest diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt index ef50d23ffd0..7a3e0ae8f28 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -648,7 +648,7 @@ class KotlinGradleIT : KGPBaseTest() { subProject("projB").buildGradle.appendText("\nkotlin.target.attributes.attribute(targetAttribute, \"bar\")") buildAndFail(":projB:compileKotlin") { when { - gradleVersion < GradleVersion.version("6.8.4") -> { + gradleVersion <= GradleVersion.version(TestVersions.Gradle.G_6_8) -> { assertOutputContains( "No matching variant of project :projA was found. The consumer was configured to find an API of a library " + "compatible with Java 8, preferably in the form of class files, " + @@ -659,14 +659,19 @@ class KotlinGradleIT : KGPBaseTest() { ) } else -> { - assertOutputContains( - "No matching variant of project :projA was found. The consumer was configured to find a library for use during compile-time, " + - "compatible with Java 8, preferably in the form of class files, " + - "preferably optimized for standard JVMs, and its dependencies declared externally, " + - "as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm', " + - "attribute 'com.example.compilation' with value 'foo', " + - "attribute 'com.example.target' with value 'bar' but:" - ) + // Attributes may come in random order + val attributeMatchingString = output.lineSequence().find { + it.trimStart().startsWith( + "> No matching variant of project :projA was found. " + + "The consumer was configured to find a library for use during compile-time, " + + "compatible with Java 8, preferably in the form of class files, " + + "preferably optimized for standard JVMs, and its dependencies declared externally, " + ) + } + assertNotNull(attributeMatchingString, "Expected variant mismatch string is not found") + assertTrue(attributeMatchingString.contains("attribute 'com.example.compilation' with value 'foo'")) + assertTrue(attributeMatchingString.contains("attribute 'com.example.target' with value 'bar'")) + assertTrue(attributeMatchingString.contains("attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'")) } } } @@ -681,7 +686,7 @@ class KotlinGradleIT : KGPBaseTest() { ) buildAndFail(":projB:compileKotlin") { when { - gradleVersion < GradleVersion.version("6.8.4") -> { + gradleVersion <= GradleVersion.version(TestVersions.Gradle.G_6_8) -> { assertOutputContains( "No matching variant of project :projA was found. The consumer was configured to find an API of a library " + "compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, " + @@ -691,14 +696,19 @@ class KotlinGradleIT : KGPBaseTest() { ) } else -> { - assertOutputContains( - "No matching variant of project :projA was found. The consumer was configured to find a library for use during compile-time, " + - "compatible with Java 8, preferably in the form of class files, preferably optimized for standard JVMs, " + - "and its dependencies declared externally, " + - "as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm', " + - "attribute 'com.example.compilation' with value 'bar', " + - "attribute 'com.example.target' with value 'foo' but:" - ) + // Attributes may come in random order + val attributeMatchingString = output.lineSequence().find { + it.contains( + "No matching variant of project :projA was found. " + + "The consumer was configured to find a library for use during compile-time, " + + "compatible with Java 8, preferably in the form of class files, " + + "preferably optimized for standard JVMs, and its dependencies declared externally, " + ) + } + assertNotNull(attributeMatchingString, "Expected variant mismatch string is not found") + assertTrue(attributeMatchingString.contains("attribute 'com.example.compilation' with value 'bar'")) + assertTrue(attributeMatchingString.contains("attribute 'com.example.target' with value 'foo'")) + assertTrue(attributeMatchingString.contains("attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'")) } } } diff --git a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt index 9b0cfef08fa..8f027e36688 100644 --- a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt +++ b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt @@ -52,8 +52,14 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge In this example we hardcoded AGP version 7.4.0-beta02 as demo */ apiElements.configure { _, configuration -> - configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) - configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */ + configuration.attributes.attributeProvider( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) } + ) + configuration.attributes.attributeProvider( + AgpVersionAttr.ATTRIBUTE, + project.provider { project.objects.named("7.4.0-beta02") } /* For demo */ + ) } /* @@ -61,8 +67,14 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge In this example we hardcoded AGP version 7.4.0-beta02 as demo */ runtimeElements.configure { _, configuration -> - configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) - configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */ + configuration.attributes.attributeProvider( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) } + ) + configuration.attributes.attributeProvider( + AgpVersionAttr.ATTRIBUTE, + project.provider { project.objects.named("7.4.0-beta02") } /* For demo */ + ) } /* @@ -70,8 +82,16 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge In this example we hardcoded AGP version 7.4.0-beta02 as demo */ sourcesElements.configure { _, configuration -> - configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) - configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */ + configuration.attributes.attributeProvider( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) } + ) + configuration.attributes.attributeProvider( + AgpVersionAttr.ATTRIBUTE, + project.provider { + project.objects.named("7.4.0-beta02") /* For demo */ + } + ) } /* @@ -80,14 +100,30 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge */ apiElementsPublished.configure { _, configuration -> /* TODO w/ Google: Find a way to deprecate this attribute */ - configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm) - configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + configuration.attributes.attributeProvider( + KotlinPlatformType.attribute, + project.provider { KotlinPlatformType.androidJvm } + ) + configuration.attributes.attributeProvider( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.provider { + project.objects.named(TargetJvmEnvironment.ANDROID) + } + ) } runtimeElementsPublished.configure { _, configuration -> /* TODO w/ Google: Find a way to deprecate this attribute */ - configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm) - configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + configuration.attributes.attributeProvider( + KotlinPlatformType.attribute, + project.provider { KotlinPlatformType.androidJvm } + ) + configuration.attributes.attributeProvider( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.provider { + project.objects.named(TargetJvmEnvironment.ANDROID) + } + ) } configureIdeImport { @@ -165,7 +201,10 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge artifactType: CLASSES_JAR */ androidTarget.apiElementsConfiguration.outgoing.variants.create("classes").let { variant -> - variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) + variant.attributes.attributeProvider( + AndroidArtifacts.ARTIFACT_TYPE, + project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type } + ) variant.artifact(mainCompilation.output.classesDirs.singleFile) { it.builtBy(mainCompilation.output.classesDirs) } @@ -178,7 +217,10 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge artifactType: CLASSES_JAR */ androidTarget.runtimeElementsConfiguration.outgoing.variants.create("classes").let { variant -> - variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) + variant.attributes.attributeProvider( + AndroidArtifacts.ARTIFACT_TYPE, + project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type } + ) variant.artifact(mainCompilation.output.classesDirs.singleFile) { it.builtBy(mainCompilation.output.classesDirs) } diff --git a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/createAndroidCompilation.kt b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/createAndroidCompilation.kt index 1e2650d8921..15b42bfe08a 100644 --- a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/createAndroidCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/createAndroidCompilation.kt @@ -41,14 +41,26 @@ internal fun PrototypeAndroidTarget.createAndroidCompilation(name: String): Prot configure { compilation -> /* Setup attributes for the compile dependencies */ compilation.configurations.compileDependencyConfiguration.apply { - attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) - attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + attributes.attributeProvider( + ARTIFACT_TYPE, + project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type } + ) + attributes.attributeProvider( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) } + ) } /* Setup attributes for the runtime dependencies */ compilation.configurations.runtimeDependencyConfiguration?.apply { - attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) - attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + attributes.attributeProvider( + ARTIFACT_TYPE, + project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type } + ) + attributes.attributeProvider( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) } + ) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCliCommonizer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCliCommonizer.kt index 8e4da1526f3..4d53db450d6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCliCommonizer.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCliCommonizer.kt @@ -20,22 +20,23 @@ import org.jetbrains.kotlin.gradle.plugin.usageByName import org.jetbrains.kotlin.gradle.utils.createResolvable import org.jetbrains.kotlin.gradle.utils.findResolvable import org.jetbrains.kotlin.gradle.utils.named +import org.jetbrains.kotlin.gradle.utils.setAttribute private const val KOTLIN_KLIB_COMMONIZER_EMBEDDABLE = "kotlin-klib-commonizer-embeddable" internal fun GradleCliCommonizer(commonizerToolRunner: KotlinNativeCommonizerToolRunner): CliCommonizer { - return CliCommonizer(CliCommonizer.Executor { arguments -> + return CliCommonizer { arguments -> commonizerToolRunner.run(arguments) - }) + } } internal fun Project.maybeCreateCommonizerClasspathConfiguration(): Configuration { return configurations.findResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME) ?: project.configurations.createResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME) .run { - attributes.attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) - attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) - attributes.attribute(Usage.USAGE_ATTRIBUTE, usageByName(Usage.JAVA_RUNTIME)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, usageByName(Usage.JAVA_RUNTIME)) defaultDependencies { dependencies -> dependencies.add( project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_KLIB_COMMONIZER_EMBEDDABLE:${getKotlinPluginVersion()}") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinLegacyCompatibilityMetadataArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinLegacyCompatibilityMetadataArtifact.kt index ef1bea4af8e..6eb8faf45a5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinLegacyCompatibilityMetadataArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinLegacyCompatibilityMetadataArtifact.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVaria import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.utils.createConsumable +import org.jetbrains.kotlin.gradle.utils.setAttribute internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact { target, _, _ -> if (target !is KotlinMetadataTarget) return@KotlinTargetArtifact @@ -39,8 +40,8 @@ internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact { target.project.configurations.createConsumable(COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME).apply { usesPlatformOf(target) - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) val commonMainApiConfiguration = target.project.configurations.sourceSetDependencyConfigurationByScope( target.project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME), diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinMetadataArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinMetadataArtifact.kt index 0d50cfcf9a7..625fdfb8fd8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinMetadataArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinMetadataArtifact.kt @@ -15,12 +15,13 @@ import org.jetbrains.kotlin.gradle.targets.metadata.createGenerateProjectStructu import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVariantEnabled import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata +import org.jetbrains.kotlin.gradle.utils.setAttribute internal val KotlinMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ -> if (target !is KotlinMetadataTarget || !target.project.isKotlinGranularMetadataEnabled) return@KotlinTargetArtifact - apiElements.attributes.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) - apiElements.attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + apiElements.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) + apiElements.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) val metadataJarTask = target.createArtifactsTask { jar -> jar.description = "Assembles a jar archive containing the metadata for all Kotlin source sets." diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeHostSpecificMetadataArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeHostSpecificMetadataArtifact.kt index a3f0cfc0a0c..e9ddc38b1cd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeHostSpecificMetadataArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeHostSpecificMetadataArtifact.kt @@ -21,8 +21,9 @@ import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask -import org.jetbrains.kotlin.gradle.utils.copyAttributes +import org.jetbrains.kotlin.gradle.utils.copyAttributesTo import org.jetbrains.kotlin.gradle.utils.createConsumable +import org.jetbrains.kotlin.gradle.utils.setAttribute import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ -> @@ -34,8 +35,14 @@ internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { t configuration.extendsFrom(*apiElements.extendsFrom.toTypedArray()) target.project.launchInStage(AfterFinaliseDsl) { - copyAttributes(from = apiElements.attributes, to = configuration.attributes) - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) + apiElements.copyAttributesTo( + target.project, + dest = configuration.attributes + ) + configuration.setAttribute( + Usage.USAGE_ATTRIBUTE, + target.project.usageByName(KotlinUsages.KOTLIN_METADATA) + ) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt index 250cf6e684d..7407314f3ec 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinNativeKlibArtifact.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.registerTask +import org.jetbrains.kotlin.gradle.utils.setAttribute import java.io.File internal val KotlinNativeKlibArtifact = KotlinTargetArtifact { target, apiElements, _ -> @@ -31,7 +32,7 @@ internal val KotlinNativeKlibArtifact = KotlinTargetArtifact { target, apiElemen it.description = "Assembles outputs for target '${target.name}'." } - apiElements.outgoing.attributes.attribute(target.project.artifactTypeAttribute, NativeArtifactFormat.KLIB) + apiElements.outgoing.attributes.setAttribute(target.project.artifactTypeAttribute, NativeArtifactFormat.KLIB) target.compilations.getByName(MAIN_COMPILATION_NAME).let { mainCompilation -> artifactsTask.dependsOn(mainCompilation.compileTaskProvider) @@ -67,7 +68,7 @@ internal fun createKlibArtifact( } compilation.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact) artifacts.add(klibArtifact) - attributes.attribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB) + attributes.setAttribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinTargetArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinTargetArtifact.kt index cd6bd35d51e..4edf2068c52 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinTargetArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/artifacts/KotlinTargetArtifact.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinGradlePluginExtensionPoint import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute import org.jetbrains.kotlin.gradle.tasks.registerTask +import org.jetbrains.kotlin.gradle.utils.setAttribute import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly internal fun interface KotlinTargetArtifact { @@ -52,8 +53,8 @@ internal fun KotlinTarget.createPublishArtifact( elementsConfiguration.filterNotNull().forEach { configuration -> configuration.outgoing.artifacts.add(artifact) - configuration.outgoing.attributes.attribute(project.artifactTypeAttribute, artifactType) + configuration.outgoing.attributes.setAttribute(project.artifactTypeAttribute, artifactType) } return artifact -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt index 66ac7bb3901..3db3b843da1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt @@ -151,7 +151,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To project.configurations.findResolvable(configurationName)?.let { return it } val aptConfiguration = project.configurations.createResolvable(configurationName).apply { - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME)) } if (aptConfiguration.name != MAIN_KAPT_CONFIGURATION_NAME) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt index 454aba55f38..ec31c3a757b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/AbstractKotlinPlugin.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.utils.whenEvaluated import org.jetbrains.kotlin.gradle.utils.archivePathCompatible +import org.jetbrains.kotlin.gradle.utils.setAttribute const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath" const val NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinNativeCompilerPluginClasspath" @@ -270,14 +271,14 @@ internal abstract class AbstractKotlinPlugin( // platform-specific modules if (kotlinTarget.platformType != KotlinPlatformType.common) { project.configurations.getByName(kotlinTarget.apiElementsConfigurationName).run { - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(kotlinTarget)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(kotlinTarget)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) usesPlatformOf(kotlinTarget) } project.configurations.getByName(kotlinTarget.runtimeElementsConfigurationName).run { - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(kotlinTarget)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(kotlinTarget)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) usesPlatformOf(kotlinTarget) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 31ec787b9f4..abcaf91dee3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -181,6 +181,11 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin { SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class, DefaultSourceSetCompatibilityHelperVariantFactory() ) + + factories.putIfAbsent( + AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class, + DefaultAttributeConfigurationHelperVariantFactory() + ) } protected fun setupAttributeMatchingStrategy( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt index 409d5822a17..d98aeca84f9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt @@ -9,6 +9,9 @@ import org.gradle.api.Named import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.attributes.* +import org.gradle.api.attributes.java.TargetJvmEnvironment +import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.runKotlinCompilationSideEffects import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute @@ -53,7 +56,7 @@ internal inline fun Project.attributeValueByName(attributeVa objects.named(T::class.java, attributeValueName) fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration { - attributes.attribute(KotlinPlatformType.attribute, target.platformType) + attributes.setAttribute(KotlinPlatformType.attribute, target.platformType) when (target.platformType) { KotlinPlatformType.jvm -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "standard-jvm") @@ -72,33 +75,31 @@ fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration { else -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "non-jvm") } - val publishJsCompilerAttribute = PropertiesProvider(target.project).publishJsCompilerAttribute + val publishJsCompilerAttribute = target.project.kotlinPropertiesProvider.publishJsCompilerAttribute if (publishJsCompilerAttribute && target is KotlinJsIrTarget) { if (target.platformType == KotlinPlatformType.js) { - attributes.attribute(KotlinJsCompilerAttribute.jsCompilerAttribute, KotlinJsCompilerAttribute.ir) + attributes.setAttribute(KotlinJsCompilerAttribute.jsCompilerAttribute, KotlinJsCompilerAttribute.ir) } else { - attributes.attribute(KotlinWasmTargetAttribute.wasmTargetAttribute, target.wasmTargetType!!.toAttribute()) + attributes.setAttributeProvider( + target.project, + KotlinWasmTargetAttribute.wasmTargetAttribute, + ) { target.wasmTargetType!!.toAttribute() } } } - // TODO: Provide an universal way to copy attributes from the target. if (target is KotlinNativeTarget) { - attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name) + attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name) } return this } private fun Configuration.setJavaTargetEnvironmentAttributeIfSupported(project: Project, value: String) { - if (isGradleVersionAtLeast(7, 0)) { - @Suppress("UNCHECKED_CAST") - val attributeClass = Class.forName("org.gradle.api.attributes.java.TargetJvmEnvironment") as Class - - @Suppress("UNCHECKED_CAST") - val attributeKey = attributeClass.getField("TARGET_JVM_ENVIRONMENT_ATTRIBUTE").get(null) as Attribute - - val attributeValue = project.objects.named(attributeClass, value) - attributes.attribute(attributeKey, attributeValue) + if (GradleVersion.current() >= GradleVersion.version("7.0")) { + attributes.setAttribute( + TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + project.objects.named(value) + ) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidPlatformDependencyResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidPlatformDependencyResolver.kt index 46b09e27bde..a2a13645de6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidPlatformDependencyResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidPlatformDependencyResolver.kt @@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers import org.gradle.api.Project import org.gradle.api.artifacts.DependencySubstitutions -import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.artifacts.component.ModuleComponentSelector import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.attributes.Category @@ -23,6 +22,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver import org.jetbrains.kotlin.gradle.plugin.usageByName import org.jetbrains.kotlin.gradle.utils.named +import org.jetbrains.kotlin.gradle.utils.setAttribute /** * Resolves dependencies of jvm and Android source sets from the perspective jvm @@ -32,10 +32,10 @@ internal fun IdeJvmAndAndroidPlatformBinaryDependencyResolver(project: Project): binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE, artifactResolutionStrategy = IdeBinaryDependencyResolver.ArtifactResolutionStrategy.PlatformLikeSourceSet( setupPlatformResolutionAttributes = { - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) - attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm) - attributes.attribute( + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) + attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm) + attributes.setAttribute( TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.STANDARD_JVM) ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidSourceDependencyResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidSourceDependencyResolver.kt index 0bb7efd3c1e..81f6812c993 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidSourceDependencyResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeJvmAndAndroidSourceDependencyResolver.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers import org.gradle.api.Project import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.attributes.Attribute -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency @@ -28,7 +27,8 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType import org.jetbrains.kotlin.gradle.plugin.sources.android.type import org.jetbrains.kotlin.gradle.plugin.sources.internal -import org.jetbrains.kotlin.gradle.utils.copyAttributes +import org.jetbrains.kotlin.gradle.utils.setAttribute +import org.jetbrains.kotlin.gradle.utils.setAttributeProvider import org.jetbrains.kotlin.gradle.utils.toMap /** @@ -112,7 +112,10 @@ internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver .map { attributes -> attributes.toMap().toList().toSet() } .reduceOrNull { acc, next -> acc intersect next } .orEmpty() - .forEach { (key, value) -> @Suppress("UNCHECKED_CAST") attribute(key as Attribute, value as Any) } + .forEach { (key, value) -> + @Suppress("UNCHECKED_CAST") + setAttributeProvider(sourceSet.project, key as Attribute) { value as Any } + } }, componentFilter = { id -> id is ProjectComponentIdentifier } ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelper.kt new file mode 100644 index 00000000000..feac36f18f0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelper.kt @@ -0,0 +1,55 @@ +/* + * 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.internal + +import org.gradle.api.Project +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.HasAttributes +import org.gradle.api.provider.ProviderFactory +import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactories +import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory + +/** + * Gradle 7.4 introduced a way of configuring attribute values using a [org.gradle.api.provider.Provider]. + * In Gradle 8.3+ using a non-Provider value caused eager task realization (see KT-60664). + */ +internal interface AttributesConfigurationHelper { + fun setAttribute( + attributesContainer: HasAttributes, + key: Attribute, + value: () -> T + ) + + interface AttributeConfigurationHelperVariantFactory : VariantImplementationFactories.VariantImplementationFactory { + fun getInstance(providerFactory: ProviderFactory): AttributesConfigurationHelper + } +} + +internal class DefaultAttributesConfigurationHelper( + private val providerFactory: ProviderFactory +) : AttributesConfigurationHelper { + override fun setAttribute( + attributesContainer: HasAttributes, + key: Attribute, + value: () -> T + ) { + attributesContainer.attributes.attributeProvider( + key, + providerFactory.provider { value() } + ) + } +} + +internal class DefaultAttributeConfigurationHelperVariantFactory : + AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory { + override fun getInstance( + providerFactory: ProviderFactory + ): AttributesConfigurationHelper = DefaultAttributesConfigurationHelper(providerFactory) +} + +internal val Project.attributesConfigurationHelper + get() = variantImplementationFactory() + .getInstance(providers) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/HierarchyAttributeContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/HierarchyAttributeContainer.kt index c563e0a01d4..af6054e8762 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/HierarchyAttributeContainer.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/HierarchyAttributeContainer.kt @@ -50,11 +50,11 @@ class HierarchyAttributeContainer( override fun isEmpty(): Boolean = lazyAttributesMap.isEmpty() && attributesMap.isEmpty() && - (parent?.keySet().orEmpty().filter(filterParentAttributes).isEmpty()) + (parent?.keySet().orEmpty().toSet().none(filterParentAttributes)) override fun keySet(): Set> = lazyAttributesMap.keys + attributesMap.keys + - parent?.keySet().orEmpty().filter(filterParentAttributes) + parent?.keySet().orEmpty().toSet().filter(filterParentAttributes) override fun attribute(key: Attribute, value: T): AttributeContainer { val checkedValue = requireNotNull(value as Any?) { "null values for attributes are not supported" } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt index a1a93763775..c5c40dcdad7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinSoftwareComponent.kt @@ -208,13 +208,11 @@ class DefaultKotlinUsageContext( */ val result = project.configurations.detachedResolvable().attributes - // Capture type parameter T: - fun copyAttribute(attribute: Attribute, from: AttributeContainer, to: AttributeContainer) { - to.attribute(attribute, from.getAttribute(attribute)!!) - } - - filterOutNonPublishableAttributes(configurationAttributes.keySet()) - .forEach { copyAttribute(it, configurationAttributes, result) } + configurationAttributes.copyAttributesTo( + project, + dest = result, + keys = filterOutNonPublishableAttributes(configurationAttributes.keySet()) + ) return result } 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 index a279863bdf5..cf1801a36c8 100644 --- 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 @@ -16,7 +16,7 @@ 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.utils.copyAttributes +import org.jetbrains.kotlin.gradle.utils.copyAttributesTo import org.jetbrains.kotlin.gradle.utils.createDependencyScope import org.jetbrains.kotlin.gradle.utils.findDependencyScope import org.jetbrains.kotlin.tooling.core.UnsafeApi @@ -39,7 +39,14 @@ internal fun KotlinTargetSoftwareComponent( publishedConfiguration.isVisible = false publishedConfiguration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName)) publishedConfiguration.artifacts.addAll(kotlinUsageContext.artifacts) - copyAttributes(from = kotlinUsageContext.attributes, to = publishedConfiguration.attributes) + // KT-64789: workaround for missing 'org.gradle.libraryelements' attribute on the kotlinUsageContext returned keys Set + // So far I don't know the reason why it appears only on the second call to `keySet()` + // Test failing without it - KotlinAndroidMppIT#testMppAndroidLibFlavorsPublication + kotlinUsageContext.attributes.keySet() + kotlinUsageContext.copyAttributesTo( + project, + dest = publishedConfiguration + ) } adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/Publishing.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/Publishing.kt index ee4fe1a949b..bf9572d4db5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/Publishing.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/Publishing.kt @@ -168,12 +168,12 @@ internal fun Configuration.configureSourcesPublicationAttributes(target: KotlinT // to be either JAVA_RUNTIME (for jvm) or KOTLIN_RUNTIME (for other targets) // the latter isn't a strong requirement since there is no tooling that consume kotlin sources through gradle variants at the moment // so consistency with Java Gradle Plugin seemed most desirable choice. - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.attributeValueByName(Category.DOCUMENTATION)) - attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.attributeValueByName(DocsType.SOURCES)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.attributeValueByName(Category.DOCUMENTATION)) + attributes.setAttribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.attributeValueByName(DocsType.SOURCES)) // Bundling attribute is about component dependencies, external means that they are provided as separate components // source variants doesn't have any dependencies (at least at the moment) so there is not much sense to use this attribute // however for Java Gradle Plugin compatibility and in order to prevent weird Variant Resolution errors we include this attribute - attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, project.attributeValueByName(Bundling.EXTERNAL)) + attributes.setAttribute(Bundling.BUNDLING_ATTRIBUTE, project.attributeValueByName(Bundling.EXTERNAL)) usesPlatformOf(target) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/applyUserDefinedAttributes.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/applyUserDefinedAttributes.kt index b1772c23890..6a1d79adfc4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/applyUserDefinedAttributes.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/applyUserDefinedAttributes.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterEvalu import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupCoroutine import org.jetbrains.kotlin.gradle.plugin.await import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation -import org.jetbrains.kotlin.gradle.utils.copyAttributes +import org.jetbrains.kotlin.gradle.utils.copyAttributesTo import org.jetbrains.kotlin.gradle.utils.forAllTargets @@ -25,22 +25,31 @@ internal val UserDefinedAttributesSetupAction = KotlinProjectSetupCoroutine { kotlinExtension.forAllTargets { target -> target.internal.kotlinComponents.flatMap { it.internal.usages }.forEach { usage -> val dependencyConfiguration = target.project.configurations.findByName(usage.dependencyConfigurationName) ?: return@forEach - copyAttributes(usage.compilation.attributes, dependencyConfiguration.attributes) + usage.compilation.copyAttributesTo( + this@KotlinProjectSetupCoroutine, + dest = dependencyConfiguration.attributes + ) } target.compilations.all { compilation -> - val compilationAttributes = compilation.attributes - compilation.allOwnedConfigurationsNames .mapNotNull { configurationName -> project.configurations.findByName(configurationName) } - .forEach { configuration -> copyAttributes(compilationAttributes, configuration.attributes) } + .forEach { configuration -> + compilation.copyAttributesTo( + this@KotlinProjectSetupCoroutine, + dest = configuration + ) + } } // Copy to host-specific metadata elements configurations if (target is KotlinNativeTarget) { val hostSpecificMetadataElements = project.configurations.findByName(target.hostSpecificMetadataElementsConfigurationName) if (hostSpecificMetadataElements != null) { - copyAttributes(from = target.attributes, to = hostSpecificMetadataElements.attributes) + target.copyAttributesTo( + this@KotlinProjectSetupCoroutine, + dest = hostSpecificMetadataElements + ) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt index bd0f74d5833..0c4f7b479af 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt @@ -138,7 +138,7 @@ private fun KotlinCompilationDependencyConfigurationsContainer( val compileOnlyConfiguration = target.project.configurations .maybeCreateDependencyScope(compileOnlyConfigurationName).apply { setupAsLocalTargetSpecificConfigurationIfSupported(target) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) isVisible = false description = "Compile only dependencies for $compilationCoordinates." } @@ -153,9 +153,9 @@ private fun KotlinCompilationDependencyConfigurationsContainer( extendsFrom(compileOnlyConfiguration, implementationConfiguration) usesPlatformOf(target) isVisible = false - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) if (target.platformType != KotlinPlatformType.androidJvm) { - attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) } description = "Compile classpath for $compilationCoordinates." } @@ -166,9 +166,9 @@ private fun KotlinCompilationDependencyConfigurationsContainer( deprecatedRuntimeConfiguration?.let { extendsFrom(it) } usesPlatformOf(target) isVisible = false - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) if (target.platformType != KotlinPlatformType.androidJvm) { - attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) } description = "Runtime classpath of $compilationCoordinates." } else null @@ -178,10 +178,11 @@ private fun KotlinCompilationDependencyConfigurationsContainer( isVisible = false description = "Host-specific Metadata dependencies for $compilationCoordinates" extendsFrom(compileDependencyConfiguration) - copyAttributes(from = compileDependencyConfiguration.attributes, to = attributes) - attributes { - it.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) - } + compileDependencyConfiguration.copyAttributesTo( + target.project, + dest = this + ) + setAttribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) } else null val pluginConfiguration = target.project.configurations.maybeCreateResolvable(pluginConfigurationName).apply { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt index f4fdf76fe52..34cd9c4b9df 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt @@ -128,14 +128,14 @@ fun KotlinMultiplatformExtension.createExter private fun ExternalKotlinTargetImpl.setupApiElements(configuration: Configuration) { configuration.usesPlatformOf(this) - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(this)) - configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) + configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(this)) + configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) } private fun ExternalKotlinTargetImpl.setupRuntimeElements(configuration: Configuration) { configuration.usesPlatformOf(this) - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(this)) - configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) + configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(this)) + configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) } private fun ExternalKotlinTargetImpl.setupSourcesElements(configuration: Configuration) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resolvableMetadataConfiguration.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resolvableMetadataConfiguration.kt index a88e2e96e92..4d376b0b313 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resolvableMetadataConfiguration.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resolvableMetadataConfiguration.kt @@ -60,7 +60,10 @@ internal val InternalKotlinSourceSet.resolvableMetadataConfiguration: Configurat /* Ensure consistent dependency resolution result within the whole module */ configuration.shouldResolveConsistentlyWith(allCompileMetadataConfiguration) - copyAttributes(allCompileMetadataConfiguration.attributes, configuration.attributes) + allCompileMetadataConfiguration.copyAttributesTo( + project, + dest = configuration + ) configureMetadataDependenciesConfigurations(configuration) @@ -96,8 +99,8 @@ private val Project.allCompileMetadataConfiguration get(): Configuration = configurations.findResolvable("allSourceSetsCompileDependenciesMetadata") ?: configurations.createResolvable("allSourceSetsCompileDependenciesMetadata").also { configuration -> configuration.usesPlatformOf(multiplatformExtension.metadata()) - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) - configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) + configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) kotlinExtension.sourceSets.all { sourceSet -> configuration.extendsFrom(configurations.getByName(sourceSet.apiConfigurationName)) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetFactory.kt index 22355bb8c56..57332503bea 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetFactory.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnab import org.jetbrains.kotlin.gradle.utils.createResolvable import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable +import org.jetbrains.kotlin.gradle.utils.setAttribute import java.io.File internal abstract class KotlinSourceSetFactory internal constructor( @@ -98,9 +99,9 @@ internal class DefaultKotlinSourceSetFactory( dependencyConfigurationWithMetadata.forEach { (configurationName, metadataName) -> project.configurations.maybeCreateResolvable(metadataName).apply { - attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_API)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.common) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_API)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) isVisible = false if (configurationName != null) { @@ -108,7 +109,7 @@ internal class DefaultKotlinSourceSetFactory( } if (project.isKotlinGranularMetadataEnabled) { - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt index 10e93b68107..2ba2ff53987 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/scripting/internal/ScriptingGradleSubplugin.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable +import org.jetbrains.kotlin.gradle.utils.setAttribute import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly private const val SCRIPTING_LOG_PREFIX = "kotlin scripting plugin:" @@ -113,7 +114,7 @@ private fun configureDiscoveryTransformation( discoveryResultsConfigurationName: String ) { project.configurations.maybeCreateResolvable(discoveryResultsConfigurationName).apply { - attributes.attribute(artifactType, scriptFilesExtensions) + attributes.setAttribute(artifactType, scriptFilesExtensions) extendsFrom(discoveryConfiguration) } val classLoadersCachingService = ClassLoadersCachingBuildService.registerIfAbsent(project) @@ -161,14 +162,14 @@ private fun DependencyHandler.registerDiscoverScriptExtensionsTransform( parameters.compilerClasspath.from(compilerClasspath) } registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec -> - transformSpec.from.attribute(artifactType, "jar") - transformSpec.to.attribute(artifactType, scriptFilesExtensions) + transformSpec.from.setAttribute(artifactType, "jar") + transformSpec.to.setAttribute(artifactType, scriptFilesExtensions) transformSpec.configureCommonParameters() } registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec -> - transformSpec.from.attribute(artifactType, "classes") - transformSpec.to.attribute(artifactType, scriptFilesExtensions) + transformSpec.from.setAttribute(artifactType, "classes") + transformSpec.to.setAttribute(artifactType, scriptFilesExtensions) transformSpec.configureCommonParameters() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt index c53bbab26b8..3c5e720e793 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateTargetConfigurationsSideEffect.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.isSourcesPublishableFuture import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget import org.jetbrains.kotlin.gradle.utils.maybeCreateConsumable import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope +import org.jetbrains.kotlin.gradle.utils.setAttribute internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { target -> val project = target.project @@ -36,8 +37,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar configurations.maybeCreateConsumable(target.apiElementsConfigurationName).apply { description = "API elements for main." isVisible = false - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) extendsFrom(configurations.maybeCreateDependencyScope(mainCompilation.apiConfigurationName)) if (mainCompilation is KotlinCompilationToRunnableFiles) { val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration @@ -50,8 +51,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar configurations.maybeCreateConsumable(target.runtimeElementsConfigurationName).apply { description = "Elements of runtime for main." isVisible = false - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration extendsFrom(implementationConfiguration) if (runtimeOnlyConfiguration != null) @@ -94,8 +95,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar ).apply { description = "Common Fake API elements for main." isVisible = false - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) - attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) + attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.common) } } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt index e9ed9061a9f..1c615159fa8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt @@ -335,7 +335,10 @@ internal class AndroidProjectHandler( val buildTypeAttrValue = project.objects.named(variant.buildType.name) listOf(compilation.compileDependencyConfigurationName, compilation.runtimeDependencyConfigurationName).forEach { - project.configurations.findByName(it)?.attributes?.attribute(Attribute.of(BuildTypeAttr::class.java), buildTypeAttrValue) + project.configurations.findByName(it)?.attributes?.setAttribute( + Attribute.of(BuildTypeAttr::class.java), + buildTypeAttrValue + ) } // TODO this code depends on the convention that is present in the Android plugin as there's no public API @@ -355,7 +358,7 @@ internal class AndroidProjectHandler( listOf(apiElementsConfigurationName, runtimeElementsConfigurationName).forEach { outputConfigurationName -> project.configurations.findByName(outputConfigurationName)?.let { configuration -> configuration.usesPlatformOf(compilation.target) - configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt index 002b5663025..8384a991a00 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.dsl.HasConfigurableCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsDefault import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.internal.attributesConfigurationHelper import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.gradle.utils.dashSeparatedName @@ -299,7 +300,7 @@ abstract class KotlinAndroidTarget @Inject constructor( description = "Source files of Android ${variantName}." isVisible = false - copyAttributes(apiElementsConfiguration.attributes, attributes) + apiElementsConfiguration.copyAttributesTo(project, dest = this) configureSourcesPublicationAttributes(this@KotlinAndroidTarget) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt index c78bc769faa..2863fc1fcb3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt @@ -135,9 +135,9 @@ class KotlinCompilationNpmResolver( val all = project.configurations.createResolvable(compilation.npmAggregatedConfigurationName) all.usesPlatformOf(target) - all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) - all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) - all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE) + all.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) + all.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + all.attributes.setAttribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE) all.isVisible = false all.description = "NPM configuration for $compilation." @@ -163,9 +163,9 @@ class KotlinCompilationNpmResolver( val all = project.configurations.createConsumable(compilation.publicPackageJsonConfigurationName) all.usesPlatformOf(target) - all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) - all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) - all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE) + all.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) + all.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + all.attributes.setAttribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE) all.isVisible = false return all diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt index 564afb6df75..0efc95331ce 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt @@ -324,7 +324,7 @@ abstract class KotlinJvmTarget @Inject constructor( ).mapNotNull { project.configurations.findByName(it) }.forEach { configuration -> - copyAttributes(attributes, configuration.attributes) + copyAttributesTo(project, dest = configuration) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/ConfigureFrameworkExportSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/ConfigureFrameworkExportSideEffect.kt index e2f985bc064..df6342bbd69 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/ConfigureFrameworkExportSideEffect.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/ConfigureFrameworkExportSideEffect.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable +import org.jetbrains.kotlin.gradle.utils.setAttribute internal val ConfigureFrameworkExportSideEffect = KotlinTargetSideEffect { target -> val project = target.project @@ -23,9 +24,9 @@ internal val ConfigureFrameworkExportSideEffect = KotlinTargetSideEffect> = Attribute.of( - "org.jetbrains.kotlin.native.framework.targets", - Set::class.java + val frameworkTargets: Attribute> = attributeOf>( + "org.jetbrains.kotlin.native.framework.targets" ) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/configureBinaryFrameworks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/configureBinaryFrameworks.kt index 153d8f0260b..e4df5b5540b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/configureBinaryFrameworks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/configureBinaryFrameworks.kt @@ -45,7 +45,7 @@ internal fun Project.createFrameworkArtifact(binaryFramework: Framework, linkTas ?: configurations.createConsumable(binaryFramework.binaryFrameworkConfigurationName).also { it.applyBinaryFrameworkGroupAttributes(project, binaryFramework.frameworkGroupDescription, listOf(binaryFramework.target)) project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseDsl) { - copyAttributes(binaryFramework.attributes, it.attributes) + binaryFramework.copyAttributesTo(project, dest = it) } } @@ -78,11 +78,13 @@ private fun Configuration.applyBinaryFrameworkGroupAttributes( targets: List, ) { with(attributes) { - attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) - attribute(project.artifactTypeAttribute, KotlinNativeTargetConfigurator.NativeArtifactFormat.FRAMEWORK) - attribute(KotlinNativeTarget.kotlinNativeBuildTypeAttribute, frameworkDescription.buildType.name) - attribute(KotlinNativeTarget.kotlinNativeFrameworkNameAttribute, frameworkDescription.frameworkName) - attribute(Framework.frameworkTargets, targets.map { it.konanTarget.name }.toSet()) + setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native) + setAttribute(project.artifactTypeAttribute, KotlinNativeTargetConfigurator.NativeArtifactFormat.FRAMEWORK) + setAttribute(KotlinNativeTarget.kotlinNativeBuildTypeAttribute, frameworkDescription.buildType.name) + setAttribute(KotlinNativeTarget.kotlinNativeFrameworkNameAttribute, frameworkDescription.frameworkName) + setAttributeProvider(project, Framework.frameworkTargets) { + targets.map { it.konanTarget.name }.toSet() + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerArtifactTypeAttribute.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerArtifactTypeAttribute.kt index d231844e43e..8d32adea23d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerArtifactTypeAttribute.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerArtifactTypeAttribute.kt @@ -18,6 +18,7 @@ import org.gradle.api.tasks.PathSensitivity import org.gradle.work.DisableCachingByDefault import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR +import org.jetbrains.kotlin.gradle.utils.setAttribute /** * Commonized CInterop artifacts can come in two shapes: @@ -52,16 +53,16 @@ internal object CInteropCommonizerArtifactTypeAttribute { */ fun setupTransform(project: Project) { project.dependencies.artifactTypes.maybeCreate(KLIB_COLLECTION_DIR).also { artifactType -> - artifactType.attributes.attribute(attribute, KLIB_COLLECTION_DIR) + artifactType.attributes.setAttribute(attribute, KLIB_COLLECTION_DIR) } project.dependencies.artifactTypes.maybeCreate(KLIB).also { artifactType -> - artifactType.attributes.attribute(attribute, KLIB) + artifactType.attributes.setAttribute(attribute, KLIB) } project.dependencies.registerTransform(KlibCollectionDirTransform::class.java) { transform -> - transform.from.attribute(attribute, KLIB_COLLECTION_DIR) - transform.to.attribute(attribute, KLIB) + transform.from.setAttribute(attribute, KLIB_COLLECTION_DIR) + transform.to.setAttribute(attribute, KLIB) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerConfigurations.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerConfigurations.kt index e60acbec69f..5594f15dae3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerConfigurations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerConfigurations.kt @@ -21,8 +21,10 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.targets.metadata.awaitMetadataCompilationsCreated import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation +import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.gradle.utils.createConsumable import org.jetbrains.kotlin.gradle.utils.createResolvable +import org.jetbrains.kotlin.gradle.utils.setAttribute import org.jetbrains.kotlin.tooling.core.UnsafeApi /* Elements configuration */ @@ -113,7 +115,10 @@ internal suspend fun Project.locateOrCreateCommonizedCInteropDependencyConfigura * If artifacts are added using [CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR] then a transformation * has to happen that will resolve the exact list of klibs. */ - configuration.attributes.attribute(CInteropCommonizerArtifactTypeAttribute.attribute, CInteropCommonizerArtifactTypeAttribute.KLIB) + configuration.attributes.setAttribute( + CInteropCommonizerArtifactTypeAttribute.attribute, + CInteropCommonizerArtifactTypeAttribute.KLIB + ) description = "Commonized CInterop dependencies for $sourceSet with targets: '$commonizerTarget'." } @@ -124,7 +129,7 @@ private fun Project.setupBasicCommonizedCInteropConfigurationAttributes( configuration: Configuration, commonizerTarget: SharedCommonizerTarget, ) { - configuration.attributes.attribute(CommonizerTargetAttribute.attribute, commonizerTarget.identityString) - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_COMMONIZED_CINTEROP)) - configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + configuration.attributes.setAttribute(CommonizerTargetAttribute.attribute, commonizerTarget.identityString) + configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_COMMONIZED_CINTEROP)) + configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt index 2c041e1d23d..4ccb490b7b1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt @@ -22,7 +22,6 @@ import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements import org.jetbrains.kotlin.gradle.tasks.CInteropProcess import org.jetbrains.kotlin.gradle.utils.* -import org.jetbrains.kotlin.gradle.utils.copyAttributes import org.jetbrains.kotlin.gradle.utils.createConsumable import org.jetbrains.kotlin.gradle.utils.findConsumable @@ -57,10 +56,10 @@ internal fun Project.locateOrCreateCInteropDependencyConfiguration( /* Deferring attributes to wait for compilation.attributes to be configured by user*/ launchInStage(AfterFinaliseDsl) { usesPlatformOf(compilation.target) - copyAttributes(compilation.attributes, attributes) - attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements()) - attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + compilation.copyAttributesTo(project, dest = attributes) + attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements()) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) description = "CInterop dependencies for compilation '${compilation.name}')." } } @@ -81,11 +80,11 @@ internal fun Project.locateOrCreateCInteropApiElementsConfiguration(target: Kotl /* Deferring attributes to wait for target.attributes to be configured by user */ launchInStage(AfterFinaliseDsl) { usesPlatformOf(target) - copyAttributes(target.attributes, attributes) - attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements()) - attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) - attributes.attribute(artifactTypeAttribute, NativeArtifactFormat.KLIB) + target.copyAttributesTo(project, dest = attributes) + attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements()) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(artifactTypeAttribute, NativeArtifactFormat.KLIB) /* Expose api dependencies */ target.compilations.findByName(MAIN_COMPILATION_NAME)?.let { compilation -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt index ce4163afa61..c9278b87cc8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt @@ -194,8 +194,8 @@ constructor( val apiConfiguration = project.configurations.getByName(compilation.apiConfigurationName) dependencies.addAll(apiConfiguration.allDependencies) usesPlatformOf(compilation.target) - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(compilation.target)) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(compilation.target)) + attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) }.filterKlibsPassedToCompiler() @get:Optional diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt index 65f7132eede..010ef9b6692 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinArtifact.kt @@ -15,6 +15,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable +import org.jetbrains.kotlin.gradle.utils.named +import org.jetbrains.kotlin.gradle.utils.setAttribute import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.presetName @@ -76,9 +78,9 @@ internal fun Project.registerLibsDependencies(target: KonanTarget, artifactName: configurations.maybeCreateResolvable(librariesConfigurationName).apply { isVisible = false isTransitive = true - attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) - attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) + attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native) + attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.name) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(KotlinUsages.KOTLIN_API)) } deps.forEach { dependencies.add(librariesConfigurationName, it) } return librariesConfigurationName @@ -89,9 +91,9 @@ internal fun Project.registerExportDependencies(target: KonanTarget, artifactNam configurations.maybeCreateResolvable(exportConfigurationName).apply { isVisible = false isTransitive = false - attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) - attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) + attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native) + attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.name) + attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(KotlinUsages.KOTLIN_API)) } deps.forEach { dependencies.add(exportConfigurationName, it) } return exportConfigurationName diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptConfig.kt index bb3d181e2a8..a5584e3dee6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptConfig.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformL import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.tasks.toCompilerPluginOptions import org.jetbrains.kotlin.gradle.utils.* -import org.jetbrains.kotlin.gradle.utils.createDependencyScope import org.jetbrains.kotlin.gradle.utils.detachedResolvable import org.jetbrains.kotlin.gradle.utils.listProperty import java.io.File @@ -101,7 +100,7 @@ internal open class KaptConfig( // the attributes that are potentially needed to resolve dependencies on MPP modules, and the classpath configuration does. classStructureConfiguration.dependencies.add(project.dependencies.create(project.files(project.provider { taskProvider.get().classpath }))) classStructureConfiguration.incoming.artifactView { viewConfig -> - viewConfig.attributes.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) + viewConfig.attributes.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) }.files } else null } @@ -114,13 +113,13 @@ internal open class KaptConfig( else StructureTransformLegacyAction::class.java project.dependencies.registerTransform(transformActionClass) { transformSpec -> - transformSpec.from.attribute(artifactType, "jar") - transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) + transformSpec.from.setAttribute(artifactType, "jar") + transformSpec.to.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) } project.dependencies.registerTransform(transformActionClass) { transformSpec -> - transformSpec.from.attribute(artifactType, "directory") - transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) + transformSpec.from.setAttribute(artifactType, "directory") + transformSpec.to.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) } project.extensions.extraProperties["KaptStructureTransformAdded"] = true diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt index 66b37ea54b0..5429f26e1fd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.utils.detachedResolvable import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention +import org.jetbrains.kotlin.gradle.utils.setAttribute internal typealias KotlinCompileConfig = BaseKotlinCompileConfig @@ -71,7 +72,7 @@ internal open class BaseKotlinCompileConfig : AbstractKotl task.classpathSnapshotProperties.useClasspathSnapshot.value(useClasspathSnapshot).disallowChanges() if (useClasspathSnapshot) { val classpathEntrySnapshotFiles = classpathConfiguration!!.incoming.artifactView { - it.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) + it.attributes.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) }.files task.classpathSnapshotProperties.classpathSnapshot.from(classpathEntrySnapshotFiles).disallowChanges() task.classpathSnapshotProperties.classpathSnapshotDir.value(getClasspathSnapshotDir(task)).disallowChanges() @@ -185,14 +186,14 @@ internal open class BaseKotlinCompileConfig : AbstractKotl val kgpVersion = project.getKotlinPluginVersion() val suppressVersionInconsistencyChecks = project.kotlinPropertiesProvider.suppressBuildToolsApiVersionConsistencyChecks project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) { - it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE) - it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) + it.from.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE) + it.to.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks) it.setupTransformActionToolingDiagnostics(project) } project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) { - it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE) - it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) + it.from.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE) + it.to.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks) it.setupTransformActionToolingDiagnostics(project) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleAttributesContainerUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleAttributesContainerUtils.kt index 18805a109d8..9f12e3c4927 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleAttributesContainerUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleAttributesContainerUtils.kt @@ -5,8 +5,11 @@ package org.jetbrains.kotlin.gradle.utils +import org.gradle.api.Project import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.attributes.HasAttributes +import org.jetbrains.kotlin.gradle.plugin.internal.attributesConfigurationHelper /** * KGP's internal analog of [org.gradle.api.internal.attributes.AttributeContainerInternal.asMap] @@ -21,15 +24,47 @@ internal fun AttributeContainer.toMap(): Map, Any?> { return result } +internal fun HasAttributes.setAttributeProvider( + project: Project, + key: Attribute, + value: () -> T +) { + project.attributesConfigurationHelper.setAttribute(this, key, value) +} -internal fun copyAttributes(from: AttributeContainer, to: AttributeContainer, keys: Iterable> = from.keySet()) { - // capture type argument T - fun copyOneAttribute(from: AttributeContainer, to: AttributeContainer, key: Attribute) { - val value = checkNotNull(from.getAttribute(key)) - to.attribute(key, value) - } - for (key in keys) { - copyOneAttribute(from, to, key) +/** + * Should only be used to configure simple attributes values! + * + * When in doubt, prefer lazy method overload. + */ +internal fun HasAttributes.setAttribute( + key: Attribute, + value: T +) { + attributes.attribute(key, value) +} + +internal fun HasAttributes.copyAttributeTo( + project: Project, + dest: HasAttributes, + key: Attribute, +) { + dest.setAttributeProvider(project, key) { + attributes.getAttribute(key) + ?: throw IllegalStateException("Failed to copy attribute. Source container is missing $key (named ${key.name}).") } } +internal fun HasAttributes.copyAttributesTo( + project: Project, + dest: HasAttributes, + keys: Iterable> = attributes.keySet(), +) { + for (key in keys) { + copyAttributeTo(project, dest, key) + } +} + +internal inline fun attributeOf( + name: String +): Attribute = Attribute.of(name, T::class.java) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt index 4a7a3fa7579..45f65e510b1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/gradleConfigurationUtils.kt @@ -34,13 +34,13 @@ internal fun Configuration.addGradlePluginMetadataAttributes( project: Project ) { attributes { - it.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) - it.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME)) - it.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR)) + it.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) + it.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME)) + it.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR)) if (GradleVersion.current() >= GradleVersion.version("7.0")) { - it.attribute( + it.setAttribute( GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE, - project.objects.named(GradlePluginApiVersion::class.java, GradleVersion.current().version) + project.objects.named(GradleVersion.current().version) ) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/BinaryFrameworksCustomAttributesTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/BinaryFrameworksCustomAttributesTest.kt index 365337d3db2..576e9f8420e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/BinaryFrameworksCustomAttributesTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/BinaryFrameworksCustomAttributesTest.kt @@ -21,7 +21,7 @@ class BinaryFrameworksCustomAttributesTest { val project = buildProjectWithMPP { kotlin { iosArm64("ios") { - attributes.attribute(disambiguationAttribute1, "someValue") + attributes.attributeProvider(disambiguationAttribute1, provider { "someValue" }) binaries { framework("main") framework("custom") { @@ -29,7 +29,7 @@ class BinaryFrameworksCustomAttributesTest { linkerOpts = mutableListOf("-L.") freeCompilerArgs = mutableListOf("-Xtime") isStatic = true - attributes.attribute(disambiguationAttribute2, "someValue2") + attributes.attributeProvider(disambiguationAttribute2, provider { "someValue2" }) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt index 1e954ec7cc5..1f47232e318 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt @@ -33,13 +33,13 @@ class KT56143CinteropConfigurationAttributes { private val project = buildProjectWithMPP { kotlin { linuxX64("variantA") { - attributes.attribute(targetAttribute, "a") - compilations.main.attributes.attribute(compilationAttribute, "compilation:a") + attributes.attributeProvider(targetAttribute, provider { "a" }) + compilations.main.attributes.attributeProvider(compilationAttribute, provider { "compilation:a" }) } linuxX64("variantB") { - attributes.attribute(targetAttribute, "b") - compilations.main.attributes.attribute(compilationAttribute, "compilation:b") + attributes.attributeProvider(targetAttribute, provider { "b" }) + compilations.main.attributes.attributeProvider(compilationAttribute, provider { "compilation:b" }) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropCommonizerArtifactTypeAttributeTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropCommonizerArtifactTypeAttributeTest.kt index f4eaf08140d..7884278162f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropCommonizerArtifactTypeAttributeTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CInteropCommonizerArtifactTypeAttributeTest.kt @@ -34,7 +34,10 @@ class CInteropCommonizerArtifactTypeAttributeTest { /* Create consumable elements configuration */ project.configurations.createConsumable("testElements").also { configuration -> - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named("test")) + configuration.attributes.attributeProvider( + Usage.USAGE_ATTRIBUTE, + project.provider { project.objects.named("test") } + ) /* Add klibCollectionDir as artifact */ configuration.outgoing.artifact(klibCollectionDir) { artifact -> @@ -45,9 +48,13 @@ class CInteropCommonizerArtifactTypeAttributeTest { /* Create resolvable configuration */ val resolvable = project.configurations.createResolvable("testDependencies").also { configuration -> - configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named("test")) - configuration.attributes.attribute( - CInteropCommonizerArtifactTypeAttribute.attribute, CInteropCommonizerArtifactTypeAttribute.KLIB + configuration.attributes.attributeProvider( + Usage.USAGE_ATTRIBUTE, + project.provider { project.objects.named("test") } + ) + configuration.attributes.attributeProvider( + CInteropCommonizerArtifactTypeAttribute.attribute, + project.provider { CInteropCommonizerArtifactTypeAttribute.KLIB } ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ExternalKotlinTargetApiTests.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ExternalKotlinTargetApiTests.kt index bbf988daa78..9aaae85313f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ExternalKotlinTargetApiTests.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/ExternalKotlinTargetApiTests.kt @@ -180,12 +180,12 @@ class ExternalKotlinTargetApiTests { defaults() sourcesElements.configure { target, configuration -> assertEquals(target.sourcesElementsConfiguration, configuration) - configuration.attributes.attribute(testAttribute, "sourcesElements") + configuration.attributes.attributeProvider(testAttribute, provider { "sourcesElements" }) } sourcesElementsPublished.configure { target, configuration -> assertEquals(target.sourcesElementsPublishedConfiguration, configuration) - configuration.attributes.attribute(testAttribute, "sourcesElements-published") + configuration.attributes.attributeProvider(testAttribute, provider { "sourcesElements-published" }) } } target.createCompilation { defaults(kotlin) } @@ -306,7 +306,7 @@ class ExternalKotlinTargetApiTests { val target = kotlin.createExternalKotlinTarget { defaults() } target.createCompilation { defaults(kotlin) } - target.attributes.attribute(userAttribute, "foo") + target.attributes.attributeProvider(userAttribute, target.project.provider { "foo" }) project.evaluate() diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/IdeaKotlinBinaryAttributesFactoryTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/IdeaKotlinBinaryAttributesFactoryTest.kt index 0e4e00051ad..d66c952acd1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/IdeaKotlinBinaryAttributesFactoryTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/IdeaKotlinBinaryAttributesFactoryTest.kt @@ -23,8 +23,14 @@ class IdeaKotlinBinaryAttributesFactoryTest { val dummyConfiguration = project.configurations.create("dummy") val container = dummyConfiguration.attributes - container.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API)) - container.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.DOCUMENTATION)) + container.attributeProvider( + Usage.USAGE_ATTRIBUTE, + project.provider { project.objects.named(Usage.JAVA_API) } + ) + container.attributeProvider( + Category.CATEGORY_ATTRIBUTE, + project.provider { project.objects.named(Category.DOCUMENTATION) } + ) assertEquals( mapOf( diff --git a/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt b/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt index 666cb4eaac2..ec4f9722f2a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt @@ -10,7 +10,6 @@ import org.gradle.api.Named import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.file.SourceDirectorySet -import org.gradle.api.model.ObjectFactory import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.jetbrains.kotlin.gradle.plugin.internal.* import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfigurationG70 @@ -155,4 +154,5 @@ private fun Project.registerVariantImplementations() { factories[UnameExecutor.UnameExecutorVariantFactory::class] = UnameExecutorG70.UnameExecutorVariantFactoryG70() factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG70.Factory() + factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG70() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG70.kt b/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG70.kt new file mode 100644 index 00000000000..2b3652baaa8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/gradle70/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG70.kt @@ -0,0 +1,26 @@ +/* + * 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.internal + +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.HasAttributes +import org.gradle.api.provider.ProviderFactory + +internal class AttributesConfigurationHelperG70 : AttributesConfigurationHelper { + override fun setAttribute( + attributesContainer: HasAttributes, + key: Attribute, + value: () -> T + ) { + attributesContainer.attributes.attribute(key, value()) + } +} + +internal class AttributeConfigurationHelperVariantFactoryG70 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory { + override fun getInstance( + providerFactory: ProviderFactory + ): AttributesConfigurationHelper = AttributesConfigurationHelperG70() +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt b/libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt index f473b8568f5..28676251ac3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt @@ -10,7 +10,6 @@ import org.gradle.api.Named import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.file.SourceDirectorySet -import org.gradle.api.model.ObjectFactory import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.jetbrains.kotlin.gradle.plugin.internal.* import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessorG71 @@ -156,4 +155,5 @@ private fun Project.registerVariantImplementations() { factories[UnameExecutor.UnameExecutorVariantFactory::class] = UnameExecutorG71.UnameExecutorVariantFactoryG71() factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG71.Factory() + factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG71() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG71.kt b/libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG71.kt new file mode 100644 index 00000000000..cbecbb6c09e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/gradle71/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG71.kt @@ -0,0 +1,26 @@ +/* + * 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.internal + +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.HasAttributes +import org.gradle.api.provider.ProviderFactory + +internal class AttributesConfigurationHelperG71 : AttributesConfigurationHelper { + override fun setAttribute( + attributesContainer: HasAttributes, + key: Attribute, + value: () -> T + ) { + attributesContainer.attributes.attribute(key, value()) + } +} + +internal class AttributeConfigurationHelperVariantFactoryG71 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory { + override fun getInstance( + providerFactory: ProviderFactory + ): AttributesConfigurationHelper = AttributesConfigurationHelperG71() +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt b/libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt index 6b67b614ca0..d185ebe40bf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt @@ -145,4 +145,6 @@ private fun Project.registerVariantImplementations() { factories[UnameExecutor.UnameExecutorVariantFactory::class] = UnameExecutorG74.UnameExecutorVariantFactoryG74() factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG74.Factory() + factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = + AttributeConfigurationHelperVariantFactoryG74() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG74.kt b/libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG74.kt new file mode 100644 index 00000000000..c703340a15d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/gradle74/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG74.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2024 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.internal + +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.attributes.HasAttributes +import org.gradle.api.provider.ProviderFactory + +/** + * While Gradle 7.4 already has [AttributeContainer.attributeProvider] method available, + * Gradle itself has a bug in mixed attributes (eager + provider) case leading to the false-positive + * deprecation message: + * ``` + * Consumable configurations with identical capabilities within a project must have unique attributes, ... + * ``` + */ +internal class AttributesConfigurationHelperG74 : AttributesConfigurationHelper { + override fun setAttribute( + attributesContainer: HasAttributes, + key: Attribute, + value: () -> T + ) { + attributesContainer.attributes.attribute(key, value()) + } +} + +internal class AttributeConfigurationHelperVariantFactoryG74 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory { + override fun getInstance( + providerFactory: ProviderFactory + ): AttributesConfigurationHelper = AttributesConfigurationHelperG74() +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt index 24db536fa0a..2b4e4403caf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/PluginWrappers.kt @@ -162,4 +162,5 @@ private fun Project.registerVariantImplementations() { factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG6.Factory() factories[SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class] = SourceSetCompatibilityHelperG6VariantFactory() + factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG6() } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG6.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG6.kt new file mode 100644 index 00000000000..025fec0d7a1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/internal/AttributesConfigurationHelperG6.kt @@ -0,0 +1,26 @@ +/* + * 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.internal + +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.HasAttributes +import org.gradle.api.provider.ProviderFactory + +internal class AttributesConfigurationHelperG6 : AttributesConfigurationHelper { + override fun setAttribute( + attributesContainer: HasAttributes, + key: Attribute, + value: () -> T + ) { + attributesContainer.attributes.attribute(key, value()) + } +} + +internal class AttributeConfigurationHelperVariantFactoryG6 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory { + override fun getInstance( + providerFactory: ProviderFactory + ): AttributesConfigurationHelper = AttributesConfigurationHelperG6() +}