diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 9fd4c2d9bb9..774f5ff8f42 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -127,6 +127,10 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { } companion object { + fun getRendererForDiagnostic(diagnostic: FirDiagnostic<*>): FirDiagnosticRenderer<*>? { + return MAP[diagnostic.factory] + } + // * - The old FE reports these diagnostics with additional parameters // & - New diagnostic that has no analogues in the old FE // + - Better message required diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt index cb7174fb01b..4a845598888 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt @@ -10,15 +10,15 @@ import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticParameterRenderer import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer class FirDiagnosticFactoryToRendererMap(val name: String) { - private val diagnosticsMap: MutableMap, DiagnosticRenderer<*>> = mutableMapOf() - val psiDiagnosticMap: DiagnosticFactoryToRendererMap = - DiagnosticFactoryToRendererMap() + private val classicRenderersMap: MutableMap, DiagnosticRenderer<*>> = mutableMapOf() + private val renderersMap: MutableMap, FirDiagnosticRenderer<*>> = mutableMapOf() + val psiDiagnosticMap: DiagnosticFactoryToRendererMap = DiagnosticFactoryToRendererMap() - operator fun get(factory: AbstractFirDiagnosticFactory<*, *>): DiagnosticRenderer<*>? = diagnosticsMap[factory] + operator fun get(factory: AbstractFirDiagnosticFactory<*, *>): FirDiagnosticRenderer<*>? = renderersMap[factory] + fun getClassicRenderer(factory: AbstractFirDiagnosticFactory<*, *>): DiagnosticRenderer<*>? = classicRenderersMap[factory] fun put(factory: FirDiagnosticFactory0<*, *>, message: String) { - psiDiagnosticMap.put(factory.psiDiagnosticFactory, message) - putToFirMap(factory) + put(factory, SimpleFirDiagnosticRenderer(message)) } fun put( @@ -26,8 +26,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) { message: String, rendererA: DiagnosticParameterRenderer? ) { - psiDiagnosticMap.put(factory.psiDiagnosticFactory, message, rendererA) - putToFirMap(factory) + put(factory, FirDiagnosticWithParameters1Renderer(message, rendererA)) } fun put( @@ -36,8 +35,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) { rendererA: DiagnosticParameterRenderer?, rendererB: DiagnosticParameterRenderer? ) { - psiDiagnosticMap.put(factory.psiDiagnosticFactory, message, rendererA, rendererB) - putToFirMap(factory) + put(factory, FirDiagnosticWithParameters2Renderer(message, rendererA, rendererB)) } fun put( @@ -47,13 +45,13 @@ class FirDiagnosticFactoryToRendererMap(val name: String) { rendererB: DiagnosticParameterRenderer?, rendererC: DiagnosticParameterRenderer? ) { - psiDiagnosticMap.put(factory.psiDiagnosticFactory, message, rendererA, rendererB, rendererC) - putToFirMap(factory) + put(factory, FirDiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC)) } - private fun putToFirMap(factory: AbstractFirDiagnosticFactory<*, *>) { - psiDiagnosticMap[factory.psiDiagnosticFactory]?.let { - diagnosticsMap[factory] = it - } + private fun put(factory: AbstractFirDiagnosticFactory<*, *>, renderer: FirDiagnosticRenderer<*>) { + val classicRenderer = renderer.toClassicDiagnosticRenderer() + renderersMap[factory] = renderer + classicRenderersMap[factory] = classicRenderer + psiDiagnosticMap.put(factory.psiDiagnosticFactory, classicRenderer) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderer.kt new file mode 100644 index 00000000000..50e16067e3f --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderer.kt @@ -0,0 +1,89 @@ +/* + * Copyright 2010-2020 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.fir.analysis.diagnostics + +import org.jetbrains.kotlin.diagnostics.rendering.* +import java.text.MessageFormat + +sealed class FirDiagnosticRenderer> { + abstract fun render(diagnostic: D): String + + abstract fun toClassicDiagnosticRenderer(): DiagnosticRenderer<*> +} + +class SimpleFirDiagnosticRenderer(private val message: String) : FirDiagnosticRenderer>() { + override fun render(diagnostic: FirSimpleDiagnostic<*>): String { + return message + } + + override fun toClassicDiagnosticRenderer(): DiagnosticRenderer<*> { + return SimpleDiagnosticRenderer(message) + } +} + +sealed class AbstractFirDiagnosticWithParametersRenderer>( + protected val message: String +) : FirDiagnosticRenderer() { + private val messageFormat = MessageFormat(message) + + override fun render(diagnostic: D): String { + return messageFormat.format(renderParameters(diagnostic)) + } + + abstract fun renderParameters(diagnostic: D): Array +} + +class FirDiagnosticWithParameters1Renderer( + message: String, + private val rendererForA: DiagnosticParameterRenderer?, +) : AbstractFirDiagnosticWithParametersRenderer>(message) { + override fun renderParameters(diagnostic: FirDiagnosticWithParameters1<*, A>): Array { + val context = RenderingContext.of(diagnostic.a) + return arrayOf(renderParameter(diagnostic.a, rendererForA, context),) + } + + override fun toClassicDiagnosticRenderer(): DiagnosticRenderer<*> { + return DiagnosticWithParameters1Renderer(message, rendererForA) + } +} + +class FirDiagnosticWithParameters2Renderer( + message: String, + private val rendererForA: DiagnosticParameterRenderer?, + private val rendererForB: DiagnosticParameterRenderer?, +) : AbstractFirDiagnosticWithParametersRenderer>(message) { + override fun renderParameters(diagnostic: FirDiagnosticWithParameters2<*, A, B>): Array { + val context = RenderingContext.of(diagnostic.a, diagnostic.b) + return arrayOf( + renderParameter(diagnostic.a, rendererForA, context), + renderParameter(diagnostic.b, rendererForB, context), + ) + } + + override fun toClassicDiagnosticRenderer(): DiagnosticRenderer<*> { + return DiagnosticWithParameters2Renderer(message, rendererForA, rendererForB) + } +} + +class FirDiagnosticWithParameters3Renderer( + message: String, + private val rendererForA: DiagnosticParameterRenderer?, + private val rendererForB: DiagnosticParameterRenderer?, + private val rendererForC: DiagnosticParameterRenderer?, +) : AbstractFirDiagnosticWithParametersRenderer>(message) { + override fun renderParameters(diagnostic: FirDiagnosticWithParameters3<*, A, B, C>): Array { + val context = RenderingContext.of(diagnostic.a, diagnostic.b, diagnostic.c) + return arrayOf( + renderParameter(diagnostic.a, rendererForA, context), + renderParameter(diagnostic.b, rendererForB, context), + renderParameter(diagnostic.c, rendererForC, context), + ) + } + + override fun toClassicDiagnosticRenderer(): DiagnosticRenderer<*> { + return DiagnosticWithParameters3Renderer(message, rendererForA, rendererForB, rendererForC) + } +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DiagnosticFactoryToRendererMap.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DiagnosticFactoryToRendererMap.java index 91a71daada5..e74dca1ed96 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DiagnosticFactoryToRendererMap.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DiagnosticFactoryToRendererMap.java @@ -79,6 +79,11 @@ public final class DiagnosticFactoryToRendererMap { map.put(factory, new DiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC)); } + public void put(@NotNull DiagnosticFactory factory, @NotNull DiagnosticRenderer renderer) { + checkMutability(); + map.put(factory, renderer); + } + @Nullable public DiagnosticRenderer get(@NotNull DiagnosticFactory factory) { return map.get(factory);