From 7c65d00f296a981a27604f46f17cd6b60bf013b7 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Mon, 13 Mar 2023 16:26:52 +0100 Subject: [PATCH] [Gradle] Introduce lazyFuture and futureExtension methods ^KT-34662 Verification Pending --- .../native/internal/CInteropCommonizerTask.kt | 14 +++++++++----- .../native/internal/commonizerTarget.kt | 12 ++++++------ .../jetbrains/kotlin/gradle/utils/Future.kt | 19 +++++++++++++++++-- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt index 9fd3b480497..08c9e9c7ca9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure +import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerTask.CInteropCommonizerDependencies import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerTask.CInteropGist import org.jetbrains.kotlin.gradle.tasks.CInteropProcess import org.jetbrains.kotlin.gradle.utils.* @@ -32,6 +33,9 @@ import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File import javax.inject.Inject +private typealias GroupedCommonizerDependencies = Map> + + @CacheableTask internal open class CInteropCommonizerTask @Inject constructor( @@ -121,8 +125,8 @@ internal open class CInteropCommonizerTask * For Gradle Configuration Cache support the Group-to-Dependencies relation should be pre-cached. * It is used during execution phase. */ - private val groupedCommonizerDependencies: Future>> = project.future { - val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@future emptyMap() + private val groupedCommonizerDependencies: Future by project.lazyFuture { + val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@lazyFuture emptyMap() val sourceSetsByTarget = multiplatformExtension.sourceSets.groupBy { sourceSet -> sourceSet.commonizerTarget.getOrThrow() } val sourceSetsByGroup = multiplatformExtension.sourceSets.groupBy { sourceSet -> @@ -228,7 +232,7 @@ internal open class CInteropCommonizerTask } @get:Internal - internal val allInteropGroups: Future> = project.future { + internal val allInteropGroups: Future> by project.lazyFuture { val dependents = allDependents.await() val allScopeSets = dependents.map { it.scopes }.toSet() val rootScopeSets = allScopeSets.filter { scopeSet -> @@ -263,8 +267,8 @@ internal open class CInteropCommonizerTask return suitableGroups.firstOrNull() } - private val allDependents: Future> = project.future { - val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@future emptySet() + private val allDependents: Future> by project.lazyFuture { + val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@lazyFuture emptySet() val fromSharedNativeCompilations = multiplatformExtension .targets.flatMap { target -> target.compilations } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/commonizerTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/commonizerTarget.kt index c70dfc8e13c..6fb7ca860c4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/commonizerTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/commonizerTarget.kt @@ -18,20 +18,20 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.utils.Future -import org.jetbrains.kotlin.gradle.utils.lazyFuture +import org.jetbrains.kotlin.gradle.utils.future +import org.jetbrains.kotlin.gradle.utils.futureExtension import org.jetbrains.kotlin.tooling.core.UnsafeApi -internal val KotlinSourceSet.commonizerTarget: Future by lazyFuture { +internal val KotlinSourceSet.commonizerTarget: Future by futureExtension { await(KotlinPluginLifecycle.Stage.AfterFinaliseRefinesEdges) @OptIn(UnsafeApi::class) inferCommonizerTarget(this) } -internal val KotlinSourceSet.sharedCommonizerTarget: Future by lazyFuture { - commonizerTarget.await() as? SharedCommonizerTarget -} +internal val KotlinSourceSet.sharedCommonizerTarget: Future + get() = project.future { commonizerTarget.await() as? SharedCommonizerTarget } -internal val KotlinCompilation<*>.commonizerTarget: Future by lazyFuture { +internal val KotlinCompilation<*>.commonizerTarget: Future by futureExtension { await(KotlinPluginLifecycle.Stage.AfterFinaliseRefinesEdges) @OptIn(UnsafeApi::class) inferCommonizerTarget(this) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Future.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Future.kt index 3a68b596d14..4a088c5f246 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Future.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/Future.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.tooling.core.ExtrasLazyProperty import org.jetbrains.kotlin.tooling.core.HasMutableExtras import org.jetbrains.kotlin.tooling.core.extrasLazyProperty import java.io.Serializable -import kotlin.reflect.KProperty /** * See [KotlinPluginLifecycle]: @@ -54,7 +53,13 @@ internal interface CompletableFuture : Future { internal fun CompletableFuture.complete() = complete(Unit) -internal inline fun lazyFuture( +/** + * Extend a given [Receiver] with data produced by [block]: + * This uses the [HasMutableExtras] infrastructure to store/share the produced future entity to the given [Receiver] + * Note: The [block] will be lazily launched on first access to this extension! + * @param name: The name of the extras key being used to store the future (see [extrasLazyProperty]) + */ +internal inline fun futureExtension( name: String? = null, noinline block: suspend Receiver.() -> T ): ExtrasLazyProperty> where Receiver : HasMutableExtras, Receiver : HasProject { return extrasLazyProperty>(name) { @@ -64,6 +69,16 @@ internal inline fun lazyFuture( internal fun Project.future(block: suspend Project.() -> T): Future = kotlinPluginLifecycle.future { block() } +/** + * Shortcut for + * ```kotlin + * lazy { future { block() } } + * ``` + * + * basically creating a future, which is launched lazily + */ +internal fun Project.lazyFuture(block: suspend Project.() -> T): Lazy> = lazy { future(block) } + internal fun KotlinPluginLifecycle.future(block: suspend () -> T): Future { return FutureImpl(CompletableDeferred()).also { future -> launch { future.completeWith(runCatching { block() }) }