Refactor diagnostic & result reporters...

to better reflect actual roles
This commit is contained in:
Ilya Chernikov
2021-10-13 12:34:33 +02:00
parent ea1edc2bd9
commit 70366dc7a6
9 changed files with 57 additions and 28 deletions
@@ -8,12 +8,9 @@ package org.jetbrains.kotlin.cli.common.fir
import org.jetbrains.kotlin.AbstractKtSourceElement import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtLightSourceElement import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticReporter import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
import java.io.Closeable import java.io.Closeable
import java.io.File import java.io.File
@@ -29,10 +26,26 @@ object FirDiagnosticsCompilerResultsReporter {
return hasErrors return hasErrors
} }
fun reportToCollector(diagnosticsReporter: BaseDiagnosticReporter, messageCollector: MessageCollector): Boolean { fun reportToMessageCollector(diagnosticsCollector: BaseDiagnosticsCollector, messageCollector: MessageCollector): Boolean {
return reportByFile(diagnosticsCollector) { diagnostic, location ->
reportDiagnosticToMessageCollector(diagnostic, location, messageCollector)
}
}
fun throwFirstErrorAsException(
diagnosticsCollector: BaseDiagnosticsCollector, messageRenderer: MessageRenderer = MessageRenderer.PLAIN_RELATIVE_PATHS
): Boolean {
return reportByFile(diagnosticsCollector) { diagnostic, location ->
throwErrorDiagnosticAsException(diagnostic, location, messageRenderer)
}
}
fun reportByFile(
diagnosticsCollector: BaseDiagnosticsCollector, report: (KtDiagnostic, CompilerMessageSourceLocation) -> Unit
): Boolean {
var hasErrors = false var hasErrors = false
for (filePath in diagnosticsReporter.diagnosticsByFilePath.keys) { for (filePath in diagnosticsCollector.diagnosticsByFilePath.keys) {
for (diagnostic in diagnosticsReporter.diagnosticsByFilePath[filePath].orEmpty().sortedWith(SingleFileDiagnosticComparator)) { for (diagnostic in diagnosticsCollector.diagnosticsByFilePath[filePath].orEmpty().sortedWith(SingleFileDiagnosticComparator)) {
var filePositionFinder: SequentialFilePositionFinder? = null var filePositionFinder: SequentialFilePositionFinder? = null
try { try {
when { when {
@@ -49,7 +62,7 @@ object FirDiagnosticsCompilerResultsReporter {
MessageUtil.createMessageLocation(filePath, position.lineContent, position.line, position.column, -1, -1) MessageUtil.createMessageLocation(filePath, position.lineContent, position.line, position.column, -1, -1)
} }
}?.let { location -> }?.let { location ->
reportDiagnostic(diagnostic, location, messageCollector) report(diagnostic, location)
hasErrors = hasErrors || diagnostic.severity == Severity.ERROR hasErrors = hasErrors || diagnostic.severity == Severity.ERROR
} }
} finally { } finally {
@@ -75,12 +88,12 @@ object FirDiagnosticsCompilerResultsReporter {
private fun reportDiagnostic(diagnostic: KtDiagnostic, reporter: MessageCollector): Boolean { private fun reportDiagnostic(diagnostic: KtDiagnostic, reporter: MessageCollector): Boolean {
if (!diagnostic.isValid) return false if (!diagnostic.isValid) return false
diagnostic.location()?.let { diagnostic.location()?.let {
reportDiagnostic(diagnostic, it, reporter) reportDiagnosticToMessageCollector(diagnostic, it, reporter)
} }
return diagnostic.severity == Severity.ERROR return diagnostic.severity == Severity.ERROR
} }
private fun reportDiagnostic( private fun reportDiagnosticToMessageCollector(
diagnostic: KtDiagnostic, diagnostic: KtDiagnostic,
location: CompilerMessageSourceLocation, location: CompilerMessageSourceLocation,
reporter: MessageCollector reporter: MessageCollector
@@ -90,6 +103,19 @@ object FirDiagnosticsCompilerResultsReporter {
reporter.report(severity, renderer.render(diagnostic), location) reporter.report(severity, renderer.render(diagnostic), location)
} }
private fun throwErrorDiagnosticAsException(
diagnostic: KtDiagnostic,
location: CompilerMessageSourceLocation,
messageRenderer: MessageRenderer
) {
if (diagnostic.severity == Severity.ERROR) {
val severity = AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity)
val renderer = RootDiagnosticRendererFactory(diagnostic)
val diagnosticText = messageRenderer.render(severity, renderer.render(diagnostic), location)
throw IllegalStateException("${diagnostic.factory.name}: $diagnosticText")
}
}
private fun KtDiagnostic.location(): CompilerMessageSourceLocation? = when (val element = element) { private fun KtDiagnostic.location(): CompilerMessageSourceLocation? = when (val element = element) {
is KtPsiSourceElement -> element.location(this) is KtPsiSourceElement -> element.location(this)
is KtLightSourceElement -> element.location(this) is KtLightSourceElement -> element.location(this)
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.codegen.CodegenFactory
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticReporter import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.Fir2IrResult import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
@@ -133,7 +133,7 @@ object FirKotlinToJvmBytecodeCompiler {
performanceManager?.notifyAnalysisFinished() performanceManager?.notifyAnalysisFinished()
} }
if (firResult == null) { if (firResult == null) {
FirDiagnosticsCompilerResultsReporter.reportToCollector(diagnosticsReporter, messageCollector) FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector)
return null return null
} }
@@ -153,7 +153,7 @@ object FirKotlinToJvmBytecodeCompiler {
diagnosticsReporter diagnosticsReporter
) )
FirDiagnosticsCompilerResultsReporter.reportToCollector(diagnosticsReporter, messageCollector) FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector)
performanceManager?.notifyIRGenerationFinished() performanceManager?.notifyIRGenerationFinished()
performanceManager?.notifyGenerationFinished() performanceManager?.notifyGenerationFinished()
@@ -168,7 +168,7 @@ object FirKotlinToJvmBytecodeCompiler {
val fir: List<FirFile> val fir: List<FirFile>
) )
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>, diagnosticsReporter: BaseDiagnosticReporter): FirResult? { private fun CompilationContext.runFrontend(ktFiles: List<KtFile>, diagnosticsReporter: BaseDiagnosticsCollector): FirResult? {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
var ktFiles = ktFiles var ktFiles = ktFiles
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile -> val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
@@ -287,7 +287,7 @@ object FirKotlinToJvmBytecodeCompiler {
fir2IrResult: Fir2IrResult, fir2IrResult: Fir2IrResult,
extensions: JvmGeneratorExtensionsImpl, extensions: JvmGeneratorExtensionsImpl,
session: FirSession, session: FirSession,
diagnosticsReporter: BaseDiagnosticReporter diagnosticsReporter: BaseDiagnosticsCollector
): GenerationState { ): GenerationState {
val (moduleFragment, symbolTable, components) = fir2IrResult val (moduleFragment, symbolTable, components) = fir2IrResult
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
@@ -375,7 +375,7 @@ object KotlinToJVMBytecodeCompiler {
), ),
environment.messageCollector environment.messageCollector
) )
FirDiagnosticsCompilerResultsReporter.reportToCollector(diagnosticsReporter, environment.messageCollector) FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, environment.messageCollector)
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
return state return state
@@ -5,16 +5,16 @@
package org.jetbrains.kotlin.diagnostics package org.jetbrains.kotlin.diagnostics
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticReporter import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.diagnostics.impl.DiagnosticReporterWithSuppress import org.jetbrains.kotlin.diagnostics.impl.DiagnosticsCollectorWithSuppress
import org.jetbrains.kotlin.diagnostics.impl.SimpleDiagnosticReporter import org.jetbrains.kotlin.diagnostics.impl.SimpleDiagnosticsCollector
object DiagnosticReporterFactory { object DiagnosticReporterFactory {
fun createReporter(disableSuppress: Boolean = false): BaseDiagnosticReporter { fun createReporter(disableSuppress: Boolean = false): BaseDiagnosticsCollector {
return if (disableSuppress) { return if (disableSuppress) {
SimpleDiagnosticReporter() SimpleDiagnosticsCollector()
} else { } else {
DiagnosticReporterWithSuppress() DiagnosticsCollectorWithSuppress()
} }
} }
} }
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.diagnostics.impl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.KtDiagnostic import org.jetbrains.kotlin.diagnostics.KtDiagnostic
abstract class BaseDiagnosticReporter : DiagnosticReporter() { abstract class BaseDiagnosticsCollector : DiagnosticReporter() {
abstract val diagnostics: List<KtDiagnostic> abstract val diagnostics: List<KtDiagnostic>
abstract val diagnosticsByFilePath: Map<String?, List<KtDiagnostic>> abstract val diagnosticsByFilePath: Map<String?, List<KtDiagnostic>>
abstract val hasErrors: Boolean abstract val hasErrors: Boolean
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.diagnostics.KtDiagnostic import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.Severity
class DiagnosticReporterWithSuppress : BaseDiagnosticReporter() { class DiagnosticsCollectorWithSuppress : BaseDiagnosticsCollector() {
private val _diagnosticsByFilePath: MutableMap<String?, MutableList<KtDiagnostic>> = mutableMapOf() private val _diagnosticsByFilePath: MutableMap<String?, MutableList<KtDiagnostic>> = mutableMapOf()
override val diagnostics: List<KtDiagnostic> override val diagnostics: List<KtDiagnostic>
get() = _diagnosticsByFilePath.flatMap { it.value } get() = _diagnosticsByFilePath.flatMap { it.value }
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.diagnostics.KtDiagnostic import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.Severity
class SimpleDiagnosticReporter : BaseDiagnosticReporter() { class SimpleDiagnosticsCollector : BaseDiagnosticsCollector() {
private val _diagnosticsByFilePath: MutableMap<String?, MutableList<KtDiagnostic>> = mutableMapOf() private val _diagnosticsByFilePath: MutableMap<String?, MutableList<KtDiagnostic>> = mutableMapOf()
override val diagnostics: List<KtDiagnostic> override val diagnostics: List<KtDiagnostic>
get() = _diagnosticsByFilePath.flatMap { it.value } get() = _diagnosticsByFilePath.flatMap { it.value }
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.test.backend.handlers package org.jetbrains.kotlin.test.backend.handlers
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticReporter import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticReporter import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticReporter
import org.jetbrains.kotlin.test.frontend.classic.handlers.withNewInferenceModeEnabled import org.jetbrains.kotlin.test.frontend.classic.handlers.withNewInferenceModeEnabled
@@ -32,7 +32,7 @@ class JvmBackendDiagnosticsHandler(testServices: TestServices) : JvmBinaryArtifa
val testFile = ktFileToTestFileMap[ktFile] ?: continue val testFile = ktFileToTestFileMap[ktFile] ?: continue
reporter.reportDiagnostic(diagnostic, module, testFile, configuration, withNewInferenceModeEnabled) reporter.reportDiagnostic(diagnostic, module, testFile, configuration, withNewInferenceModeEnabled)
} }
val ktDiagnosticReporter = generationState.diagnosticReporter as BaseDiagnosticReporter val ktDiagnosticReporter = generationState.diagnosticReporter as BaseDiagnosticsCollector
val globalMetadataInfoHandler = testServices.globalMetadataInfoHandler val globalMetadataInfoHandler = testServices.globalMetadataInfoHandler
for ((testFile, ktFile) in testFileToKtFileMap.entries) { for ((testFile, ktFile) in testFileToKtFileMap.entries) {
val ktDiagnostics = ktDiagnosticReporter.diagnosticsByFilePath[ktFile.virtualFilePath] ?: continue val ktDiagnostics = ktDiagnosticReporter.diagnosticsByFilePath[ktFile.virtualFilePath] ?: continue
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.test.backend.handlers package org.jetbrains.kotlin.test.backend.handlers
import org.jetbrains.kotlin.TestsCompiletimeError import org.jetbrains.kotlin.TestsCompiletimeError
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.resolve.AnalyzingUtils import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.test.model.BinaryArtifacts import org.jetbrains.kotlin.test.model.BinaryArtifacts
import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.model.TestModule
@@ -16,6 +18,7 @@ class NoJvmSpecificCompilationErrorsHandler(testServices: TestServices) : JvmBin
val generationState = info.classFileFactory.generationState val generationState = info.classFileFactory.generationState
try { try {
AnalyzingUtils.throwExceptionOnErrors(generationState.collectedExtraJvmDiagnostics) AnalyzingUtils.throwExceptionOnErrors(generationState.collectedExtraJvmDiagnostics)
FirDiagnosticsCompilerResultsReporter.throwFirstErrorAsException(generationState.diagnosticReporter as BaseDiagnosticsCollector)
} catch (e: Throwable) { } catch (e: Throwable) {
throw TestsCompiletimeError(e) throw TestsCompiletimeError(e)
} }