[FIR] Safe KClass of PSI type in diagnostic factory
This commit is contained in:
+17
-10
@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.diagnostics.Severity
|
|||||||
import org.jetbrains.kotlin.fir.FirLightSourceElement
|
import org.jetbrains.kotlin.fir.FirLightSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirPsiSourceElement
|
import org.jetbrains.kotlin.fir.FirPsiSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@RequiresOptIn("Please use DiagnosticReporter.reportOn method if possible")
|
@RequiresOptIn("Please use DiagnosticReporter.reportOn method if possible")
|
||||||
annotation class InternalDiagnosticFactoryMethod
|
annotation class InternalDiagnosticFactoryMethod
|
||||||
@@ -15,6 +16,7 @@ sealed class AbstractFirDiagnosticFactory<D : FirDiagnostic<*>, P : PsiElement>(
|
|||||||
val name: String,
|
val name: String,
|
||||||
val severity: Severity,
|
val severity: Severity,
|
||||||
val defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
val defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
|
val psiType: KClass<*>
|
||||||
) {
|
) {
|
||||||
abstract val firRenderer: FirDiagnosticRenderer<D>
|
abstract val firRenderer: FirDiagnosticRenderer<D>
|
||||||
}
|
}
|
||||||
@@ -22,8 +24,9 @@ sealed class AbstractFirDiagnosticFactory<D : FirDiagnostic<*>, P : PsiElement>(
|
|||||||
class FirDiagnosticFactory0<P : PsiElement>(
|
class FirDiagnosticFactory0<P : PsiElement>(
|
||||||
name: String,
|
name: String,
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
) : AbstractFirDiagnosticFactory<FirSimpleDiagnostic<*>, P>(name, severity, defaultPositioningStrategy) {
|
psiType: KClass<*>
|
||||||
|
) : AbstractFirDiagnosticFactory<FirSimpleDiagnostic<*>, P>(name, severity, defaultPositioningStrategy, psiType) {
|
||||||
override val firRenderer: FirDiagnosticRenderer<FirSimpleDiagnostic<*>> = SimpleFirDiagnosticRenderer("")
|
override val firRenderer: FirDiagnosticRenderer<FirSimpleDiagnostic<*>> = SimpleFirDiagnosticRenderer("")
|
||||||
|
|
||||||
@InternalDiagnosticFactoryMethod
|
@InternalDiagnosticFactoryMethod
|
||||||
@@ -44,8 +47,9 @@ class FirDiagnosticFactory0<P : PsiElement>(
|
|||||||
class FirDiagnosticFactory1<P : PsiElement, A>(
|
class FirDiagnosticFactory1<P : PsiElement, A>(
|
||||||
name: String,
|
name: String,
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters1<*, A>, P>(name, severity, defaultPositioningStrategy) {
|
psiType: KClass<*>
|
||||||
|
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters1<*, A>, P>(name, severity, defaultPositioningStrategy, psiType) {
|
||||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters1<*, A>> = FirDiagnosticWithParameters1Renderer(
|
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters1<*, A>> = FirDiagnosticWithParameters1Renderer(
|
||||||
"{0}",
|
"{0}",
|
||||||
FirDiagnosticRenderers.TO_STRING
|
FirDiagnosticRenderers.TO_STRING
|
||||||
@@ -76,8 +80,9 @@ class FirDiagnosticFactory1<P : PsiElement, A>(
|
|||||||
class FirDiagnosticFactory2<P : PsiElement, A, B>(
|
class FirDiagnosticFactory2<P : PsiElement, A, B>(
|
||||||
name: String,
|
name: String,
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters2<*, A, B>, P>(name, severity, defaultPositioningStrategy) {
|
psiType: KClass<*>
|
||||||
|
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters2<*, A, B>, P>(name, severity, defaultPositioningStrategy, psiType) {
|
||||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters2<*, A, B>> = FirDiagnosticWithParameters2Renderer(
|
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters2<*, A, B>> = FirDiagnosticWithParameters2Renderer(
|
||||||
"{0}, {1}",
|
"{0}, {1}",
|
||||||
FirDiagnosticRenderers.TO_STRING,
|
FirDiagnosticRenderers.TO_STRING,
|
||||||
@@ -111,8 +116,9 @@ class FirDiagnosticFactory2<P : PsiElement, A, B>(
|
|||||||
class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
|
class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
|
||||||
name: String,
|
name: String,
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters3<*, A, B, C>, P>(name, severity, defaultPositioningStrategy) {
|
psiType: KClass<*>
|
||||||
|
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters3<*, A, B, C>, P>(name, severity, defaultPositioningStrategy, psiType) {
|
||||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters3<*, A, B, C>> = FirDiagnosticWithParameters3Renderer(
|
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters3<*, A, B, C>> = FirDiagnosticWithParameters3Renderer(
|
||||||
"{0}, {1}, {2}",
|
"{0}, {1}, {2}",
|
||||||
FirDiagnosticRenderers.TO_STRING,
|
FirDiagnosticRenderers.TO_STRING,
|
||||||
@@ -149,8 +155,9 @@ class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
|
|||||||
class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
|
class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
|
||||||
name: String,
|
name: String,
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
defaultPositioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
|
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters4<*, A, B, C, D>, P>(name, severity, defaultPositioningStrategy) {
|
psiType: KClass<*>
|
||||||
|
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters4<*, A, B, C, D>, P>(name, severity, defaultPositioningStrategy, psiType) {
|
||||||
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters4<*, A, B, C, D>> = FirDiagnosticWithParameters4Renderer(
|
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters4<*, A, B, C, D>> = FirDiagnosticWithParameters4Renderer(
|
||||||
"{0}, {1}, {2}, {3}",
|
"{0}, {1}, {2}, {3}",
|
||||||
FirDiagnosticRenderers.TO_STRING,
|
FirDiagnosticRenderers.TO_STRING,
|
||||||
|
|||||||
+34
-28
@@ -8,106 +8,112 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
fun <P : PsiElement> warning0(
|
inline fun <reified P : PsiElement> warning0(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory0DelegateProvider<P> {
|
): DiagnosticFactory0DelegateProvider<P> {
|
||||||
return DiagnosticFactory0DelegateProvider(Severity.WARNING, positioningStrategy)
|
return DiagnosticFactory0DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement, A> warning1(
|
inline fun <reified P : PsiElement, A> warning1(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory1DelegateProvider<P, A> {
|
): DiagnosticFactory1DelegateProvider<P, A> {
|
||||||
return DiagnosticFactory1DelegateProvider(Severity.WARNING, positioningStrategy)
|
return DiagnosticFactory1DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement, A, B> warning2(
|
inline fun <reified P : PsiElement, A, B> warning2(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory2DelegateProvider<P, A, B> {
|
): DiagnosticFactory2DelegateProvider<P, A, B> {
|
||||||
return DiagnosticFactory2DelegateProvider(Severity.WARNING, positioningStrategy)
|
return DiagnosticFactory2DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement, A, B, C> warning3(
|
inline fun <reified P : PsiElement, A, B, C> warning3(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory3DelegateProvider<P, A, B, C> {
|
): DiagnosticFactory3DelegateProvider<P, A, B, C> {
|
||||||
return DiagnosticFactory3DelegateProvider(Severity.WARNING, positioningStrategy)
|
return DiagnosticFactory3DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement> error0(
|
inline fun <reified P : PsiElement> error0(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory0DelegateProvider<P> {
|
): DiagnosticFactory0DelegateProvider<P> {
|
||||||
return DiagnosticFactory0DelegateProvider(Severity.ERROR, positioningStrategy)
|
return DiagnosticFactory0DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement, A> error1(
|
inline fun <reified P : PsiElement, A> error1(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory1DelegateProvider<P, A> {
|
): DiagnosticFactory1DelegateProvider<P, A> {
|
||||||
return DiagnosticFactory1DelegateProvider(Severity.ERROR, positioningStrategy)
|
return DiagnosticFactory1DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement, A, B> error2(
|
inline fun <reified P : PsiElement, A, B> error2(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory2DelegateProvider<P, A, B> {
|
): DiagnosticFactory2DelegateProvider<P, A, B> {
|
||||||
return DiagnosticFactory2DelegateProvider(Severity.ERROR, positioningStrategy)
|
return DiagnosticFactory2DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement, A, B, C> error3(
|
inline fun <reified P : PsiElement, A, B, C> error3(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory3DelegateProvider<P, A, B, C> {
|
): DiagnosticFactory3DelegateProvider<P, A, B, C> {
|
||||||
return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy)
|
return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : PsiElement, A, B, C, D> error4(
|
inline fun <reified P : PsiElement, A, B, C, D> error4(
|
||||||
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
|
||||||
): DiagnosticFactory4DelegateProvider<P, A, B, C, D> {
|
): DiagnosticFactory4DelegateProvider<P, A, B, C, D> {
|
||||||
return DiagnosticFactory4DelegateProvider(Severity.ERROR, positioningStrategy)
|
return DiagnosticFactory4DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------ Providers ------------------------------
|
// ------------------------------ Providers ------------------------------
|
||||||
|
|
||||||
class DiagnosticFactory0DelegateProvider<P : PsiElement>(
|
class DiagnosticFactory0DelegateProvider<P : PsiElement>(
|
||||||
private val severity: Severity,
|
private val severity: Severity,
|
||||||
private val positioningStrategy: SourceElementPositioningStrategy<P>
|
private val positioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
|
private val psiType: KClass<*>
|
||||||
) {
|
) {
|
||||||
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory0<P>> {
|
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory0<P>> {
|
||||||
return DummyDelegate(FirDiagnosticFactory0(prop.name, severity, positioningStrategy))
|
return DummyDelegate(FirDiagnosticFactory0(prop.name, severity, positioningStrategy, psiType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiagnosticFactory1DelegateProvider<P : PsiElement, A>(
|
class DiagnosticFactory1DelegateProvider<P : PsiElement, A>(
|
||||||
private val severity: Severity,
|
private val severity: Severity,
|
||||||
private val positioningStrategy: SourceElementPositioningStrategy<P>
|
private val positioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
|
private val psiType: KClass<*>
|
||||||
) {
|
) {
|
||||||
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory1<P, A>> {
|
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory1<P, A>> {
|
||||||
return DummyDelegate(FirDiagnosticFactory1(prop.name, severity, positioningStrategy))
|
return DummyDelegate(FirDiagnosticFactory1(prop.name, severity, positioningStrategy, psiType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiagnosticFactory2DelegateProvider<P : PsiElement, A, B>(
|
class DiagnosticFactory2DelegateProvider<P : PsiElement, A, B>(
|
||||||
private val severity: Severity,
|
private val severity: Severity,
|
||||||
private val positioningStrategy: SourceElementPositioningStrategy<P>
|
private val positioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
|
private val psiType: KClass<*>
|
||||||
) {
|
) {
|
||||||
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory2<P, A, B>> {
|
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory2<P, A, B>> {
|
||||||
return DummyDelegate(FirDiagnosticFactory2(prop.name, severity, positioningStrategy))
|
return DummyDelegate(FirDiagnosticFactory2(prop.name, severity, positioningStrategy, psiType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiagnosticFactory3DelegateProvider<P : PsiElement, A, B, C>(
|
class DiagnosticFactory3DelegateProvider<P : PsiElement, A, B, C>(
|
||||||
private val severity: Severity,
|
private val severity: Severity,
|
||||||
private val positioningStrategy: SourceElementPositioningStrategy<P>
|
private val positioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
|
private val psiType: KClass<*>
|
||||||
) {
|
) {
|
||||||
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory3<P, A, B, C>> {
|
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory3<P, A, B, C>> {
|
||||||
return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, positioningStrategy))
|
return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, positioningStrategy, psiType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiagnosticFactory4DelegateProvider<P : PsiElement, A, B, C, D>(
|
class DiagnosticFactory4DelegateProvider<P : PsiElement, A, B, C, D>(
|
||||||
private val severity: Severity,
|
private val severity: Severity,
|
||||||
private val positioningStrategy: SourceElementPositioningStrategy<P>
|
private val positioningStrategy: SourceElementPositioningStrategy<P>,
|
||||||
|
private val psiType: KClass<*>
|
||||||
) {
|
) {
|
||||||
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory4<P, A, B, C, D>> {
|
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory4<P, A, B, C, D>> {
|
||||||
return DummyDelegate(FirDiagnosticFactory4(prop.name, severity, positioningStrategy))
|
return DummyDelegate(FirDiagnosticFactory4(prop.name, severity, positioningStrategy, psiType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -245,7 +245,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
}
|
}
|
||||||
|
|
||||||
val argumentText = argument()
|
val argumentText = argument()
|
||||||
val factory = FirDiagnosticFactory1<PsiElement, String>(name, severity)
|
val factory = FirDiagnosticFactory1<PsiElement, String>(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class)
|
||||||
return when (positionedElement) {
|
return when (positionedElement) {
|
||||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
|
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
|
||||||
positionedElement,
|
positionedElement,
|
||||||
|
|||||||
@@ -215,14 +215,14 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
|
|||||||
sourceElement,
|
sourceElement,
|
||||||
argumentText,
|
argumentText,
|
||||||
severity,
|
severity,
|
||||||
FirDiagnosticFactory1(name, severity),
|
FirDiagnosticFactory1(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class),
|
||||||
SourceElementPositioningStrategy.DEFAULT
|
SourceElementPositioningStrategy.DEFAULT
|
||||||
)
|
)
|
||||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
|
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
|
||||||
sourceElement,
|
sourceElement,
|
||||||
argumentText,
|
argumentText,
|
||||||
severity,
|
severity,
|
||||||
FirDiagnosticFactory1<PsiElement, String>(name, severity),
|
FirDiagnosticFactory1(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class),
|
||||||
SourceElementPositioningStrategy.DEFAULT
|
SourceElementPositioningStrategy.DEFAULT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user