Add abstract source element and switch diagnostics to it

This commit is contained in:
Ilya Chernikov
2021-09-27 20:08:27 +02:00
parent 524e40708d
commit 9e60c70db7
12 changed files with 181 additions and 54 deletions
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.fir.backend.jvm.jvmTypeMapper
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -40,6 +39,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.types.model.SimpleTypeMarker import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import java.text.StringCharacterIterator import java.text.StringCharacterIterator
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.cli.common.fir package org.jetbrains.kotlin.cli.common.fir
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtLightSourceElement import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
@@ -12,9 +13,9 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
object FirDiagnosticsCompilerResultsReporter { object FirDiagnosticsCompilerResultsReporter {
fun reportDiagnostics(diagnostics: Collection<KtDiagnostic>, reporter: MessageCollector): Boolean { fun reportDiagnostics(diagnostics: Collection<KtDiagnostic>, reporter: MessageCollector): Boolean {
@@ -51,6 +52,7 @@ object FirDiagnosticsCompilerResultsReporter {
private fun KtDiagnostic.location(): CompilerMessageSourceLocation? = when (val element = element) { private fun KtDiagnostic.location(): CompilerMessageSourceLocation? = when (val element = element) {
is KtPsiSourceElement -> element.location(this) is KtPsiSourceElement -> element.location(this)
is KtLightSourceElement -> element.location(this) is KtLightSourceElement -> element.location(this)
else -> element.genericLocation(this)
} }
private fun KtPsiSourceElement.location(diagnostic: KtDiagnostic): CompilerMessageSourceLocation? { private fun KtPsiSourceElement.location(diagnostic: KtDiagnostic): CompilerMessageSourceLocation? {
@@ -64,6 +66,12 @@ object FirDiagnosticsCompilerResultsReporter {
return null return null
} }
@Suppress("UNUSED_PARAMETER")
private fun AbstractKtSourceElement.genericLocation(diagnostic: KtDiagnostic): CompilerMessageSourceLocation? {
// TODO: support generic location
return null
}
private object DiagnosticComparator : Comparator<KtDiagnostic> { private object DiagnosticComparator : Comparator<KtDiagnostic> {
override fun compare(o1: KtDiagnostic, o2: KtDiagnostic): Int { override fun compare(o1: KtDiagnostic, o2: KtDiagnostic): Int {
val element1 = o1.element val element1 = o1.element
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.fir.backend package org.jetbrains.kotlin.fir.backend
import com.intellij.psi.PsiCompiledElement import com.intellij.psi.PsiCompiledElement
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.InlineClassRepresentation import org.jetbrains.kotlin.descriptors.InlineClassRepresentation
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -42,7 +44,10 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
@@ -52,6 +57,7 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
@@ -65,7 +71,7 @@ internal fun <T : IrElement> FirElement.convertWithOffsets(
return source.convertWithOffsets(f) return source.convertWithOffsets(f)
} }
internal fun <T : IrElement> FirSourceElement?.convertWithOffsets( internal fun <T : IrElement> KtSourceElement?.convertWithOffsets(
f: (startOffset: Int, endOffset: Int) -> T f: (startOffset: Int, endOffset: Int) -> T
): T { ): T {
val psi = psi val psi = psi
@@ -466,7 +472,7 @@ internal fun FirReference.statementOrigin(): IrStatementOrigin? {
IrStatementOrigin.FOR_LOOP_ITERATOR IrStatementOrigin.FOR_LOOP_ITERATOR
source?.elementType == KtNodeTypes.OPERATION_REFERENCE -> source?.elementType == KtNodeTypes.OPERATION_REFERENCE ->
nameToOperationConventionOrigin[symbol.callableId.callableName] nameToOperationConventionOrigin[symbol.callableId.callableName]
source?.kind is FirFakeSourceElementKind.DesugaredComponentFunctionCall -> source?.kind is KtFakeSourceElementKind.DesugaredComponentFunctionCall ->
IrStatementOrigin.COMPONENT_N.withIndex(name.asString().removePrefix("component").toInt()) IrStatementOrigin.COMPONENT_N.withIndex(name.asString().removePrefix("component").toInt())
else -> else ->
null null
@@ -631,7 +637,7 @@ fun FirVariableAssignment.getIrAssignmentOrigin(): IrStatementOrigin {
IrStatementOrigin.POSTFIX_DECR IrStatementOrigin.POSTFIX_DECR
} }
if (calleeReference.source?.kind is FirFakeSourceElementKind && if (calleeReference.source?.kind is KtFakeSourceElementKind &&
calleeReferenceSymbol == rValue.explicitReceiver?.toResolvedCallableSymbol() calleeReferenceSymbol == rValue.explicitReceiver?.toResolvedCallableSymbol()
) { ) {
if (callableName == OperatorNameConventions.PLUS) { if (callableName == OperatorNameConventions.PLUS) {
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -625,7 +626,7 @@ class Fir2IrVisitor(
} }
private fun List<FirStatement>.convertToIrExpressionOrBlock( private fun List<FirStatement>.convertToIrExpressionOrBlock(
source: FirSourceElement?, source: KtSourceElement?,
origin: IrStatementOrigin? = null origin: IrStatementOrigin? = null
): IrExpression { ): IrExpression {
if (size == 1) { if (size == 1) {
@@ -7,29 +7,28 @@ package org.jetbrains.kotlin.diagnostics
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtLightSourceElement import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.diagnostics.AbstractSourceElementPositioningStrategy
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.diagnostics.LightTreePositioningStrategy
import org.jetbrains.kotlin.diagnostics.PositioningStrategy
class SourceElementPositioningStrategy( class SourceElementPositioningStrategy(
private val lightTreeStrategy: LightTreePositioningStrategy, private val lightTreeStrategy: LightTreePositioningStrategy,
private val psiStrategy: PositioningStrategy<*> private val psiStrategy: PositioningStrategy<*>,
private val offsetsOnlyPositioningStrategy: OffsetsOnlyPositioningStrategy = OffsetsOnlyPositioningStrategy(),
) : AbstractSourceElementPositioningStrategy() { ) : AbstractSourceElementPositioningStrategy() {
override fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange> { override fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange> {
return when (val element = diagnostic.element) { return when (val element = diagnostic.element) {
is KtPsiSourceElement -> psiStrategy.markDiagnostic(diagnostic) is KtPsiSourceElement -> psiStrategy.markDiagnostic(diagnostic)
is KtLightSourceElement -> lightTreeStrategy.markKtDiagnostic(element, diagnostic) is KtLightSourceElement -> lightTreeStrategy.markKtDiagnostic(element, diagnostic)
else -> offsetsOnlyPositioningStrategy.markKtDiagnostic(element, diagnostic)
} }
} }
override fun isValid(element: KtSourceElement): Boolean { override fun isValid(element: AbstractKtSourceElement): Boolean {
return when (element) { return when (element) {
is KtPsiSourceElement -> psiStrategy.hackyIsValid(element.psi) is KtPsiSourceElement -> psiStrategy.hackyIsValid(element.psi)
is KtLightSourceElement -> lightTreeStrategy.isValid(element.lighterASTNode, element.treeStructure) is KtLightSourceElement -> lightTreeStrategy.isValid(element.lighterASTNode, element.treeStructure)
else -> true
} }
} }
@@ -190,10 +190,19 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() {
object ParameterNameAnnotationCall : KtFakeSourceElementKind() object ParameterNameAnnotationCall : KtFakeSourceElementKind()
} }
sealed class KtSourceElement { abstract class AbstractKtSourceElement {
abstract val elementType: IElementType
abstract val startOffset: Int abstract val startOffset: Int
abstract val endOffset: Int abstract val endOffset: Int
}
class KtOffsetsOnlySourceElement(
override val startOffset: Int,
override val endOffset: Int,
) : AbstractKtSourceElement()
// TODO: consider renaming to something like AstBasedSourceElement
sealed class KtSourceElement : AbstractKtSourceElement() {
abstract val elementType: IElementType
abstract val kind: KtSourceElementKind abstract val kind: KtSourceElementKind
abstract val lighterASTNode: LighterASTNode abstract val lighterASTNode: LighterASTNode
abstract val treeStructure: FlyweightCapableTreeStructure<LighterASTNode> abstract val treeStructure: FlyweightCapableTreeStructure<LighterASTNode>
@@ -390,7 +399,7 @@ class KtLightSourceElement(
} }
} }
val KtSourceElement?.psi: PsiElement? get() = (this as? KtPsiSourceElement)?.psi val AbstractKtSourceElement?.psi: PsiElement? get() = (this as? KtPsiSourceElement)?.psi
val KtSourceElement?.text: CharSequence? val KtSourceElement?.text: CharSequence?
get() = when (this) { get() = when (this) {
@@ -6,27 +6,21 @@
package org.jetbrains.kotlin.diagnostics package org.jetbrains.kotlin.diagnostics
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.AbstractKtSourceElement
abstract class AbstractSourceElementPositioningStrategy { abstract class AbstractSourceElementPositioningStrategy {
abstract fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange> abstract fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange>
abstract fun isValid(element: KtSourceElement): Boolean abstract fun isValid(element: AbstractKtSourceElement): Boolean
companion object { companion object {
private val defaultProxy = object : AbstractSourceElementPositioningStrategy() {
lateinit var currentDefault: AbstractSourceElementPositioningStrategy
override fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange> = currentDefault.markDiagnostic(diagnostic)
override fun isValid(element: KtSourceElement): Boolean = currentDefault.isValid(element)
}
@JvmStatic @JvmStatic
fun setDefault(default: AbstractSourceElementPositioningStrategy) { fun setDefault(default: AbstractSourceElementPositioningStrategy) {
defaultProxy.currentDefault = default DEFAULT = default
} }
val DEFAULT: AbstractSourceElementPositioningStrategy = defaultProxy var DEFAULT: AbstractSourceElementPositioningStrategy = OffsetsOnlyPositioningStrategy()
private set
} }
} }
@@ -8,15 +8,14 @@ package org.jetbrains.kotlin.diagnostics
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtLightSourceElement import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.diagnostics.*
// ------------------------------ diagnostics ------------------------------ // ------------------------------ diagnostics ------------------------------
sealed class KtDiagnostic : DiagnosticMarker { sealed class KtDiagnostic : DiagnosticMarker {
abstract val element: KtSourceElement abstract val element: AbstractKtSourceElement
abstract val severity: Severity abstract val severity: Severity
abstract val factory: AbstractKtDiagnosticFactory abstract val factory: AbstractKtDiagnosticFactory
abstract val positioningStrategy: AbstractSourceElementPositioningStrategy abstract val positioningStrategy: AbstractSourceElementPositioningStrategy
@@ -206,3 +205,58 @@ data class KtLightDiagnosticWithParameters4<A, B, C, D>(
override val factory: KtDiagnosticFactory4<A, B, C, D>, override val factory: KtDiagnosticFactory4<A, B, C, D>,
override val positioningStrategy: AbstractSourceElementPositioningStrategy override val positioningStrategy: AbstractSourceElementPositioningStrategy
) : KtDiagnosticWithParameters4<A, B, C, D>(), KtLightDiagnostic ) : KtDiagnosticWithParameters4<A, B, C, D>(), KtLightDiagnostic
// ------------------------------ light tree diagnostics ------------------------------
interface KtOffsetsOnlyDiagnostic : DiagnosticMarker {
val element: AbstractKtSourceElement
@Deprecated("Should not be called", level = DeprecationLevel.HIDDEN)
override val psiElement: PsiElement
get() = error("psiElement should not be called on KtOffsetsOnlyDiagnostic")
}
data class KtOffsetsOnlySimpleDiagnostic(
override val element: AbstractKtSourceElement,
override val severity: Severity,
override val factory: KtDiagnosticFactory0,
override val positioningStrategy: AbstractSourceElementPositioningStrategy
) : KtSimpleDiagnostic(), KtOffsetsOnlyDiagnostic
data class KtOffsetsOnlyDiagnosticWithParameters1<A>(
override val element: AbstractKtSourceElement,
override val a: A,
override val severity: Severity,
override val factory: KtDiagnosticFactory1<A>,
override val positioningStrategy: AbstractSourceElementPositioningStrategy
) : KtDiagnosticWithParameters1<A>(), KtOffsetsOnlyDiagnostic
data class KtOffsetsOnlyDiagnosticWithParameters2<A, B>(
override val element: AbstractKtSourceElement,
override val a: A,
override val b: B,
override val severity: Severity,
override val factory: KtDiagnosticFactory2<A, B>,
override val positioningStrategy: AbstractSourceElementPositioningStrategy
) : KtDiagnosticWithParameters2<A, B>(), KtOffsetsOnlyDiagnostic
data class KtOffsetsOnlyDiagnosticWithParameters3<A, B, C>(
override val element: AbstractKtSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val severity: Severity,
override val factory: KtDiagnosticFactory3<A, B, C>,
override val positioningStrategy: AbstractSourceElementPositioningStrategy
) : KtDiagnosticWithParameters3<A, B, C>(), KtOffsetsOnlyDiagnostic
data class KtOffsetsOnlyDiagnosticWithParameters4<A, B, C, D>(
override val element: AbstractKtSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val d: D,
override val severity: Severity,
override val factory: KtDiagnosticFactory4<A, B, C, D>,
override val positioningStrategy: AbstractSourceElementPositioningStrategy
) : KtDiagnosticWithParameters4<A, B, C, D>(), KtOffsetsOnlyDiagnostic
@@ -7,9 +7,9 @@
package org.jetbrains.kotlin.diagnostics package org.jetbrains.kotlin.diagnostics
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtLightSourceElement import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import kotlin.reflect.KClass import kotlin.reflect.KClass
@@ -39,7 +39,7 @@ class KtDiagnosticFactory0(
@InternalDiagnosticFactoryMethod @InternalDiagnosticFactoryMethod
fun on( fun on(
element: KtSourceElement, element: AbstractKtSourceElement,
positioningStrategy: AbstractSourceElementPositioningStrategy? positioningStrategy: AbstractSourceElementPositioningStrategy?
): KtSimpleDiagnostic { ): KtSimpleDiagnostic {
return when (element) { return when (element) {
@@ -47,6 +47,7 @@ class KtDiagnosticFactory0(
element, severity, this, positioningStrategy ?: defaultPositioningStrategy element, severity, this, positioningStrategy ?: defaultPositioningStrategy
) )
is KtLightSourceElement -> KtLightSimpleDiagnostic(element, severity, this, positioningStrategy ?: defaultPositioningStrategy) is KtLightSourceElement -> KtLightSimpleDiagnostic(element, severity, this, positioningStrategy ?: defaultPositioningStrategy)
else -> KtOffsetsOnlySimpleDiagnostic(element, severity, this, positioningStrategy ?: defaultPositioningStrategy)
} }
} }
} }
@@ -64,7 +65,7 @@ class KtDiagnosticFactory1<A>(
@InternalDiagnosticFactoryMethod @InternalDiagnosticFactoryMethod
fun on( fun on(
element: KtSourceElement, element: AbstractKtSourceElement,
a: A, a: A,
positioningStrategy: AbstractSourceElementPositioningStrategy? positioningStrategy: AbstractSourceElementPositioningStrategy?
): KtDiagnosticWithParameters1<A> { ): KtDiagnosticWithParameters1<A> {
@@ -79,6 +80,9 @@ class KtDiagnosticFactory1<A>(
this, this,
positioningStrategy ?: defaultPositioningStrategy positioningStrategy ?: defaultPositioningStrategy
) )
else -> KtOffsetsOnlyDiagnosticWithParameters1(
element, a, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
} }
} }
} }
@@ -97,7 +101,7 @@ class KtDiagnosticFactory2<A, B>(
@InternalDiagnosticFactoryMethod @InternalDiagnosticFactoryMethod
fun on( fun on(
element: KtSourceElement, element: AbstractKtSourceElement,
a: A, a: A,
b: B, b: B,
positioningStrategy: AbstractSourceElementPositioningStrategy? positioningStrategy: AbstractSourceElementPositioningStrategy?
@@ -114,6 +118,9 @@ class KtDiagnosticFactory2<A, B>(
this, this,
positioningStrategy ?: defaultPositioningStrategy positioningStrategy ?: defaultPositioningStrategy
) )
else -> KtOffsetsOnlyDiagnosticWithParameters2(
element, a, b, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
} }
} }
} }
@@ -133,7 +140,7 @@ class KtDiagnosticFactory3<A, B, C>(
@InternalDiagnosticFactoryMethod @InternalDiagnosticFactoryMethod
fun on( fun on(
element: KtSourceElement, element: AbstractKtSourceElement,
a: A, a: A,
b: B, b: B,
c: C, c: C,
@@ -152,6 +159,9 @@ class KtDiagnosticFactory3<A, B, C>(
this, this,
positioningStrategy ?: defaultPositioningStrategy positioningStrategy ?: defaultPositioningStrategy
) )
else -> KtOffsetsOnlyDiagnosticWithParameters3(
element, a, b, c, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
} }
} }
} }
@@ -172,7 +182,7 @@ class KtDiagnosticFactory4<A, B, C, D>(
@InternalDiagnosticFactoryMethod @InternalDiagnosticFactoryMethod
fun on( fun on(
element: KtSourceElement, element: AbstractKtSourceElement,
a: A, a: A,
b: B, b: B,
c: C, c: C,
@@ -193,14 +203,13 @@ class KtDiagnosticFactory4<A, B, C, D>(
this, this,
positioningStrategy ?: defaultPositioningStrategy positioningStrategy ?: defaultPositioningStrategy
) )
else -> KtOffsetsOnlyDiagnosticWithParameters4(
element, a, b, c, d, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
} }
} }
} }
private fun incorrectElement(element: KtSourceElement): Nothing {
throw IllegalArgumentException("Unknown element type: ${element::class}")
}
// ------------------------------ factories for deprecation ------------------------------ // ------------------------------ factories for deprecation ------------------------------
sealed class KtDiagnosticFactoryForDeprecation<F : AbstractKtDiagnosticFactory>( sealed class KtDiagnosticFactoryForDeprecation<F : AbstractKtDiagnosticFactory>(
@@ -7,10 +7,10 @@
package org.jetbrains.kotlin.diagnostics package org.jetbrains.kotlin.diagnostics
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.AbstractKtSourceElement
fun DiagnosticReporter.reportOn( fun DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactory0, factory: KtDiagnosticFactory0,
context: DiagnosticContext, context: DiagnosticContext,
positioningStrategy: AbstractSourceElementPositioningStrategy? = null positioningStrategy: AbstractSourceElementPositioningStrategy? = null
@@ -19,7 +19,7 @@ fun DiagnosticReporter.reportOn(
} }
fun <A : Any> DiagnosticReporter.reportOn( fun <A : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactory1<A>, factory: KtDiagnosticFactory1<A>,
a: A, a: A,
context: DiagnosticContext, context: DiagnosticContext,
@@ -29,7 +29,7 @@ fun <A : Any> DiagnosticReporter.reportOn(
} }
fun <A : Any, B : Any> DiagnosticReporter.reportOn( fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactory2<A, B>, factory: KtDiagnosticFactory2<A, B>,
a: A, a: A,
b: B, b: B,
@@ -40,7 +40,7 @@ fun <A : Any, B : Any> DiagnosticReporter.reportOn(
} }
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn( fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactory3<A, B, C>, factory: KtDiagnosticFactory3<A, B, C>,
a: A, a: A,
b: B, b: B,
@@ -52,7 +52,7 @@ fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
} }
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn( fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactory4<A, B, C, D>, factory: KtDiagnosticFactory4<A, B, C, D>,
a: A, a: A,
b: B, b: B,
@@ -65,7 +65,7 @@ fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
} }
fun DiagnosticReporter.reportOn( fun DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation0, factory: KtDiagnosticFactoryForDeprecation0,
context: DiagnosticContext, context: DiagnosticContext,
positioningStrategy: AbstractSourceElementPositioningStrategy? = null positioningStrategy: AbstractSourceElementPositioningStrategy? = null
@@ -74,7 +74,7 @@ fun DiagnosticReporter.reportOn(
} }
fun <A : Any> DiagnosticReporter.reportOn( fun <A : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation1<A>, factory: KtDiagnosticFactoryForDeprecation1<A>,
a: A, a: A,
context: DiagnosticContext, context: DiagnosticContext,
@@ -84,7 +84,7 @@ fun <A : Any> DiagnosticReporter.reportOn(
} }
fun <A : Any, B : Any> DiagnosticReporter.reportOn( fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation2<A, B>, factory: KtDiagnosticFactoryForDeprecation2<A, B>,
a: A, a: A,
b: B, b: B,
@@ -95,7 +95,7 @@ fun <A : Any, B : Any> DiagnosticReporter.reportOn(
} }
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn( fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation3<A, B, C>, factory: KtDiagnosticFactoryForDeprecation3<A, B, C>,
a: A, a: A,
b: B, b: B,
@@ -107,7 +107,7 @@ fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
} }
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn( fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?, source: AbstractKtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation4<A, B, C, D>, factory: KtDiagnosticFactoryForDeprecation4<A, B, C, D>,
a: A, a: A,
b: B, b: B,
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2021 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.diagnostics
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement
open class OffsetsOnlyPositioningStrategy : AbstractSourceElementPositioningStrategy() {
open fun markKtDiagnostic(element: AbstractKtSourceElement, diagnostic: KtDiagnostic): List<TextRange> {
return mark(element.startOffset, element.endOffset)
}
open fun mark(
startOffset: Int,
endOffset: Int,
): List<TextRange> {
return markElement(startOffset, endOffset)
}
override fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange> = markKtDiagnostic(diagnostic.element, diagnostic)
override fun isValid(element: AbstractKtSourceElement): Boolean = true
}
fun markElement(
startOffset: Int,
endOffset: Int,
): List<TextRange> = markRange(startOffset, endOffset)
fun markRange(
startOffset: Int,
endOffset: Int,
): List<TextRange> {
return listOf(markSingleElement(startOffset, endOffset))
}
fun markSingleElement(
startOffset: Int,
endOffset: Int,
): TextRange {
return TextRange(startOffset, endOffset)
}
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.diagnostics.impl package org.jetbrains.kotlin.diagnostics.impl
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.diagnostics.AbstractKtDiagnosticFactory import org.jetbrains.kotlin.diagnostics.AbstractKtDiagnosticFactory
import org.jetbrains.kotlin.diagnostics.DiagnosticContext import org.jetbrains.kotlin.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.diagnostics.KtDiagnostic
class DeduplicatingDiagnosticReporter(private val inner: DiagnosticReporter) : DiagnosticReporter() { class DeduplicatingDiagnosticReporter(private val inner: DiagnosticReporter) : DiagnosticReporter() {
private val reported = mutableSetOf<Pair<KtSourceElement, AbstractKtDiagnosticFactory>>() private val reported = mutableSetOf<Pair<AbstractKtSourceElement, AbstractKtDiagnosticFactory>>()
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) { override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) {
if (diagnostic != null && reported.add(Pair(diagnostic.element, diagnostic.factory))) { if (diagnostic != null && reported.add(Pair(diagnostic.element, diagnostic.factory))) {