[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
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<BuildFinishedListenerService>
}
abstract class BuildFinishedListenerService : BuildService<BuildServiceParameters.None>, AutoCloseable {
private val actionsOnClose = mutableListOf<() -> Unit>()
private val keys = hashSetOf<String>()
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<BuildServiceParameter
}
companion object {
fun getInstance(gradle: Gradle): BuildFinishedListenerService {
// Use class loader hashcode in case there are multiple class loaders in the same build
return gradle.sharedServices
.registerIfAbsent(
"build-finished-listener_${BuildFinishedListenerService::class.java.classLoader.hashCode()}",
BuildFinishedListenerService::class.java
) {}.get()
}
fun registerIfAbsent(project: Project): Provider<BuildFinishedListenerService> = 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<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_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 {
@@ -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)
}
}
}
@@ -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<T : CommonCompilerArguments> @Inject constr
UsesIncrementalModuleInfoBuildService,
UsesCompilerSystemPropertiesService,
UsesVariantImplementationFactories,
UsesBuildFinishedListenerService,
BaseKotlinCompile {
init {
@@ -194,12 +198,37 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
@get:Internal
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). */
@get:Internal
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
fun execute(inputChanges: InputChanges) {
notifyUserAboutExperimentalICOptimizations()
val buildMetrics = metrics.get()
buildMetrics.addTimeMetric(BuildPerformanceMetric.START_TASK_ACTION_EXECUTION)
buildMetrics.measure(BuildTime.OUT_OF_WORKER_TASK_ACTION) {
@@ -63,6 +63,7 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
IncrementalModuleInfoBuildService.registerIfAbsent(project, objectFactory.providerWithLazyConvention {
GradleCompilerRunner.buildModulesInfo(project.gradle)
})
val buildFinishedListenerService = BuildFinishedListenerService.registerIfAbsent(project)
configureTask { task ->
val propertiesProvider = project.kotlinPropertiesProvider
@@ -106,6 +107,10 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
task.taskOutputsBackupExcludes.addAll(task.keepIncrementalCompilationCachesInMemory.map {
if (it) listOf(task.taskBuildCacheableOutputDirectory.get().asFile) else emptyList()
})
task.suppressExperimentalIcOptimizationsWarning
.convention(propertiesProvider.suppressExperimentalICOptimizationsWarning)
.finalizeValueOnRead()
task.buildFinishedListenerService.value(buildFinishedListenerService).disallowChanges()
task.incremental = false
task.useModuleDetection.convention(false)