diff --git a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/BuildToolsApiBuildICReporter.kt b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/BuildToolsApiBuildICReporter.kt new file mode 100644 index 00000000000..8c7dd977237 --- /dev/null +++ b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/BuildToolsApiBuildICReporter.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2023 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.buildtools.internal + +import org.jetbrains.kotlin.build.report.ICReporter +import org.jetbrains.kotlin.build.report.ICReporterBase +import org.jetbrains.kotlin.buildtools.api.KotlinLogger +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.daemon.common.CompileIterationResult +import java.io.File + +internal class BuildToolsApiBuildICReporter( + private val kotlinLogger: KotlinLogger, + private val rootProjectDir: File?, +) : ICReporterBase() { + override fun report(message: () -> String, severity: ICReporter.ReportSeverity) { + when (severity) { + ICReporter.ReportSeverity.DEBUG -> if (kotlinLogger.isDebugEnabled) { + kotlinLogger.debug(message()) + } + ICReporter.ReportSeverity.INFO -> kotlinLogger.info(message()) + ICReporter.ReportSeverity.WARNING -> kotlinLogger.warn(message()) + } + } + + override fun reportCompileIteration(incremental: Boolean, sourceFiles: Collection, exitCode: ExitCode) { + kotlinLogger.debug(CompileIterationResult(sourceFiles, exitCode.toString()), rootProjectDir) + } +} \ No newline at end of file diff --git a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt index f1c4baac626..d539ff51fec 100644 --- a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt +++ b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.buildtools.internal import com.intellij.openapi.vfs.impl.ZipHandler import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS -import org.jetbrains.kotlin.build.report.DoNothingBuildReporter +import org.jetbrains.kotlin.build.report.BuildReporter import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter import org.jetbrains.kotlin.buildtools.api.* import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity @@ -139,9 +139,13 @@ internal object CompilationServiceImpl : CompilationService { @Suppress("UNCHECKED_CAST") val classpathChanges = (aggregatedIcConfiguration as AggregatedIcConfiguration).classpathChanges + val buildReporter = BuildReporter( + icReporter = BuildToolsApiBuildICReporter(loggerAdapter.kotlinLogger, options.rootProjectDir), + buildMetricsReporter = DoNothingBuildMetricsReporter + ) val incrementalCompiler = IncrementalJvmCompilerRunner( aggregatedIcConfiguration.workingDir, - DoNothingBuildReporter, + buildReporter, buildHistoryFile = null, modulesApiHistory = EmptyModulesApiHistory, usePreciseJavaTracking = options.preciseJavaTrackingEnabled, @@ -208,7 +212,10 @@ internal object CompilationServiceImpl : CompilationService { arguments.toTypedArray() + sources.map { it.absolutePath }, // TODO: pass the sources explicitly KT-62759 daemonCompileOptions, BasicCompilerServicesWithResultsFacadeServer(loggerAdapter), - DaemonCompilationResults() + DaemonCompilationResults( + loggerAdapter.kotlinLogger, + compilationConfiguration.aggregatedIcConfiguration?.options?.rootProjectDir + ) ).get() return (ExitCode.entries.find { it.code == exitCode } ?: if (exitCode == 0) { diff --git a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/KotlinLoggerMessageCollectorAdapter.kt b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/KotlinLoggerMessageCollectorAdapter.kt index d7ac135874e..eb88d1f3464 100644 --- a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/KotlinLoggerMessageCollectorAdapter.kt +++ b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/KotlinLoggerMessageCollectorAdapter.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageRenderer -internal class KotlinLoggerMessageCollectorAdapter(private val kotlinLogger: KotlinLogger) : MessageCollector { +internal class KotlinLoggerMessageCollectorAdapter(internal val kotlinLogger: KotlinLogger) : MessageCollector { private val messageRenderer = MessageRenderer.GRADLE_STYLE override fun clear() {} diff --git a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt index 230f8c4784a..a58a288dfa7 100644 --- a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt +++ b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt @@ -6,12 +6,12 @@ package org.jetbrains.kotlin.buildtools.internal import org.jetbrains.kotlin.build.report.metrics.BuildMetrics +import org.jetbrains.kotlin.buildtools.api.KotlinLogger import org.jetbrains.kotlin.buildtools.api.SourcesChanges import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalCompilationApproachParameters import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration import org.jetbrains.kotlin.daemon.common.* -import org.jetbrains.kotlin.incremental.ClasspathChanges -import org.jetbrains.kotlin.incremental.ClasspathSnapshotFiles +import java.io.File import java.io.Serializable import java.rmi.server.UnicastRemoteObject @@ -19,12 +19,18 @@ internal val JvmCompilationConfigurationImpl.asDaemonCompilationOptions: Compila get() { val ktsExtensionsAsArray = if (kotlinScriptFilenameExtensions.isEmpty()) null else kotlinScriptFilenameExtensions.toTypedArray() val reportCategories = arrayOf(ReportCategory.COMPILER_MESSAGE.code, ReportCategory.IC_MESSAGE.code) // TODO: automagically compute the value, related to BasicCompilerServicesWithResultsFacadeServer - val reportSeverity = ReportSeverity.INFO.code // TODO: automagically compute the value, related to BasicCompilerServicesWithResultsFacadeServer - val requestedCompilationResults = emptyArray() // TODO: automagically compute the value, related to DaemonCompilationResults + val reportSeverity = if (logger.isDebugEnabled) { + ReportSeverity.DEBUG.code + } else { + ReportSeverity.INFO.code + } val aggregatedIcConfiguration = aggregatedIcConfiguration return when (val options = aggregatedIcConfiguration?.options) { is ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration -> { val sourcesChanges = aggregatedIcConfiguration.sourcesChanges + val requestedCompilationResults = arrayOf( + CompilationResultCategory.IC_COMPILE_ITERATION.code, + ) @Suppress("UNCHECKED_CAST") val classpathChanges = @@ -57,13 +63,13 @@ internal val JvmCompilationConfigurationImpl.asDaemonCompilationOptions: Compila targetPlatform = CompileService.TargetPlatform.JVM, reportCategories = reportCategories, reportSeverity = reportSeverity, - requestedCompilationResults = requestedCompilationResults, + requestedCompilationResults = emptyArray(), kotlinScriptExtensions = ktsExtensionsAsArray, ) } } -internal class DaemonCompilationResults : CompilationResults, +internal class DaemonCompilationResults(private val kotlinLogger: KotlinLogger, private val rootProjectDir: File?) : CompilationResults, UnicastRemoteObject( SOCKET_ANY_FREE_PORT, LoopbackNetworkInterface.clientLoopbackSocketFactory, @@ -78,7 +84,10 @@ internal class DaemonCompilationResults : CompilationResults, **/ override fun add(compilationResultCategory: Int, value: Serializable) { // TODO propagate the values to the caller via callbacks, requires to make metrics a part of the API - println("Result category=$compilationResultCategory value=$value") + when (compilationResultCategory) { + CompilationResultCategory.IC_COMPILE_ITERATION.code -> kotlinLogger.debug(value as? CompileIterationResult, rootProjectDir) + else -> kotlinLogger.debug("Result category=$compilationResultCategory value=$value") + } } } @@ -86,4 +95,20 @@ internal val clientIsAliveFile by lazy { makeAutodeletingFlagFile() } +internal fun KotlinLogger.debug(compileIterationResult: CompileIterationResult?, rootProjectDir: File?) { + if (compileIterationResult != null && isDebugEnabled) { + if (compileIterationResult.sourceFiles.any()) { + val sourceFiles = compileIterationResult.sourceFiles + .let { files -> + files.map { + val relativePath = if (rootProjectDir != null) it.relativeToOrNull(rootProjectDir)?.path else null + return@map relativePath ?: it.normalize().absolutePath + } + } + debug("compile iteration: ${sourceFiles.joinToString()}") + } + debug("compiler exit code: ${compileIterationResult.exitCode}") + } +} + internal fun createSessionIsAliveFlagFile() = makeAutodeletingFlagFile(keyword = "compilation-session") \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt index e5b308fd9b7..74535911d31 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt @@ -37,6 +37,8 @@ import java.io.File import java.rmi.RemoteException import javax.inject.Inject +private const val LOGGER_PREFIX = "[KOTLIN] " + internal abstract class BuildToolsApiCompilationWork @Inject constructor( private val fileSystemOperations: FileSystemOperations, ) : @@ -59,12 +61,12 @@ internal abstract class BuildToolsApiCompilationWork @Inject constructor( get() = workArguments.taskPath private val log: KotlinLogger by lazy(LazyThreadSafetyMode.NONE) { - TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } } + TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it, LOGGER_PREFIX).apply { debug("Using '$taskPath' logger") } } ?: run { val logger = LoggerFactory.getLogger("GradleKotlinCompilerWork") val kotlinLogger = if (logger is org.gradle.api.logging.Logger) { - GradleKotlinLogger(logger) - } else SL4JKotlinLogger(logger) + GradleKotlinLogger(logger, LOGGER_PREFIX) + } else SL4JKotlinLogger(logger, LOGGER_PREFIX) kotlinLogger.apply { debug("Could not get logger for '$taskPath'. Falling back to sl4j logger") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/GradleKotlinLogger.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/GradleKotlinLogger.kt index 46e2cb2f902..055ba81efa7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/GradleKotlinLogger.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/GradleKotlinLogger.kt @@ -8,25 +8,30 @@ package org.jetbrains.kotlin.gradle.logging import org.gradle.api.logging.Logger import org.jetbrains.kotlin.buildtools.api.KotlinLogger -internal class GradleKotlinLogger(private val log: Logger) : KotlinLogger { +internal class GradleKotlinLogger(private val log: Logger, private val prefix: String? = null) : KotlinLogger { + private fun transformMessage(msg: String): String { + if (prefix.isNullOrBlank()) return msg + return prefix + msg + } + override fun debug(msg: String) { - log.debug(msg) + log.debug(transformMessage(msg)) } override fun error(msg: String, throwable: Throwable?) { - log.error(msg, throwable) + log.error(transformMessage(msg), throwable) } override fun info(msg: String) { - log.info(msg) + log.info(transformMessage(msg)) } override fun warn(msg: String) { - log.warn(msg) + log.warn(transformMessage(msg)) } override fun lifecycle(msg: String) { - log.lifecycle(msg) + log.lifecycle(transformMessage(msg)) } override val isDebugEnabled: Boolean diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/SL4JKotlinLogger.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/SL4JKotlinLogger.kt index d168d489e30..c4b341c0465 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/SL4JKotlinLogger.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/SL4JKotlinLogger.kt @@ -8,25 +8,30 @@ package org.jetbrains.kotlin.gradle.logging import org.jetbrains.kotlin.buildtools.api.KotlinLogger import org.slf4j.Logger -internal class SL4JKotlinLogger(private val log: Logger) : KotlinLogger { +internal class SL4JKotlinLogger(private val log: Logger, private val prefix: String? = null) : KotlinLogger { + private fun transformMessage(msg: String): String { + if (prefix.isNullOrBlank()) return msg + return prefix + msg + } + override fun debug(msg: String) { - log.debug(msg) + log.debug(transformMessage(msg)) } override fun lifecycle(msg: String) { - log.info(msg) + log.info(transformMessage(msg)) } override fun error(msg: String, throwable: Throwable?) { - log.error(msg, throwable) + log.error(transformMessage(msg), throwable) } override fun info(msg: String) { - log.info(msg) + log.info(transformMessage(msg)) } override fun warn(msg: String) { - log.warn(msg) + log.warn(transformMessage(msg)) } override val isDebugEnabled: Boolean