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? protected val jdkToolsJar: File?
) { ) {
internal val pathProvider = taskProvider.path internal val pathProvider = taskProvider.path.get()
internal val loggerProvider = taskProvider.logger internal val loggerProvider = taskProvider.logger.get()
internal val buildDirProvider = taskProvider.buildDir internal val buildDirProvider = taskProvider.buildDir.get().asFile
internal val projectDirProvider = taskProvider.projectDir internal val projectDirProvider = taskProvider.projectDir.get()
internal val projectRootDirProvider = taskProvider.rootDir internal val projectRootDirProvider = taskProvider.rootDir.get()
internal val sessionDirProvider = taskProvider.sessionsDir internal val sessionDirProvider = taskProvider.sessionsDir.get()
internal val projectNameProvider = taskProvider.projectName internal val projectNameProvider = taskProvider.projectName.get()
internal val incrementalModuleInfoProvider = taskProvider.buildModulesInfo internal val incrementalModuleInfoProvider = taskProvider.buildModulesInfo
/** /**
@@ -336,8 +336,8 @@ internal open class GradleCompilerRunner(
return sessionFlagFile!! return sessionFlagFile!!
} }
internal fun sessionsDir(project: Project): File = internal fun sessionsDir(rootProjectBuildDir: File): File =
File(File(project.rootProject.buildDir, "kotlin"), "sessions") 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.file.ConfigurableFileCollection
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.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments 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.logging.GradlePrintingMessageCollector
import org.jetbrains.kotlin.gradle.report.ReportingSettings import org.jetbrains.kotlin.gradle.report.ReportingSettings
import org.jetbrains.kotlin.gradle.tasks.* 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 org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
import java.io.File import java.io.File
import javax.inject.Inject import javax.inject.Inject
@@ -49,7 +52,9 @@ abstract class KaptWithKotlincTask @Inject constructor(
abstract val pluginClasspath: ConfigurableFileCollection abstract val pluginClasspath: ConfigurableFileCollection
@get:Internal @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() override fun createCompilerArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
@@ -111,7 +116,7 @@ abstract class KaptWithKotlincTask @Inject constructor(
) )
val compilerRunner = GradleCompilerRunner( val compilerRunner = GradleCompilerRunner(
taskProvider, taskProvider.get(),
kotlinJavaToolchainProvider.get().currentJvmJdkToolsJar.orNull kotlinJavaToolchainProvider.get().currentJvmJdkToolsJar.orNull
) )
compilerRunner.runJvmCompilerAsync( compilerRunner.runJvmCompilerAsync(
@@ -35,7 +35,7 @@ class KotlinGradleFinishBuildHandler {
GradleCompilerRunner.clearBuildModulesInfo() GradleCompilerRunner.clearBuildModulesInfo()
val rootProject = gradle.rootProject val rootProject = gradle.rootProject
val sessionsDir = GradleCompilerRunner.sessionsDir(rootProject) val sessionsDir = GradleCompilerRunner.sessionsDir(rootProject.buildDir)
if (sessionsDir.exists()) { if (sessionsDir.exists()) {
val sessionFiles = sessionsDir.listFiles() val sessionFiles = sessionsDir.listFiles()
@@ -7,10 +7,8 @@ package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.*
import org.gradle.api.file.DirectoryProperty import org.gradle.api.invocation.Gradle
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty 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 @get:Internal
val logger: Logger = task.logger val path: Provider<String> = objectFactory.property(task.path)
val buildDir: File = task.project.buildDir
val projectDir: File = task.project.rootProject.projectDir @get:Internal
val rootDir: File = task.project.rootProject.rootDir val logger: Provider<Logger> = objectFactory.property(task.logger)
val sessionsDir: File = GradleCompilerRunner.sessionsDir(task.project)
val projectName: String = task.project.rootProject.name.normalizeForFlagFile() @get:Internal
val buildModulesInfo: Provider<out IncrementalModuleInfoProvider> = run { val buildDir: DirectoryProperty = projectLayout.buildDirectory
val modulesInfo = GradleCompilerRunner.buildModulesInfo(task.project.gradle)
@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 * 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 * 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. * underlying mechanism does not support multi-threaded access, we need to add external synchronization.
*/ */
synchronized(task.project.gradle.sharedServices) { synchronized(gradle.sharedServices) {
task.project.gradle.sharedServices.registerIfAbsent( gradle.sharedServices.registerIfAbsent(
IncrementalModuleInfoBuildService.getServiceName(), IncrementalModuleInfoBuildService::class.java 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>() { abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotlinCompileTool<T>() {
@@ -258,7 +284,9 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
@get:Internal @get:Internal
protected val gradleCompileTaskProvider: Provider<GradleCompileTaskProvider> = objects protected val gradleCompileTaskProvider: Provider<GradleCompileTaskProvider> = objects
.providerWithLazyConvention { GradleCompileTaskProvider(this) } .property(
objects.newInstance<GradleCompileTaskProvider>(project.gradle, this, project)
)
@get:Internal @get:Internal
internal open val compilerRunner: Provider<GradleCompilerRunner> = internal open val compilerRunner: Provider<GradleCompilerRunner> =