[FIR] Fix reporting diagnostics in CLI which was broken in previous commit

Note: reporting properly works only for PSI
This commit is contained in:
Dmitriy Novozhilov
2021-06-08 19:17:46 +03:00
parent d807ac2f05
commit 399b7aceef
5 changed files with 101 additions and 16 deletions
@@ -0,0 +1,88 @@
/*
* Copyright 2010-2021 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.cli.common.fir
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
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.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
object FirDiagnosticsCompilerResultsReporter {
fun reportDiagnostics(diagnostics: Collection<FirDiagnostic<*>>, reporter: MessageCollector): Boolean {
var hasErrors = false
for (diagnostic in diagnostics.sortedWith(DiagnosticComparator)) {
hasErrors = reportDiagnostic(diagnostic, reporter) || hasErrors
}
reportSpecialErrors(diagnostics)
return hasErrors
}
@Suppress("UNUSED_PARAMETER")
private fun reportSpecialErrors(diagnostics: Collection<FirDiagnostic<*>>) {
/*
* TODO: handle next diagnostics when they will be supported in FIR:
* - INCOMPATIBLE_CLASS
* - PRE_RELEASE_CLASS
* - IR_WITH_UNSTABLE_ABI_COMPILED_CLASS
* - FIR_COMPILED_CLASS
*/
}
private fun reportDiagnostic(diagnostic: FirDiagnostic<*>, reporter: MessageCollector): Boolean {
if (!diagnostic.isValid) return false
diagnostic.location()?.let { location ->
val severity = AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity)
// TODO: support multiple maps with messages
val renderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic)
reporter.report(severity, renderer.render(diagnostic), location)
}
return diagnostic.severity == Severity.ERROR
}
private fun FirDiagnostic<*>.location(): CompilerMessageSourceLocation? = when (val element = element) {
is FirPsiSourceElement<*> -> element.location(this)
is FirLightSourceElement -> element.location(this)
}
private fun FirPsiSourceElement<*>.location(diagnostic: FirDiagnostic<*>): CompilerMessageSourceLocation? {
val file = psi.containingFile
return MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumnRange(file, diagnostic.textRanges))
}
@Suppress("UNUSED_PARAMETER")
private fun FirLightSourceElement.location(diagnostic: FirDiagnostic<*>): CompilerMessageSourceLocation? {
// TODO: support light tree
return null
}
private object DiagnosticComparator : Comparator<FirDiagnostic<*>> {
override fun compare(o1: FirDiagnostic<*>, o2: FirDiagnostic<*>): Int {
val element1 = o1.element
val element2 = o1.element
// TODO: support light tree
if (element1 !is FirPsiSourceElement<*> || element2 !is FirPsiSourceElement<*>) return 0
val file1 = element1.psi.containingFile
val file2 = element2.psi.containingFile
val path1 = file1.viewProvider.virtualFile.path
val path2 = file2.viewProvider.virtualFile.path
if (path1 != path2) return path1.compareTo(path2)
val range1 = DiagnosticUtils.firstRange(o1.textRanges)
val range2 = DiagnosticUtils.firstRange(o2.textRanges)
return if (range1 != range2) {
DiagnosticUtils.TEXT_RANGE_COMPARATOR.compare(range1, range2)
} else o1.factory.name.compareTo(o2.factory.name)
}
}
}
@@ -19,10 +19,9 @@ import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.backend.jvm.jvmPhases
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
@@ -32,14 +31,12 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.fir.session.FirSessionFactory.createSessionWithDependencies
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.modules.TargetId
@@ -48,7 +45,6 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.diagnostics.SimpleGenericDiagnostics
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
@@ -147,14 +143,10 @@ object FirKotlinToJvmBytecodeCompiler {
firAnalyzerFacade.runResolution()
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
// TODO
// AnalyzerWithCompilerReport.reportDiagnostics(
// SimpleGenericDiagnostics(firDiagnostics),
// environment.messageCollector
// )
val hasErrors = FirDiagnosticsCompilerResultsReporter.reportDiagnostics(firDiagnostics, environment.messageCollector)
performanceManager?.notifyAnalysisFinished()
if (syntaxErrors || firDiagnostics.any { it.severity == Severity.ERROR }) {
if (syntaxErrors || hasErrors) {
return false
}
@@ -379,9 +379,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETU
@Suppress("unused")
class FirDefaultErrorMessages {
companion object {
fun getRendererForDiagnostic(diagnostic: FirDiagnostic<*>): FirDiagnosticRenderer<*> {
fun getRendererForDiagnostic(diagnostic: FirDiagnostic<*>): FirDiagnosticRenderer<FirDiagnostic<*>> {
val factory = diagnostic.factory
return MAP[factory] ?: factory.firRenderer
@Suppress("UNCHECKED_CAST")
return (MAP[factory] ?: factory.firRenderer) as FirDiagnosticRenderer<FirDiagnostic<*>>
}
// * - The old FE reports these diagnostics with additional parameters
@@ -36,7 +36,7 @@ import java.util.List;
public class DiagnosticUtils {
@NotNull
private static final Comparator<TextRange> TEXT_RANGE_COMPARATOR = (o1, o2) -> {
public static final Comparator<TextRange> TEXT_RANGE_COMPARATOR = (o1, o2) -> {
if (o1.getStartOffset() != o2.getStartOffset()) {
return o1.getStartOffset() - o2.getStartOffset();
}
@@ -87,6 +87,11 @@ public class DiagnosticUtils {
public static PsiDiagnosticUtils.LineAndColumnRange getLineAndColumnRange(@NotNull Diagnostic diagnostic) {
PsiFile file = diagnostic.getPsiFile();
List<TextRange> textRanges = diagnostic.getTextRanges();
return getLineAndColumnRange(file, textRanges);
}
@NotNull
public static PsiDiagnosticUtils.LineAndColumnRange getLineAndColumnRange(PsiFile file, List<TextRange> textRanges) {
if (textRanges.isEmpty()) return PsiDiagnosticUtils.LineAndColumnRange.NONE;
TextRange firstRange = firstRange(textRanges);
return getLineAndColumnRangeInPsiFile(file, firstRange);
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.codeMetaInfo.renderConfigurations.AbstractCodeMetaIn
import org.jetbrains.kotlin.fir.analysis.diagnostics.AbstractFirDiagnosticWithParametersRenderer
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderer
object FirMetaInfoUtils {
val renderDiagnosticNoArgs = FirDiagnosticCodeMetaRenderConfiguration().apply { renderParams = false }
@@ -67,7 +66,7 @@ class FirDiagnosticCodeMetaRenderConfiguration(
val diagnostic = codeMetaInfo.diagnostic
@Suppress("UNCHECKED_CAST")
val renderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic) as FirDiagnosticRenderer<FirDiagnostic<*>>
val renderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic)
if (renderer is AbstractFirDiagnosticWithParametersRenderer<*>) {
renderer.renderParameters(diagnostic).mapTo(params, Any?::toString)
}