From d7facce71fe9e61cd00fa60e11b7bdbf0102726a Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Tue, 20 Jun 2023 09:08:10 +0200 Subject: [PATCH] [Gradle] KotlinPluginLifecycle: Implement .toString for better diagnostics ^KT-59446 In Progress --- .../gradle/plugin/KotlinPluginLifecycle.kt | 4 ++++ .../plugin/KotlinPluginLifecycleImpl.kt | 24 +++++++++++++++---- .../jetbrains/kotlin/gradle/utils/Future.kt | 10 ++++---- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycle.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycle.kt index c338eed9428..548203e4776 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycle.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycle.kt @@ -296,6 +296,10 @@ internal interface KotlinPluginLifecycle { val stage: Stage + val isStarted: Boolean + + val isFinished: Boolean + fun launch(block: suspend KotlinPluginLifecycle.() -> Unit) suspend fun await(stage: Stage) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycleImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycleImpl.kt index 62a98c5d02a..f2863a20c37 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycleImpl.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginLifecycleImpl.kt @@ -24,15 +24,21 @@ internal class KotlinPluginLifecycleImpl(override val project: Project) : Kotlin KotlinPluginLifecycle.Stage.values().associateWith { ArrayDeque() } private val loopRunning = AtomicBoolean(false) - private val isStarted = AtomicBoolean(false) + private val isStartedImpl = AtomicBoolean(false) private val isFinishedSuccessfully = AtomicBoolean(false) private val isFinishedWithFailures = AtomicBoolean(false) override var stage: KotlinPluginLifecycle.Stage = KotlinPluginLifecycle.Stage.values.first() + override val isStarted: Boolean + get() = isStartedImpl.get() + + override val isFinished: Boolean + get() = isFinishedSuccessfully.get() || isFinishedWithFailures.get() + fun start() { - check(!isStarted.getAndSet(true)) { + check(!isStartedImpl.getAndSet(true)) { "${KotlinPluginLifecycle::class.java.name} already started" } @@ -103,13 +109,13 @@ internal class KotlinPluginLifecycleImpl(override val project: Project) : Kotlin private fun finishWithFailures(failures: List) { assert(failures.isNotEmpty()) - assert(isStarted.get()) + assert(isStartedImpl.get()) assert(!isFinishedWithFailures.getAndSet(true)) configurationResult.complete(ProjectConfigurationResult.Failure(failures)) } private fun finishSuccessfully() { - assert(isStarted.get()) + assert(isStartedImpl.get()) assert(!isFinishedSuccessfully.getAndSet(true)) configurationResult.complete(ProjectConfigurationResult.Success) } @@ -140,7 +146,7 @@ internal class KotlinPluginLifecycleImpl(override val project: Project) : Kotlin enqueuedActions.getValue(stage).addLast(action) - if (stage == KotlinPluginLifecycle.Stage.EvaluateBuildscript && isStarted.get()) { + if (stage == KotlinPluginLifecycle.Stage.EvaluateBuildscript && isStartedImpl.get()) { loopIfNecessary() } } @@ -168,6 +174,14 @@ internal class KotlinPluginLifecycleImpl(override val project: Project) : Kotlin } } } + + override fun toString(): String = buildString { + append("Kotlin Plugin Lifecycle: (${project.displayName})") + if (!isStarted) append(" *not started*") + else append(" stage '$stage'") + if (isFinishedSuccessfully.get()) append(" *finished successfully*") + if (isFinishedWithFailures.get()) append(" *finished with failures*") + } } private class KotlinPluginLifecycleCoroutineContextElement( 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 c4baa2a93fa..6c1b7d0b225 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 @@ -64,7 +64,7 @@ internal fun CompletableFuture.complete() = complete(Unit) * @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 + name: String? = null, noinline block: suspend Receiver.() -> T, ): ExtrasLazyProperty> where Receiver : HasMutableExtras, Receiver : HasProject { return extrasLazyProperty>(name) { project.future { block() } @@ -97,7 +97,7 @@ internal fun CompletableFuture(): CompletableFuture { private class FutureImpl( private val deferred: Completable = Completable(), - private val lifecycle: KotlinPluginLifecycle? = null + private val lifecycle: KotlinPluginLifecycle? = null, ) : CompletableFuture, Serializable { fun completeWith(result: Result) = deferred.completeWith(result) @@ -111,7 +111,7 @@ private class FutureImpl( override fun getOrThrow(): T { return if (deferred.isCompleted) deferred.getCompleted() else throw IllegalLifecycleException( - "Future was not completed yet" + if (lifecycle != null) " (stage '${lifecycle.stage}') (${lifecycle.project.displayName})" + "Future was not completed yet" + if (lifecycle != null) " '$lifecycle'" else "" ) } @@ -128,7 +128,7 @@ private class FutureImpl( } private class LenientFutureImpl( - private val future: Future + private val future: Future, ) : LenientFuture, Serializable { override suspend fun await(): T { return future.await() @@ -181,7 +181,7 @@ private class LazyFutureImpl(private val future: Lazy>) : Future * Simple, Single Threaded, replacement for kotlinx.coroutines.CompletableDeferred. */ private class Completable( - private var value: Result? = null + private var value: Result? = null, ) { constructor(value: T) : this(Result.success(value))