Pass arguments to GradleKotlinCompilerWork in GradleKotlinCompilerWorkArguments

It's less error prone to add/remove/reorder arguments this way,
because named arguments can be used and the compiler actually
checks that all arguments are passed to GradleKotlinCompilerWorkArguments's
constructor.
This commit is contained in:
Alexey Tsvetkov
2018-11-01 19:29:05 +03:00
parent 349386960e
commit ff81a46233
4 changed files with 57 additions and 65 deletions
@@ -9,33 +9,16 @@ import org.gradle.api.Project
import org.gradle.workers.ForkMode
import org.gradle.workers.IsolationMode
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.gradle.utils.SerializableOptional
internal class GradleCompilerRunnerWithWorkers(
project: Project,
private val workersExecutor: WorkerExecutor
) : GradleCompilerRunner(project) {
override fun compileWithDaemonOrFallback(
compilerClassName: String,
compilerArgs: CommonCompilerArguments,
environment: GradleCompilerEnvironment
) {
val icEnv = environment.incrementalCompilationEnvironment
val modulesInfo = icEnv?.let { buildModulesInfo(project.gradle) }
workersExecutor.submit(KotlinCompilerRunnable::class.java) { config ->
override fun compileWithDaemonOrFallback(workArgs: GradleKotlinCompilerWorkArguments) {
workersExecutor.submit(GradleKotlinCompilerWork::class.java) { config ->
config.isolationMode = IsolationMode.NONE
config.forkMode = ForkMode.NEVER
config.params(
ProjectFilesForCompilation(project),
environment.compilerFullClasspath,
compilerClassName,
ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray(),
compilerArgs.verbose,
SerializableOptional(icEnv),
SerializableOptional(modulesInfo)
)
config.params(workArgs)
}
}
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.daemon.client.CompileServiceSession
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.utils.SerializableOptional
import org.jetbrains.kotlin.gradle.utils.newTmpFile
import org.jetbrains.kotlin.gradle.utils.relativeToRoot
import org.jetbrains.kotlin.incremental.*
@@ -117,23 +116,23 @@ internal open class GradleCompilerRunner(protected val project: Project) {
)
compilerArgs.version = false
}
compileWithDaemonOrFallback(compilerClassName, compilerArgs, environment)
}
protected open fun compileWithDaemonOrFallback(
compilerClassName: String,
compilerArgs: CommonCompilerArguments,
environment: GradleCompilerEnvironment
) {
val kotlinCompilerRunnable = KotlinCompilerRunnable(
val argsArray = ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray()
val incrementalCompilationEnvironment = environment.incrementalCompilationEnvironment
val modulesInfo = incrementalCompilationEnvironment?.let { buildModulesInfo(project.gradle) }
val workArgs = GradleKotlinCompilerWorkArguments(
projectFiles = ProjectFilesForCompilation(project),
compilerFullClasspath = environment.compilerFullClasspath,
compilerClassName = compilerClassName,
compilerArgs = ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray(),
compilerArgs = argsArray,
isVerbose = compilerArgs.verbose,
incrementalCompilationEnvironment = SerializableOptional(environment.incrementalCompilationEnvironment),
incrementalModuleInfo = SerializableOptional(buildModulesInfo(project.gradle))
incrementalCompilationEnvironment = incrementalCompilationEnvironment,
incrementalModuleInfo = modulesInfo
)
compileWithDaemonOrFallback(workArgs)
}
protected open fun compileWithDaemonOrFallback(workArgs: GradleKotlinCompilerWorkArguments) {
val kotlinCompilerRunnable = GradleKotlinCompilerWork(workArgs)
kotlinCompilerRunnable.run()
}
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
import org.jetbrains.kotlin.gradle.utils.SerializableOptional
import org.jetbrains.kotlin.incremental.ChangedFiles
import org.slf4j.LoggerFactory
import java.io.ByteArrayOutputStream
@@ -43,21 +42,46 @@ internal class ProjectFilesForCompilation(
}
}
internal class KotlinCompilerRunnable @Inject constructor(
private val projectFiles: ProjectFilesForCompilation,
private val compilerFullClasspath: List<File>,
private val compilerClassName: String,
private val compilerArgs: Array<String>,
private val isVerbose: Boolean,
private val incrementalCompilationEnvironment: SerializableOptional<IncrementalCompilationEnvironment>,
private val incrementalModuleInfo: SerializableOptional<IncrementalModuleInfo>
internal class GradleKotlinCompilerWorkArguments(
val projectFiles: ProjectFilesForCompilation,
val compilerFullClasspath: List<File>,
val compilerClassName: String,
val compilerArgs: Array<String>,
val isVerbose: Boolean,
val incrementalCompilationEnvironment: IncrementalCompilationEnvironment?,
val incrementalModuleInfo: IncrementalModuleInfo?
) : Serializable {
companion object {
const val serialVersionUID: Long = 0
}
}
internal class GradleKotlinCompilerWork @Inject constructor(
/**
* Arguments are passed through [GradleKotlinCompilerWorkArguments],
* because Gradle Workers API does not support nullable arguments (https://github.com/gradle/gradle/issues/2405),
* and because Workers API does not support named arguments,
* which are useful when there are many arguments with the same type
* (to protect against parameters reordering bugs)
*/
config: GradleKotlinCompilerWorkArguments
) : Runnable {
private val projectRootFile = config.projectFiles.projectRootFile
private val clientIsAliveFlagFile = config.projectFiles.clientIsAliveFlagFile
private val sessionFlagFile = config.projectFiles.sessionFlagFile
private val compilerFullClasspath = config.compilerFullClasspath
private val compilerClassName = config.compilerClassName
private val compilerArgs = config.compilerArgs
private val isVerbose = config.isVerbose
private val incrementalCompilationEnvironment = config.incrementalCompilationEnvironment
private val incrementalModuleInfo = config.incrementalModuleInfo
private val log: KotlinLogger =
SL4JKotlinLogger(LoggerFactory.getLogger("KotlinCompilerRunnable"))
SL4JKotlinLogger(LoggerFactory.getLogger("GradleKotlinCompilerWork"))
private val messageCollector = GradleMessageCollector(log)
private val isIncremental: Boolean
get() = incrementalCompilationEnvironment.value != null
get() = incrementalCompilationEnvironment != null
override fun run() {
val exitCode = compileWithDaemonOrFallbackImpl()
@@ -66,8 +90,8 @@ internal class KotlinCompilerRunnable @Inject constructor(
private fun compileWithDaemonOrFallbackImpl(): ExitCode {
with(log) {
kotlinDebug { "Kotlin compiler class: $compilerClassName" }
kotlinDebug { "Kotlin compiler classpath: ${compilerFullClasspath.map { it.canonicalPath }.joinToString()}" }
kotlinDebug { "Kotlin compiler class: ${compilerClassName}" }
kotlinDebug { "Kotlin compiler classpath: ${compilerFullClasspath.joinToString { it.canonicalPath }}" }
kotlinDebug { "Kotlin compiler args: ${compilerArgs.joinToString(" ")}" }
}
@@ -94,8 +118,8 @@ internal class KotlinCompilerRunnable @Inject constructor(
val connection =
try {
GradleCompilerRunner.getDaemonConnectionImpl(
projectFiles.clientIsAliveFlagFile,
projectFiles.sessionFlagFile,
clientIsAliveFlagFile,
sessionFlagFile,
compilerFullClasspath,
messageCollector,
log.isDebugEnabled
@@ -166,7 +190,7 @@ internal class KotlinCompilerRunnable @Inject constructor(
sessionId: Int,
targetPlatform: CompileService.TargetPlatform
): CompileService.CallResult<Int> {
val icEnv = incrementalCompilationEnvironment.value ?: error("incrementalCompilationEnvironment is null!")
val icEnv = incrementalCompilationEnvironment ?: error("incrementalCompilationEnvironment is null!")
val knownChangedFiles = icEnv.changedFiles as? ChangedFiles.Known
val compilationOptions = IncrementalCompilationOptions(
@@ -182,12 +206,12 @@ internal class KotlinCompilerRunnable @Inject constructor(
usePreciseJavaTracking = icEnv.usePreciseJavaTracking,
localStateDirs = icEnv.localStateDirs,
multiModuleICSettings = icEnv.multiModuleICSettings,
modulesInfo = incrementalModuleInfo.value!!
modulesInfo = incrementalModuleInfo!!
)
log.info("Options for KOTLIN DAEMON: $compilationOptions")
val servicesFacade = GradleIncrementalCompilerServicesFacadeImpl(log, messageCollector)
val compilationResults = GradleCompilationResults(log, projectFiles.projectRootFile)
val compilationResults = GradleCompilationResults(log, projectRootFile)
return daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults)
}
@@ -1,14 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.gradle.utils
import java.io.Serializable
internal class SerializableOptional<T>(val value: T?) : Serializable {
companion object {
const val serialVersionUID: Long = 0
}
}