diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt index 2307c8220e613..ac9747f0b073e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnostic.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement sealed class FirDiagnostic : UnboundDiagnostic { abstract val element: E abstract override val severity: Severity - abstract override val factory: AbstractFirDiagnosticFactory<*, *> + abstract override val factory: AbstractFirDiagnosticFactory<*, *, *> override val textRanges: List get() = factory.getTextRanges(this) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactory.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactory.kt index d8428c7053a17..78b5e8ebacd92 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactory.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactory.kt @@ -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>( +sealed class AbstractFirDiagnosticFactory, P : PsiElement>( override var name: String?, override val severity: Severity, - val positioningStrategy: LightTreePositioningStrategy, + val positioningStrategy: SourceElementPositioningStrategy

, ) : DiagnosticFactory(name, severity) { abstract val firRenderer: FirDiagnosticRenderer @@ -32,15 +32,15 @@ sealed class AbstractFirDiagnosticFactory): Boolean { val element = diagnostic.element - return positioningStrategy.isValid(element.lighterASTNode, element.treeStructure) + return positioningStrategy.isValid(element) } } class FirDiagnosticFactory0( name: String, severity: Severity, - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT, -) : AbstractFirDiagnosticFactory>(name, severity, positioningStrategy) { + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT, +) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) { override val firRenderer: FirDiagnosticRenderer> = SimpleFirDiagnosticRenderer("") fun on(element: E): FirSimpleDiagnostic { @@ -57,8 +57,8 @@ class FirDiagnosticFactory0( class FirDiagnosticFactory1( name: String, severity: Severity, - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT, -) : AbstractFirDiagnosticFactory>(name, severity, positioningStrategy) { + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT, +) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) { override val firRenderer: FirDiagnosticRenderer> = FirDiagnosticWithParameters1Renderer( "{0}", FirDiagnosticRenderers.TO_STRING @@ -78,8 +78,8 @@ class FirDiagnosticFactory1( class FirDiagnosticFactory2( name: String, severity: Severity, - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT, -) : AbstractFirDiagnosticFactory>(name, severity, positioningStrategy) { + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT, +) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) { override val firRenderer: FirDiagnosticRenderer> = FirDiagnosticWithParameters2Renderer( "{0}, {1}", FirDiagnosticRenderers.TO_STRING, @@ -100,8 +100,8 @@ class FirDiagnosticFactory2( name: String, severity: Severity, - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT, -) : AbstractFirDiagnosticFactory>(name, severity, positioningStrategy) { + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT, +) : AbstractFirDiagnosticFactory, P>(name, severity, positioningStrategy) { override val firRenderer: FirDiagnosticRenderer> = FirDiagnosticWithParameters3Renderer( "{0}, {1}, {2}", FirDiagnosticRenderers.TO_STRING, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt index 37a46ae40bcbe..21fdf5540c612 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt @@ -12,49 +12,49 @@ import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty fun warning0( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory0DelegateProvider { return DiagnosticFactory0DelegateProvider(Severity.WARNING, positioningStrategy) } fun warning1( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory1DelegateProvider { return DiagnosticFactory1DelegateProvider(Severity.WARNING, positioningStrategy) } fun warning2( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory2DelegateProvider { return DiagnosticFactory2DelegateProvider(Severity.WARNING, positioningStrategy) } fun warning3( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory3DelegateProvider { return DiagnosticFactory3DelegateProvider(Severity.WARNING, positioningStrategy) } fun error0( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory0DelegateProvider { return DiagnosticFactory0DelegateProvider(Severity.ERROR, positioningStrategy) } fun error1( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory1DelegateProvider { return DiagnosticFactory1DelegateProvider(Severity.ERROR, positioningStrategy) } fun error2( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory2DelegateProvider { return DiagnosticFactory2DelegateProvider(Severity.ERROR, positioningStrategy) } fun error3( - positioningStrategy: LightTreePositioningStrategy = LightTreePositioningStrategy.DEFAULT + positioningStrategy: SourceElementPositioningStrategy

= SourceElementPositioningStrategy.DEFAULT ): DiagnosticFactory3DelegateProvider { return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy) } @@ -64,26 +64,26 @@ fun error3( * that takes `PsiElement` as first type parameter */ fun existing0(): DiagnosticFactory0DelegateProvider { - return DiagnosticFactory0DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) + return DiagnosticFactory0DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) } fun existing1(): DiagnosticFactory1DelegateProvider { - return DiagnosticFactory1DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) + return DiagnosticFactory1DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) } fun existing2(): DiagnosticFactory2DelegateProvider { - return DiagnosticFactory2DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) + return DiagnosticFactory2DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) } fun existing3(): DiagnosticFactory3DelegateProvider { - return DiagnosticFactory3DelegateProvider(Severity.ERROR, LightTreePositioningStrategy.DEFAULT) + return DiagnosticFactory3DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) } // ------------------------------ Providers ------------------------------ class DiagnosticFactory0DelegateProvider( private val severity: Severity, - private val positioningStrategy: LightTreePositioningStrategy + private val positioningStrategy: SourceElementPositioningStrategy

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

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

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

) { operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty> { return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, positioningStrategy)) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt index 362a11fd8f2a7..910e196d50ce5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryToRendererMap.kt @@ -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, FirDiagnosticRenderer<*>> = mutableMapOf() + private val renderersMap: MutableMap, FirDiagnosticRenderer<*>> = mutableMapOf() val psiDiagnosticMap: DiagnosticFactoryToRendererMap = DiagnosticFactoryToRendererMap() - operator fun get(factory: AbstractFirDiagnosticFactory<*, *>): FirDiagnosticRenderer<*>? = renderersMap[factory] + operator fun get(factory: AbstractFirDiagnosticFactory<*, *, *>): FirDiagnosticRenderer<*>? = renderersMap[factory] fun put(factory: FirDiagnosticFactory0, message: String) { put(factory, SimpleFirDiagnosticRenderer(message)) @@ -46,7 +46,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) { put(factory, FirDiagnosticWithParameters3Renderer(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) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index fefec26e9d0a5..02e8527602e58 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -66,16 +66,16 @@ object FirErrors { val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0() // Constructor problems - val CONSTRUCTOR_IN_OBJECT by error0(LightTreePositioningStrategies.DECLARATION_SIGNATURE) - val CONSTRUCTOR_IN_INTERFACE by error0(LightTreePositioningStrategies.DECLARATION_SIGNATURE) + val CONSTRUCTOR_IN_OBJECT by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + val CONSTRUCTOR_IN_INTERFACE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by existing0() val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by existing0() val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning0() - val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0(LightTreePositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) + val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0() val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0() val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning0() - val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0(LightTreePositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) + val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SEALED_CLASS_CONSTRUCTOR_CALL by error0() // Annotations @@ -91,17 +91,17 @@ object FirErrors { val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by existing0() val NOT_AN_ANNOTATION_CLASS by error1() val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing0() - val VAR_ANNOTATION_PARAMETER by error0(LightTreePositioningStrategies.VAL_OR_VAR_NODE) + val VAR_ANNOTATION_PARAMETER by error0(SourceElementPositioningStrategies.VAL_OR_VAR_NODE) // Exposed visibility group - val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3(LightTreePositioningStrategies.DECLARATION_NAME) - val EXPOSED_FUNCTION_RETURN_TYPE by error3(LightTreePositioningStrategies.DECLARATION_NAME) - val EXPOSED_RECEIVER_TYPE by error3(LightTreePositioningStrategies.DECLARATION_NAME) - val EXPOSED_PROPERTY_TYPE by error3(LightTreePositioningStrategies.DECLARATION_NAME) + val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3(SourceElementPositioningStrategies.DECLARATION_NAME) + val EXPOSED_FUNCTION_RETURN_TYPE by error3(SourceElementPositioningStrategies.DECLARATION_NAME) + val EXPOSED_RECEIVER_TYPE by error3() + val EXPOSED_PROPERTY_TYPE by error3(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_PARAMETER_TYPE by error3(/* // NB: for parameter FE 1.0 reports not on a name for some reason */) - val EXPOSED_SUPER_INTERFACE by error3(LightTreePositioningStrategies.DECLARATION_NAME) - val EXPOSED_SUPER_CLASS by error3(LightTreePositioningStrategies.DECLARATION_NAME) - val EXPOSED_TYPE_PARAMETER_BOUND by error3(LightTreePositioningStrategies.DECLARATION_NAME) + val EXPOSED_SUPER_INTERFACE by error3() + val EXPOSED_SUPER_CLASS by error3() + val EXPOSED_TYPE_PARAMETER_BOUND by error3() // Modifiers val INAPPLICABLE_INFIX_MODIFIER by existing1() @@ -144,11 +144,11 @@ object FirErrors { val ANY_METHOD_IMPLEMENTED_IN_INTERFACE by error0() // Invalid local declarations - val LOCAL_OBJECT_NOT_ALLOWED by error1(LightTreePositioningStrategies.DECLARATION_NAME) - val LOCAL_INTERFACE_NOT_ALLOWED by error1(LightTreePositioningStrategies.DECLARATION_NAME) + val LOCAL_OBJECT_NOT_ALLOWED by error1(SourceElementPositioningStrategies.DECLARATION_NAME) + val LOCAL_INTERFACE_NOT_ALLOWED by error1(SourceElementPositioningStrategies.DECLARATION_NAME) // Control flow diagnostics - val UNINITIALIZED_VARIABLE by error1(LightTreePositioningStrategies.DECLARATION_SIGNATURE) + val UNINITIALIZED_VARIABLE by error1() val WRONG_INVOCATION_KIND by warning3, EventOccurrencesRange, EventOccurrencesRange>() val LEAKED_IN_PLACE_LAMBDA by error1>() val WRONG_IMPLIES_CONDITION by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt new file mode 100644 index 0000000000000..f27903dfcc502 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.diagnostics + +import org.jetbrains.kotlin.diagnostics.PositioningStrategies + +object SourceElementPositioningStrategies { + internal val DEFAULT = SourceElementPositioningStrategy( + LightTreePositioningStrategies.DEFAULT, + PositioningStrategies.DEFAULT + ) + + val VAL_OR_VAR_NODE = SourceElementPositioningStrategy( + LightTreePositioningStrategies.VAL_OR_VAR_NODE, + PositioningStrategies.VAL_OR_VAR_NODE + ) + + val SECONDARY_CONSTRUCTOR_DELEGATION_CALL = SourceElementPositioningStrategy( + LightTreePositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL, + PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL + ) + + val DECLARATION_NAME = SourceElementPositioningStrategy( + LightTreePositioningStrategies.DECLARATION_NAME, + PositioningStrategies.DECLARATION_NAME + ) + + val DECLARATION_SIGNATURE = SourceElementPositioningStrategy( + LightTreePositioningStrategies.DECLARATION_SIGNATURE, + PositioningStrategies.DECLARATION_SIGNATURE + ) +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategy.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategy.kt new file mode 100644 index 0000000000000..f4b47aeea2557 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategy.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.diagnostics + +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.diagnostics.PositioningStrategy +import org.jetbrains.kotlin.fir.FirPsiSourceElement +import org.jetbrains.kotlin.fir.FirSourceElement + +open class SourceElementPositioningStrategy( + val lightTreeStrategy: LightTreePositioningStrategy, + val psiStrategy: PositioningStrategy +) { + fun markDiagnostic(diagnostic: FirDiagnostic<*>): List { + val element = diagnostic.element + if (element is FirPsiSourceElement<*>) { + return psiStrategy.mark(element.psi as E) + } + return lightTreeStrategy.mark(element.lighterASTNode, element.treeStructure) + } + + fun isValid(element: FirSourceElement): Boolean { + if (element is FirPsiSourceElement<*>) { + return psiStrategy.isValid(element.psi as E) + } + return lightTreeStrategy.isValid(element.lighterASTNode, element.treeStructure) + } + + companion object { + val DEFAULT: SourceElementPositioningStrategy = SourceElementPositioningStrategies.DEFAULT + } +} \ No newline at end of file