From cef557c4073822149ece3f80e3a8481d3c87aaf2 Mon Sep 17 00:00:00 2001 From: "Alexander.Likhachev" Date: Mon, 30 Jan 2023 23:17:56 +0100 Subject: [PATCH] [IC] Notify user about enabled IC backup optimizations KT-52625, KT-55995, KT-56052 Related --- .../plugin/BuildFinishedListenerService.kt | 42 +++++++++++++++---- .../gradle/plugin/PropertiesProvider.kt | 5 +++ .../js/MultiplePluginDeclarationDetector.kt | 7 ++-- .../gradle/tasks/AbstractKotlinCompile.kt | 29 +++++++++++++ .../AbstractKotlinCompileConfig.kt | 5 +++ 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/BuildFinishedListenerService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/BuildFinishedListenerService.kt index 51dc6db6162..0b4cf184bba 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/BuildFinishedListenerService.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/BuildFinishedListenerService.kt @@ -5,17 +5,35 @@ package org.jetbrains.kotlin.gradle.plugin -import org.gradle.api.invocation.Gradle +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.api.services.BuildService import org.gradle.api.services.BuildServiceParameters +import org.gradle.api.tasks.Internal +import org.jetbrains.kotlin.gradle.tasks.withType +import org.jetbrains.kotlin.gradle.utils.SingleActionPerProject + +internal interface UsesBuildFinishedListenerService : Task { + @get:Internal + val buildFinishedListenerService: Property +} abstract class BuildFinishedListenerService : BuildService, AutoCloseable { private val actionsOnClose = mutableListOf<() -> Unit>() + private val keys = hashSetOf() fun onClose(action: () -> Unit) { actionsOnClose.add(action) } + fun onCloseOnceByKey(key: String, action: () -> Unit) { + if (keys.add(key)) { + onClose(action) + } + } + override fun close() { for (action in actionsOnClose) { action() @@ -24,13 +42,19 @@ abstract class BuildFinishedListenerService : BuildService = project.gradle.sharedServices + .registerIfAbsent( + // Use class loader hashcode in case there are multiple class loaders in the same build + "build-finished-listener_${BuildFinishedListenerService::class.java.classLoader.hashCode()}", + BuildFinishedListenerService::class.java + ) {}.also { serviceProvider -> + SingleActionPerProject.run(project, UsesBuildFinishedListenerService::class.java.name) { + project.tasks.withType().configureEach { task -> + task.usesService(serviceProvider) + } + } + } + + fun getInstance(project: Project): BuildFinishedListenerService = registerIfAbsent(project).get() } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index 08e70d848ab..4e3e9a624ea 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_USE_XCODE_MESSAGE_STYLE import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_STDLIB_DEFAULT_DEPENDENCY import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_STDLIB_JDK_VARIANTS_VERSION_ALIGNMENT +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinIrJsGeneratedTSValidationStrategy import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrOutputGranularity @@ -518,6 +519,9 @@ internal class PropertiesProvider private constructor(private val project: Proje val keepIncrementalCompilationCachesInMemory: Boolean get() = booleanProperty(KOTLIN_COMPILER_KEEP_INCREMENTAL_COMPILATION_CACHES_IN_MEMORY) ?: false + val suppressExperimentalICOptimizationsWarning: Boolean + get() = booleanProperty(KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING) ?: false + /** * Retrieves a comma-separated list of browsers to use when running karma tests for [target] * @see KOTLIN_JS_KARMA_BROWSERS @@ -601,6 +605,7 @@ internal class PropertiesProvider private constructor(private val project: Proje const val KOTLIN_NATIVE_USE_XCODE_MESSAGE_STYLE = "kotlin.native.useXcodeMessageStyle" const val KOTLIN_COMPILER_USE_PRECISE_COMPILATION_RESULTS_BACKUP = "kotlin.compiler.preciseCompilationResultsBackup" const val KOTLIN_COMPILER_KEEP_INCREMENTAL_COMPILATION_CACHES_IN_MEMORY = "kotlin.compiler.keepIncrementalCompilationCachesInMemory" + const val KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING = "kotlin.compiler.suppressExperimentalICOptimizationsWarning" } companion object { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/MultiplePluginDeclarationDetector.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/MultiplePluginDeclarationDetector.kt index 6926c63310e..16b62ccfba1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/MultiplePluginDeclarationDetector.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/MultiplePluginDeclarationDetector.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.gradle.targets.js import org.gradle.api.Project -import org.gradle.api.invocation.Gradle import org.jetbrains.kotlin.gradle.plugin.BuildFinishedListenerService import org.jetbrains.kotlin.gradle.plugin.KotlinPluginInMultipleProjectsHolder import org.jetbrains.kotlin.gradle.plugin.MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING @@ -34,7 +33,7 @@ private constructor() { @JvmStatic @Synchronized - private fun getInstance(gradle: Gradle): MultiplePluginDeclarationDetector { + private fun getInstance(project: Project): MultiplePluginDeclarationDetector { if (instance != null) { return instance!! } @@ -42,13 +41,13 @@ private constructor() { val detector = MultiplePluginDeclarationDetector() instance = detector - BuildFinishedListenerService.getInstance(gradle).onClose { instance = null } + BuildFinishedListenerService.getInstance(project).onClose { instance = null } return detector } fun detect(project: Project) { - getInstance(project.gradle).detect(project) + getInstance(project).detect(project) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt index 0b3e09632c3..8e16a3d98b2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt @@ -9,6 +9,7 @@ import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileCollection import org.gradle.api.file.FileSystemOperations +import org.gradle.api.logging.Logging import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property import org.gradle.api.provider.Provider @@ -36,6 +37,8 @@ import org.jetbrains.kotlin.gradle.internal.prepareCompilerArguments import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger import org.jetbrains.kotlin.gradle.logging.kotlinDebug +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING +import org.jetbrains.kotlin.gradle.plugin.UsesBuildFinishedListenerService import org.jetbrains.kotlin.gradle.plugin.UsesVariantImplementationFactories import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.report.* @@ -63,6 +66,7 @@ abstract class AbstractKotlinCompile @Inject constr UsesIncrementalModuleInfoBuildService, UsesCompilerSystemPropertiesService, UsesVariantImplementationFactories, + UsesBuildFinishedListenerService, BaseKotlinCompile { init { @@ -194,12 +198,37 @@ abstract class AbstractKotlinCompile @Inject constr @get:Internal internal abstract val keepIncrementalCompilationCachesInMemory: Property + @get:Internal + internal abstract val suppressExperimentalIcOptimizationsWarning: Property + /** Task outputs that we don't want to include in [TaskOutputsBackup] (see [TaskOutputsBackup.outputsToRestore] for more info). */ @get:Internal internal abstract val taskOutputsBackupExcludes: SetProperty + private fun notifyUserAboutExperimentalICOptimizations() { + if (suppressExperimentalIcOptimizationsWarning.get()) { + return + } + if (!preciseCompilationResultsBackup.get() && !keepIncrementalCompilationCachesInMemory.get()) { + return + } + val key = "experimental-ic-optimizations" + buildFinishedListenerService.get().onCloseOnceByKey(key) { + Logging.getLogger(key).warn( + """ + + The build has experimental Kotlin incremental compilation optimizations enabled. + If you notice incorrect compilation results after enabling it, please file a bug report at https://kotl.in/issue/experimental-ic-optimizations + + You can suppress this warning by adding `${KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING}=true` to the gradle.properties + """.trimIndent() + ) + } + } + @TaskAction fun execute(inputChanges: InputChanges) { + notifyUserAboutExperimentalICOptimizations() val buildMetrics = metrics.get() buildMetrics.addTimeMetric(BuildPerformanceMetric.START_TASK_ACTION_EXECUTION) buildMetrics.measure(BuildTime.OUT_OF_WORKER_TASK_ACTION) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt index 95d02a10321..6b05c1eeb58 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt @@ -63,6 +63,7 @@ internal abstract class AbstractKotlinCompileConfig val propertiesProvider = project.kotlinPropertiesProvider @@ -106,6 +107,10 @@ internal abstract class AbstractKotlinCompileConfig