From 00069b1d2ffcd35309dfb8cdc111bc4983d69203 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 8 Sep 2021 18:13:28 +0300 Subject: [PATCH] [FIR] Use diagnostic markers in FIR diagnostics --- .../fir/analysis/diagnostics/FirDiagnostic.kt | 45 +++++++++++-------- .../SourceElementPositioningStrategy.kt | 26 ++++------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt index 5e3b59c8126..c2d730110d8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt @@ -8,14 +8,14 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import org.jetbrains.kotlin.diagnostics.Severity +import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.fir.FirLightSourceElement import org.jetbrains.kotlin.fir.FirPsiSourceElement import org.jetbrains.kotlin.fir.FirSourceElement // ------------------------------ diagnostics ------------------------------ -sealed class FirDiagnostic { +sealed class FirDiagnostic : DiagnosticMarker { abstract val element: FirSourceElement abstract val severity: Severity abstract val factory: AbstractFirDiagnosticFactory @@ -26,47 +26,50 @@ sealed class FirDiagnostic { val isValid: Boolean get() = positioningStrategy.isValid(element) + + override val factoryName: String + get() = factory.name } sealed class FirSimpleDiagnostic : FirDiagnostic() { abstract override val factory: FirDiagnosticFactory0 } -sealed class FirDiagnosticWithParameters1 : FirDiagnostic() { - abstract val a: A +sealed class FirDiagnosticWithParameters1 : FirDiagnostic(), DiagnosticWithParameters1Marker { + abstract override val a: A abstract override val factory: FirDiagnosticFactory1 } -sealed class FirDiagnosticWithParameters2 : FirDiagnostic() { - abstract val a: A - abstract val b: B +sealed class FirDiagnosticWithParameters2 : FirDiagnostic(), DiagnosticWithParameters2Marker { + abstract override val a: A + abstract override val b: B abstract override val factory: FirDiagnosticFactory2 } -sealed class FirDiagnosticWithParameters3 : FirDiagnostic() { - abstract val a: A - abstract val b: B - abstract val c: C +sealed class FirDiagnosticWithParameters3 : FirDiagnostic(), DiagnosticWithParameters3Marker { + abstract override val a: A + abstract override val b: B + abstract override val c: C abstract override val factory: FirDiagnosticFactory3 } -sealed class FirDiagnosticWithParameters4 : FirDiagnostic() { - abstract val a: A - abstract val b: B - abstract val c: C - abstract val d: D +sealed class FirDiagnosticWithParameters4 : FirDiagnostic(), DiagnosticWithParameters4Marker { + abstract override val a: A + abstract override val b: B + abstract override val c: C + abstract override val d: D abstract override val factory: FirDiagnosticFactory4 } // ------------------------------ psi diagnostics ------------------------------ -interface FirPsiDiagnostic { +interface FirPsiDiagnostic : DiagnosticMarker { val factory: AbstractFirDiagnosticFactory val element: FirPsiSourceElement val textRanges: List val severity: Severity - val psiElement: PsiElement + override val psiElement: PsiElement get() = element.psi val psiFile: PsiFile @@ -151,8 +154,12 @@ data class FirPsiDiagnosticWithParameters4( // ------------------------------ light tree diagnostics ------------------------------ -interface FirLightDiagnostic { +interface FirLightDiagnostic : DiagnosticMarker { val element: FirLightSourceElement + + @Deprecated("Should not be called", level = DeprecationLevel.HIDDEN) + override val psiElement: PsiElement + get() = error("psiElement should not be called on FirLightDiagnostic") } data class FirLightSimpleDiagnostic( diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategy.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategy.kt index 7a9ae0f11be..6459660e973 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategy.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategy.kt @@ -8,37 +8,27 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import org.jetbrains.kotlin.diagnostics.PositioningStrategy +import org.jetbrains.kotlin.fir.FirLightSourceElement import org.jetbrains.kotlin.fir.FirPsiSourceElement import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.psi class SourceElementPositioningStrategy( private val lightTreeStrategy: LightTreePositioningStrategy, private val psiStrategy: PositioningStrategy<*> ) { fun markDiagnostic(diagnostic: FirDiagnostic): List { - val element = diagnostic.element - if (element is FirPsiSourceElement) { - return if (psiStrategy is FirPsiPositioningStrategy<*>) { - psiStrategy.markFirDiagnostic(element, diagnostic) - } else { - @Suppress("UNCHECKED_CAST") - psiStrategy.hackyMark(element.psi) - } + return when (val element = diagnostic.element) { + is FirPsiSourceElement -> psiStrategy.markDiagnostic(diagnostic) + is FirLightSourceElement -> lightTreeStrategy.markFirDiagnostic(element, diagnostic) } - return lightTreeStrategy.markFirDiagnostic(element, diagnostic) } fun isValid(element: FirSourceElement): Boolean { - if (element is FirPsiSourceElement) { - @Suppress("UNCHECKED_CAST") - return psiStrategy.hackyIsValid(element.psi) + return when (element) { + is FirPsiSourceElement -> psiStrategy.hackyIsValid(element.psi) + is FirLightSourceElement -> lightTreeStrategy.isValid(element.lighterASTNode, element.treeStructure) } - return lightTreeStrategy.isValid(element.lighterASTNode, element.treeStructure) - } - - private fun PositioningStrategy<*>.hackyMark(psi: PsiElement): List { - @Suppress("UNCHECKED_CAST") - return (this as PositioningStrategy).mark(psi) } private fun PositioningStrategy<*>.hackyIsValid(psi: PsiElement): Boolean {