diff --git a/build-common/src/org/jetbrains/kotlin/build/report/ICReporter.kt b/build-common/src/org/jetbrains/kotlin/build/report/ICReporter.kt index 0d2a51dce84..9ae63f4b476 100644 --- a/build-common/src/org/jetbrains/kotlin/build/report/ICReporter.kt +++ b/build-common/src/org/jetbrains/kotlin/build/report/ICReporter.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.build.report import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector import java.io.File +import kotlin.reflect.KFunction1 interface ICReporter { @@ -24,6 +27,7 @@ interface ICReporter { fun reportMarkDirty(affectedFiles: Iterable, reason: String) } +//TODO check and remove? fun ICReporter.warn(message: () -> String) = report(message, severity = ICReporter.ReportSeverity.WARNING) fun ICReporter.info(message: () -> String) = report(message, severity = ICReporter.ReportSeverity.INFO) fun ICReporter.debug(message: () -> String) = report(message, severity = ICReporter.ReportSeverity.DEBUG) @@ -35,3 +39,4 @@ object DoNothingICReporter : ICReporter { override fun reportMarkDirtyMember(affectedFiles: Iterable, scope: String, name: String) {} override fun reportMarkDirty(affectedFiles: Iterable, reason: String) {} } + diff --git a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildAttribute.kt b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildAttribute.kt index 3fb89625df7..5190bbead38 100644 --- a/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildAttribute.kt +++ b/build-common/src/org/jetbrains/kotlin/build/report/metrics/BuildAttribute.kt @@ -18,6 +18,8 @@ enum class BuildAttributeKind : Serializable { enum class BuildAttribute(val kind: BuildAttributeKind, val readableString: String) : Serializable { NO_BUILD_HISTORY(BuildAttributeKind.REBUILD_REASON, "Build history file not found"), NO_ABI_SNAPSHOT(BuildAttributeKind.REBUILD_REASON, "ABI snapshot not found"), + NO_LAST_BUILD_INFO(BuildAttributeKind.REBUILD_REASON, "Last build info not found"), + INVALID_LAST_BUILD_INFO(BuildAttributeKind.REBUILD_REASON, "Last build info corrupted"), CLASSPATH_SNAPSHOT_NOT_FOUND(BuildAttributeKind.REBUILD_REASON, "Classpath snapshot not found"), IC_FAILED_TO_GET_CHANGED_FILES(BuildAttributeKind.REBUILD_REASON, "Failed to get changed files"), IC_FAILED_TO_COMPUTE_FILES_TO_RECOMPILE(BuildAttributeKind.REBUILD_REASON, "Failed to compute files to recompile"), diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/BuildInfo.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/BuildInfo.kt index 24b6cf13862..16aab4f9d5c 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/BuildInfo.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/BuildInfo.kt @@ -16,8 +16,10 @@ package org.jetbrains.kotlin.incremental +import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.incremental.AbiSnapshotImpl.Companion.readAbiSnapshot import org.jetbrains.kotlin.incremental.AbiSnapshotImpl.Companion.writeAbiSnapshot +import org.jetbrains.kotlin.incremental.util.reportException import java.io.* data class BuildInfo(val startTS: Long, val dependencyToAbiSnapshot: Map = mapOf()) : Serializable { @@ -43,10 +45,16 @@ data class BuildInfo(val startTS: Long, val dependencyToAbiSnapshot: Map { + messageCollector.reportException(result.cause) reporter.warn { // The indentation after the first line is intentional (so that this message is distinct from next message) """ diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt index 6baca2c20db..cbba33ef3c7 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt @@ -126,7 +126,7 @@ class IncrementalJsCompilerRunner( if (!withAbiSnapshot && !buildHistoryFile.isFile) { return CompilationMode.Rebuild(BuildAttribute.NO_BUILD_HISTORY) } - val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) + val lastBuildInfo = BuildInfo.read(lastBuildInfoFile, messageCollector) ?: return CompilationMode.Rebuild(BuildAttribute.INVALID_LAST_BUILD_INFO) val dirtyFiles = DirtyFilesContainer(caches, reporter, kotlinSourceFilesExtensions) initDirtyFiles(dirtyFiles, changedFiles) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index 484f888f6e0..2f27915a9c4 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -195,7 +195,7 @@ open class IncrementalJvmCompilerRunner( classpathAbiSnapshots: Map ): CompilationMode { return try { - calculateSourcesToCompileImpl(caches, changedFiles, args, classpathAbiSnapshots, withAbiSnapshot) + calculateSourcesToCompileImpl(caches, changedFiles, args, messageCollector, classpathAbiSnapshots, withAbiSnapshot) } finally { psiFileProvider.messageCollector.flush(messageCollector) psiFileProvider.messageCollector.clear() @@ -238,6 +238,7 @@ open class IncrementalJvmCompilerRunner( caches: IncrementalJvmCachesManager, changedFiles: ChangedFiles.Known, args: K2JVMCompilerArguments, + messageCollector: MessageCollector, abiSnapshots: Map, withAbiSnapshot: Boolean ): CompilationMode { @@ -273,7 +274,10 @@ open class IncrementalJvmCompilerRunner( // workingDir as workingDir is an @OutputDirectory, so the files must be present in an incremental build.) return CompilationMode.Rebuild(BuildAttribute.NO_BUILD_HISTORY) } - val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) + if (!lastBuildInfoFile.exists()) { + return CompilationMode.Rebuild(BuildAttribute.NO_LAST_BUILD_INFO) + } + val lastBuildInfo = BuildInfo.read(lastBuildInfoFile, messageCollector) ?: return CompilationMode.Rebuild(BuildAttribute.INVALID_LAST_BUILD_INFO) reporter.debug { "Last Kotlin Build info -- $lastBuildInfo" } val scopes = caches.lookupCache.lookupSymbols.map { it.scope.ifBlank { it.name } }.distinct() diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/util/messageCollectorUtil.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/util/messageCollectorUtil.kt new file mode 100644 index 00000000000..7de9f1f5e93 --- /dev/null +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/util/messageCollectorUtil.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2010-2022 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.incremental.util + +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector + + +internal fun MessageCollector.reportException(e: Throwable) { + report(severity = CompilerMessageSeverity.EXCEPTION, message = "Incremental compilation failed:${e.message}\n${e.stackTraceToString()}") +} + diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt index 77b8e29a73a..ad2b903e99a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt @@ -12,6 +12,10 @@ import org.jetbrains.kotlin.gradle.report.BuildReportType import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.DisplayName import java.io.ObjectInputStream +import kotlin.io.path.exists +import kotlin.io.path.listDirectoryEntries +import kotlin.io.path.name +import kotlin.io.path.notExists import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertTrue @@ -140,4 +144,22 @@ class BuildReportsIT : KGPBaseTest() { } } } + + @DisplayName("Error file is created") + @GradleTest + fun testErrorsFileSmokeTest(gradleVersion: GradleVersion) { + project("simpleProject", gradleVersion) { + build("compileKotlin") { + assertTrue { projectPath.resolve(".gradle/build_errors").listDirectoryEntries().isEmpty() } + } + val kotlinFile = kotlinSourcesDir().resolve("helloWorld.kt") + kotlinFile.modify { it.replace("ArrayList","skjfghsjk") } + buildAndFail("compileKotlin") { + val buildErrorDir = projectPath.resolve(".gradle/build_errors").toFile() + val files = buildErrorDir.listFiles() + assertTrue { files?.first()?.exists() ?: false } + } + } + } + } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt index 5f6be178f96..5c8c1834a31 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt @@ -6,13 +6,13 @@ package org.jetbrains.kotlin.compilerRunner import org.jetbrains.kotlin.config.Services -import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector +import org.jetbrains.kotlin.gradle.logging.GradleErrorMessageCollector import org.jetbrains.kotlin.gradle.report.ReportingSettings import java.io.File internal class GradleCompilerEnvironment( val compilerClasspath: Iterable, - messageCollector: GradlePrintingMessageCollector, + messageCollector: GradleErrorMessageCollector, outputItemsCollector: OutputItemsCollector, val outputFiles: List, val reportingSettings: ReportingSettings, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index 3b801e0c44a..aa67ffc682b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.daemon.common.filterExtractProps import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull +import org.jetbrains.kotlin.gradle.logging.GradleErrorMessageCollector import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinInfo import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation @@ -67,6 +68,7 @@ internal open class GradleCompilerRunner( internal val sessionDirProvider = taskProvider.sessionsDir.get() internal val projectNameProvider = taskProvider.projectName.get() internal val incrementalModuleInfoProvider = taskProvider.buildModulesInfo + internal val errorsFile = taskProvider.errorsFile.get() /** * Compiler might be executed asynchronously. Do not do anything requiring end of compilation after this function is called. @@ -203,6 +205,7 @@ internal open class GradleCompilerRunner( kotlinScriptExtensions = environment.kotlinScriptExtensions, allWarningsAsErrors = compilerArgs.allWarningsAsErrors, compilerExecutionSettings = compilerExecutionSettings, + errorsFile = errorsFile ) TaskLoggers.put(pathProvider, loggerProvider) return runCompilerAsync( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt index 34559cbde3f..da0b99da273 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt @@ -65,6 +65,7 @@ internal class GradleKotlinCompilerWorkArguments( val kotlinScriptExtensions: Array, val allWarningsAsErrors: Boolean, val compilerExecutionSettings: CompilerExecutionSettings, + val errorsFile: File?, ) : Serializable { companion object { const val serialVersionUID: Long = 1 @@ -100,6 +101,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( private val metrics = if (reportingSettings.buildReportOutputs.isNotEmpty()) BuildMetricsReporterImpl() else DoNothingBuildMetricsReporter private var icLogLines: List = emptyList() private val compilerExecutionSettings = config.compilerExecutionSettings + private val errorsFile = config.errorsFile private val log: KotlinLogger = TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } } @@ -119,11 +121,13 @@ internal class GradleKotlinCompilerWork @Inject constructor( override fun run() { try { - val messageCollector = GradlePrintingMessageCollector(log, allWarningsAsErrors) - val (exitCode, executionStrategy) = compileWithDaemonOrFallbackImpl(messageCollector) + val gradlePrintingMessageCollector = GradlePrintingMessageCollector(log, allWarningsAsErrors) + val gradleMessageCollector = GradleErrorMessageCollector(gradlePrintingMessageCollector) + val (exitCode, executionStrategy) = compileWithDaemonOrFallbackImpl(gradleMessageCollector) if (incrementalCompilationEnvironment?.disableMultiModuleIC == true) { incrementalCompilationEnvironment.multiModuleICSettings.buildHistoryFile.delete() } + errorsFile?.also { gradleMessageCollector.flush(it) } throwExceptionIfCompilationFailed(exitCode, executionStrategy) } finally { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/GradleErrorMessageCollector.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/GradleErrorMessageCollector.kt new file mode 100644 index 00000000000..2b19455ba8c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/GradleErrorMessageCollector.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2010-2022 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.gradle.logging + +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import java.io.File +import java.io.FileWriter + +class GradleErrorMessageCollector(private val delegate: MessageCollector? = null) : MessageCollector { + private val errors = ArrayList() + + override fun clear() { + delegate?.clear() + errors.clear() + } + + fun report(error: Throwable, location: CompilerMessageSourceLocation?) { + report(CompilerMessageSeverity.EXCEPTION, "${error.message}\n${error.stackTraceToString()}", location) + } + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) { + delegate?.report(severity, message, location) + + if (severity in listOf(CompilerMessageSeverity.ERROR, CompilerMessageSeverity.EXCEPTION)) { + synchronized(errors) { + errors.add(message) + } + } + } + + override fun hasErrors(): Boolean { + return errors.isNotEmpty() + } + + fun flush(file: File) { + if (!hasErrors()) { + return + } + file.createNewFile() + println("Errors were stored into ${file.absolutePath}") + FileWriter(file).use { + for (error in errors) { + it.append("error message: $error\n\n") + } + it.flush() + } + clear() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt index 9a0dd1b6642..ca6bf218acd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles +import org.jetbrains.kotlin.gradle.logging.GradleErrorMessageCollector import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector import org.jetbrains.kotlin.gradle.tasks.internal.KotlinMultiplatformCommonOptionsCompat import java.io.File @@ -109,11 +110,12 @@ abstract class KotlinCompileCommon @Inject constructor( inputChanges: InputChanges, taskOutputsBackup: TaskOutputsBackup? ) { - val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors) + val gradlePrintingMessageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors) + val gradleMessageCollector = GradleErrorMessageCollector(gradlePrintingMessageCollector) val outputItemCollector = OutputItemsCollectorImpl() val compilerRunner = compilerRunner.get() val environment = GradleCompilerEnvironment( - defaultCompilerClasspath, messageCollector, outputItemCollector, + defaultCompilerClasspath, gradleMessageCollector, outputItemCollector, reportingSettings = reportingSettings(), outputFiles = allOutputFiles() ) @@ -123,5 +125,6 @@ abstract class KotlinCompileCommon @Inject constructor( args, environment ) + compilerRunner.errorsFile?.also { gradleMessageCollector.flush(it) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 5c438b8b6cf..1ced9802c61 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.gradle.incremental.* import org.jetbrains.kotlin.gradle.internal.* import org.jetbrains.kotlin.gradle.internal.tasks.TaskWithLocalState import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles +import org.jetbrains.kotlin.gradle.logging.GradleErrorMessageCollector import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector import org.jetbrains.kotlin.gradle.logging.kotlinDebug @@ -232,6 +233,12 @@ abstract class GradleCompileTaskProvider @Inject constructor( } } ) + + @get:Internal + val errorsFile: Provider = objectFactory + .property( + gradle.rootProject.rootDir.resolve(".gradle/build_errors/").also { it.mkdirs() } + .resolve("errors-${System.currentTimeMillis()}.log")) } abstract class AbstractKotlinCompile @Inject constructor( @@ -723,7 +730,8 @@ abstract class KotlinCompile @Inject constructor( validateKotlinAndJavaHasSameTargetCompatibility(args, kotlinSources) val scriptSources = scriptSources.asFileTree.files - val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors) + val gradlePrintingMessageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors,) + val gradleMessageCollector = GradleErrorMessageCollector(gradlePrintingMessageCollector) val outputItemCollector = OutputItemsCollectorImpl() val compilerRunner = compilerRunner.get() @@ -742,7 +750,7 @@ abstract class KotlinCompile @Inject constructor( @Suppress("ConvertArgumentToSet", "DEPRECATION") val environment = GradleCompilerEnvironment( - defaultCompilerClasspath, messageCollector, outputItemCollector, + defaultCompilerClasspath, gradleMessageCollector, outputItemCollector, // In the incremental compiler, outputFiles will be cleaned on rebuild. However, because classpathSnapshotDir is not included in // TaskOutputsBackup, we don't want classpathSnapshotDir to be cleaned immediately on rebuild, and therefore we exclude it from // outputFiles here. (See TaskOutputsBackup's kdoc for more info.) @@ -765,6 +773,7 @@ abstract class KotlinCompile @Inject constructor( defaultKotlinJavaToolchain.get().providedJvm.get().javaHome, taskOutputsBackup ) + compilerRunner.errorsFile?.also { gradleMessageCollector.flush(it) } } private fun validateKotlinAndJavaHasSameTargetCompatibility( @@ -1152,7 +1161,8 @@ abstract class Kotlin2JsCompile @Inject constructor( logger.kotlinDebug("compiling with args ${ArgumentUtils.convertArgumentsToStringList(args)}") - val messageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors) + val gradlePrintingMessageCollector = GradlePrintingMessageCollector(logger, args.allWarningsAsErrors) + val gradleMessageCollector = GradleErrorMessageCollector(gradlePrintingMessageCollector) val outputItemCollector = OutputItemsCollectorImpl() val compilerRunner = compilerRunner.get() @@ -1167,7 +1177,7 @@ abstract class Kotlin2JsCompile @Inject constructor( } else null val environment = GradleCompilerEnvironment( - defaultCompilerClasspath, messageCollector, outputItemCollector, + defaultCompilerClasspath, gradleMessageCollector, outputItemCollector, outputFiles = allOutputFiles(), reportingSettings = reportingSettings(), incrementalCompilationEnvironment = icEnv @@ -1180,6 +1190,8 @@ abstract class Kotlin2JsCompile @Inject constructor( environment, taskOutputsBackup ) + compilerRunner.errorsFile?.also { gradleMessageCollector.flush(it) } + } private val projectRootDir = project.rootDir