Make GradleCompileTaskProvider compatible with configuration cache.

Refactor it such way that it could be used via Provider and
don't raise configuration cache errors.

^KT-45611 In Progress
^KT-43095 In Progress
This commit is contained in:
Yahor Berdnikau
2021-06-15 17:17:47 +02:00
committed by Space
parent 84ec4106f7
commit 0f1da3c412
4 changed files with 64 additions and 31 deletions
@@ -59,13 +59,13 @@ internal open class GradleCompilerRunner(
protected val jdkToolsJar: File?
) {
internal val pathProvider = taskProvider.path
internal val loggerProvider = taskProvider.logger
internal val buildDirProvider = taskProvider.buildDir
internal val projectDirProvider = taskProvider.projectDir
internal val projectRootDirProvider = taskProvider.rootDir
internal val sessionDirProvider = taskProvider.sessionsDir
internal val projectNameProvider = taskProvider.projectName
internal val pathProvider = taskProvider.path.get()
internal val loggerProvider = taskProvider.logger.get()
internal val buildDirProvider = taskProvider.buildDir.get().asFile
internal val projectDirProvider = taskProvider.projectDir.get()
internal val projectRootDirProvider = taskProvider.rootDir.get()
internal val sessionDirProvider = taskProvider.sessionsDir.get()
internal val projectNameProvider = taskProvider.projectName.get()
internal val incrementalModuleInfoProvider = taskProvider.buildModulesInfo
/**
@@ -336,8 +336,8 @@ internal open class GradleCompilerRunner(
return sessionFlagFile!!
}
internal fun sessionsDir(project: Project): File =
File(File(project.rootProject.buildDir, "kotlin"), "sessions")
internal fun sessionsDir(rootProjectBuildDir: File): File =
File(File(rootProjectBuildDir, "kotlin"), "sessions")
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
@@ -20,6 +21,8 @@ import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
import org.jetbrains.kotlin.gradle.report.ReportingSettings
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.utils.newInstance
import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
import java.io.File
import javax.inject.Inject
@@ -49,7 +52,9 @@ abstract class KaptWithKotlincTask @Inject constructor(
abstract val pluginClasspath: ConfigurableFileCollection
@get:Internal
val taskProvider by lazy { GradleCompileTaskProvider(this) }
val taskProvider: Provider<GradleCompileTaskProvider> = objectFactory.property(
objectFactory.newInstance<GradleCompileTaskProvider>(project.gradle, this, project)
)
override fun createCompilerArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
@@ -111,7 +116,7 @@ abstract class KaptWithKotlincTask @Inject constructor(
)
val compilerRunner = GradleCompilerRunner(
taskProvider,
taskProvider.get(),
kotlinJavaToolchainProvider.get().currentJvmJdkToolsJar.orNull
)
compilerRunner.runJvmCompilerAsync(
@@ -35,7 +35,7 @@ class KotlinGradleFinishBuildHandler {
GradleCompilerRunner.clearBuildModulesInfo()
val rootProject = gradle.rootProject
val sessionsDir = GradleCompilerRunner.sessionsDir(rootProject)
val sessionsDir = GradleCompilerRunner.sessionsDir(rootProject.buildDir)
if (sessionsDir.exists()) {
val sessionFiles = sessionsDir.listFiles()
@@ -7,10 +7,8 @@ package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.file.*
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
@@ -112,30 +110,58 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments>
}
}
class GradleCompileTaskProvider(task: Task) {
abstract class GradleCompileTaskProvider @Inject constructor(
objectFactory: ObjectFactory,
projectLayout: ProjectLayout,
gradle: Gradle,
task: Task,
project: Project
) {
val path: String = task.path
val logger: Logger = task.logger
val buildDir: File = task.project.buildDir
val projectDir: File = task.project.rootProject.projectDir
val rootDir: File = task.project.rootProject.rootDir
val sessionsDir: File = GradleCompilerRunner.sessionsDir(task.project)
val projectName: String = task.project.rootProject.name.normalizeForFlagFile()
val buildModulesInfo: Provider<out IncrementalModuleInfoProvider> = run {
val modulesInfo = GradleCompilerRunner.buildModulesInfo(task.project.gradle)
@get:Internal
val path: Provider<String> = objectFactory.property(task.path)
@get:Internal
val logger: Provider<Logger> = objectFactory.property(task.logger)
@get:Internal
val buildDir: DirectoryProperty = projectLayout.buildDirectory
@get:Internal
val projectDir: Provider<File> = objectFactory
.property(project.rootProject.projectDir)
@get:Internal
val rootDir: Provider<File> = objectFactory
.property(project.rootProject.rootDir)
@get:Internal
val sessionsDir: Provider<File> = objectFactory
.property(GradleCompilerRunner.sessionsDir(project.rootProject.buildDir))
@get:Internal
val projectName: Provider<String> = objectFactory
.property(project.rootProject.name.normalizeForFlagFile())
@get:Internal
val buildModulesInfo: Provider<out IncrementalModuleInfoProvider> = objectFactory.property(
/**
* See https://youtrack.jetbrains.com/issue/KT-46820. Build service that holds the incremental info may
* be instantiated during execution phase and there could be multiple threads trying to do that. Because the
* underlying mechanism does not support multi-threaded access, we need to add external synchronization.
*/
synchronized(task.project.gradle.sharedServices) {
task.project.gradle.sharedServices.registerIfAbsent(
synchronized(gradle.sharedServices) {
gradle.sharedServices.registerIfAbsent(
IncrementalModuleInfoBuildService.getServiceName(), IncrementalModuleInfoBuildService::class.java
) {
it.parameters.info.set(modulesInfo)
it.parameters.info.set(
objectFactory.providerWithLazyConvention {
GradleCompilerRunner.buildModulesInfo(gradle)
}
)
}
}
}
)
}
abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotlinCompileTool<T>() {
@@ -258,7 +284,9 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
@get:Internal
protected val gradleCompileTaskProvider: Provider<GradleCompileTaskProvider> = objects
.providerWithLazyConvention { GradleCompileTaskProvider(this) }
.property(
objects.newInstance<GradleCompileTaskProvider>(project.gradle, this, project)
)
@get:Internal
internal open val compilerRunner: Provider<GradleCompilerRunner> =