org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory.kt Maven / Gradle / Ivy
/*
* 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.
*/
@file:Suppress("UNCHECKED_CAST")
package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
sealed class AbstractFirDiagnosticFactory, P : PsiElement>(
override val name: String,
override val severity: Severity,
val positioningStrategy: SourceElementPositioningStrategy,
) : DiagnosticFactory(name, severity) {
abstract val firRenderer: FirDiagnosticRenderer
override var defaultRenderer: DiagnosticRenderer?
get() = firRenderer
set(_) {
}
fun getTextRanges(diagnostic: FirDiagnostic<*>): List =
positioningStrategy.markDiagnostic(diagnostic)
fun isValid(diagnostic: FirDiagnostic<*>): Boolean {
val element = diagnostic.element
return positioningStrategy.isValid(element)
}
}
class FirDiagnosticFactory0(
name: String,
severity: Severity,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer> = SimpleFirDiagnosticRenderer("")
fun on(element: E): FirSimpleDiagnostic {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiSimpleDiagnostic(
element as FirPsiSourceElement, severity, this as FirDiagnosticFactory0, P>
)
is FirLightSourceElement -> FirLightSimpleDiagnostic(element, severity, this)
else -> incorrectElement(element)
} as FirSimpleDiagnostic
}
}
class FirDiagnosticFactory1(
name: String,
severity: Severity,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer> = FirDiagnosticWithParameters1Renderer(
"{0}",
FirDiagnosticRenderers.TO_STRING
)
fun on(element: E, a: A): FirDiagnosticWithParameters1 {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
element as FirPsiSourceElement, a, severity, this as FirDiagnosticFactory1, P, A>
)
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(element, a, severity, this)
else -> incorrectElement(element)
} as FirDiagnosticWithParameters1
}
}
class FirDiagnosticFactory2(
name: String,
severity: Severity,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer> = FirDiagnosticWithParameters2Renderer(
"{0}, {1}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
)
fun on(element: E, a: A, b: B): FirDiagnosticWithParameters2 {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters2(
element as FirPsiSourceElement, a, b, severity, this as FirDiagnosticFactory2, P, A, B>
)
is FirLightSourceElement -> FirLightDiagnosticWithParameters2(element, a, b, severity, this)
else -> incorrectElement(element)
} as FirDiagnosticWithParameters2
}
}
class FirDiagnosticFactory3(
name: String,
severity: Severity,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer> = FirDiagnosticWithParameters3Renderer(
"{0}, {1}, {2}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
)
fun on(element: E, a: A, b: B, c: C): FirDiagnosticWithParameters3 {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters3(
element as FirPsiSourceElement, a, b, c, severity, this as FirDiagnosticFactory3, P, A, B, C>
)
is FirLightSourceElement -> FirLightDiagnosticWithParameters3(element, a, b, c, severity, this)
else -> incorrectElement(element)
} as FirDiagnosticWithParameters3
}
}
private fun incorrectElement(element: FirSourceElement): Nothing {
throw IllegalArgumentException("Unknown element type: ${element::class}")
}
fun FirDiagnosticFactory0.on(element: E?): FirSimpleDiagnostic? {
return element?.let { on(it) }
}
fun FirDiagnosticFactory1.on(
element: E?, a: A
): FirDiagnosticWithParameters1? {
return element?.let { on(it, a) }
}
fun FirDiagnosticFactory2.on(
element: E?,
a: A,
b: B
): FirDiagnosticWithParameters2? {
return element?.let { on(it, a, b) }
}
fun FirDiagnosticFactory3.on(
element: E?,
a: A,
b: B,
c: C
): FirDiagnosticWithParameters3? {
return element?.let { on(it, a, b, c) }
}