diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt index 4739a731335..309a41e0e0d 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt @@ -40,25 +40,19 @@ enum class CompilerSystemProperties(val property: String) { ; var value - get() = systemPropertyGetter(property) + get() = (systemPropertyGetter ?: System::getProperty)(property) set(value) { - systemPropertySetter(property, value!!) + (systemPropertySetter ?: System::setProperty)(property, value!!) } - fun clear(): String? = systemPropertyCleaner(property) + fun clear(): String? = (systemPropertyCleaner ?: System::clearProperty)(property) companion object { - var systemPropertyGetter: (String) -> String? = { - System.getProperty(it) - } + var systemPropertyGetter: ((String) -> String?)? = null - var systemPropertySetter: (String, String) -> String? = { key, value -> - System.setProperty(key, value) - } + var systemPropertySetter: ((String, String) -> String?)? = null - var systemPropertyCleaner: (String) -> String? = { key -> - System.clearProperty(key) - } + var systemPropertyCleaner: ((String) -> String?)? = null } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/CompilerSystemPropertiesService.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/CompilerSystemPropertiesService.kt new file mode 100644 index 00000000000..fec32ca1687 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/CompilerSystemPropertiesService.kt @@ -0,0 +1,70 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.compilerRunner + +import org.gradle.api.Project +import org.gradle.api.invocation.Gradle +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Provider +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters +import org.jetbrains.kotlin.cli.common.CompilerSystemProperties +import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable + +internal abstract class CompilerSystemPropertiesService : BuildService, AutoCloseable { + internal interface Parameters : BuildServiceParameters { + val properties: MapProperty> + } + + private val properties by lazy { parameters.properties.get().mapValues { it.value.orNull }.toMutableMap() } + + fun startIntercept() { + if (!parameters.properties.isPresent) return + + CompilerSystemProperties.systemPropertyGetter = { + if (it in properties) properties[it] else System.getProperty(it) + } + CompilerSystemProperties.systemPropertySetter = setter@{ key, value -> + val oldValue = properties[key] + if (oldValue == value) return@setter oldValue + properties[key] = value + System.setProperty(key, value) + oldValue + } + CompilerSystemProperties.systemPropertyCleaner = { + val oldValue = properties[it] + properties.remove(it) + System.clearProperty(it) + oldValue + } + } + + override fun close() { + CompilerSystemProperties.systemPropertyGetter = null + CompilerSystemProperties.systemPropertySetter = null + CompilerSystemProperties.systemPropertyCleaner = null + } + + companion object { + private val Project.isBuildSrc get() = name == ":buildSrc" + + fun registerIfAbsent(gradle: Gradle): Provider = + gradle.sharedServices.registerIfAbsent( + "${CompilerSystemPropertiesService::class.java.canonicalName}_${CompilerSystemPropertiesService::class.java.classLoader.hashCode()}", + CompilerSystemPropertiesService::class.java + ) { service -> + val rootProject = gradle.rootProject + if (rootProject.isBuildSrc && isConfigurationCacheAvailable(gradle)) { + service.parameters.properties.set( + CompilerSystemProperties.values() + .associate { + it.property to rootProject.providers.systemProperty(it.property).forUseAtConfigurationTime() + }.toMap() + ) + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 3f99347986e..0a96eba13e8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -50,7 +50,6 @@ import org.jetbrains.kotlin.incremental.ChangedFiles import org.jetbrains.kotlin.library.impl.isKotlinLibrary import org.jetbrains.kotlin.utils.JsLibraryUtils import java.io.File -import java.util.zip.ZipFile import javax.inject.Inject const val KOTLIN_BUILD_DIR_NAME = "kotlin" @@ -335,24 +334,11 @@ abstract class AbstractKotlinCompile() : AbstractKo internal open fun compilerRunner(): GradleCompilerRunner = GradleCompilerRunner(GradleCompileTaskProvider(this)) + private val systemPropertiesService = CompilerSystemPropertiesService.registerIfAbsent(project.gradle) + @TaskAction fun execute(inputs: IncrementalTaskInputs) { - CompilerSystemProperties.systemPropertyGetter = { - if (it in kotlinDaemonProperties) kotlinDaemonProperties[it] else System.getProperty(it) - } - CompilerSystemProperties.systemPropertySetter = setter@{ key, value -> - val oldValue = kotlinDaemonProperties[key] - if (oldValue == value) return@setter oldValue - kotlinDaemonProperties[key] = value - System.setProperty(key, value) - oldValue - } - CompilerSystemProperties.systemPropertyCleaner = { - val oldValue = kotlinDaemonProperties[it] - kotlinDaemonProperties.remove(it) - System.clearProperty(it) - oldValue - } + systemPropertiesService.get().startIntercept() CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true" // If task throws exception, but its outputs are changed during execution, @@ -446,15 +432,6 @@ abstract class AbstractKotlinCompile() : AbstractKo val taskBuildDir = taskBuildDirectory return taskBuildDir.walk().any { it != taskBuildDir && it.isFile } } - - @get:Internal - val kotlinDaemonProperties: MutableMap by lazy { - if (isGradleVersionAtLeast(6, 5)) { - CompilerSystemProperties.values() - .associate { it.property to project.providers.systemProperty(it.property).forUseAtConfigurationTime().orNull } - .toMutableMap() - } else mutableMapOf() - } } open class KotlinCompileArgumentsProvider>(taskProvider: T) {