From 83af85706d2d9e1e04ce279943d79366b278fd61 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Thu, 17 Nov 2022 10:32:17 +0100 Subject: [PATCH] [Gradle] ExternalKotlinTarget Api: Implement 'configureIdeImport' API ^KT-55010 Verification Pending --- .../build.gradle.kts | 1 + .../gradle/android/AndroidKotlinSourceSet.kt | 23 ++++++++++++++++++ .../gradle/android/AndroidTargetPrototype.kt | 11 +++++++++ .../gradle/android/androidBootClasspath.kt | 23 +++++++++++++++++- .../android/createAndroidCompilation.kt | 16 +++++++++---- .../ExternalKotlinTargetDescriptor.kt | 24 ++++++++++++++++--- .../mpp/external/KotlinSourceSetExtensions.kt | 14 +++++++++++ .../external/createExternalKotlinTarget.kt | 2 ++ .../plugin/sources/DefaultKotlinSourceSet.kt | 5 +++- .../plugin/sources/InternalKotlinSourceSet.kt | 4 +++- 10 files changed, 112 insertions(+), 11 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidKotlinSourceSet.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/KotlinSourceSetExtensions.kt diff --git a/libraries/tools/kotlin-gradle-plugin-tcs-android/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-tcs-android/build.gradle.kts index 79ed8f17c9f..85c0c06f375 100644 --- a/libraries/tools/kotlin-gradle-plugin-tcs-android/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-tcs-android/build.gradle.kts @@ -7,6 +7,7 @@ dependencies { compileOnly(gradleKotlinDsl()) compileOnly("com.android.tools.build:gradle:7.2.1") compileOnly(project(":kotlin-gradle-plugin")) + compileOnly(project(":kotlin-gradle-plugin-idea")) } configureKotlinCompileTasksGradleCompatibility() diff --git a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidKotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidKotlinSourceSet.kt new file mode 100644 index 00000000000..18ccb5ad76e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidKotlinSourceSet.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2022 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.android + +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.external.extras +import org.jetbrains.kotlin.tooling.core.extrasKeyOf + +class AndroidKotlinSourceSet { + companion object { + private val extrasKey = extrasKeyOf() + + var KotlinSourceSet.android: AndroidKotlinSourceSet? + get() = extras[extrasKey] + internal set(value) { + if (value != null) extras[extrasKey] = value + else extras.remove(extrasKey) + } + } +} 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 c6c8a36a113..89eda36852f 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 @@ -14,10 +14,12 @@ import org.gradle.api.attributes.java.TargetJvmEnvironment import org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.named +import org.jetbrains.kotlin.gradle.android.AndroidKotlinSourceSet.Companion.android import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.kpm.external.ExternalVariantApi import org.jetbrains.kotlin.gradle.kpm.external.project import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport import org.jetbrains.kotlin.gradle.plugin.mpp.external.* import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.TargetFactory @@ -81,6 +83,15 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm) configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) } + + configureIdeImport { + registerDependencyResolver( + AndroidBootClasspathIdeDependencyResolver(project), + constraint = IdeMultiplatformImport.SourceSetConstraint { sourceSet -> sourceSet.android != null }, + phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution, + level = IdeMultiplatformImport.DependencyResolutionLevel.Default + ) + } } /* diff --git a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/androidBootClasspath.kt b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/androidBootClasspath.kt index 14d4d1dd8b2..b3cf3c7c49f 100644 --- a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/androidBootClasspath.kt +++ b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/androidBootClasspath.kt @@ -9,8 +9,29 @@ import com.android.build.gradle.BaseExtension import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.kotlin.dsl.getByType +import org.jetbrains.kotlin.gradle.android.AndroidKotlinSourceSet.Companion.android +import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates +import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency +import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver +import org.jetbrains.kotlin.tooling.core.mutableExtrasOf import java.util.concurrent.Callable internal fun Project.androidBootClasspath(): FileCollection { return project.files(Callable { project.extensions.getByType().bootClasspath }) -} \ No newline at end of file +} + +internal class AndroidBootClasspathIdeDependencyResolver(private val project: Project) : IdeDependencyResolver { + override fun resolve(sourceSet: KotlinSourceSet): Set { + if (sourceSet.android == null) return emptySet() + return project.androidBootClasspath().files.map { file -> + IdeaKotlinResolvedBinaryDependency( + binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE, + binaryFile = file, + extras = mutableExtrasOf(), + coordinates = IdeaKotlinBinaryCoordinates("com.android", "sdk", "7.4") + ) + }.toSet() + } +} 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 65a8de036e5..6e730f506d3 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 @@ -6,16 +6,22 @@ package org.jetbrains.kotlin.gradle.android import com.android.build.gradle.internal.publishing.AndroidArtifacts +import com.android.build.gradle.internal.publishing.AndroidArtifacts.ARTIFACT_TYPE import org.gradle.api.attributes.java.TargetJvmEnvironment +import org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE import org.gradle.kotlin.dsl.named +import org.jetbrains.kotlin.gradle.android.AndroidKotlinSourceSet.Companion.android import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.DecoratedKotlinCompilationFactory import org.jetbrains.kotlin.gradle.plugin.mpp.external.createCompilation + internal fun PrototypeAndroidTarget.createAndroidCompilation(name: String): PrototypeAndroidCompilation { return createCompilation { compilationName = name - defaultSourceSet = kotlin.sourceSets.maybeCreate(camelCase("prototype", targetName, name)) + defaultSourceSet = kotlin.sourceSets.maybeCreate(camelCase("prototype", targetName, name)).apply { + android = AndroidKotlinSourceSet() + } decoratedKotlinCompilationFactory = DecoratedKotlinCompilationFactory(::PrototypeAndroidCompilation) compileTaskName = camelCase("prototype", "compile", targetName, name) @@ -35,14 +41,14 @@ internal fun PrototypeAndroidTarget.createAndroidCompilation(name: String): Prot configure { compilation -> /* Setup attributes for the compile dependencies */ compilation.configurations.compileDependencyConfiguration.apply { - attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) - attributes.attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) + attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) } /* Setup attributes for the runtime dependencies */ compilation.configurations.runtimeDependencyConfiguration?.apply { - attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) - attributes.attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) + attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt index a37b3b9d271..4b8f36d3694 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.external import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.TargetFactory import kotlin.properties.Delegates @@ -21,12 +22,13 @@ interface ExternalKotlinTargetDescriptor { val platformType: KotlinPlatformType val targetFactory: TargetFactory - val configure: ((T) -> Unit)? - val apiElements: ExternalKotlinTargetConfigurationDescriptor val runtimeElements: ExternalKotlinTargetConfigurationDescriptor val apiElementsPublished: ExternalKotlinTargetConfigurationDescriptor val runtimeElementsPublished: ExternalKotlinTargetConfigurationDescriptor + + val configure: ((T) -> Unit)? + val configureIdeImport: (IdeMultiplatformImport.() -> Unit)? } @ExternalKotlinTargetApi @@ -56,6 +58,20 @@ class ExternalKotlinTargetDescriptorBuilder i var configure: ((T) -> Unit)? = null + fun configure(action: (T) -> Unit) { + val configure = this.configure + if (configure == null) this.configure = action + else this.configure = { configure(it); action(it) } + } + + var configureIdeImport: (IdeMultiplatformImport.() -> Unit)? = null + + fun configureIdeImport(action: IdeMultiplatformImport.() -> Unit) { + val configureIdeImport = this.configureIdeImport + if (configureIdeImport == null) this.configureIdeImport = action + else this.configureIdeImport = { configureIdeImport(); action() } + } + internal fun build(): ExternalKotlinTargetDescriptor = ExternalKotlinTargetDescriptorImpl( targetName = targetName, platformType = platformType, @@ -64,7 +80,8 @@ class ExternalKotlinTargetDescriptorBuilder i runtimeElements = runtimeElements.build(), apiElementsPublished = apiElementsPublished.build(), runtimeElementsPublished = runtimeElementsPublished.build(), - configure = configure + configure = configure, + configureIdeImport = configureIdeImport ) } @@ -77,6 +94,7 @@ private data class ExternalKotlinTargetDescriptorImpl, override val runtimeElementsPublished: ExternalKotlinTargetConfigurationDescriptor, override val configure: ((T) -> Unit)?, + override val configureIdeImport: (IdeMultiplatformImport.() -> Unit)?, ) : ExternalKotlinTargetDescriptor diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/KotlinSourceSetExtensions.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/KotlinSourceSetExtensions.kt new file mode 100644 index 00000000000..d4a28fea12f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/KotlinSourceSetExtensions.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.external + +import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.sources.internal +import org.jetbrains.kotlin.tooling.core.MutableExtras + +@ExternalKotlinTargetApi +val KotlinSourceSet.extras: MutableExtras get() = this.internal.extras 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 dc47bbe9e52..c7347b812d5 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 @@ -13,6 +13,7 @@ import org.gradle.api.attributes.Usage import org.gradle.jvm.tasks.Jar import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.markConsumable import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf @@ -77,6 +78,7 @@ fun KotlinMultiplatformExtension.createExter descriptor.runtimeElements.configure?.invoke(decorated, runtimeElementsConfiguration) descriptor.apiElementsPublished.configure?.invoke(decorated, apiElementsPublishedConfiguration) descriptor.runtimeElementsPublished.configure?.invoke(decorated, runtimeElementsPublishedConfiguration) + descriptor.configureIdeImport?.invoke(project.kotlinIdeMultiplatformImport) targets.add(decorated) decorated.logger.info("Created ${descriptor.platformType} target") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt index 21338ae7a42..5e13763a991 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt @@ -11,14 +11,15 @@ import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.file.SourceDirectorySet import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS -import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.utils.* +import org.jetbrains.kotlin.tooling.core.MutableExtras import org.jetbrains.kotlin.tooling.core.closure +import org.jetbrains.kotlin.tooling.core.mutableExtrasOf import java.io.File import java.util.* import javax.inject.Inject @@ -30,6 +31,8 @@ abstract class DefaultKotlinSourceSet @Inject constructor( val displayName: String ) : AbstractKotlinSourceSet() { + override val extras: MutableExtras = mutableExtrasOf() + override val apiConfigurationName: String get() = disambiguateName(API) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/InternalKotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/InternalKotlinSourceSet.kt index 7958abcb9f7..7df6d87d02b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/InternalKotlinSourceSet.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/InternalKotlinSourceSet.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.utils.MutableObservableSet import org.jetbrains.kotlin.gradle.utils.ObservableSet +import org.jetbrains.kotlin.tooling.core.MutableExtras internal val KotlinSourceSet.internal: InternalKotlinSourceSet get() = (this as? InternalKotlinSourceSet) ?: throw IllegalArgumentException( @@ -22,6 +23,7 @@ internal interface InternalKotlinSourceSet : KotlinSourceSet { val dependsOnClosure: ObservableSet val withDependsOnClosure: ObservableSet val compilations: MutableObservableSet> + val extras: MutableExtras } -internal val KotlinSourceSet.project: Project get() = this.internal.project \ No newline at end of file +internal val KotlinSourceSet.project: Project get() = this.internal.project