Refactoring: pass MessageCollector, OutputItemsCollector in CompilerEnvironment

This commit is contained in:
Alexey Tsvetkov
2016-11-29 12:57:50 +03:00
parent 3f91df4c84
commit 9654607f42
9 changed files with 84 additions and 94 deletions
@@ -16,8 +16,13 @@
package org.jetbrains.kotlin.compilerRunner package org.jetbrains.kotlin.compilerRunner
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.utils.KotlinPaths import org.jetbrains.kotlin.utils.KotlinPaths
open class CompilerEnvironment(val services: Services) open class CompilerEnvironment(
val services: Services,
val messageCollector: MessageCollector,
open val outputItemsCollector: OutputItemsCollector
)
@@ -53,10 +53,10 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
class DaemonConnection(val daemon: CompileService?, val sessionId: Int = CompileService.NO_SESSION) class DaemonConnection(val daemon: CompileService?, val sessionId: Int = CompileService.NO_SESSION)
protected abstract fun getDaemonConnection(environment: Env, messageCollector: MessageCollector): DaemonConnection protected abstract fun getDaemonConnection(environment: Env): DaemonConnection
@Synchronized @Synchronized
protected fun newDaemonConnection(compilerPath: File, messageCollector: MessageCollector, flagFile: File): DaemonConnection { protected fun newDaemonConnection(compilerPath: File, flagFile: File, environment: Env): DaemonConnection {
val compilerId = CompilerId.makeCompilerId(compilerPath) val compilerId = CompilerId.makeCompilerId(compilerPath)
val daemonOptions = configureDaemonOptions() val daemonOptions = configureDaemonOptions()
val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true, inheritAdditionalProperties = true) val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true, inheritAdditionalProperties = true)
@@ -71,9 +71,9 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
} }
for (msg in daemonReportMessages) { for (msg in daemonReportMessages) {
messageCollector.report(CompilerMessageSeverity.INFO, environment.messageCollector.report(CompilerMessageSeverity.INFO,
(if (msg.category == DaemonReportCategory.EXCEPTION && connection.daemon == null) "Falling back to compilation without daemon due to error: " else "") + msg.message, (if (msg.category == DaemonReportCategory.EXCEPTION && connection.daemon == null) "Falling back to compilation without daemon due to error: " else "") + msg.message,
CompilerMessageLocation.NO_LOCATION) CompilerMessageLocation.NO_LOCATION)
} }
fun reportTotalAndThreadPerf(message: String, daemonOptions: DaemonOptions, messageCollector: MessageCollector, profiler: Profiler) { fun reportTotalAndThreadPerf(message: String, daemonOptions: DaemonOptions, messageCollector: MessageCollector, profiler: Profiler) {
@@ -86,21 +86,20 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
} }
} }
reportTotalAndThreadPerf("Daemon connect", daemonOptions, messageCollector, profiler) reportTotalAndThreadPerf("Daemon connect", daemonOptions, environment.messageCollector, profiler)
return connection return connection
} }
protected fun processCompilerOutput( protected fun processCompilerOutput(
messageCollector: MessageCollector, environment: Env,
collector: OutputItemsCollector,
stream: ByteArrayOutputStream, stream: ByteArrayOutputStream,
exitCode: ExitCode exitCode: ExitCode
) { ) {
val reader = BufferedReader(StringReader(stream.toString())) val reader = BufferedReader(StringReader(stream.toString()))
CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader, collector) CompilerOutputParser.parseCompilerMessagesFromReader(environment.messageCollector, reader, environment.outputItemsCollector)
if (ExitCode.INTERNAL_ERROR == exitCode) { if (ExitCode.INTERNAL_ERROR == exitCode) {
reportInternalCompilerError(messageCollector) reportInternalCompilerError(environment.messageCollector)
} }
} }
@@ -113,28 +112,24 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
compilerClassName: String, compilerClassName: String,
arguments: CommonCompilerArguments, arguments: CommonCompilerArguments,
additionalArguments: String, additionalArguments: String,
messageCollector: MessageCollector,
collector: OutputItemsCollector,
environment: Env): ExitCode { environment: Env): ExitCode {
return try { return try {
val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments) val argumentsList = ArgumentUtils.convertArgumentsToStringList(arguments)
argumentsList.addAll(additionalArguments.split(" ")) argumentsList.addAll(additionalArguments.split(" "))
val argsArray = argumentsList.toTypedArray() val argsArray = argumentsList.toTypedArray()
doRunCompiler(compilerClassName, argsArray, environment, messageCollector, collector) doRunCompiler(compilerClassName, argsArray, environment)
} }
catch (e: Throwable) { catch (e: Throwable) {
MessageCollectorUtil.reportException(messageCollector, e) MessageCollectorUtil.reportException(environment.messageCollector, e)
reportInternalCompilerError(messageCollector) reportInternalCompilerError(environment.messageCollector)
} }
} }
protected abstract fun doRunCompiler( protected abstract fun doRunCompiler(
compilerClassName: String, compilerClassName: String,
argsArray: Array<String>, argsArray: Array<String>,
environment: Env, environment: Env
messageCollector: MessageCollector,
collector: OutputItemsCollector
): ExitCode ): ExitCode
/** /**
@@ -144,12 +139,10 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
compilerClassName: String, compilerClassName: String,
argsArray: Array<String>, argsArray: Array<String>,
environment: Env, environment: Env,
messageCollector: MessageCollector,
collector: OutputItemsCollector,
retryOnConnectionError: Boolean = true retryOnConnectionError: Boolean = true
): ExitCode? { ): ExitCode? {
log.debug("Try to connect to daemon") log.debug("Try to connect to daemon")
val connection = getDaemonConnection(environment, messageCollector) val connection = getDaemonConnection(environment)
if (connection.daemon != null) { if (connection.daemon != null) {
log.info("Connected to daemon") log.info("Connected to daemon")
@@ -170,7 +163,7 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
fun retryOrFalse(e: Exception): ExitCode? { fun retryOrFalse(e: Exception): ExitCode? {
if (retryOnConnectionError) { if (retryOnConnectionError) {
log.debug("retrying once on daemon connection error: ${e.message}") log.debug("retrying once on daemon connection error: ${e.message}")
return compileWithDaemon(compilerClassName, argsArray, environment, messageCollector, collector, retryOnConnectionError = false) return compileWithDaemon(compilerClassName, argsArray, environment, retryOnConnectionError = false)
} }
log.info("daemon connection error: ${e.message}") log.info("daemon connection error: ${e.message}")
return null return null
@@ -187,9 +180,9 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
} }
val exitCode = exitCodeFromProcessExitCode(res) val exitCode = exitCodeFromProcessExitCode(res)
processCompilerOutput(messageCollector, collector, compilerOut, exitCode) processCompilerOutput(environment, compilerOut, exitCode)
BufferedReader(StringReader(daemonOut.toString())).forEachLine { BufferedReader(StringReader(daemonOut.toString())).forEachLine {
messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION) environment.messageCollector.report(CompilerMessageSeverity.INFO, it, CompilerMessageLocation.NO_LOCATION)
} }
return exitCode return exitCode
} }
@@ -74,10 +74,9 @@ public class CompilerRunnerUtil {
@NotNull String compilerClassName, @NotNull String compilerClassName,
@NotNull String[] arguments, @NotNull String[] arguments,
@NotNull JpsCompilerEnvironment environment, @NotNull JpsCompilerEnvironment environment,
@NotNull MessageCollector messageCollector,
@NotNull PrintStream out @NotNull PrintStream out
) throws Exception { ) throws Exception {
File libPath = getLibPath(environment.getKotlinPaths(), messageCollector); File libPath = getLibPath(environment.getKotlinPaths(), environment.getMessageCollector());
if (libPath == null) return null; if (libPath == null) return null;
ClassLoader classLoader = getOrCreateClassLoader(environment, libPath); ClassLoader classLoader = getOrCreateClassLoader(environment, libPath);
@@ -27,8 +27,10 @@ import org.jetbrains.kotlin.utils.PathUtil
class JpsCompilerEnvironment( class JpsCompilerEnvironment(
val kotlinPaths: KotlinPaths, val kotlinPaths: KotlinPaths,
services: Services, services: Services,
val classesToLoadByParent: ClassCondition val classesToLoadByParent: ClassCondition,
) : CompilerEnvironment(services) { messageCollector: MessageCollector,
override val outputItemsCollector: OutputItemsCollectorImpl
) : CompilerEnvironment(services, messageCollector, outputItemsCollector) {
fun success(): Boolean { fun success(): Boolean {
return kotlinPaths.homePath.exists() return kotlinPaths.homePath.exists()
} }
@@ -44,24 +44,20 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
commonArguments: CommonCompilerArguments, commonArguments: CommonCompilerArguments,
k2jvmArguments: K2JVMCompilerArguments, k2jvmArguments: K2JVMCompilerArguments,
compilerSettings: CompilerSettings, compilerSettings: CompilerSettings,
messageCollector: MessageCollector,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment,
moduleFile: File, moduleFile: File
collector: OutputItemsCollector
) { ) {
val arguments = mergeBeans(commonArguments, k2jvmArguments) val arguments = mergeBeans(commonArguments, k2jvmArguments)
setupK2JvmArguments(moduleFile, arguments) setupK2JvmArguments(moduleFile, arguments)
runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) runCompiler(K2JVM_COMPILER, arguments, compilerSettings.additionalArguments, environment)
} }
fun runK2JsCompiler( fun runK2JsCompiler(
commonArguments: CommonCompilerArguments, commonArguments: CommonCompilerArguments,
k2jsArguments: K2JSCompilerArguments, k2jsArguments: K2JSCompilerArguments,
compilerSettings: CompilerSettings, compilerSettings: CompilerSettings,
messageCollector: MessageCollector,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment,
collector: OutputItemsCollector,
sourceFiles: Collection<File>, sourceFiles: Collection<File>,
libraryFiles: List<String>, libraryFiles: List<String>,
outputFile: File outputFile: File
@@ -69,27 +65,25 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
val arguments = mergeBeans(commonArguments, k2jsArguments) val arguments = mergeBeans(commonArguments, k2jsArguments)
setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments) setupK2JsArguments(outputFile, sourceFiles, libraryFiles, arguments)
runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, messageCollector, collector, environment) runCompiler(K2JS_COMPILER, arguments, compilerSettings.additionalArguments, environment)
} }
override fun doRunCompiler(compilerClassName: String, argsArray: Array<String>, environment: JpsCompilerEnvironment, messageCollector: MessageCollector, collector: OutputItemsCollector): ExitCode { override fun doRunCompiler(compilerClassName: String, argsArray: Array<String>, environment: JpsCompilerEnvironment): ExitCode {
messageCollector.report(CompilerMessageSeverity.INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION) environment.messageCollector.report(CompilerMessageSeverity.INFO, "Using kotlin-home = " + environment.kotlinPaths.homePath, CompilerMessageLocation.NO_LOCATION)
return if (isDaemonEnabled()) { return if (isDaemonEnabled()) {
val daemonExitCode = compileWithDaemon(compilerClassName, argsArray, environment, messageCollector, collector) val daemonExitCode = compileWithDaemon(compilerClassName, argsArray, environment)
daemonExitCode ?: fallbackCompileStrategy(argsArray, collector, compilerClassName, environment, messageCollector) daemonExitCode ?: fallbackCompileStrategy(argsArray, compilerClassName, environment)
} }
else { else {
fallbackCompileStrategy(argsArray, collector, compilerClassName, environment, messageCollector) fallbackCompileStrategy(argsArray, compilerClassName, environment)
} }
} }
private fun fallbackCompileStrategy( private fun fallbackCompileStrategy(
argsArray: Array<String>, argsArray: Array<String>,
collector: OutputItemsCollector,
compilerClassName: String, compilerClassName: String,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment
messageCollector: MessageCollector
): ExitCode { ): ExitCode {
// otherwise fallback to in-process // otherwise fallback to in-process
log.info("Compile in-process") log.info("Compile in-process")
@@ -103,12 +97,12 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
if (System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "false").toBoolean()) if (System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "false").toBoolean())
System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true") System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, out)
// exec() returns an ExitCode object, class of which is loaded with a different class loader, // exec() returns an ExitCode object, class of which is loaded with a different class loader,
// so we take it's contents through reflection // so we take it's contents through reflection
val exitCode = ExitCode.valueOf(getReturnCodeFromObject(rc)) val exitCode = ExitCode.valueOf(getReturnCodeFromObject(rc))
processCompilerOutput(messageCollector, collector, stream, exitCode) processCompilerOutput(environment, stream, exitCode)
return exitCode return exitCode
} }
@@ -140,14 +134,14 @@ class JpsKotlinCompilerRunner : KotlinCompilerRunner<JpsCompilerEnvironment>() {
} }
@Synchronized @Synchronized
override fun getDaemonConnection(environment: JpsCompilerEnvironment, messageCollector: MessageCollector): DaemonConnection { override fun getDaemonConnection(environment: JpsCompilerEnvironment): DaemonConnection {
if (jpsDaemonConnection == null) { if (jpsDaemonConnection == null) {
val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, messageCollector) val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, environment.messageCollector)
val compilerPath = File(libPath, "kotlin-compiler.jar") val compilerPath = File(libPath, "kotlin-compiler.jar")
val flagFile = File.createTempFile("kotlin-compiler-jps-session-", "-is-running").apply { val flagFile = File.createTempFile("kotlin-compiler-jps-session-", "-is-running").apply {
deleteOnExit() deleteOnExit()
} }
newDaemonConnection(compilerPath, messageCollector, flagFile) newDaemonConnection(compilerPath, flagFile, environment)
} }
return jpsDaemonConnection!! return jpsDaemonConnection!!
} }
@@ -205,7 +205,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val project = projectDescriptor.project val project = projectDescriptor.project
val lookupTracker = getLookupTracker(project) val lookupTracker = getLookupTracker(project)
val incrementalCaches = getIncrementalCaches(chunk, context) val incrementalCaches = getIncrementalCaches(chunk, context)
val environment = createCompileEnvironment(incrementalCaches, lookupTracker, context) val environment = createCompileEnvironment(incrementalCaches, lookupTracker, context, messageCollector)
if (!environment.success()) { if (!environment.success()) {
environment.reportErrorsTo(messageCollector) environment.reportErrorsTo(messageCollector)
return ABORT return ABORT
@@ -238,7 +238,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
LOG.info("Compiled successfully") LOG.info("Compiled successfully")
} }
val generatedFiles = getGeneratedFiles(chunk, outputItemCollector) val generatedFiles = getGeneratedFiles(chunk, environment.outputItemsCollector)
registerOutputItems(outputConsumer, generatedFiles) registerOutputItems(outputConsumer, generatedFiles)
saveVersions(context, chunk) saveVersions(context, chunk)
@@ -368,11 +368,11 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, environment: JpsCompilerEnvironment, dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>, incrementalCaches: Map<ModuleBuildTarget, IncrementalCacheImpl<*>>, filesToCompile: MultiMap<ModuleBuildTarget, File>, incrementalCaches: Map<ModuleBuildTarget, IncrementalCacheImpl<*>>,
messageCollector: MessageCollectorAdapter, project: JpsProject messageCollector: MessageCollectorAdapter, project: JpsProject
): OutputItemsCollectorImpl? { ): OutputItemsCollector? {
if (JpsUtils.isJsKotlinModule(chunk.representativeTarget())) { if (JpsUtils.isJsKotlinModule(chunk.representativeTarget())) {
LOG.debug("Compiling to JS ${filesToCompile.values().size} files in ${filesToCompile.keySet().joinToString { it.presentableName }}") LOG.debug("Compiling to JS ${filesToCompile.values().size} files in ${filesToCompile.keySet().joinToString { it.presentableName }}")
return compileToJs(chunk, commonArguments, environment, messageCollector, project) return compileToJs(chunk, commonArguments, environment, project)
} }
if (IncrementalCompilation.isEnabled()) { if (IncrementalCompilation.isEnabled()) {
@@ -402,13 +402,14 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
) )
} }
return compileToJvm(allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder, environment, filesToCompile, messageCollector) return compileToJvm(allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder, environment, filesToCompile)
} }
private fun createCompileEnvironment( private fun createCompileEnvironment(
incrementalCaches: Map<ModuleBuildTarget, IncrementalCache>, incrementalCaches: Map<ModuleBuildTarget, IncrementalCache>,
lookupTracker: LookupTracker, lookupTracker: LookupTracker,
context: CompileContext context: CompileContext,
messageCollector: MessageCollectorAdapter
): JpsCompilerEnvironment { ): JpsCompilerEnvironment {
val compilerServices = with(Services.Builder()) { val compilerServices = with(Services.Builder()) {
register(IncrementalCompilationComponents::class.java, register(IncrementalCompilationComponents::class.java,
@@ -433,7 +434,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|| className == "org.jetbrains.kotlin.progress.CompilationCanceledStatus" || className == "org.jetbrains.kotlin.progress.CompilationCanceledStatus"
|| className == "org.jetbrains.kotlin.progress.CompilationCanceledException" || className == "org.jetbrains.kotlin.progress.CompilationCanceledException"
|| className == "org.jetbrains.kotlin.modules.TargetId" || className == "org.jetbrains.kotlin.modules.TargetId"
} },
messageCollector,
OutputItemsCollectorImpl()
) )
} }
@@ -585,16 +588,13 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
private fun compileToJs(chunk: ModuleChunk, private fun compileToJs(chunk: ModuleChunk,
commonArguments: CommonCompilerArguments, commonArguments: CommonCompilerArguments,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment,
messageCollector: MessageCollectorAdapter,
project: JpsProject project: JpsProject
): OutputItemsCollectorImpl? { ): OutputItemsCollector? {
val outputItemCollector = OutputItemsCollectorImpl()
val representativeTarget = chunk.representativeTarget() val representativeTarget = chunk.representativeTarget()
if (chunk.modules.size > 1) { if (chunk.modules.size > 1) {
// We do not support circular dependencies, but if they are present, we do our best should not break the build, // We do not support circular dependencies, but if they are present, we do our best should not break the build,
// so we simply yield a warning and report NOTHING_DONE // so we simply yield a warning and report NOTHING_DONE
messageCollector.report( environment.messageCollector.report(
WARNING, WARNING,
"Circular dependencies are not supported. The following JS modules depend on each other: " "Circular dependencies are not supported. The following JS modules depend on each other: "
+ chunk.modules.map { it.name }.joinToString(", ") + ". " + chunk.modules.map { it.name }.joinToString(", ") + ". "
@@ -619,8 +619,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val k2JsArguments = JpsKotlinCompilerSettings.getK2JsCompilerArguments(representativeModule) val k2JsArguments = JpsKotlinCompilerSettings.getK2JsCompilerArguments(representativeModule)
val compilerRunner = JpsKotlinCompilerRunner() val compilerRunner = JpsKotlinCompilerRunner()
compilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, messageCollector, environment, outputItemCollector, sourceFiles, libraryFiles, outputFile) compilerRunner.runK2JsCompiler(commonArguments, k2JsArguments, compilerSettings, environment, sourceFiles, libraryFiles, outputFile)
return outputItemCollector return environment.outputItemsCollector
} }
private fun copyJsLibraryFilesIfNeeded(chunk: ModuleChunk, project: JpsProject) { private fun copyJsLibraryFilesIfNeeded(chunk: ModuleChunk, project: JpsProject) {
@@ -642,12 +642,10 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
context: CompileContext, context: CompileContext,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>, dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
environment: JpsCompilerEnvironment, environment: JpsCompilerEnvironment,
filesToCompile: MultiMap<ModuleBuildTarget, File>, messageCollector: MessageCollectorAdapter filesToCompile: MultiMap<ModuleBuildTarget, File>
): OutputItemsCollectorImpl? { ): OutputItemsCollector? {
val outputItemCollector = OutputItemsCollectorImpl()
if (chunk.modules.size > 1) { if (chunk.modules.size > 1) {
messageCollector.report( environment.messageCollector.report(
WARNING, WARNING,
"Circular dependencies are only partially supported. The following modules depend on each other: " "Circular dependencies are only partially supported. The following modules depend on each other: "
+ chunk.modules.map { it.name }.joinToString(", ") + ". " + chunk.modules.map { it.name }.joinToString(", ") + ". "
@@ -686,10 +684,10 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
+ " in " + filesToCompile.keySet().joinToString { it.presentableName }) + " in " + filesToCompile.keySet().joinToString { it.presentableName })
val compilerRunner = JpsKotlinCompilerRunner() val compilerRunner = JpsKotlinCompilerRunner()
compilerRunner.runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, messageCollector, environment, moduleFile, outputItemCollector) compilerRunner.runK2JvmCompiler(commonArguments, k2JvmArguments, compilerSettings, environment, moduleFile)
moduleFile.delete() moduleFile.delete()
return outputItemCollector return environment.outputItemsCollector
} }
class MessageCollectorAdapter(private val context: CompileContext) : MessageCollector { class MessageCollectorAdapter(private val context: CompileContext) : MessageCollector {
@@ -1,12 +1,15 @@
package org.jetbrains.kotlin.compilerRunner package org.jetbrains.kotlin.compilerRunner
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.config.Services
import java.io.File import java.io.File
import java.net.URL import java.net.URL
internal class GradleCompilerEnvironment( internal class GradleCompilerEnvironment(
val compilerJar: File val compilerJar: File,
) : CompilerEnvironment(Services.EMPTY) { messageCollector: MessageCollector,
outputItemsCollector: OutputItemsCollector
) : CompilerEnvironment(Services.EMPTY, messageCollector, outputItemsCollector) {
val compilerClasspath: List<File> val compilerClasspath: List<File>
get() = listOf(compilerJar).filterNotNull() get() = listOf(compilerJar).filterNotNull()
@@ -55,13 +55,11 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
sourcesToCompile: List<File>, sourcesToCompile: List<File>,
javaSourceRoots: Iterable<File>, javaSourceRoots: Iterable<File>,
args: K2JVMCompilerArguments, args: K2JVMCompilerArguments,
messageCollector: MessageCollector, environment: GradleCompilerEnvironment
outputItemsCollector: OutputItemsCollector,
kotlinCompilerJar: File
): ExitCode { ): ExitCode {
val outputDir = args.destinationAsFile val outputDir = args.destinationAsFile
log.debug("Removing all kotlin classes in $outputDir") log.debug("Removing all kotlin classes in $outputDir")
log.info("Using kotlin compiler jar: $kotlinCompilerJar") log.info("Using kotlin compiler jar: ${environment.compilerJar}")
// we're free to delete all classes since only we know about that directory // we're free to delete all classes since only we know about that directory
outputDir.deleteRecursively() outputDir.deleteRecursively()
@@ -79,7 +77,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val additionalArguments = "" val additionalArguments = ""
try { try {
return runCompiler(K2JVM_COMPILER, args, additionalArguments, messageCollector, outputItemsCollector, GradleCompilerEnvironment(kotlinCompilerJar)) return runCompiler(K2JVM_COMPILER, args, additionalArguments, environment)
} }
finally { finally {
moduleFile.delete() moduleFile.delete()
@@ -89,15 +87,13 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
fun runJsCompiler( fun runJsCompiler(
kotlinSources: List<File>, kotlinSources: List<File>,
args: K2JSCompilerArguments, args: K2JSCompilerArguments,
messageCollector: MessageCollector, environment: GradleCompilerEnvironment
outputItemsCollector: OutputItemsCollector,
kotlinCompilerJar: File
): ExitCode { ): ExitCode {
val additionalArguments = kotlinSources.joinToString(separator = " ") { it.absolutePath } val additionalArguments = kotlinSources.joinToString(separator = " ") { it.absolutePath }
return runCompiler(K2JS_COMPILER, args, additionalArguments, messageCollector, outputItemsCollector, GradleCompilerEnvironment(kotlinCompilerJar)) return runCompiler(K2JS_COMPILER, args, additionalArguments, environment)
} }
override fun doRunCompiler(compilerClassName: String, argsArray: Array<String>, environment: GradleCompilerEnvironment, messageCollector: MessageCollector, collector: OutputItemsCollector): ExitCode { override fun doRunCompiler(compilerClassName: String, argsArray: Array<String>, environment: GradleCompilerEnvironment): ExitCode {
with (project.logger) { with (project.logger) {
kotlinDebug { "Kotlin compiler class: $compilerClassName" } kotlinDebug { "Kotlin compiler class: $compilerClassName" }
kotlinDebug { "Kotlin compiler jar: ${environment.compilerJar}" } kotlinDebug { "Kotlin compiler jar: ${environment.compilerJar}" }
@@ -106,7 +102,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val executionStrategy = System.getProperty(KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY) ?: DAEMON_EXECUTION_STRATEGY val executionStrategy = System.getProperty(KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY) ?: DAEMON_EXECUTION_STRATEGY
if (executionStrategy == DAEMON_EXECUTION_STRATEGY) { if (executionStrategy == DAEMON_EXECUTION_STRATEGY) {
val daemonExitCode = compileWithDaemon(compilerClassName, argsArray, environment, messageCollector, collector) val daemonExitCode = compileWithDaemon(compilerClassName, argsArray, environment)
if (daemonExitCode != null) { if (daemonExitCode != null) {
return daemonExitCode return daemonExitCode
@@ -118,15 +114,15 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val isGradleDaemonUsed = System.getProperty("org.gradle.daemon")?.let(String::toBoolean) val isGradleDaemonUsed = System.getProperty("org.gradle.daemon")?.let(String::toBoolean)
return if (executionStrategy == IN_PROCESS_EXECUTION_STRATEGY || isGradleDaemonUsed == false) { return if (executionStrategy == IN_PROCESS_EXECUTION_STRATEGY || isGradleDaemonUsed == false) {
compileInProcess(argsArray, collector, compilerClassName, environment, messageCollector) compileInProcess(argsArray, compilerClassName, environment)
} }
else { else {
compileOutOfProcess(argsArray, compilerClassName, environment) compileOutOfProcess(argsArray, compilerClassName, environment)
} }
} }
override fun compileWithDaemon(compilerClassName: String, argsArray: Array<String>, environment: GradleCompilerEnvironment, messageCollector: MessageCollector, collector: OutputItemsCollector, retryOnConnectionError: Boolean): ExitCode? { override fun compileWithDaemon(compilerClassName: String, argsArray: Array<String>, environment: GradleCompilerEnvironment, retryOnConnectionError: Boolean): ExitCode? {
val exitCode = super.compileWithDaemon(compilerClassName, argsArray, environment, messageCollector, collector, retryOnConnectionError) val exitCode = super.compileWithDaemon(compilerClassName, argsArray, environment, retryOnConnectionError)
exitCode?.let { exitCode?.let {
logFinish(DAEMON_EXECUTION_STRATEGY) logFinish(DAEMON_EXECUTION_STRATEGY)
} }
@@ -162,10 +158,8 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
private fun compileInProcess( private fun compileInProcess(
argsArray: Array<String>, argsArray: Array<String>,
collector: OutputItemsCollector,
compilerClassName: String, compilerClassName: String,
environment: GradleCompilerEnvironment, environment: GradleCompilerEnvironment
messageCollector: MessageCollector
): ExitCode { ): ExitCode {
val stream = ByteArrayOutputStream() val stream = ByteArrayOutputStream()
val out = PrintStream(stream) val out = PrintStream(stream)
@@ -184,7 +178,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val res = exec.invoke(compiler.newInstance(), out, emptyServices, argsArray) val res = exec.invoke(compiler.newInstance(), out, emptyServices, argsArray)
val exitCode = ExitCode.valueOf(res.toString()) val exitCode = ExitCode.valueOf(res.toString())
processCompilerOutput(messageCollector, collector, stream, exitCode) processCompilerOutput(environment, stream, exitCode)
logFinish(IN_PROCESS_EXECUTION_STRATEGY) logFinish(IN_PROCESS_EXECUTION_STRATEGY)
return exitCode return exitCode
} }
@@ -194,8 +188,8 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
@Synchronized @Synchronized
override fun getDaemonConnection(environment: GradleCompilerEnvironment, messageCollector: MessageCollector): DaemonConnection { override fun getDaemonConnection(environment: GradleCompilerEnvironment): DaemonConnection {
return newDaemonConnection(environment.compilerJar, messageCollector, flagFile) return newDaemonConnection(environment.compilerJar, flagFile, environment)
} }
} }
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.js.K2JSCompiler import org.jetbrains.kotlin.cli.js.K2JSCompiler
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.dsl.*
@@ -209,8 +210,8 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
if (!incremental) { if (!incremental) {
anyClassesCompiled = true anyClassesCompiled = true
val compilerRunner = GradleCompilerRunner(project) val compilerRunner = GradleCompilerRunner(project)
val exitCode = compilerRunner.runJvmCompiler(sourceRoots.kotlinSourceFiles, sourceRoots.javaSourceRoots, args, messageCollector, val environment = GradleCompilerEnvironment(compilerJar, messageCollector, outputItemCollector)
outputItemCollector, compilerJar) val exitCode = compilerRunner.runJvmCompiler(sourceRoots.kotlinSourceFiles, sourceRoots.javaSourceRoots, args, environment)
processCompilerExitCode(exitCode) processCompilerExitCode(exitCode)
return return
} }
@@ -376,7 +377,8 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
val outputItemCollector = OutputItemsCollectorImpl() val outputItemCollector = OutputItemsCollectorImpl()
val compilerRunner = GradleCompilerRunner(project) val compilerRunner = GradleCompilerRunner(project)
val exitCode = compilerRunner.runJsCompiler(sourceRoots.kotlinSourceFiles, args, messageCollector, outputItemCollector, compilerJar) val environment = GradleCompilerEnvironment(compilerJar, messageCollector, outputItemCollector)
val exitCode = compilerRunner.runJsCompiler(sourceRoots.kotlinSourceFiles, args, environment)
when (exitCode) { when (exitCode) {
ExitCode.OK -> { ExitCode.OK -> {