[IC] Notify user about enabled IC backup optimizations

KT-52625, KT-55995, KT-56052 Related
This commit is contained in:
Alexander.Likhachev
2023-01-30 23:17:56 +01:00
committed by Space Team
parent 4d080c1a82
commit cef557c407
5 changed files with 75 additions and 13 deletions
@@ -5,17 +5,35 @@
package org.jetbrains.kotlin.gradle.plugin 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.BuildService
import org.gradle.api.services.BuildServiceParameters 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<BuildFinishedListenerService>
}
abstract class BuildFinishedListenerService : BuildService<BuildServiceParameters.None>, AutoCloseable { abstract class BuildFinishedListenerService : BuildService<BuildServiceParameters.None>, AutoCloseable {
private val actionsOnClose = mutableListOf<() -> Unit>() private val actionsOnClose = mutableListOf<() -> Unit>()
private val keys = hashSetOf<String>()
fun onClose(action: () -> Unit) { fun onClose(action: () -> Unit) {
actionsOnClose.add(action) actionsOnClose.add(action)
} }
fun onCloseOnceByKey(key: String, action: () -> Unit) {
if (keys.add(key)) {
onClose(action)
}
}
override fun close() { override fun close() {
for (action in actionsOnClose) { for (action in actionsOnClose) {
action() action()
@@ -24,13 +42,19 @@ abstract class BuildFinishedListenerService : BuildService<BuildServiceParameter
} }
companion object { companion object {
fun getInstance(gradle: Gradle): BuildFinishedListenerService { fun registerIfAbsent(project: Project): Provider<BuildFinishedListenerService> = project.gradle.sharedServices
// Use class loader hashcode in case there are multiple class loaders in the same build .registerIfAbsent(
return gradle.sharedServices // Use class loader hashcode in case there are multiple class loaders in the same build
.registerIfAbsent( "build-finished-listener_${BuildFinishedListenerService::class.java.classLoader.hashCode()}",
"build-finished-listener_${BuildFinishedListenerService::class.java.classLoader.hashCode()}", BuildFinishedListenerService::class.java
BuildFinishedListenerService::class.java ) {}.also { serviceProvider ->
) {}.get() SingleActionPerProject.run(project, UsesBuildFinishedListenerService::class.java.name) {
} project.tasks.withType<UsesBuildFinishedListenerService>().configureEach { task ->
task.usesService(serviceProvider)
}
}
}
fun getInstance(project: Project): BuildFinishedListenerService = registerIfAbsent(project).get()
} }
} }
@@ -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_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_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_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.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinIrJsGeneratedTSValidationStrategy import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinIrJsGeneratedTSValidationStrategy
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrOutputGranularity 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 val keepIncrementalCompilationCachesInMemory: Boolean
get() = booleanProperty(KOTLIN_COMPILER_KEEP_INCREMENTAL_COMPILATION_CACHES_IN_MEMORY) ?: false 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] * Retrieves a comma-separated list of browsers to use when running karma tests for [target]
* @see KOTLIN_JS_KARMA_BROWSERS * @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_NATIVE_USE_XCODE_MESSAGE_STYLE = "kotlin.native.useXcodeMessageStyle"
const val KOTLIN_COMPILER_USE_PRECISE_COMPILATION_RESULTS_BACKUP = "kotlin.compiler.preciseCompilationResultsBackup" 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_COMPILER_KEEP_INCREMENTAL_COMPILATION_CACHES_IN_MEMORY = "kotlin.compiler.keepIncrementalCompilationCachesInMemory"
const val KOTLIN_SUPPRESS_EXPERIMENTAL_IC_OPTIMIZATIONS_WARNING = "kotlin.compiler.suppressExperimentalICOptimizationsWarning"
} }
companion object { companion object {
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.gradle.targets.js package org.jetbrains.kotlin.gradle.targets.js
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.invocation.Gradle
import org.jetbrains.kotlin.gradle.plugin.BuildFinishedListenerService import org.jetbrains.kotlin.gradle.plugin.BuildFinishedListenerService
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginInMultipleProjectsHolder import org.jetbrains.kotlin.gradle.plugin.KotlinPluginInMultipleProjectsHolder
import org.jetbrains.kotlin.gradle.plugin.MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING import org.jetbrains.kotlin.gradle.plugin.MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING
@@ -34,7 +33,7 @@ private constructor() {
@JvmStatic @JvmStatic
@Synchronized @Synchronized
private fun getInstance(gradle: Gradle): MultiplePluginDeclarationDetector { private fun getInstance(project: Project): MultiplePluginDeclarationDetector {
if (instance != null) { if (instance != null) {
return instance!! return instance!!
} }
@@ -42,13 +41,13 @@ private constructor() {
val detector = MultiplePluginDeclarationDetector() val detector = MultiplePluginDeclarationDetector()
instance = detector instance = detector
BuildFinishedListenerService.getInstance(gradle).onClose { instance = null } BuildFinishedListenerService.getInstance(project).onClose { instance = null }
return detector return detector
} }
fun detect(project: Project) { fun detect(project: Project) {
getInstance(project.gradle).detect(project) getInstance(project).detect(project)
} }
} }
} }
@@ -9,6 +9,7 @@ import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.FileSystemOperations
import org.gradle.api.logging.Logging
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider 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.internal.tasks.allOutputFiles
import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
import org.jetbrains.kotlin.gradle.logging.kotlinDebug 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.UsesVariantImplementationFactories
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.report.* import org.jetbrains.kotlin.gradle.report.*
@@ -63,6 +66,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
UsesIncrementalModuleInfoBuildService, UsesIncrementalModuleInfoBuildService,
UsesCompilerSystemPropertiesService, UsesCompilerSystemPropertiesService,
UsesVariantImplementationFactories, UsesVariantImplementationFactories,
UsesBuildFinishedListenerService,
BaseKotlinCompile { BaseKotlinCompile {
init { init {
@@ -194,12 +198,37 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
@get:Internal @get:Internal
internal abstract val keepIncrementalCompilationCachesInMemory: Property<Boolean> internal abstract val keepIncrementalCompilationCachesInMemory: Property<Boolean>
@get:Internal
internal abstract val suppressExperimentalIcOptimizationsWarning: Property<Boolean>
/** Task outputs that we don't want to include in [TaskOutputsBackup] (see [TaskOutputsBackup.outputsToRestore] for more info). */ /** Task outputs that we don't want to include in [TaskOutputsBackup] (see [TaskOutputsBackup.outputsToRestore] for more info). */
@get:Internal @get:Internal
internal abstract val taskOutputsBackupExcludes: SetProperty<File> internal abstract val taskOutputsBackupExcludes: SetProperty<File>
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 @TaskAction
fun execute(inputChanges: InputChanges) { fun execute(inputChanges: InputChanges) {
notifyUserAboutExperimentalICOptimizations()
val buildMetrics = metrics.get() val buildMetrics = metrics.get()
buildMetrics.addTimeMetric(BuildPerformanceMetric.START_TASK_ACTION_EXECUTION) buildMetrics.addTimeMetric(BuildPerformanceMetric.START_TASK_ACTION_EXECUTION)
buildMetrics.measure(BuildTime.OUT_OF_WORKER_TASK_ACTION) { buildMetrics.measure(BuildTime.OUT_OF_WORKER_TASK_ACTION) {
@@ -63,6 +63,7 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
IncrementalModuleInfoBuildService.registerIfAbsent(project, objectFactory.providerWithLazyConvention { IncrementalModuleInfoBuildService.registerIfAbsent(project, objectFactory.providerWithLazyConvention {
GradleCompilerRunner.buildModulesInfo(project.gradle) GradleCompilerRunner.buildModulesInfo(project.gradle)
}) })
val buildFinishedListenerService = BuildFinishedListenerService.registerIfAbsent(project)
configureTask { task -> configureTask { task ->
val propertiesProvider = project.kotlinPropertiesProvider val propertiesProvider = project.kotlinPropertiesProvider
@@ -106,6 +107,10 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
task.taskOutputsBackupExcludes.addAll(task.keepIncrementalCompilationCachesInMemory.map { task.taskOutputsBackupExcludes.addAll(task.keepIncrementalCompilationCachesInMemory.map {
if (it) listOf(task.taskBuildCacheableOutputDirectory.get().asFile) else emptyList() if (it) listOf(task.taskBuildCacheableOutputDirectory.get().asFile) else emptyList()
}) })
task.suppressExperimentalIcOptimizationsWarning
.convention(propertiesProvider.suppressExperimentalICOptimizationsWarning)
.finalizeValueOnRead()
task.buildFinishedListenerService.value(buildFinishedListenerService).disallowChanges()
task.incremental = false task.incremental = false
task.useModuleDetection.convention(false) task.useModuleDetection.convention(false)