Skip to content

Commit

Permalink
[FIR] Introduce & use "multiplexing" SourceElementPositioningStrategy
Browse files Browse the repository at this point in the history
  • Loading branch information
mglukhikh committed Nov 26, 2020
1 parent f3334b0 commit 915a66f
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement
sealed class FirDiagnostic<out E : FirSourceElement> : UnboundDiagnostic {
abstract val element: E
abstract override val severity: Severity
abstract override val factory: AbstractFirDiagnosticFactory<*, *>
abstract override val factory: AbstractFirDiagnosticFactory<*, *, *>

override val textRanges: List<TextRange>
get() = factory.getTextRanges(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement

sealed class AbstractFirDiagnosticFactory<out E : FirSourceElement, D : FirDiagnostic<E>>(
sealed class AbstractFirDiagnosticFactory<out E : FirSourceElement, D : FirDiagnostic<E>, P : PsiElement>(
override var name: String?,
override val severity: Severity,
val positioningStrategy: LightTreePositioningStrategy,
val positioningStrategy: SourceElementPositioningStrategy<P>,
) : DiagnosticFactory<D>(name, severity) {
abstract val firRenderer: FirDiagnosticRenderer<D>

Expand All @@ -32,15 +32,15 @@ sealed class AbstractFirDiagnosticFactory<out E : FirSourceElement, D : FirDiagn

fun isValid(diagnostic: FirDiagnostic<*>): Boolean {
val element = diagnostic.element
return positioningStrategy.isValid(element.lighterASTNode, element.treeStructure)
return positioningStrategy.isValid(element)
}
}

class FirDiagnosticFactory0<E : FirSourceElement, P : PsiElement>(
name: String,
severity: Severity,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirSimpleDiagnostic<E>>(name, severity, positioningStrategy) {
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirSimpleDiagnostic<E>, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer<FirSimpleDiagnostic<E>> = SimpleFirDiagnosticRenderer("")

fun on(element: E): FirSimpleDiagnostic<E> {
Expand All @@ -57,8 +57,8 @@ class FirDiagnosticFactory0<E : FirSourceElement, P : PsiElement>(
class FirDiagnosticFactory1<E : FirSourceElement, P : PsiElement, A : Any>(
name: String,
severity: Severity,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters1<E, A>>(name, severity, positioningStrategy) {
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters1<E, A>, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters1<E, A>> = FirDiagnosticWithParameters1Renderer(
"{0}",
FirDiagnosticRenderers.TO_STRING
Expand All @@ -78,8 +78,8 @@ class FirDiagnosticFactory1<E : FirSourceElement, P : PsiElement, A : Any>(
class FirDiagnosticFactory2<E : FirSourceElement, P : PsiElement, A : Any, B : Any>(
name: String,
severity: Severity,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters2<E, A, B>>(name, severity, positioningStrategy) {
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters2<E, A, B>, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters2<E, A, B>> = FirDiagnosticWithParameters2Renderer(
"{0}, {1}",
FirDiagnosticRenderers.TO_STRING,
Expand All @@ -100,8 +100,8 @@ class FirDiagnosticFactory2<E : FirSourceElement, P : PsiElement, A : Any, B : A
class FirDiagnosticFactory3<E : FirSourceElement, P : PsiElement, A : Any, B : Any, C : Any>(
name: String,
severity: Severity,
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters3<E, A, B, C>>(name, severity, positioningStrategy) {
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT,
) : AbstractFirDiagnosticFactory<E, FirDiagnosticWithParameters3<E, A, B, C>, P>(name, severity, positioningStrategy) {
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters3<E, A, B, C>> = FirDiagnosticWithParameters3Renderer(
"{0}, {1}, {2}",
FirDiagnosticRenderers.TO_STRING,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,49 +12,49 @@ import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

fun <E : FirSourceElement, P : PsiElement> warning0(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory0DelegateProvider<E, P> {
return DiagnosticFactory0DelegateProvider(Severity.WARNING, positioningStrategy)
}

fun <E : FirSourceElement, P : PsiElement, A : Any> warning1(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory1DelegateProvider<E, P, A> {
return DiagnosticFactory1DelegateProvider(Severity.WARNING, positioningStrategy)
}

fun <E : FirSourceElement, P : PsiElement, A : Any, B : Any> warning2(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory2DelegateProvider<E, P, A, B> {
return DiagnosticFactory2DelegateProvider(Severity.WARNING, positioningStrategy)
}

fun <E : FirSourceElement, P : PsiElement, A : Any, B : Any, C : Any> warning3(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory3DelegateProvider<E, P, A, B, C> {
return DiagnosticFactory3DelegateProvider(Severity.WARNING, positioningStrategy)
}

fun <E : FirSourceElement, P : PsiElement> error0(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory0DelegateProvider<E, P> {
return DiagnosticFactory0DelegateProvider(Severity.ERROR, positioningStrategy)
}

fun <E : FirSourceElement, P : PsiElement, A : Any> error1(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory1DelegateProvider<E, P, A> {
return DiagnosticFactory1DelegateProvider(Severity.ERROR, positioningStrategy)
}

fun <E : FirSourceElement, P : PsiElement, A : Any, B : Any> error2(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory2DelegateProvider<E, P, A, B> {
return DiagnosticFactory2DelegateProvider(Severity.ERROR, positioningStrategy)
}

fun <E : FirSourceElement, P : PsiElement, A : Any, B : Any, C : Any> error3(
positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory3DelegateProvider<E, P, A, B, C> {
return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy)
}
Expand All @@ -64,26 +64,26 @@ fun <E : FirSourceElement, P : PsiElement, A : Any, B : Any, C : Any> error3(
* that takes `PsiElement` as first type parameter
*/
fun <E : FirSourceElement, P : PsiElement> existing0(): DiagnosticFactory0DelegateProvider<E, P> {
return DiagnosticFactory0DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT)
return DiagnosticFactory0DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT)
}

fun <E : FirSourceElement, P : PsiElement, A : Any> existing1(): DiagnosticFactory1DelegateProvider<E, P, A> {
return DiagnosticFactory1DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT)
return DiagnosticFactory1DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT)
}

fun <E : FirSourceElement, P : PsiElement, A : Any, B : Any> existing2(): DiagnosticFactory2DelegateProvider<E, P, A, B> {
return DiagnosticFactory2DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT)
return DiagnosticFactory2DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT)
}

fun <E : FirSourceElement, P : PsiElement, A : Any, B : Any, C : Any> existing3(): DiagnosticFactory3DelegateProvider<E, P, A, B, C> {
return DiagnosticFactory3DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT)
return DiagnosticFactory3DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT)
}

// ------------------------------ Providers ------------------------------

class DiagnosticFactory0DelegateProvider<E : FirSourceElement, P : PsiElement>(
private val severity: Severity,
private val positioningStrategy: LightTreePositioningStrategy
private val positioningStrategy: SourceElementPositioningStrategy<P>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory0<E, P>> {
return DummyDelegate(FirDiagnosticFactory0(prop.name, severity, positioningStrategy))
Expand All @@ -92,7 +92,7 @@ class DiagnosticFactory0DelegateProvider<E : FirSourceElement, P : PsiElement>(

class DiagnosticFactory1DelegateProvider<E : FirSourceElement, P : PsiElement, A : Any>(
private val severity: Severity,
private val positioningStrategy: LightTreePositioningStrategy
private val positioningStrategy: SourceElementPositioningStrategy<P>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory1<E, P, A>> {
return DummyDelegate(FirDiagnosticFactory1(prop.name, severity, positioningStrategy))
Expand All @@ -101,7 +101,7 @@ class DiagnosticFactory1DelegateProvider<E : FirSourceElement, P : PsiElement, A

class DiagnosticFactory2DelegateProvider<E : FirSourceElement, P : PsiElement, A : Any, B : Any>(
private val severity: Severity,
private val positioningStrategy: LightTreePositioningStrategy
private val positioningStrategy: SourceElementPositioningStrategy<P>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory2<E, P, A, B>> {
return DummyDelegate(FirDiagnosticFactory2(prop.name, severity, positioningStrategy))
Expand All @@ -110,7 +110,7 @@ class DiagnosticFactory2DelegateProvider<E : FirSourceElement, P : PsiElement, A

class DiagnosticFactory3DelegateProvider<E : FirSourceElement, P : PsiElement, A : Any, B : Any, C : Any>(
private val severity: Severity,
private val positioningStrategy: LightTreePositioningStrategy
private val positioningStrategy: SourceElementPositioningStrategy<P>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory3<E, P, A, B, C>> {
return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, positioningStrategy))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticParameterRenderer
import org.jetbrains.kotlin.fir.FirSourceElement

class FirDiagnosticFactoryToRendererMap(val name: String) {
private val renderersMap: MutableMap<AbstractFirDiagnosticFactory<*, *>, FirDiagnosticRenderer<*>> = mutableMapOf()
private val renderersMap: MutableMap<AbstractFirDiagnosticFactory<*, *, *>, FirDiagnosticRenderer<*>> = mutableMapOf()
val psiDiagnosticMap: DiagnosticFactoryToRendererMap = DiagnosticFactoryToRendererMap()

operator fun get(factory: AbstractFirDiagnosticFactory<*, *>): FirDiagnosticRenderer<*>? = renderersMap[factory]
operator fun get(factory: AbstractFirDiagnosticFactory<*, *, *>): FirDiagnosticRenderer<*>? = renderersMap[factory]

fun <E : FirSourceElement> put(factory: FirDiagnosticFactory0<E, *>, message: String) {
put(factory, SimpleFirDiagnosticRenderer<E>(message))
Expand Down Expand Up @@ -46,7 +46,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) {
put(factory, FirDiagnosticWithParameters3Renderer<E, A, B, C>(message, rendererA, rendererB, rendererC))
}

private fun put(factory: AbstractFirDiagnosticFactory<*, *>, renderer: FirDiagnosticRenderer<*>) {
private fun put(factory: AbstractFirDiagnosticFactory<*, *, *>, renderer: FirDiagnosticRenderer<*>) {
renderersMap[factory] = renderer
psiDiagnosticMap.put(factory, renderer)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@ object FirErrors {
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0<FirSourceElement, PsiElement>()

// Constructor problems
val CONSTRUCTOR_IN_OBJECT by error0<FirSourceElement, KtDeclaration>(LightTreePositioningStrategies.DECLARATION_SIGNATURE)
val CONSTRUCTOR_IN_INTERFACE by error0<FirSourceElement, KtDeclaration>(LightTreePositioningStrategies.DECLARATION_SIGNATURE)
val CONSTRUCTOR_IN_OBJECT by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val CONSTRUCTOR_IN_INTERFACE by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by existing0<FirSourceElement, PsiElement>()
val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by existing0<FirSourceElement, PsiElement>()
val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning0<FirSourceElement, PsiElement>()
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0<FirSourceElement, PsiElement>(LightTreePositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning0<FirSourceElement, PsiElement>()
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0<FirSourceElement, PsiElement>(LightTreePositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
val SEALED_CLASS_CONSTRUCTOR_CALL by error0<FirSourceElement, PsiElement>()

// Annotations
Expand All @@ -91,17 +91,17 @@ object FirErrors {
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by existing0<FirSourceElement, KtExpression>()
val NOT_AN_ANNOTATION_CLASS by error1<FirSourceElement, PsiElement, String>()
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing0<FirSourceElement, KtTypeReference>()
val VAR_ANNOTATION_PARAMETER by error0<FirSourceElement, KtParameter>(LightTreePositioningStrategies.VAL_OR_VAR_NODE)
val VAR_ANNOTATION_PARAMETER by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)

// Exposed visibility group
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(LightTreePositioningStrategies.DECLARATION_NAME)
val EXPOSED_FUNCTION_RETURN_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(LightTreePositioningStrategies.DECLARATION_NAME)
val EXPOSED_RECEIVER_TYPE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(LightTreePositioningStrategies.DECLARATION_NAME)
val EXPOSED_PROPERTY_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(LightTreePositioningStrategies.DECLARATION_NAME)
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_FUNCTION_RETURN_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_RECEIVER_TYPE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_PROPERTY_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_PARAMETER_TYPE by error3<FirSourceElement, KtParameter, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(/* // NB: for parameter FE 1.0 reports not on a name for some reason */)
val EXPOSED_SUPER_INTERFACE by error3<FirSourceElement, KtSuperTypeListEntry, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(LightTreePositioningStrategies.DECLARATION_NAME)
val EXPOSED_SUPER_CLASS by error3<FirSourceElement, KtSuperTypeListEntry, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(LightTreePositioningStrategies.DECLARATION_NAME)
val EXPOSED_TYPE_PARAMETER_BOUND by error3<FirSourceElement, KtTypeParameter, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(LightTreePositioningStrategies.DECLARATION_NAME)
val EXPOSED_SUPER_INTERFACE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_SUPER_CLASS by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_TYPE_PARAMETER_BOUND by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()

// Modifiers
val INAPPLICABLE_INFIX_MODIFIER by existing1<FirSourceElement, PsiElement, String>()
Expand Down Expand Up @@ -144,11 +144,11 @@ object FirErrors {
val ANY_METHOD_IMPLEMENTED_IN_INTERFACE by error0<FirSourceElement, PsiElement>()

// Invalid local declarations
val LOCAL_OBJECT_NOT_ALLOWED by error1<FirSourceElement, PsiElement, Name>(LightTreePositioningStrategies.DECLARATION_NAME)
val LOCAL_INTERFACE_NOT_ALLOWED by error1<FirSourceElement, PsiElement, Name>(LightTreePositioningStrategies.DECLARATION_NAME)
val LOCAL_OBJECT_NOT_ALLOWED by error1<FirSourceElement, KtNamedDeclaration, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)
val LOCAL_INTERFACE_NOT_ALLOWED by error1<FirSourceElement, KtNamedDeclaration, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)

// Control flow diagnostics
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>(LightTreePositioningStrategies.DECLARATION_SIGNATURE)
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>()
val WRONG_INVOCATION_KIND by warning3<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>, EventOccurrencesRange, EventOccurrencesRange>()
val LEAKED_IN_PLACE_LAMBDA by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>()
val WRONG_IMPLIES_CONDITION by error0<FirSourceElement, PsiElement>()
Expand Down
Loading

0 comments on commit 915a66f

Please sign in to comment.