diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt index 6dd7adeb84e..a9dbf4ea131 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt @@ -17,15 +17,21 @@ import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.internal.KOTLIN_BUILD_TOOLS_API_IMPL import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.CoroutineStart.Undispatched +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrSingleTargetPreset import org.jetbrains.kotlin.gradle.tasks.CompileUsingKotlinDaemon import org.jetbrains.kotlin.gradle.tasks.withType +import org.jetbrains.kotlin.gradle.utils.* +import org.jetbrains.kotlin.gradle.utils.CompletableFuture +import org.jetbrains.kotlin.gradle.utils.Future import org.jetbrains.kotlin.gradle.utils.castIsolatedKotlinPluginClassLoaderAware import org.jetbrains.kotlin.gradle.utils.configureExperimentalTryK2 import org.jetbrains.kotlin.konan.target.CompilerOutputKind +import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.tooling.core.HasMutableExtras import org.jetbrains.kotlin.tooling.core.MutableExtras import org.jetbrains.kotlin.tooling.core.mutableExtrasOf @@ -180,17 +186,21 @@ open class KotlinProjectExtension @Inject constructor(project: Project) : Kotlin abstract class KotlinSingleTargetExtension(project: Project) : KotlinProjectExtension(project) { abstract val target: TARGET - + internal abstract val targetFuture: Future fun target(body: Action) = body.execute(target) } abstract class KotlinSingleJavaTargetExtension(project: Project) : KotlinSingleTargetExtension>(project) abstract class KotlinJvmProjectExtension(project: Project) : KotlinSingleJavaTargetExtension(project) { - override lateinit var target: KotlinWithJavaTarget - internal set + override val target: KotlinWithJavaTarget + get() = targetFuture.getOrThrow() - open fun target(body: KotlinWithJavaTarget.() -> Unit) = target.run(body) + override val targetFuture = CompletableFuture>() + + open fun target(body: KotlinWithJavaTarget.() -> Unit) { + project.launch(Undispatched) { targetFuture.await().body() } + } val compilerOptions: KotlinJvmCompilerOptions = project.objects .newInstance(KotlinJvmCompilerOptionsDefault::class.java) @@ -206,20 +216,16 @@ abstract class KotlinJvmProjectExtension(project: Project) : KotlinSingleJavaTar } abstract class Kotlin2JsProjectExtension(project: Project) : KotlinSingleJavaTargetExtension(project) { - private lateinit var _target: KotlinWithJavaTarget - override val target: KotlinWithJavaTarget get() { - if (!::_target.isInitialized) throw IllegalStateException("Extension target is not initialized!") - - return _target + if (!targetFuture.isCompleted) throw IllegalStateException("Extension target is not initialized!") + return targetFuture.getOrThrow() } - internal fun setTarget(target: KotlinWithJavaTarget) { - _target = target + override val targetFuture = CompletableFuture>() + open fun target(body: KotlinWithJavaTarget.() -> Unit) { + project.launch(Undispatched) { targetFuture.await().body() } } - - open fun target(body: KotlinWithJavaTarget.() -> Unit) = target.run(body) } abstract class KotlinJsProjectExtension(project: Project) : @@ -227,45 +233,31 @@ abstract class KotlinJsProjectExtension(project: Project) : KotlinJsCompilerTypeHolder { lateinit var irPreset: KotlinJsIrSingleTargetPreset - private val targetSetObservers = mutableListOf<(KotlinJsTargetDsl?) -> Unit>() + @Deprecated("Use js() instead", ReplaceWith("js()")) + override val target: KotlinJsTargetDsl + get() = targetFuture.lenient.getOrNull() ?: js() @Deprecated("Because only IR compiler is left, no more necessary to know about compiler type in properties") override val compilerTypeFromProperties: KotlinJsCompilerType? = null - // target is public property - // Users can write kotlin.target and it should work - // So call of target should init default configuration - @Deprecated("Use `target` instead", ReplaceWith("target")) - var _target: KotlinJsTargetDsl? = null - private set(value) { - field = value - targetSetObservers.forEach { it(value) } - } + override val targetFuture = CompletableFuture() fun registerTargetObserver(observer: (KotlinJsTargetDsl?) -> Unit) { - targetSetObservers.add(observer) - } - - @Deprecated("Use js() instead", ReplaceWith("js()")) - @Suppress("DEPRECATION") - override val target: KotlinJsTargetDsl - get() { - if (_target == null) { - js {} - } - return _target!! + project.launch(Undispatched) { + observer(targetFuture.await()) } + } @Suppress("DEPRECATION") private fun jsInternal( compiler: KotlinJsCompilerType? = null, body: KotlinJsTargetDsl.() -> Unit, ): KotlinJsTargetDsl { - if (_target == null) { + if (!targetFuture.isCompleted) { val target: KotlinJsTargetDsl = irPreset .createTargetInternal("js") - this._target = target + this.targetFuture.complete(target) target.project.components.addAll(target.components) } @@ -317,26 +309,31 @@ abstract class KotlinJsProjectExtension(project: Project) : ) @Suppress("DEPRECATION") fun getTargets(): NamedDomainObjectContainer? = - _target?.let { target -> + targetFuture.lenient.getOrNull()?.let { target -> target.project.container(KotlinTarget::class.java) .apply { add(target) } } } abstract class KotlinCommonProjectExtension(project: Project) : KotlinSingleJavaTargetExtension(project) { - override lateinit var target: KotlinWithJavaTarget - internal set + override val target: KotlinWithJavaTarget<*, *> get() = targetFuture.getOrThrow() + override val targetFuture = + CompletableFuture>() open fun target( body: KotlinWithJavaTarget.() -> Unit, - ) = target.run(body) + ) = project.launch(Undispatched) { + targetFuture.await().body() + } } abstract class KotlinAndroidProjectExtension(project: Project) : KotlinSingleTargetExtension(project) { - override lateinit var target: KotlinAndroidTarget - internal set + override val target: KotlinAndroidTarget get() = targetFuture.getOrThrow() + override val targetFuture = CompletableFuture() - open fun target(body: KotlinAndroidTarget.() -> Unit) = target.run(body) + open fun target(body: KotlinAndroidTarget.() -> Unit) = project.launch(Undispatched) { + targetFuture.await().body() + } val compilerOptions: KotlinJvmCompilerOptions = project.objects .newInstance(KotlinJvmCompilerOptionsDefault::class.java) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt index 3c820f65c01..72c1d2134fd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt @@ -52,7 +52,7 @@ internal open class Kotlin2JsPlugin( } ) as KotlinWithJavaTarget - (project.kotlinExtension as Kotlin2JsProjectExtension).setTarget(target) + (project.kotlinExtension as Kotlin2JsProjectExtension).targetFuture.complete(target) super.apply(project) } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinAndroidPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinAndroidPlugin.kt index 3ed0beeead0..de308e61bc0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinAndroidPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinAndroidPlugin.kt @@ -38,7 +38,7 @@ internal open class KotlinAndroidPlugin( project ).also { target -> val kotlinAndroidExtension = project.kotlinExtension as KotlinAndroidProjectExtension - kotlinAndroidExtension.target = target + kotlinAndroidExtension.targetFuture.complete(target) project.configureCompilerOptionsForTarget( kotlinAndroidExtension.compilerOptions, target.compilerOptions diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt index 8227026ec4a..add5e8d104d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt @@ -47,7 +47,7 @@ internal open class KotlinCommonPlugin( } } ) as KotlinWithJavaTarget - (project.kotlinExtension as KotlinCommonProjectExtension).target = target + (project.kotlinExtension as KotlinCommonProjectExtension).targetFuture.complete(target) super.apply(project) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt index cf2995a9ee0..11e165f5513 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt @@ -72,7 +72,7 @@ internal open class KotlinJvmPlugin( disambiguationClassifier = null // don't add anything to the task names } val kotlinExtension = project.kotlinExtension as KotlinJvmProjectExtension - kotlinExtension.target = target + kotlinExtension.targetFuture.complete(target) super.apply(project) 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 b368d0d6e06..80616d815c2 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 @@ -319,8 +319,7 @@ abstract class AbstractKotlinJsPluginWrapper : KotlinBasePluginWrapper() { get() = KotlinJsProjectExtension::class override fun whenBuildEvaluated(project: Project) = project.runProjectConfigurationHealthCheck { - val isJsTargetUninitialized = (project.kotlinExtension as KotlinJsProjectExtension) - ._target == null + val isJsTargetUninitialized = !(project.kotlinExtension as KotlinJsProjectExtension).targetFuture.isCompleted if (isJsTargetUninitialized) { throw GradleException( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsPlugin.kt index d4a608b7e60..78bbccdfbaa 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsPlugin.kt @@ -38,8 +38,7 @@ open class KotlinJsPlugin: Plugin { } project.runProjectConfigurationHealthCheckWhenEvaluated { - @Suppress("DEPRECATION") - if (kotlinExtension._target == null) { + if (!kotlinExtension.targetFuture.isCompleted) { project.logger.warn( """ Please initialize the Kotlin/JS target. Use: diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/kotlinExtensionUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/kotlinExtensionUtils.kt index b3887287c46..93f83431a2c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/kotlinExtensionUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/kotlinExtensionUtils.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle.utils import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.CoroutineStart.Undispatched import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.launch internal val KotlinProjectExtension.targets: Iterable get() = when (this) { @@ -20,8 +22,8 @@ internal val KotlinProjectExtension.targets: Iterable internal fun KotlinProjectExtension.forAllTargets(action: (target: KotlinTarget) -> Unit) { when (this) { - is KotlinSingleTargetExtension<*> -> action(this.target) + is KotlinSingleTargetExtension<*> -> project.launch(Undispatched) { action(targetFuture.await()) } is KotlinMultiplatformExtension -> targets.all(action) else -> error("Unexpected 'kotlin' extension $this") } -} \ No newline at end of file +}