[FIR] Add ability to specify custom position strategy for specific diagnostic
This commit is contained in:
+30
-20
@@ -20,9 +20,10 @@ abstract class DiagnosticReporter {
|
||||
fun <P : PsiElement> DiagnosticReporter.reportOn(
|
||||
source: FirSourceElement?,
|
||||
factory: FirDiagnosticFactory0<P>,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
source?.let { report(factory.on(it), context) }
|
||||
source?.let { report(factory.on(it, positioningStrategy), context) }
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
@@ -30,9 +31,10 @@ fun <P : PsiElement, A : Any> DiagnosticReporter.reportOn(
|
||||
source: FirSourceElement?,
|
||||
factory: FirDiagnosticFactory1<P, A>,
|
||||
a: A,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
source?.let { report(factory.on(it, a), context) }
|
||||
source?.let { report(factory.on(it, a, positioningStrategy), context) }
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
@@ -41,9 +43,10 @@ fun <P : PsiElement, A : Any, B : Any> DiagnosticReporter.reportOn(
|
||||
factory: FirDiagnosticFactory2<P, A, B>,
|
||||
a: A,
|
||||
b: B,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
source?.let { report(factory.on(it, a, b), context) }
|
||||
source?.let { report(factory.on(it, a, b, positioningStrategy), context) }
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
@@ -53,9 +56,10 @@ fun <P : PsiElement, A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
source?.let { report(factory.on(it, a, b, c), context) }
|
||||
source?.let { report(factory.on(it, a, b, c, positioningStrategy), context) }
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
@@ -66,9 +70,10 @@ fun <P : PsiElement, A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.repo
|
||||
b: B,
|
||||
c: C,
|
||||
d: D,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
source?.let { report(factory.on(it, a, b, c, d), context) }
|
||||
source?.let { report(factory.on(it, a, b, c, d, positioningStrategy), context) }
|
||||
}
|
||||
|
||||
inline fun withSuppressedDiagnostics(
|
||||
@@ -94,10 +99,11 @@ inline fun withSuppressedDiagnostics(
|
||||
fun <P : PsiElement> DiagnosticReporter.reportOnWithSuppression(
|
||||
element: FirElement,
|
||||
factory: FirDiagnosticFactory0<P>,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
withSuppressedDiagnostics(element, context) {
|
||||
reportOn(element.source, factory, it)
|
||||
reportOn(element.source, factory, it, positioningStrategy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,10 +111,11 @@ fun <P : PsiElement, A : Any> DiagnosticReporter.reportOnWithSuppression(
|
||||
element: FirElement,
|
||||
factory: FirDiagnosticFactory1<P, A>,
|
||||
a: A,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
withSuppressedDiagnostics(element, context) {
|
||||
reportOn(element.source, factory, a, it)
|
||||
reportOn(element.source, factory, a, it, positioningStrategy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,10 +124,11 @@ fun <P : PsiElement, A : Any, B : Any> DiagnosticReporter.reportOnWithSuppressio
|
||||
factory: FirDiagnosticFactory2<P, A, B>,
|
||||
a: A,
|
||||
b: B,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
withSuppressedDiagnostics(element, context) {
|
||||
reportOn(element.source, factory, a, b, it)
|
||||
reportOn(element.source, factory, a, b, it, positioningStrategy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,10 +138,11 @@ fun <P : PsiElement, A : Any, B : Any, C : Any> DiagnosticReporter.reportOnWithS
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
withSuppressedDiagnostics(element, context) {
|
||||
reportOn(element.source, factory, a, b, c, it)
|
||||
reportOn(element.source, factory, a, b, c, it, positioningStrategy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,10 +153,11 @@ fun <P : PsiElement, A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.repo
|
||||
b: B,
|
||||
c: C,
|
||||
d: D,
|
||||
context: CheckerContext
|
||||
context: CheckerContext,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>? = null
|
||||
) {
|
||||
withSuppressedDiagnostics(element, context) {
|
||||
reportOn(element.source, factory, a, b, c, d, it)
|
||||
reportOn(element.source, factory, a, b, c, d, it, positioningStrategy)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-12
@@ -21,12 +21,13 @@ sealed class FirDiagnostic<out E : FirSourceElement> : UnboundDiagnostic {
|
||||
abstract val element: E
|
||||
abstract override val severity: Severity
|
||||
abstract override val factory: AbstractFirDiagnosticFactory<*, *>
|
||||
abstract val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
|
||||
override val textRanges: List<TextRange>
|
||||
get() = factory.getTextRanges(this)
|
||||
get() = positioningStrategy.markDiagnostic(this)
|
||||
|
||||
override val isValid: Boolean
|
||||
get() = factory.isValid(this)
|
||||
get() = positioningStrategy.isValid(element)
|
||||
}
|
||||
|
||||
sealed class FirSimpleDiagnostic<out E : FirSourceElement> : FirDiagnostic<E>() {
|
||||
@@ -74,14 +75,16 @@ interface FirPsiDiagnostic<P : PsiElement> : Diagnostic {
|
||||
data class FirPsiSimpleDiagnostic<P : PsiElement>(
|
||||
override val element: FirPsiSourceElement<P>,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory0<P>
|
||||
override val factory: FirDiagnosticFactory0<P>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirSimpleDiagnostic<FirPsiSourceElement<P>>(), FirPsiDiagnostic<P>
|
||||
|
||||
data class FirPsiDiagnosticWithParameters1<P : PsiElement, A>(
|
||||
override val element: FirPsiSourceElement<P>,
|
||||
override val a: A,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory1<P, A>
|
||||
override val factory: FirDiagnosticFactory1<P, A>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters1<FirPsiSourceElement<P>, A>(), FirPsiDiagnostic<P>
|
||||
|
||||
data class FirPsiDiagnosticWithParameters2<P : PsiElement, A, B>(
|
||||
@@ -89,7 +92,8 @@ data class FirPsiDiagnosticWithParameters2<P : PsiElement, A, B>(
|
||||
override val a: A,
|
||||
override val b: B,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory2<P, A, B>
|
||||
override val factory: FirDiagnosticFactory2<P, A, B>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters2<FirPsiSourceElement<P>, A, B>(), FirPsiDiagnostic<P>
|
||||
|
||||
data class FirPsiDiagnosticWithParameters3<P : PsiElement, A, B, C>(
|
||||
@@ -98,7 +102,8 @@ data class FirPsiDiagnosticWithParameters3<P : PsiElement, A, B, C>(
|
||||
override val b: B,
|
||||
override val c: C,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory3<P, A, B, C>
|
||||
override val factory: FirDiagnosticFactory3<P, A, B, C>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters3<FirPsiSourceElement<P>, A, B, C>(), FirPsiDiagnostic<P>
|
||||
|
||||
data class FirPsiDiagnosticWithParameters4<P : PsiElement, A, B, C, D>(
|
||||
@@ -108,7 +113,8 @@ data class FirPsiDiagnosticWithParameters4<P : PsiElement, A, B, C, D>(
|
||||
override val c: C,
|
||||
override val d: D,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory4<P, A, B, C, D>
|
||||
override val factory: FirDiagnosticFactory4<P, A, B, C, D>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters4<FirPsiSourceElement<P>, A, B, C, D>(), FirPsiDiagnostic<P>
|
||||
|
||||
// ------------------------------ light tree diagnostics ------------------------------
|
||||
@@ -120,14 +126,16 @@ interface FirLightDiagnostic : UnboundDiagnostic {
|
||||
data class FirLightSimpleDiagnostic(
|
||||
override val element: FirLightSourceElement,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory0<*>
|
||||
override val factory: FirDiagnosticFactory0<*>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirSimpleDiagnostic<FirLightSourceElement>(), FirLightDiagnostic
|
||||
|
||||
data class FirLightDiagnosticWithParameters1<A>(
|
||||
override val element: FirLightSourceElement,
|
||||
override val a: A,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory1<*, A>
|
||||
override val factory: FirDiagnosticFactory1<*, A>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters1<FirLightSourceElement, A>(), FirLightDiagnostic
|
||||
|
||||
data class FirLightDiagnosticWithParameters2<A, B>(
|
||||
@@ -135,7 +143,8 @@ data class FirLightDiagnosticWithParameters2<A, B>(
|
||||
override val a: A,
|
||||
override val b: B,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory2<*, A, B>
|
||||
override val factory: FirDiagnosticFactory2<*, A, B>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters2<FirLightSourceElement, A, B>(), FirLightDiagnostic
|
||||
|
||||
data class FirLightDiagnosticWithParameters3<A, B, C>(
|
||||
@@ -144,7 +153,8 @@ data class FirLightDiagnosticWithParameters3<A, B, C>(
|
||||
override val b: B,
|
||||
override val c: C,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory3<*, A, B, C>
|
||||
override val factory: FirDiagnosticFactory3<*, A, B, C>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters3<FirLightSourceElement, A, B, C>(), FirLightDiagnostic
|
||||
|
||||
data class FirLightDiagnosticWithParameters4<A, B, C, D>(
|
||||
@@ -154,5 +164,6 @@ data class FirLightDiagnosticWithParameters4<A, B, C, D>(
|
||||
override val c: C,
|
||||
override val d: D,
|
||||
override val severity: Severity,
|
||||
override val factory: FirDiagnosticFactory4<*, A, B, C, D>
|
||||
override val factory: FirDiagnosticFactory4<*, A, B, C, D>,
|
||||
override val positioningStrategy: SourceElementPositioningStrategy<*>
|
||||
) : FirDiagnosticWithParameters4<FirLightSourceElement, A, B, C, D>(), FirLightDiagnostic
|
||||
|
||||
+81
-77
@@ -7,7 +7,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
@@ -22,7 +21,7 @@ annotation class InternalDiagnosticFactoryMethod
|
||||
sealed class AbstractFirDiagnosticFactory<D : FirDiagnostic<*>, P : PsiElement>(
|
||||
override val name: String,
|
||||
override val severity: Severity,
|
||||
val positioningStrategy: SourceElementPositioningStrategy<P>,
|
||||
val defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
||||
) : DiagnosticFactory<D>(name, severity) {
|
||||
abstract val firRenderer: FirDiagnosticRenderer<D>
|
||||
|
||||
@@ -30,30 +29,25 @@ sealed class AbstractFirDiagnosticFactory<D : FirDiagnostic<*>, P : PsiElement>(
|
||||
get() = firRenderer
|
||||
set(_) {
|
||||
}
|
||||
|
||||
fun getTextRanges(diagnostic: FirDiagnostic<*>): List<TextRange> =
|
||||
positioningStrategy.markDiagnostic(diagnostic)
|
||||
|
||||
fun isValid(diagnostic: FirDiagnostic<*>): Boolean {
|
||||
val element = diagnostic.element
|
||||
return positioningStrategy.isValid(element)
|
||||
}
|
||||
}
|
||||
|
||||
class FirDiagnosticFactory0<P : PsiElement>(
|
||||
name: String,
|
||||
severity: Severity,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirSimpleDiagnostic<*>, P>(name, severity, positioningStrategy) {
|
||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirSimpleDiagnostic<*>, P>(name, severity, defaultPositioningStrategy) {
|
||||
override val firRenderer: FirDiagnosticRenderer<FirSimpleDiagnostic<*>> = SimpleFirDiagnosticRenderer("")
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun on(element: FirSourceElement): FirSimpleDiagnostic<*> {
|
||||
fun on(
|
||||
element: FirSourceElement,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>?
|
||||
): FirSimpleDiagnostic<*> {
|
||||
return when (element) {
|
||||
is FirPsiSourceElement<*> -> FirPsiSimpleDiagnostic(
|
||||
element as FirPsiSourceElement<P>, severity, this
|
||||
element as FirPsiSourceElement<P>, severity, this, positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightSimpleDiagnostic(element, severity, this)
|
||||
is FirLightSourceElement -> FirLightSimpleDiagnostic(element, severity, this, positioningStrategy ?: defaultPositioningStrategy)
|
||||
else -> incorrectElement(element)
|
||||
}
|
||||
}
|
||||
@@ -62,20 +56,30 @@ class FirDiagnosticFactory0<P : PsiElement>(
|
||||
class FirDiagnosticFactory1<P : PsiElement, A>(
|
||||
name: String,
|
||||
severity: Severity,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters1<*, A>, P>(name, severity, positioningStrategy) {
|
||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters1<*, A>, P>(name, severity, defaultPositioningStrategy) {
|
||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters1<*, A>> = FirDiagnosticWithParameters1Renderer(
|
||||
"{0}",
|
||||
FirDiagnosticRenderers.TO_STRING
|
||||
)
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun on(element: FirSourceElement, a: A): FirDiagnosticWithParameters1<*, A> {
|
||||
fun on(
|
||||
element: FirSourceElement,
|
||||
a: A,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>?
|
||||
): FirDiagnosticWithParameters1<*, A> {
|
||||
return when (element) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
|
||||
element as FirPsiSourceElement<P>, a, severity, this
|
||||
element as FirPsiSourceElement<P>, a, severity, this, positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
|
||||
element,
|
||||
a,
|
||||
severity,
|
||||
this,
|
||||
positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(element, a, severity, this)
|
||||
else -> incorrectElement(element)
|
||||
}
|
||||
}
|
||||
@@ -84,8 +88,8 @@ class FirDiagnosticFactory1<P : PsiElement, A>(
|
||||
class FirDiagnosticFactory2<P : PsiElement, A, B>(
|
||||
name: String,
|
||||
severity: Severity,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters2<*, A, B>, P>(name, severity, positioningStrategy) {
|
||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters2<*, A, B>, P>(name, severity, defaultPositioningStrategy) {
|
||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters2<*, A, B>> = FirDiagnosticWithParameters2Renderer(
|
||||
"{0}, {1}",
|
||||
FirDiagnosticRenderers.TO_STRING,
|
||||
@@ -93,12 +97,24 @@ class FirDiagnosticFactory2<P : PsiElement, A, B>(
|
||||
)
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun on(element: FirSourceElement, a: A, b: B): FirDiagnosticWithParameters2<*, A, B> {
|
||||
fun on(
|
||||
element: FirSourceElement,
|
||||
a: A,
|
||||
b: B,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>?
|
||||
): FirDiagnosticWithParameters2<*, A, B> {
|
||||
return when (element) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters2(
|
||||
element as FirPsiSourceElement<P>, a, b, severity, this
|
||||
element as FirPsiSourceElement<P>, a, b, severity, this, positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters2(
|
||||
element,
|
||||
a,
|
||||
b,
|
||||
severity,
|
||||
this,
|
||||
positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters2(element, a, b, severity, this)
|
||||
else -> incorrectElement(element)
|
||||
}
|
||||
}
|
||||
@@ -107,8 +123,8 @@ class FirDiagnosticFactory2<P : PsiElement, A, B>(
|
||||
class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
|
||||
name: String,
|
||||
severity: Severity,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters3<*, A, B, C>, P>(name, severity, positioningStrategy) {
|
||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters3<*, A, B, C>, P>(name, severity, defaultPositioningStrategy) {
|
||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters3<*, A, B, C>> = FirDiagnosticWithParameters3Renderer(
|
||||
"{0}, {1}, {2}",
|
||||
FirDiagnosticRenderers.TO_STRING,
|
||||
@@ -117,12 +133,26 @@ class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
|
||||
)
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun on(element: FirSourceElement, a: A, b: B, c: C): FirDiagnosticWithParameters3<*, A, B, C> {
|
||||
fun on(
|
||||
element: FirSourceElement,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>?
|
||||
): FirDiagnosticWithParameters3<*, A, B, C> {
|
||||
return when (element) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters3(
|
||||
element as FirPsiSourceElement<P>, a, b, c, severity, this
|
||||
element as FirPsiSourceElement<P>, a, b, c, severity, this, positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters3(
|
||||
element,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
severity,
|
||||
this,
|
||||
positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters3(element, a, b, c, severity, this)
|
||||
else -> incorrectElement(element)
|
||||
}
|
||||
}
|
||||
@@ -131,8 +161,8 @@ class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
|
||||
class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
|
||||
name: String,
|
||||
severity: Severity,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters4<*, A, B, C, D>, P>(name, severity, positioningStrategy) {
|
||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters4<*, A, B, C, D>, P>(name, severity, defaultPositioningStrategy) {
|
||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters4<*, A, B, C, D>> = FirDiagnosticWithParameters4Renderer(
|
||||
"{0}, {1}, {2}, {3}",
|
||||
FirDiagnosticRenderers.TO_STRING,
|
||||
@@ -142,12 +172,28 @@ class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
|
||||
)
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun on(element: FirSourceElement, a: A, b: B, c: C, d: D): FirDiagnosticWithParameters4<*, A, B, C, D> {
|
||||
fun on(
|
||||
element: FirSourceElement,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
d: D,
|
||||
positioningStrategy: SourceElementPositioningStrategy<P>?
|
||||
): FirDiagnosticWithParameters4<*, A, B, C, D> {
|
||||
return when (element) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters4(
|
||||
element as FirPsiSourceElement<P>, a, b, c, d, severity, this
|
||||
element as FirPsiSourceElement<P>, a, b, c, d, severity, this, positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters4(
|
||||
element,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
severity,
|
||||
this,
|
||||
positioningStrategy ?: defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters4(element, a, b, c, d, severity, this)
|
||||
else -> incorrectElement(element)
|
||||
}
|
||||
}
|
||||
@@ -156,45 +202,3 @@ class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
|
||||
private fun incorrectElement(element: FirSourceElement): Nothing {
|
||||
throw IllegalArgumentException("Unknown element type: ${element::class}")
|
||||
}
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun <P : PsiElement> FirDiagnosticFactory0<P>.on(element: FirSourceElement?): FirSimpleDiagnostic<*>? {
|
||||
return element?.let { on(it) }
|
||||
}
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun <P : PsiElement, A> FirDiagnosticFactory1<P, A>.on(
|
||||
element: FirSourceElement?, a: A
|
||||
): FirDiagnosticWithParameters1<*, A>? {
|
||||
return element?.let { on(it, a) }
|
||||
}
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun <P : PsiElement, A, B> FirDiagnosticFactory2<P, A, B>.on(
|
||||
element: FirSourceElement?,
|
||||
a: A,
|
||||
b: B
|
||||
): FirDiagnosticWithParameters2<*, A, B>? {
|
||||
return element?.let { on(it, a, b) }
|
||||
}
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun <P : PsiElement, A, B, C> FirDiagnosticFactory3<P, A, B, C>.on(
|
||||
element: FirSourceElement?,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C
|
||||
): FirDiagnosticWithParameters3<*, A, B, C>? {
|
||||
return element?.let { on(it, a, b, c) }
|
||||
}
|
||||
|
||||
@InternalDiagnosticFactoryMethod
|
||||
fun <P : PsiElement, A, B, C, D> FirDiagnosticFactory4<P, A, B, C, D>.on(
|
||||
element: FirSourceElement?,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
d: D
|
||||
): FirDiagnosticWithParameters4<*, A, B, C, D>? {
|
||||
return element?.let { on(it, a, b, c, d) }
|
||||
}
|
||||
|
||||
+97
-65
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
@@ -32,58 +33,58 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun ConeDiagnostic.toFirDiagnostic(
|
||||
source: FirSourceElement,
|
||||
qualifiedAccessSource: FirSourceElement?
|
||||
): FirDiagnostic<FirSourceElement>? = when (this) {
|
||||
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.name?.asString() ?: "<No name>")
|
||||
is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.classId.asString())
|
||||
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.name.asString())
|
||||
is ConeUnresolvedQualifierError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.qualifier)
|
||||
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.on(source, this.candidateSymbol)
|
||||
is ConeAmbiguityError -> if (this.applicability.isSuccess) {
|
||||
FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.on(source, this.candidates.map { it.symbol })
|
||||
} else if (this.applicability == CandidateApplicability.UNSAFE_CALL) {
|
||||
val candidate = candidates.first { it.currentApplicability == CandidateApplicability.UNSAFE_CALL }
|
||||
val unsafeCall = candidate.diagnostics.firstIsInstance<UnsafeCall>()
|
||||
mapUnsafeCallError(candidate, unsafeCall, source, qualifiedAccessSource)
|
||||
} else if (this.applicability == CandidateApplicability.UNSTABLE_SMARTCAST) {
|
||||
val unstableSmartcast =
|
||||
this.candidates.first { it.currentApplicability == CandidateApplicability.UNSTABLE_SMARTCAST }.diagnostics.firstIsInstance<UnstableSmartCast>()
|
||||
FirErrors.SMARTCAST_IMPOSSIBLE.on(
|
||||
unstableSmartcast.argument.source,
|
||||
unstableSmartcast.targetType,
|
||||
unstableSmartcast.argument,
|
||||
unstableSmartcast.argument.smartcastStability.description
|
||||
)
|
||||
} else {
|
||||
FirErrors.NONE_APPLICABLE.on(source, this.candidates.map { it.symbol })
|
||||
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.name?.asString() ?: "<No name>")
|
||||
is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.classId.asString())
|
||||
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.name.asString())
|
||||
is ConeUnresolvedQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier)
|
||||
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol)
|
||||
is ConeAmbiguityError -> when {
|
||||
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
|
||||
applicability == CandidateApplicability.UNSAFE_CALL -> {
|
||||
val candidate = candidates.first { it.currentApplicability == CandidateApplicability.UNSAFE_CALL }
|
||||
val unsafeCall = candidate.diagnostics.firstIsInstance<UnsafeCall>()
|
||||
mapUnsafeCallError(candidate, unsafeCall, source, qualifiedAccessSource)
|
||||
}
|
||||
applicability == CandidateApplicability.UNSTABLE_SMARTCAST -> {
|
||||
val unstableSmartcast =
|
||||
this.candidates.first { it.currentApplicability == CandidateApplicability.UNSTABLE_SMARTCAST }.diagnostics.firstIsInstance<UnstableSmartCast>()
|
||||
FirErrors.SMARTCAST_IMPOSSIBLE.createOn(
|
||||
unstableSmartcast.argument.source,
|
||||
unstableSmartcast.targetType,
|
||||
unstableSmartcast.argument,
|
||||
unstableSmartcast.argument.smartcastStability.description
|
||||
)
|
||||
}
|
||||
else -> FirErrors.NONE_APPLICABLE.createOn(source, this.candidates.map { it.symbol })
|
||||
}
|
||||
is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.on(source, this.candidates)
|
||||
is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source)
|
||||
is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.createOn(source, this.candidates)
|
||||
is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.createOn(source)
|
||||
is ConeValReassignmentError -> when (val symbol = this.variable) {
|
||||
is FirBackingFieldSymbol -> FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR.on(source, symbol.fir.symbol)
|
||||
else -> FirErrors.VAL_REASSIGNMENT.on(source, symbol)
|
||||
is FirBackingFieldSymbol -> FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR.createOn(source, symbol.fir.symbol)
|
||||
else -> FirErrors.VAL_REASSIGNMENT.createOn(source, symbol)
|
||||
}
|
||||
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(this.source.safeAs() ?: source)
|
||||
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.on(source, this.name.asString())
|
||||
is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.createOn(this.source.safeAs() ?: source)
|
||||
is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.createOn(source, this.name.asString())
|
||||
is ConeWrongNumberOfTypeArgumentsError ->
|
||||
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(qualifiedAccessSource ?: source, this.desiredCount, this.type)
|
||||
FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
|
||||
is ConeNoTypeArgumentsOnRhsError ->
|
||||
FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.on(qualifiedAccessSource ?: source, this.desiredCount, this.type)
|
||||
FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.type)
|
||||
is ConeSimpleDiagnostic -> when (source.kind) {
|
||||
is FirFakeSourceElementKind -> null
|
||||
else -> this.getFactory(source).on(qualifiedAccessSource ?: source)
|
||||
else -> this.getFactory(source).createOn(qualifiedAccessSource ?: source)
|
||||
}
|
||||
is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.on(source, this.target)
|
||||
is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target)
|
||||
is ConeStubDiagnostic -> null
|
||||
is ConeIntermediateDiagnostic -> null
|
||||
is ConeContractDescriptionError -> FirErrors.ERROR_IN_CONTRACT_DESCRIPTION.on(source, this.reason)
|
||||
is ConeTypeParameterSupertype -> FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE.on(source, this.reason)
|
||||
is ConeContractDescriptionError -> FirErrors.ERROR_IN_CONTRACT_DESCRIPTION.createOn(source, this.reason)
|
||||
is ConeTypeParameterSupertype -> FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE.createOn(source, this.reason)
|
||||
is ConeTypeParameterInQualifiedAccess -> null // reported in various checkers instead
|
||||
is ConeNotAnnotationContainer -> null
|
||||
is ConeImportFromSingleton -> FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON.on(source, this.name)
|
||||
is ConeImportFromSingleton -> FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON.createOn(source, this.name)
|
||||
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
|
||||
}
|
||||
|
||||
@@ -98,15 +99,14 @@ fun ConeDiagnostic.toFirDiagnostics(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun mapUnsafeCallError(
|
||||
candidate: Candidate,
|
||||
rootCause: UnsafeCall,
|
||||
source: FirSourceElement,
|
||||
qualifiedAccessSource: FirSourceElement?,
|
||||
): FirDiagnostic<*> {
|
||||
): FirDiagnostic<*>? {
|
||||
if (candidate.callInfo.isImplicitInvoke) {
|
||||
return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.on(source, rootCause.actualType)
|
||||
return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.createOn(source, rootCause.actualType)
|
||||
}
|
||||
|
||||
val candidateFunction = candidate.symbol.fir as? FirSimpleFunction
|
||||
@@ -126,14 +126,14 @@ private fun mapUnsafeCallError(
|
||||
source
|
||||
}
|
||||
return if (operationSource?.getChild(KtTokens.IDENTIFIER) != null) {
|
||||
FirErrors.UNSAFE_INFIX_CALL.on(
|
||||
FirErrors.UNSAFE_INFIX_CALL.createOn(
|
||||
source,
|
||||
receiverExpression,
|
||||
candidateFunctionName!!.asString(),
|
||||
singleArgument,
|
||||
)
|
||||
} else {
|
||||
FirErrors.UNSAFE_OPERATOR_CALL.on(
|
||||
FirErrors.UNSAFE_OPERATOR_CALL.createOn(
|
||||
source,
|
||||
receiverExpression,
|
||||
candidateFunctionName!!.asString(),
|
||||
@@ -142,51 +142,50 @@ private fun mapUnsafeCallError(
|
||||
}
|
||||
}
|
||||
return if (source.kind == FirFakeSourceElementKind.ArrayAccessNameReference) {
|
||||
FirErrors.UNSAFE_CALL.on(source, rootCause.actualType, receiverExpression)
|
||||
FirErrors.UNSAFE_CALL.createOn(source, rootCause.actualType, receiverExpression)
|
||||
} else {
|
||||
FirErrors.UNSAFE_CALL.on(qualifiedAccessSource ?: source, rootCause.actualType, receiverExpression)
|
||||
FirErrors.UNSAFE_CALL.createOn(qualifiedAccessSource ?: source, rootCause.actualType, receiverExpression)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun mapInapplicableCandidateError(
|
||||
diagnostic: ConeInapplicableCandidateError,
|
||||
source: FirSourceElement,
|
||||
qualifiedAccessSource: FirSourceElement?,
|
||||
): List<FirDiagnostic<FirSourceElement>> {
|
||||
val genericDiagnostic = FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)
|
||||
val genericDiagnostic = FirErrors.INAPPLICABLE_CANDIDATE.createOn(source, diagnostic.candidate.symbol)
|
||||
val diagnostics = diagnostic.candidate.diagnostics.filter { it.applicability == diagnostic.applicability }.mapNotNull { rootCause ->
|
||||
when (rootCause) {
|
||||
is VarargArgumentOutsideParentheses -> FirErrors.VARARG_OUTSIDE_PARENTHESES.on(
|
||||
is VarargArgumentOutsideParentheses -> FirErrors.VARARG_OUTSIDE_PARENTHESES.createOn(
|
||||
rootCause.argument.source ?: qualifiedAccessSource
|
||||
)
|
||||
is NamedArgumentNotAllowed -> FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED.on(
|
||||
is NamedArgumentNotAllowed -> FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED.createOn(
|
||||
rootCause.argument.source,
|
||||
rootCause.forbiddenNamedArgumentsTarget
|
||||
)
|
||||
is ArgumentTypeMismatch -> FirErrors.ARGUMENT_TYPE_MISMATCH.on(
|
||||
is ArgumentTypeMismatch -> FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
|
||||
rootCause.argument.source ?: source,
|
||||
rootCause.expectedType,
|
||||
rootCause.actualType,
|
||||
rootCause.isMismatchDueToNullability
|
||||
)
|
||||
is NullForNotNullType -> FirErrors.NULL_FOR_NONNULL_TYPE.on(
|
||||
is NullForNotNullType -> FirErrors.NULL_FOR_NONNULL_TYPE.createOn(
|
||||
rootCause.argument.source ?: source
|
||||
)
|
||||
is NonVarargSpread -> FirErrors.NON_VARARG_SPREAD.on(rootCause.argument.source?.getChild(KtTokens.MUL, depth = 1)!!)
|
||||
is ArgumentPassedTwice -> FirErrors.ARGUMENT_PASSED_TWICE.on(rootCause.argument.source)
|
||||
is TooManyArguments -> FirErrors.TOO_MANY_ARGUMENTS.on(rootCause.argument.source ?: source, rootCause.function)
|
||||
is NoValueForParameter -> FirErrors.NO_VALUE_FOR_PARAMETER.on(qualifiedAccessSource ?: source, rootCause.valueParameter)
|
||||
is NameNotFound -> FirErrors.NAMED_PARAMETER_NOT_FOUND.on(
|
||||
is NonVarargSpread -> FirErrors.NON_VARARG_SPREAD.createOn(rootCause.argument.source?.getChild(KtTokens.MUL, depth = 1)!!)
|
||||
is ArgumentPassedTwice -> FirErrors.ARGUMENT_PASSED_TWICE.createOn(rootCause.argument.source)
|
||||
is TooManyArguments -> FirErrors.TOO_MANY_ARGUMENTS.createOn(rootCause.argument.source ?: source, rootCause.function)
|
||||
is NoValueForParameter -> FirErrors.NO_VALUE_FOR_PARAMETER.createOn(qualifiedAccessSource ?: source, rootCause.valueParameter)
|
||||
is NameNotFound -> FirErrors.NAMED_PARAMETER_NOT_FOUND.createOn(
|
||||
rootCause.argument.source ?: source,
|
||||
rootCause.argument.name.asString()
|
||||
)
|
||||
is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource)
|
||||
is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.on(rootCause.argument.source ?: source)
|
||||
is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.on(source, rootCause.function)
|
||||
is ManyLambdaExpressionArguments -> FirErrors.MANY_LAMBDA_EXPRESSION_ARGUMENTS.createOn(rootCause.argument.source ?: source)
|
||||
is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.createOn(source, rootCause.function)
|
||||
is OperatorCallOfNonOperatorFunction ->
|
||||
FirErrors.OPERATOR_MODIFIER_REQUIRED.on(source, rootCause.function, rootCause.function.fir.name.asString())
|
||||
is UnstableSmartCast -> FirErrors.SMARTCAST_IMPOSSIBLE.on(
|
||||
FirErrors.OPERATOR_MODIFIER_REQUIRED.createOn(source, rootCause.function, rootCause.function.fir.name.asString())
|
||||
is UnstableSmartCast -> FirErrors.SMARTCAST_IMPOSSIBLE.createOn(
|
||||
rootCause.argument.source,
|
||||
rootCause.targetType,
|
||||
rootCause.argument,
|
||||
@@ -203,7 +202,7 @@ private fun mapInapplicableCandidateError(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class, InternalDiagnosticFactoryMethod::class)
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun mapSystemHasContradictionError(
|
||||
diagnostic: ConeConstraintSystemHasContradiction,
|
||||
source: FirSourceElement,
|
||||
@@ -241,13 +240,12 @@ private fun mapSystemHasContradictionError(
|
||||
if (morePreciseDiagnosticExists) return@firstNotNullOfOrNull null
|
||||
}
|
||||
|
||||
FirErrors.NEW_INFERENCE_ERROR.on(qualifiedAccessSource ?: source, message)
|
||||
FirErrors.NEW_INFERENCE_ERROR.createOn(qualifiedAccessSource ?: source, message)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun ConstraintSystemError.toDiagnostic(
|
||||
source: FirSourceElement,
|
||||
qualifiedAccessSource: FirSourceElement?,
|
||||
@@ -267,7 +265,7 @@ private fun ConstraintSystemError.toDiagnostic(
|
||||
}
|
||||
|
||||
argument?.let {
|
||||
return FirErrors.ARGUMENT_TYPE_MISMATCH.on(
|
||||
return FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
|
||||
it.source ?: source,
|
||||
lowerConeType,
|
||||
upperConeType,
|
||||
@@ -287,13 +285,13 @@ private fun ConstraintSystemError.toDiagnostic(
|
||||
else
|
||||
upperConeType.withNullability(ConeNullability.NULLABLE, typeContext)
|
||||
|
||||
FirErrors.TYPE_MISMATCH.on(qualifiedAccessSource ?: source, upperConeType, inferredType)
|
||||
FirErrors.TYPE_MISMATCH.createOn(qualifiedAccessSource ?: source, upperConeType, inferredType)
|
||||
}
|
||||
is ExplicitTypeParameterConstraintPosition<*> -> {
|
||||
val conePosition = position as ConeExplicitTypeParameterConstraintPosition
|
||||
val typeArgument = conePosition.typeArgument
|
||||
|
||||
FirErrors.UPPER_BOUND_VIOLATED.on(
|
||||
FirErrors.UPPER_BOUND_VIOLATED.createOn(
|
||||
typeArgument.source ?: qualifiedAccessSource ?: source,
|
||||
upperConeType,
|
||||
)
|
||||
@@ -319,7 +317,7 @@ private fun ConstraintSystemError.toDiagnostic(
|
||||
else -> error("Unsupported type variable: $typeVariable")
|
||||
}
|
||||
|
||||
FirErrors.NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(
|
||||
FirErrors.NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER.createOn(
|
||||
source,
|
||||
typeVariableName,
|
||||
)
|
||||
@@ -375,3 +373,37 @@ private fun ConeSimpleDiagnostic.getFactory(source: FirSourceElement): FirDiagno
|
||||
else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass")
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun <P : PsiElement> FirDiagnosticFactory0<P>.createOn(
|
||||
element: FirSourceElement?
|
||||
): FirSimpleDiagnostic<*>? {
|
||||
return element?.let { on(it, positioningStrategy = null) }
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun <P : PsiElement, A> FirDiagnosticFactory1<P, A>.createOn(
|
||||
element: FirSourceElement?,
|
||||
a: A
|
||||
): FirDiagnosticWithParameters1<*, A>? {
|
||||
return element?.let { on(it, a, positioningStrategy = null) }
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun <P : PsiElement, A, B> FirDiagnosticFactory2<P, A, B>.createOn(
|
||||
element: FirSourceElement?,
|
||||
a: A,
|
||||
b: B
|
||||
): FirDiagnosticWithParameters2<*, A, B>? {
|
||||
return element?.let { on(it, a, b, positioningStrategy = null) }
|
||||
}
|
||||
|
||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||
private fun <P : PsiElement, A, B, C> FirDiagnosticFactory3<P, A, B, C>.createOn(
|
||||
element: FirSourceElement?,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C
|
||||
): FirDiagnosticWithParameters3<*, A, B, C>? {
|
||||
return element?.let { on(it, a, b, c, positioningStrategy = null) }
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ class FirDiagnosticCodeMetaInfo(
|
||||
renderConfiguration: FirDiagnosticCodeMetaRenderConfiguration
|
||||
) : CodeMetaInfo {
|
||||
private val textRangeFromClassicDiagnostic: TextRange = run {
|
||||
diagnostic.factory.positioningStrategy.markDiagnostic(diagnostic).first()
|
||||
diagnostic.factory.defaultPositioningStrategy.markDiagnostic(diagnostic).first()
|
||||
}
|
||||
|
||||
override var renderConfiguration: FirDiagnosticCodeMetaRenderConfiguration = renderConfiguration
|
||||
|
||||
+18
-4
@@ -120,11 +120,13 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
) {
|
||||
val metaInfos = if (firFile.psi != null) {
|
||||
AnalyzingUtils.getSyntaxErrorRanges(firFile.psi!!).map {
|
||||
FirErrors.SYNTAX.on(FirRealPsiSourceElement(it)).toMetaInfo(testFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||
FirErrors.SYNTAX.on(FirRealPsiSourceElement(it), positioningStrategy = null)
|
||||
.toMetaInfo(testFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||
}
|
||||
} else {
|
||||
collectLightTreeSyntaxErrors(firFile).map { sourceElement ->
|
||||
FirErrors.SYNTAX.on(sourceElement).toMetaInfo(testFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||
FirErrors.SYNTAX.on(sourceElement, positioningStrategy = null)
|
||||
.toMetaInfo(testFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,8 +247,20 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
val argumentText = argument()
|
||||
val factory = FirDiagnosticFactory1<PsiElement, String>(name, severity)
|
||||
return when (positionedElement) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(positionedElement, argumentText, severity, factory)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(positionedElement, argumentText, severity, factory)
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
|
||||
positionedElement,
|
||||
argumentText,
|
||||
severity,
|
||||
factory,
|
||||
factory.defaultPositioningStrategy
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
|
||||
positionedElement,
|
||||
argumentText,
|
||||
severity,
|
||||
factory,
|
||||
factory.defaultPositioningStrategy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -215,13 +215,15 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
|
||||
sourceElement,
|
||||
argumentText,
|
||||
severity,
|
||||
FirDiagnosticFactory1(name, severity)
|
||||
FirDiagnosticFactory1(name, severity),
|
||||
SourceElementPositioningStrategy.DEFAULT
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
|
||||
sourceElement,
|
||||
argumentText,
|
||||
severity,
|
||||
FirDiagnosticFactory1<PsiElement, String>(name, severity)
|
||||
FirDiagnosticFactory1<PsiElement, String>(name, severity),
|
||||
SourceElementPositioningStrategy.DEFAULT
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -276,7 +278,10 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
|
||||
}
|
||||
|
||||
private fun createCollector(session: FirSession): AbstractDiagnosticCollector {
|
||||
return FirDiagnosticsCollector.create(session, ScopeSession()) // seems this class is obsolete, so do not care about correctness of the scope session here
|
||||
return FirDiagnosticsCollector.create(
|
||||
session,
|
||||
ScopeSession()
|
||||
) // seems this class is obsolete, so do not care about correctness of the scope session here
|
||||
}
|
||||
|
||||
private fun checkCfgDump(testDataFile: File, firFiles: List<FirFile>) {
|
||||
|
||||
+11
-6
@@ -34,36 +34,41 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
|
||||
is FirLightSimpleDiagnostic -> FirPsiSimpleDiagnostic(
|
||||
psiSourceElement,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory0<PsiElement>
|
||||
factory as FirDiagnosticFactory0<PsiElement>,
|
||||
positioningStrategy
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters1<*> -> FirPsiDiagnosticWithParameters1(
|
||||
psiSourceElement,
|
||||
a,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory1<PsiElement, Any?>
|
||||
factory as FirDiagnosticFactory1<PsiElement, Any?>,
|
||||
positioningStrategy
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters2<*, *> -> FirPsiDiagnosticWithParameters2(
|
||||
psiSourceElement,
|
||||
a, b,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory2<PsiElement, Any?, Any?>
|
||||
factory as FirDiagnosticFactory2<PsiElement, Any?, Any?>,
|
||||
positioningStrategy
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters3<*, *, *> -> FirPsiDiagnosticWithParameters3(
|
||||
psiSourceElement,
|
||||
a, b, c,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory3<PsiElement, Any?, Any?, Any?>
|
||||
factory as FirDiagnosticFactory3<PsiElement, Any?, Any?, Any?>,
|
||||
positioningStrategy
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters4<*, *, *, *> -> FirPsiDiagnosticWithParameters4(
|
||||
psiSourceElement,
|
||||
a, b, c, d,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory4<PsiElement, Any?, Any?, Any?, Any?>
|
||||
factory as FirDiagnosticFactory4<PsiElement, Any?, Any?, Any?, Any?>,
|
||||
positioningStrategy
|
||||
)
|
||||
else -> error("Unknown diagnostic type ${this::class.simpleName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user