[FIR] Fix reporting diagnostics in CLI which was broken in previous commit
Note: reporting properly works only for PSI
This commit is contained in:
+88
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-11
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -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);
|
||||
|
||||
+1
-2
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user