FIR: Allow 4 parameters for diagnostics
This commit is contained in:
committed by
Ilya Kirillov
parent
d2b8204fdc
commit
594fbbb4ef
+6
-2
@@ -47,8 +47,8 @@ class DiagnosticBuilder(
|
||||
|
||||
@OptIn(PrivateForInline::class, ExperimentalStdlibApi::class)
|
||||
inline fun <reified T> parameter(name: String) {
|
||||
if (parameters.size == 3) {
|
||||
error("Diagnostic cannot have more than 3 parameters")
|
||||
if (parameters.size >= MAX_DIAGNOSTIC_PARAMETER_COUNT) {
|
||||
error("Diagnostic cannot have more than $MAX_DIAGNOSTIC_PARAMETER_COUNT parameters")
|
||||
}
|
||||
parameters += DiagnosticParameter(
|
||||
name = name,
|
||||
@@ -64,4 +64,8 @@ class DiagnosticBuilder(
|
||||
parameters,
|
||||
positioningStrategy,
|
||||
)
|
||||
|
||||
companion object {
|
||||
const val MAX_DIAGNOSTIC_PARAMETER_COUNT = 4
|
||||
}
|
||||
}
|
||||
|
||||
+28
@@ -51,6 +51,14 @@ sealed class FirDiagnosticWithParameters3<out E : FirSourceElement, A : Any, B :
|
||||
abstract override val factory: FirDiagnosticFactory3<*, A, B, C>
|
||||
}
|
||||
|
||||
sealed class FirDiagnosticWithParameters4<out E : FirSourceElement, A : Any, B : Any, C : Any, D : Any> : FirDiagnostic<E>() {
|
||||
abstract val a: A
|
||||
abstract val b: B
|
||||
abstract val c: C
|
||||
abstract val d: D
|
||||
abstract override val factory: FirDiagnosticFactory4<*, A, B, C, D>
|
||||
}
|
||||
|
||||
// ------------------------------ psi diagnostics ------------------------------
|
||||
|
||||
interface FirPsiDiagnostic<P : PsiElement> : Diagnostic {
|
||||
@@ -93,6 +101,16 @@ data class FirPsiDiagnosticWithParameters3<P : PsiElement, A : Any, B : Any, C :
|
||||
override val factory: FirDiagnosticFactory3<P, A, B, C>
|
||||
) : FirDiagnosticWithParameters3<FirPsiSourceElement<P>, A, B, C>(), FirPsiDiagnostic<P>
|
||||
|
||||
data class FirPsiDiagnosticWithParameters4<P : PsiElement, A : Any, B : Any, C : Any, D : Any>(
|
||||
override val element: FirPsiSourceElement<P>,
|
||||
override val a: A,
|
||||
override val b: B,
|
||||
override val c: C,
|
||||
override val d: D,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory4<P, A, B, C, D>
|
||||
) : FirDiagnosticWithParameters4<FirPsiSourceElement<P>, A, B, C, D>(), FirPsiDiagnostic<P>
|
||||
|
||||
// ------------------------------ light tree diagnostics ------------------------------
|
||||
|
||||
interface FirLightDiagnostic : UnboundDiagnostic {
|
||||
@@ -128,3 +146,13 @@ data class FirLightDiagnosticWithParameters3<A : Any, B : Any, C : Any>(
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory3<*, A, B, C>
|
||||
) : FirDiagnosticWithParameters3<FirLightSourceElement, A, B, C>(), FirLightDiagnostic
|
||||
|
||||
data class FirLightDiagnosticWithParameters4<A : Any, B : Any, C : Any, D : Any>(
|
||||
override val element: FirLightSourceElement,
|
||||
override val a: A,
|
||||
override val b: B,
|
||||
override val c: C,
|
||||
override val d: D,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory4<*, A, B, C, D>
|
||||
) : FirDiagnosticWithParameters4<FirLightSourceElement, A, B, C, D>(), FirLightDiagnostic
|
||||
|
||||
+25
-1
@@ -9,7 +9,8 @@ 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.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer
|
||||
import org.jetbrains.kotlin.fir.FirLightSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirPsiSourceElement
|
||||
@@ -120,6 +121,29 @@ class FirDiagnosticFactory3<P : PsiElement, A : Any, B : Any, C : Any>(
|
||||
}
|
||||
}
|
||||
|
||||
class FirDiagnosticFactory4<P : PsiElement, A : Any, B : Any, C : Any, D : Any>(
|
||||
name: String,
|
||||
severity: Severity,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters4<*, A, B, C, D>, P>(name, severity, positioningStrategy) {
|
||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters4<*, A, B, C, D>> = FirDiagnosticWithParameters4Renderer(
|
||||
"{0}, {1}, {2}, {3}",
|
||||
FirDiagnosticRenderers.TO_STRING,
|
||||
FirDiagnosticRenderers.TO_STRING,
|
||||
FirDiagnosticRenderers.TO_STRING,
|
||||
FirDiagnosticRenderers.TO_STRING
|
||||
)
|
||||
|
||||
fun on(element: FirSourceElement, a: A, b: B, c: C, d: D): FirDiagnosticWithParameters4<*, A, B, C, D> {
|
||||
return when (element) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters4(
|
||||
element as FirPsiSourceElement<P>, a, b, c, d, severity, this
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters4(element, a, b, c, d, severity, this)
|
||||
else -> incorrectElement(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun incorrectElement(element: FirSourceElement): Nothing {
|
||||
throw IllegalArgumentException("Unknown element type: ${element::class}")
|
||||
}
|
||||
|
||||
+16
-1
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -58,6 +58,11 @@ fun <P : PsiElement, A : Any, B : Any, C : Any> error3(
|
||||
return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy)
|
||||
}
|
||||
|
||||
fun <P : PsiElement, A : Any, B : Any, C : Any, D : Any> error4(
|
||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||
): DiagnosticFactory4DelegateProvider<P, A, B, C, D> {
|
||||
return DiagnosticFactory4DelegateProvider(Severity.ERROR, positioningStrategy)
|
||||
}
|
||||
|
||||
// ------------------------------ Providers ------------------------------
|
||||
|
||||
@@ -97,6 +102,16 @@ class DiagnosticFactory3DelegateProvider<P : PsiElement, A : Any, B : Any, C : A
|
||||
}
|
||||
}
|
||||
|
||||
class DiagnosticFactory4DelegateProvider<P : PsiElement, A : Any, B : Any, C : Any, D : Any>(
|
||||
private val severity: Severity,
|
||||
private val positioningStrategy: SourceElementPositioningStrategy<P>
|
||||
) {
|
||||
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory4<P, A, B, C, D>> {
|
||||
return DummyDelegate(FirDiagnosticFactory4(prop.name, severity, positioningStrategy))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class DummyDelegate<T>(val value: T) : ReadOnlyProperty<Any?, T> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||
return value
|
||||
|
||||
+11
@@ -45,6 +45,17 @@ class FirDiagnosticFactoryToRendererMap(val name: String) {
|
||||
put(factory, FirDiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC))
|
||||
}
|
||||
|
||||
fun <A : Any, B : Any, C : Any, D : Any> put(
|
||||
factory: FirDiagnosticFactory4<*, A, B, C, D>,
|
||||
message: String,
|
||||
rendererA: DiagnosticParameterRenderer<A>?,
|
||||
rendererB: DiagnosticParameterRenderer<B>?,
|
||||
rendererC: DiagnosticParameterRenderer<C>?,
|
||||
rendererD: DiagnosticParameterRenderer<D>?
|
||||
) {
|
||||
put(factory, FirDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
|
||||
}
|
||||
|
||||
private fun put(factory: AbstractFirDiagnosticFactory<*, *>, renderer: FirDiagnosticRenderer<*>) {
|
||||
renderersMap[factory] = renderer
|
||||
psiDiagnosticMap.put(factory, renderer)
|
||||
|
||||
+18
@@ -60,3 +60,21 @@ class FirDiagnosticWithParameters3Renderer<A : Any, B : Any, C : Any>(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class FirDiagnosticWithParameters4Renderer<A : Any, B : Any, C : Any, D : Any>(
|
||||
message: String,
|
||||
private val rendererForA: DiagnosticParameterRenderer<A>?,
|
||||
private val rendererForB: DiagnosticParameterRenderer<B>?,
|
||||
private val rendererForC: DiagnosticParameterRenderer<C>?,
|
||||
private val rendererForD: DiagnosticParameterRenderer<D>?,
|
||||
) : AbstractFirDiagnosticWithParametersRenderer<FirDiagnosticWithParameters4<*, A, B, C, D>>(message) {
|
||||
override fun renderParameters(diagnostic: FirDiagnosticWithParameters4<*, A, B, C, D>): Array<out Any> {
|
||||
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),
|
||||
renderParameter(diagnostic.d, rendererForD, context),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-1
@@ -13,7 +13,10 @@ import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.render
|
||||
|
||||
@@ -105,4 +108,8 @@ object FirDiagnosticRenderers {
|
||||
"$list $branches or 'else' branch instead"
|
||||
}
|
||||
}
|
||||
|
||||
val NOT_RENDERED = Renderer<Any> {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -57,6 +57,13 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
|
||||
severity,
|
||||
factory as FirDiagnosticFactory3<PsiElement, Any, Any, Any>
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters4<*, *, *, *> -> FirPsiDiagnosticWithParameters4(
|
||||
psiSourceElement,
|
||||
a, b, c, d,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory4<PsiElement, Any, Any, Any, Any>
|
||||
)
|
||||
else -> error("Unknown diagnostic type ${this::class.simpleName}")
|
||||
}
|
||||
}
|
||||
+11
@@ -27,6 +27,10 @@ internal fun interface KtFirDiagnostic3Creator<A : Any, B : Any, C : Any> : KtFi
|
||||
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters3<*, A, B, C>): KtFirDiagnostic<*>
|
||||
}
|
||||
|
||||
internal fun interface KtFirDiagnostic4Creator<A : Any, B : Any, C : Any, D : Any> : KtFirDiagnosticCreator {
|
||||
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters4<*, A, B, C, D>): KtFirDiagnostic<*>
|
||||
}
|
||||
|
||||
internal class KtDiagnosticConverter(private val conversions: Map<AbstractFirDiagnosticFactory<*, *>, KtFirDiagnosticCreator>) {
|
||||
fun convert(analysisSession: KtFirAnalysisSession, diagnostic: FirDiagnostic<*>): KtFirDiagnostic<*> {
|
||||
val creator = conversions[diagnostic.factory]
|
||||
@@ -47,6 +51,9 @@ internal class KtDiagnosticConverter(private val conversions: Map<AbstractFirDia
|
||||
is KtFirDiagnostic3Creator<*, *, *> -> with(creator as KtFirDiagnostic3Creator<Any, Any, Any>) {
|
||||
create(diagnostic as FirDiagnosticWithParameters3<FirSourceElement, Any, Any, Any>)
|
||||
}
|
||||
is KtFirDiagnostic4Creator<*, *, *, *> -> with(creator as KtFirDiagnostic4Creator<Any, Any, Any, Any>) {
|
||||
create(diagnostic as FirDiagnosticWithParameters4<FirSourceElement, Any, Any, Any, Any>)
|
||||
}
|
||||
else -> error("Invalid KtFirDiagnosticCreator ${creator::class.simpleName}")
|
||||
}
|
||||
}
|
||||
@@ -72,6 +79,10 @@ internal class KtDiagnosticConverterBuilder private constructor() {
|
||||
conversions[diagnostic] = creator
|
||||
}
|
||||
|
||||
fun <A : Any, B : Any, C : Any, D : Any> add(diagnostic: FirDiagnosticFactory4<*, A, B, C, D>, creator: KtFirDiagnostic4Creator<A, B, C, D>) {
|
||||
conversions[diagnostic] = creator
|
||||
}
|
||||
|
||||
private fun build() = KtDiagnosticConverter(conversions)
|
||||
|
||||
companion object {
|
||||
|
||||
Reference in New Issue
Block a user