[FIR] Remove useless type parameters from classes related to diagnostics

Generics removed from:
 - FirPsiSourceElement
 - FirDiagnostic
 - FirDiagnosticRenderer
 - FirDiagnosticFactory
This commit is contained in:
Dmitriy Novozhilov
2021-06-09 11:47:17 +03:00
parent 386f6d9331
commit a288b8b00e
63 changed files with 1629 additions and 1613 deletions
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
object FirDiagnosticsCompilerResultsReporter {
fun reportDiagnostics(diagnostics: Collection<FirDiagnostic<*>>, reporter: MessageCollector): Boolean {
fun reportDiagnostics(diagnostics: Collection<FirDiagnostic>, reporter: MessageCollector): Boolean {
var hasErrors = false
for (diagnostic in diagnostics.sortedWith(DiagnosticComparator)) {
hasErrors = reportDiagnostic(diagnostic, reporter) || hasErrors
@@ -27,7 +27,7 @@ object FirDiagnosticsCompilerResultsReporter {
}
@Suppress("UNUSED_PARAMETER")
private fun reportSpecialErrors(diagnostics: Collection<FirDiagnostic<*>>) {
private fun reportSpecialErrors(diagnostics: Collection<FirDiagnostic>) {
/*
* TODO: handle next diagnostics when they will be supported in FIR:
* - INCOMPATIBLE_CLASS
@@ -37,7 +37,7 @@ object FirDiagnosticsCompilerResultsReporter {
*/
}
private fun reportDiagnostic(diagnostic: FirDiagnostic<*>, reporter: MessageCollector): Boolean {
private fun reportDiagnostic(diagnostic: FirDiagnostic, reporter: MessageCollector): Boolean {
if (!diagnostic.isValid) return false
diagnostic.location()?.let { location ->
val severity = AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity)
@@ -48,28 +48,28 @@ object FirDiagnosticsCompilerResultsReporter {
return diagnostic.severity == Severity.ERROR
}
private fun FirDiagnostic<*>.location(): CompilerMessageSourceLocation? = when (val element = element) {
is FirPsiSourceElement<*> -> element.location(this)
private fun FirDiagnostic.location(): CompilerMessageSourceLocation? = when (val element = element) {
is FirPsiSourceElement -> element.location(this)
is FirLightSourceElement -> element.location(this)
}
private fun FirPsiSourceElement<*>.location(diagnostic: FirDiagnostic<*>): CompilerMessageSourceLocation? {
private fun FirPsiSourceElement.location(diagnostic: FirDiagnostic): CompilerMessageSourceLocation? {
val file = psi.containingFile
return MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumnRange(file, diagnostic.textRanges))
}
@Suppress("UNUSED_PARAMETER")
private fun FirLightSourceElement.location(diagnostic: FirDiagnostic<*>): CompilerMessageSourceLocation? {
private fun FirLightSourceElement.location(diagnostic: FirDiagnostic): CompilerMessageSourceLocation? {
// TODO: support light tree
return null
}
private object DiagnosticComparator : Comparator<FirDiagnostic<*>> {
override fun compare(o1: FirDiagnostic<*>, o2: FirDiagnostic<*>): Int {
private object DiagnosticComparator : Comparator<FirDiagnostic> {
override fun compare(o1: FirDiagnostic, o2: FirDiagnostic): Int {
val element1 = o1.element
val element2 = o1.element
// TODO: support light tree
if (element1 !is FirPsiSourceElement<*> || element2 !is FirPsiSourceElement<*>) return 0
if (element1 !is FirPsiSourceElement || element2 !is FirPsiSourceElement) return 0
val file1 = element1.psi.containingFile
val file2 = element2.psi.containingFile
@@ -20,7 +20,7 @@ fun FirSourceElement.getChild(types: TokenSet, index: Int = 0, depth: Int = -1):
fun FirSourceElement.getChild(types: Set<IElementType>, index: Int = 0, depth: Int = -1): FirSourceElement? {
return when (this) {
is FirPsiSourceElement<*> -> {
is FirPsiSourceElement -> {
getChild(types, index, depth)
}
is FirLightSourceElement -> {
@@ -30,7 +30,7 @@ fun FirSourceElement.getChild(types: Set<IElementType>, index: Int = 0, depth: I
}
}
private fun FirPsiSourceElement<*>.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
private fun FirPsiSourceElement.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
val visitor = PsiElementFinderByType(types, index, depth)
return visitor.find(psi)?.toFirPsiSourceElement()
}
@@ -84,7 +84,7 @@ sealed class FirModifier<Node : Any>(val node: Node, val token: KtModifierKeywor
fun FirSourceElement?.getModifierList(): FirModifierList? {
return when (this) {
null -> null
is FirPsiSourceElement<*> -> (psi as? KtModifierListOwner)?.modifierList?.let { FirModifierList.FirPsiModifierList(it) }
is FirPsiSourceElement -> (psi as? KtModifierListOwner)?.modifierList?.let { FirModifierList.FirPsiModifierList(it) }
is FirLightSourceElement -> {
val modifierListNode = lighterASTNode.getChildren(treeStructure).find { it?.tokenType == KtNodeTypes.MODIFIER_LIST }
?: return null
@@ -103,6 +103,6 @@ fun FirElement.hasModifier(token: KtModifierKeywordToken): Boolean = token in so
internal val FirSourceElement?.valOrVarKeyword: KtKeywordToken?
get() = when (this) {
null -> null
is FirPsiSourceElement<*> -> (psi as? KtValVarKeywordOwner)?.valOrVarKeyword?.let { it.node?.elementType as? KtKeywordToken }
is FirPsiSourceElement -> (psi as? KtValVarKeywordOwner)?.valOrVarKeyword?.let { it.node?.elementType as? KtKeywordToken }
is FirLightSourceElement -> treeStructure.valOrVarKeyword(lighterASTNode)?.tokenType as? KtKeywordToken
}
@@ -32,7 +32,7 @@ interface SourceNavigator {
fun forElement(e: FirElement): SourceNavigator = when (e.source) {
is FirLightSourceElement -> lightTreeInstance
is FirPsiSourceElement<*> -> PsiSourceNavigator
is FirPsiSourceElement -> PsiSourceNavigator
null -> lightTreeInstance //shouldn't matter
}
@@ -62,7 +62,7 @@ object PsiSourceNavigator : LightTreeSourceNavigator() {
//Swallows incorrect casts!!!
private inline fun <reified P : PsiElement> FirElement.psi(): P? {
val psi = (source as? FirPsiSourceElement<*>)?.psi
val psi = (source as? FirPsiSourceElement)?.psi
return psi as? P
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
import org.jetbrains.kotlin.fir.resolve.SessionHolder
@@ -43,7 +42,7 @@ abstract class CheckerContext {
allErrorsSuppressed: Boolean
): PersistentCheckerContext
fun isDiagnosticSuppressed(diagnostic: FirDiagnostic<*>): Boolean {
fun isDiagnosticSuppressed(diagnostic: FirDiagnostic): Boolean {
val factory = diagnostic.factory
val name = factory.name
val suppressedByAll = when (factory.severity) {
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.fqName
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.RequireKotlinConstants
object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
@@ -60,9 +59,9 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
session: FirSession,
reporter: DiagnosticReporter,
context: CheckerContext
): FirDiagnosticFactory0<KtExpression>? {
): FirDiagnosticFactory0? {
fun checkArgumentList(args: FirArgumentList): FirDiagnosticFactory0<KtExpression>? {
fun checkArgumentList(args: FirArgumentList): FirDiagnosticFactory0? {
var usedNonConst = false
for (arg in args.arguments) {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
@@ -34,7 +33,6 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateErr
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
object FirForLoopChecker : FirBlockChecker() {
@@ -95,10 +93,10 @@ object FirForLoopChecker : FirBlockChecker() {
reporter: DiagnosticReporter,
reportSource: FirSourceElement?,
context: CheckerContext,
ambiguityFactory: FirDiagnosticFactory1<PsiElement, Collection<AbstractFirBasedSymbol<*>>>,
missingFactory: FirDiagnosticFactory0<KtExpression>,
noneApplicableFactory: FirDiagnosticFactory1<KtExpression, Collection<AbstractFirBasedSymbol<*>>>? = null,
unsafeCallFactory: FirDiagnosticFactory0<KtExpression>? = null,
ambiguityFactory: FirDiagnosticFactory1<Collection<AbstractFirBasedSymbol<*>>>,
missingFactory: FirDiagnosticFactory0,
noneApplicableFactory: FirDiagnosticFactory1<Collection<AbstractFirBasedSymbol<*>>>? = null,
unsafeCallFactory: FirDiagnosticFactory0? = null,
): Boolean {
when (val calleeReference = call.calleeReference) {
is FirErrorNamedReference -> {
@@ -145,4 +143,4 @@ object FirForLoopChecker : FirBlockChecker() {
}
return false
}
}
}
@@ -42,7 +42,7 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
isSubtypeForTypeMismatch(typeContext, subtype = resultExpression.smartcastType.coneType, supertype = functionReturnType)
) {
reporter.reportOn(
returnExpressionSource,
resultExpression.source,
SMARTCAST_IMPOSSIBLE,
functionReturnType,
resultExpression,
@@ -51,11 +51,11 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
)
} else {
reporter.reportOn(
resultExpression.source,
resultExpression.source,
RETURN_TYPE_MISMATCH,
functionReturnType,
returnExpressionType,
targetElement,
functionReturnType,
returnExpressionType,
targetElement,
context
)
}
@@ -10,13 +10,16 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.text
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.stubs.elements.KtDotQualifiedExpressionElementType
@@ -37,7 +40,7 @@ object FirReservedUnderscoreExpressionChecker : FirBasicExpressionChecker() {
isExpression = true
)
} else if (expression is FirQualifiedAccess) {
if (source is FirPsiSourceElement<*>) {
if (source is FirPsiSourceElement) {
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
} else if (source is FirLightSourceElement) {
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
@@ -48,7 +51,7 @@ object FirReservedUnderscoreExpressionChecker : FirBasicExpressionChecker() {
}
} else if (expression is FirReturnExpression) {
var labelName: String? = null
if (source is FirPsiSourceElement<*>) {
if (source is FirPsiSourceElement) {
labelName = (source.psi.parent as? KtLabeledExpression)?.getLabelName()
} else if (source is FirLightSourceElement) {
val parent = source.treeStructure.getParent(source.lighterASTNode)
@@ -63,7 +66,7 @@ object FirReservedUnderscoreExpressionChecker : FirBasicExpressionChecker() {
}
private fun reportIfUnderscoreInQualifiedAccess(
source: FirPsiSourceElement<*>,
source: FirPsiSourceElement,
expression: FirStatement,
context: CheckerContext,
reporter: DiagnosticReporter
@@ -145,7 +148,7 @@ private fun reportIfUnderscore(
) {
val source = declaration.source
val rawIdentifier = when (source) {
is FirPsiSourceElement<*> ->
is FirPsiSourceElement ->
(source.psi as? PsiNameIdentifierOwner)?.nameIdentifier?.text
is FirLightSourceElement ->
source.treeStructure.nameIdentifier(source.lighterASTNode)?.toString()
@@ -162,7 +165,7 @@ private fun reportIfUnderscore(
}
val isReportUnderscoreInReturnOrReceiverTypeRef = when (returnOrReceiverTypeRef) {
is FirPsiSourceElement<*> -> {
is FirPsiSourceElement -> {
val psi = returnOrReceiverTypeRef.psi
psi is KtTypeReference && psi.anyDescendantOfType<LeafPsiElement> { isUnderscore(it.text) }
}
@@ -203,4 +206,4 @@ private fun reportIfUnderscore(
}
}
private fun isUnderscore(text: CharSequence) = text.all { it == '_' }
private fun isUnderscore(text: CharSequence) = text.all { it == '_' }
@@ -41,7 +41,7 @@ object CanBeReplacedWithOperatorAssignmentChecker : FirVariableAssignmentChecker
var needToReport = false
val assignmentSource = expression.source
if (assignmentSource is FirPsiSourceElement<*>) {
if (assignmentSource is FirPsiSourceElement) {
val lValuePsi = lValue.psi as? KtNameReferenceExpression ?: return
val rValuePsi = rValue.psi as? KtBinaryExpression ?: return
@@ -40,7 +40,7 @@ object CanBeValChecker : AbstractFirPropertyInitializationChecker() {
for (property in unprocessedProperties) {
val source = property.fir.source
if (source is FirFakeSourceElement<*>) continue
if (source is FirFakeSourceElement) continue
if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION) continue
propertiesCharacteristics[property] = EventOccurrencesRange.ZERO
}
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
object EmptyRangeChecker : FirFunctionCallChecker() {
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
if (expression.source is FirFakeSourceElement<*>) return
if (expression.source is FirFakeSourceElement) return
val left = expression.rangeLeft ?: return
val right = expression.rangeRight ?: return
@@ -20,9 +20,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.FirStringConcatenationCall
import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
object RedundantSingleExpressionStringTemplateChecker : FirStringConcatenationCallChecker() {
@@ -38,7 +38,7 @@ object RedundantSingleExpressionStringTemplateChecker : FirStringConcatenationCa
private fun FirStatement.stringParentChildrenCount(): Int? {
return when (val source = source) {
is FirPsiSourceElement<*> -> source.psi.stringParentChildrenCount()
is FirPsiSourceElement -> source.psi.stringParentChildrenCount()
is FirLightSourceElement -> source.lighterASTNode.stringParentChildrenCount(source)
null -> null
}
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirFakeSourceElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
@@ -32,7 +31,7 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
reporter: DiagnosticReporter
) {
if (element is FirConstructor && source.kind is FirFakeSourceElementKind) return
if (source is FirFakeSourceElement<*>) return
if (source is FirFakeSourceElement) return
if (
element !is FirMemberDeclaration
&& !(element is FirPropertyAccessor && element.visibility == context.containingPropertyVisibility)
@@ -18,11 +18,12 @@ import org.jetbrains.kotlin.psi.KtFunction
object FirAnonymousFunctionSyntaxChecker : FirExpressionSyntaxChecker<FirAnonymousFunction, KtFunction>() {
override fun checkPsi(
element: FirAnonymousFunction,
source: FirPsiSourceElement<KtFunction>,
source: FirPsiSourceElement,
psi: KtFunction,
context: CheckerContext,
reporter: DiagnosticReporter
) {
if (source.psi.typeParameterList != null) {
if (psi.typeParameterList != null) {
reporter.reportOn(
source,
FirErrors.TYPE_PARAMETERS_NOT_ALLOWED,
@@ -6,13 +6,15 @@
package org.jetbrains.kotlin.fir.analysis.checkers.syntax
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.isInterface
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
@@ -22,7 +24,8 @@ object FirDelegationInInterfaceSyntaxChecker : FirDeclarationSyntaxChecker<FirRe
override fun checkPsi(
element: FirRegularClass,
source: FirPsiSourceElement<KtClass>,
source: FirPsiSourceElement,
psi: KtClass,
context: CheckerContext,
reporter: DiagnosticReporter
) {
@@ -20,12 +20,13 @@ object FirFunctionTypeParametersSyntaxChecker : FirDeclarationSyntaxChecker<FirS
override fun checkPsi(
element: FirSimpleFunction,
source: FirPsiSourceElement<KtFunction>,
source: FirPsiSourceElement,
psi: KtFunction,
context: CheckerContext,
reporter: DiagnosticReporter
) {
val typeParamsNode = source.psi.typeParameterList
val nameNode = source.psi.nameIdentifier
val typeParamsNode = psi.typeParameterList
val nameNode = psi.nameIdentifier
if (typeParamsNode != null && nameNode != null && typeParamsNode.startOffset > nameNode.startOffset) {
reporter.reportOn(
@@ -27,7 +27,7 @@ interface FirSyntaxChecker<in D : FirElement, P : PsiElement> {
if (!isApplicable(element, source)) return
@Suppress("UNCHECKED_CAST")
when (source) {
is FirPsiSourceElement<*> -> checkPsi(element, source as FirPsiSourceElement<P>, context, reporter)
is FirPsiSourceElement -> checkPsi(element, source, source.psi as P, context, reporter)
is FirLightSourceElement -> checkLightTree(element, source, context, reporter)
}
}
@@ -37,7 +37,7 @@ interface FirSyntaxChecker<in D : FirElement, P : PsiElement> {
/**
* By default psi tree should be equivalent to light tree and can be processed the same way
*/
fun checkPsi(element: D, source: FirPsiSourceElement<P>, context: CheckerContext, reporter: DiagnosticReporter) {
fun checkPsi(element: D, source: FirPsiSourceElement, psi: P, context: CheckerContext, reporter: DiagnosticReporter) {
checkLightTree(element, source, context, reporter)
}
@@ -24,7 +24,8 @@ object FirTypeParameterSyntaxChecker : FirDeclarationSyntaxChecker<FirTypeParame
override fun checkPsi(
element: FirTypeParameter,
source: FirPsiSourceElement<KtTypeParameter>,
source: FirPsiSourceElement,
psi: KtTypeParameter,
context: CheckerContext,
reporter: DiagnosticReporter
) {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSourceElement
@@ -13,65 +12,65 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
abstract class DiagnosticReporter {
abstract fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext)
abstract fun report(diagnostic: FirDiagnostic?, context: CheckerContext)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <P : PsiElement> DiagnosticReporter.reportOn(
fun DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactory0<P>,
factory: FirDiagnosticFactory0,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <P : PsiElement, A : Any> DiagnosticReporter.reportOn(
fun <A : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactory1<P, A>,
factory: FirDiagnosticFactory1<A>,
a: A,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <P : PsiElement, A : Any, B : Any> DiagnosticReporter.reportOn(
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactory2<P, A, B>,
factory: FirDiagnosticFactory2<A, B>,
a: A,
b: B,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <P : PsiElement, A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactory3<P, A, B, C>,
factory: FirDiagnosticFactory3<A, B, C>,
a: A,
b: B,
c: C,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, c, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <P : PsiElement, A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactory4<P, A, B, C, D>,
factory: FirDiagnosticFactory4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, c, d, positioningStrategy), context) }
}
@@ -96,65 +95,65 @@ inline fun withSuppressedDiagnostics(
f(context)
}
fun <P : PsiElement> DiagnosticReporter.reportOnWithSuppression(
fun DiagnosticReporter.reportOnWithSuppression(
element: FirElement,
factory: FirDiagnosticFactory0<P>,
factory: FirDiagnosticFactory0,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, it, positioningStrategy)
}
}
fun <P : PsiElement, A : Any> DiagnosticReporter.reportOnWithSuppression(
fun <A : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirElement,
factory: FirDiagnosticFactory1<P, A>,
factory: FirDiagnosticFactory1<A>,
a: A,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, it, positioningStrategy)
}
}
fun <P : PsiElement, A : Any, B : Any> DiagnosticReporter.reportOnWithSuppression(
fun <A : Any, B : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirElement,
factory: FirDiagnosticFactory2<P, A, B>,
factory: FirDiagnosticFactory2<A, B>,
a: A,
b: B,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, it, positioningStrategy)
}
}
fun <P : PsiElement, A : Any, B : Any, C : Any> DiagnosticReporter.reportOnWithSuppression(
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirElement,
factory: FirDiagnosticFactory3<P, A, B, C>,
factory: FirDiagnosticFactory3<A, B, C>,
a: A,
b: B,
c: C,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, it, positioningStrategy)
}
}
fun <P : PsiElement, A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOnWithSuppression(
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirElement,
factory: FirDiagnosticFactory4<P, A, B, C, D>,
factory: FirDiagnosticFactory4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy<P>? = null
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, d, it, positioningStrategy)
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.diagnostics.rendering.*
import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.RENDER_POSITION_VARIANCE
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
@@ -379,10 +379,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETU
@Suppress("unused")
class FirDefaultErrorMessages {
companion object {
fun getRendererForDiagnostic(diagnostic: FirDiagnostic<*>): FirDiagnosticRenderer<FirDiagnostic<*>> {
fun getRendererForDiagnostic(diagnostic: FirDiagnostic): FirDiagnosticRenderer {
val factory = diagnostic.factory
@Suppress("UNCHECKED_CAST")
return (MAP[factory] ?: factory.firRenderer) as FirDiagnosticRenderer<FirDiagnostic<*>>
return (MAP[factory] ?: factory.firRenderer)
}
// * - The old FE reports these diagnostics with additional parameters
@@ -15,11 +15,11 @@ import org.jetbrains.kotlin.fir.FirSourceElement
// ------------------------------ diagnostics ------------------------------
sealed class FirDiagnostic<out E : FirSourceElement> {
abstract val element: E
sealed class FirDiagnostic {
abstract val element: FirSourceElement
abstract val severity: Severity
abstract val factory: AbstractFirDiagnosticFactory<*, *>
abstract val positioningStrategy: SourceElementPositioningStrategy<*>
abstract val factory: AbstractFirDiagnosticFactory
abstract val positioningStrategy: SourceElementPositioningStrategy
val textRanges: List<TextRange>
get() = positioningStrategy.markDiagnostic(this)
@@ -28,41 +28,41 @@ sealed class FirDiagnostic<out E : FirSourceElement> {
get() = positioningStrategy.isValid(element)
}
sealed class FirSimpleDiagnostic<out E : FirSourceElement> : FirDiagnostic<E>() {
abstract override val factory: FirDiagnosticFactory0<*>
sealed class FirSimpleDiagnostic : FirDiagnostic() {
abstract override val factory: FirDiagnosticFactory0
}
sealed class FirDiagnosticWithParameters1<out E : FirSourceElement, A> : FirDiagnostic<E>() {
sealed class FirDiagnosticWithParameters1<A> : FirDiagnostic() {
abstract val a: A
abstract override val factory: FirDiagnosticFactory1<*, A>
abstract override val factory: FirDiagnosticFactory1<A>
}
sealed class FirDiagnosticWithParameters2<out E : FirSourceElement, A, B> : FirDiagnostic<E>() {
sealed class FirDiagnosticWithParameters2<A, B> : FirDiagnostic() {
abstract val a: A
abstract val b: B
abstract override val factory: FirDiagnosticFactory2<*, A, B>
abstract override val factory: FirDiagnosticFactory2<A, B>
}
sealed class FirDiagnosticWithParameters3<out E : FirSourceElement, A, B, C> : FirDiagnostic<E>() {
sealed class FirDiagnosticWithParameters3<A, B, C> : FirDiagnostic() {
abstract val a: A
abstract val b: B
abstract val c: C
abstract override val factory: FirDiagnosticFactory3<*, A, B, C>
abstract override val factory: FirDiagnosticFactory3<A, B, C>
}
sealed class FirDiagnosticWithParameters4<out E : FirSourceElement, A, B, C, D> : FirDiagnostic<E>() {
sealed class FirDiagnosticWithParameters4<A, B, C, D> : FirDiagnostic() {
abstract val a: A
abstract val b: B
abstract val c: C
abstract val d: D
abstract override val factory: FirDiagnosticFactory4<*, A, B, C, D>
abstract override val factory: FirDiagnosticFactory4<A, B, C, D>
}
// ------------------------------ psi diagnostics ------------------------------
interface FirPsiDiagnostic<P : PsiElement> {
val factory: AbstractFirDiagnosticFactory<*, P>
val element: FirPsiSourceElement<P>
interface FirPsiDiagnostic {
val factory: AbstractFirDiagnosticFactory
val element: FirPsiSourceElement
val textRanges: List<TextRange>
val severity: Severity
@@ -73,50 +73,50 @@ interface FirPsiDiagnostic<P : PsiElement> {
get() = psiElement.containingFile
}
data class FirPsiSimpleDiagnostic<P : PsiElement>(
override val element: FirPsiSourceElement<P>,
data class FirPsiSimpleDiagnostic(
override val element: FirPsiSourceElement,
override val severity: Severity,
override val factory: FirDiagnosticFactory0<P>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirSimpleDiagnostic<FirPsiSourceElement<P>>(), FirPsiDiagnostic<P>
override val factory: FirDiagnosticFactory0,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirSimpleDiagnostic(), FirPsiDiagnostic
data class FirPsiDiagnosticWithParameters1<P : PsiElement, A>(
override val element: FirPsiSourceElement<P>,
data class FirPsiDiagnosticWithParameters1<A>(
override val element: FirPsiSourceElement,
override val a: A,
override val severity: Severity,
override val factory: FirDiagnosticFactory1<P, A>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters1<FirPsiSourceElement<P>, A>(), FirPsiDiagnostic<P>
override val factory: FirDiagnosticFactory1<A>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters1<A>(), FirPsiDiagnostic
data class FirPsiDiagnosticWithParameters2<P : PsiElement, A, B>(
override val element: FirPsiSourceElement<P>,
data class FirPsiDiagnosticWithParameters2<A, B>(
override val element: FirPsiSourceElement,
override val a: A,
override val b: B,
override val severity: Severity,
override val factory: FirDiagnosticFactory2<P, A, B>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters2<FirPsiSourceElement<P>, A, B>(), FirPsiDiagnostic<P>
override val factory: FirDiagnosticFactory2<A, B>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters2<A, B>(), FirPsiDiagnostic
data class FirPsiDiagnosticWithParameters3<P : PsiElement, A, B, C>(
override val element: FirPsiSourceElement<P>,
data class FirPsiDiagnosticWithParameters3<A, B, C>(
override val element: FirPsiSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val severity: Severity,
override val factory: FirDiagnosticFactory3<P, A, B, C>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters3<FirPsiSourceElement<P>, A, B, C>(), FirPsiDiagnostic<P>
override val factory: FirDiagnosticFactory3<A, B, C>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters3<A, B, C>(), FirPsiDiagnostic
data class FirPsiDiagnosticWithParameters4<P : PsiElement, A, B, C, D>(
override val element: FirPsiSourceElement<P>,
data class FirPsiDiagnosticWithParameters4<A, B, C, D>(
override val element: FirPsiSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val d: D,
override val severity: Severity,
override val factory: FirDiagnosticFactory4<P, A, B, C, D>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters4<FirPsiSourceElement<P>, A, B, C, D>(), FirPsiDiagnostic<P>
override val factory: FirDiagnosticFactory4<A, B, C, D>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters4<A, B, C, D>(), FirPsiDiagnostic
// ------------------------------ light tree diagnostics ------------------------------
@@ -127,26 +127,26 @@ interface FirLightDiagnostic {
data class FirLightSimpleDiagnostic(
override val element: FirLightSourceElement,
override val severity: Severity,
override val factory: FirDiagnosticFactory0<*>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirSimpleDiagnostic<FirLightSourceElement>(), FirLightDiagnostic
override val factory: FirDiagnosticFactory0,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirSimpleDiagnostic(), FirLightDiagnostic
data class FirLightDiagnosticWithParameters1<A>(
override val element: FirLightSourceElement,
override val a: A,
override val severity: Severity,
override val factory: FirDiagnosticFactory1<*, A>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters1<FirLightSourceElement, A>(), FirLightDiagnostic
override val factory: FirDiagnosticFactory1<A>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters1<A>(), FirLightDiagnostic
data class FirLightDiagnosticWithParameters2<A, B>(
override val element: FirLightSourceElement,
override val a: A,
override val b: B,
override val severity: Severity,
override val factory: FirDiagnosticFactory2<*, A, B>,
override val positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters2<FirLightSourceElement, A, B>(), FirLightDiagnostic
override val factory: FirDiagnosticFactory2<A, B>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters2<A, B>(), FirLightDiagnostic
data class FirLightDiagnosticWithParameters3<A, B, C>(
override val element: FirLightSourceElement,
@@ -154,9 +154,9 @@ 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 positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters3<FirLightSourceElement, A, B, C>(), FirLightDiagnostic
override val factory: FirDiagnosticFactory3<A, B, C>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters3<A, B, C>(), FirLightDiagnostic
data class FirLightDiagnosticWithParameters4<A, B, C, D>(
override val element: FirLightSourceElement,
@@ -165,6 +165,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 positioningStrategy: SourceElementPositioningStrategy<*>
) : FirDiagnosticWithParameters4<FirLightSourceElement, A, B, C, D>(), FirLightDiagnostic
override val factory: FirDiagnosticFactory4<A, B, C, D>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters4<A, B, C, D>(), FirLightDiagnostic
@@ -2,7 +2,6 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
@@ -12,31 +11,31 @@ import kotlin.reflect.KClass
@RequiresOptIn("Please use DiagnosticReporter.reportOn method if possible")
annotation class InternalDiagnosticFactoryMethod
sealed class AbstractFirDiagnosticFactory<D : FirDiagnostic<*>, P : PsiElement>(
sealed class AbstractFirDiagnosticFactory(
val name: String,
val severity: Severity,
val defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
val defaultPositioningStrategy: SourceElementPositioningStrategy,
val psiType: KClass<*>
) {
abstract val firRenderer: FirDiagnosticRenderer<D>
abstract val firRenderer: FirDiagnosticRenderer
}
class FirDiagnosticFactory0<P : PsiElement>(
class FirDiagnosticFactory0(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory<FirSimpleDiagnostic<*>, P>(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer<FirSimpleDiagnostic<*>> = SimpleFirDiagnosticRenderer("")
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = SimpleFirDiagnosticRenderer("")
@InternalDiagnosticFactoryMethod
fun on(
element: FirSourceElement,
positioningStrategy: SourceElementPositioningStrategy<P>?
): FirSimpleDiagnostic<*> {
positioningStrategy: SourceElementPositioningStrategy?
): FirSimpleDiagnostic {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiSimpleDiagnostic(
element as FirPsiSourceElement<P>, severity, this, positioningStrategy ?: defaultPositioningStrategy
is FirPsiSourceElement -> FirPsiSimpleDiagnostic(
element, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is FirLightSourceElement -> FirLightSimpleDiagnostic(element, severity, this, positioningStrategy ?: defaultPositioningStrategy)
else -> incorrectElement(element)
@@ -44,13 +43,13 @@ class FirDiagnosticFactory0<P : PsiElement>(
}
}
class FirDiagnosticFactory1<P : PsiElement, A>(
class FirDiagnosticFactory1<A>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters1<*, A>, P>(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters1<*, A>> = FirDiagnosticWithParameters1Renderer(
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters1Renderer(
"{0}",
FirDiagnosticRenderers.TO_STRING
)
@@ -59,11 +58,11 @@ class FirDiagnosticFactory1<P : PsiElement, A>(
fun on(
element: FirSourceElement,
a: A,
positioningStrategy: SourceElementPositioningStrategy<P>?
): FirDiagnosticWithParameters1<*, A> {
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters1<A> {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
element as FirPsiSourceElement<P>, a, severity, this, positioningStrategy ?: defaultPositioningStrategy
is FirPsiSourceElement -> FirPsiDiagnosticWithParameters1(
element, a, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
element,
@@ -77,13 +76,13 @@ class FirDiagnosticFactory1<P : PsiElement, A>(
}
}
class FirDiagnosticFactory2<P : PsiElement, A, B>(
class FirDiagnosticFactory2<A, B>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters2<*, A, B>, P>(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters2<*, A, B>> = FirDiagnosticWithParameters2Renderer(
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters2Renderer(
"{0}, {1}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
@@ -94,11 +93,11 @@ class FirDiagnosticFactory2<P : PsiElement, A, B>(
element: FirSourceElement,
a: A,
b: B,
positioningStrategy: SourceElementPositioningStrategy<P>?
): FirDiagnosticWithParameters2<*, A, B> {
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters2<A, B> {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters2(
element as FirPsiSourceElement<P>, a, b, severity, this, positioningStrategy ?: defaultPositioningStrategy
is FirPsiSourceElement -> FirPsiDiagnosticWithParameters2(
element, a, b, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is FirLightSourceElement -> FirLightDiagnosticWithParameters2(
element,
@@ -113,13 +112,13 @@ class FirDiagnosticFactory2<P : PsiElement, A, B>(
}
}
class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
class FirDiagnosticFactory3<A, B, C>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters3<*, A, B, C>, P>(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters3<*, A, B, C>> = FirDiagnosticWithParameters3Renderer(
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters3Renderer(
"{0}, {1}, {2}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
@@ -132,11 +131,11 @@ class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
a: A,
b: B,
c: C,
positioningStrategy: SourceElementPositioningStrategy<P>?
): FirDiagnosticWithParameters3<*, A, B, C> {
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters3<A, B, C> {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters3(
element as FirPsiSourceElement<P>, a, b, c, severity, this, positioningStrategy ?: defaultPositioningStrategy
is FirPsiSourceElement -> FirPsiDiagnosticWithParameters3(
element, a, b, c, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is FirLightSourceElement -> FirLightDiagnosticWithParameters3(
element,
@@ -152,13 +151,13 @@ class FirDiagnosticFactory3<P : PsiElement, A, B, C>(
}
}
class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
class FirDiagnosticFactory4<A, B, C, D>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy<P>,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory<FirDiagnosticWithParameters4<*, A, B, C, D>, P>(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer<FirDiagnosticWithParameters4<*, A, B, C, D>> = FirDiagnosticWithParameters4Renderer(
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters4Renderer(
"{0}, {1}, {2}, {3}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
@@ -173,11 +172,11 @@ class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
b: B,
c: C,
d: D,
positioningStrategy: SourceElementPositioningStrategy<P>?
): FirDiagnosticWithParameters4<*, A, B, C, D> {
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters4<A, B, C, D> {
return when (element) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters4(
element as FirPsiSourceElement<P>, a, b, c, d, severity, this, positioningStrategy ?: defaultPositioningStrategy
is FirPsiSourceElement -> FirPsiDiagnosticWithParameters4(
element, a, b, c, d, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is FirLightSourceElement -> FirLightDiagnosticWithParameters4(
element,
@@ -12,107 +12,107 @@ import kotlin.reflect.KClass
import kotlin.reflect.KProperty
inline fun <reified P : PsiElement> warning0(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory0DelegateProvider<P> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory0DelegateProvider {
return DiagnosticFactory0DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A> warning1(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory1DelegateProvider<P, A> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory1DelegateProvider<A> {
return DiagnosticFactory1DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B> warning2(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory2DelegateProvider<P, A, B> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory2DelegateProvider<A, B> {
return DiagnosticFactory2DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B, C> warning3(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory3DelegateProvider<P, A, B, C> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory3DelegateProvider<A, B, C> {
return DiagnosticFactory3DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement> error0(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory0DelegateProvider<P> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory0DelegateProvider {
return DiagnosticFactory0DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A> error1(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory1DelegateProvider<P, A> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory1DelegateProvider<A> {
return DiagnosticFactory1DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B> error2(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory2DelegateProvider<P, A, B> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory2DelegateProvider<A, B> {
return DiagnosticFactory2DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B, C> error3(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory3DelegateProvider<P, A, B, C> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory3DelegateProvider<A, B, C> {
return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B, C, D> error4(
positioningStrategy: SourceElementPositioningStrategy<P> = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory4DelegateProvider<P, A, B, C, D> {
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory4DelegateProvider<A, B, C, D> {
return DiagnosticFactory4DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
}
// ------------------------------ Providers ------------------------------
class DiagnosticFactory0DelegateProvider<P : PsiElement>(
class DiagnosticFactory0DelegateProvider(
private val severity: Severity,
private val positioningStrategy: SourceElementPositioningStrategy<P>,
private val positioningStrategy: SourceElementPositioningStrategy,
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> {
return DummyDelegate(FirDiagnosticFactory0(prop.name, severity, positioningStrategy, psiType))
}
}
class DiagnosticFactory1DelegateProvider<P : PsiElement, A>(
class DiagnosticFactory1DelegateProvider<A>(
private val severity: Severity,
private val positioningStrategy: SourceElementPositioningStrategy<P>,
private val positioningStrategy: SourceElementPositioningStrategy,
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<A>> {
return DummyDelegate(FirDiagnosticFactory1(prop.name, severity, positioningStrategy, psiType))
}
}
class DiagnosticFactory2DelegateProvider<P : PsiElement, A, B>(
class DiagnosticFactory2DelegateProvider<A, B>(
private val severity: Severity,
private val positioningStrategy: SourceElementPositioningStrategy<P>,
private val positioningStrategy: SourceElementPositioningStrategy,
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<A, B>> {
return DummyDelegate(FirDiagnosticFactory2(prop.name, severity, positioningStrategy, psiType))
}
}
class DiagnosticFactory3DelegateProvider<P : PsiElement, A, B, C>(
class DiagnosticFactory3DelegateProvider<A, B, C>(
private val severity: Severity,
private val positioningStrategy: SourceElementPositioningStrategy<P>,
private val positioningStrategy: SourceElementPositioningStrategy,
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<A, B, C>> {
return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, positioningStrategy, psiType))
}
}
class DiagnosticFactory4DelegateProvider<P : PsiElement, A, B, C, D>(
class DiagnosticFactory4DelegateProvider<A, B, C, D>(
private val severity: Severity,
private val positioningStrategy: SourceElementPositioningStrategy<P>,
private val positioningStrategy: SourceElementPositioningStrategy,
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<A, B, C, D>> {
return DummyDelegate(FirDiagnosticFactory4(prop.name, severity, positioningStrategy, psiType))
}
}
@@ -8,16 +8,16 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticParameterRenderer
class FirDiagnosticFactoryToRendererMap(val name: String) {
private val renderersMap: MutableMap<AbstractFirDiagnosticFactory<*, *>, FirDiagnosticRenderer<*>> = mutableMapOf()
private val renderersMap: MutableMap<AbstractFirDiagnosticFactory, FirDiagnosticRenderer> = mutableMapOf()
operator fun get(factory: AbstractFirDiagnosticFactory<*, *>): FirDiagnosticRenderer<*>? = renderersMap[factory]
operator fun get(factory: AbstractFirDiagnosticFactory): FirDiagnosticRenderer? = renderersMap[factory]
fun put(factory: FirDiagnosticFactory0<*>, message: String) {
fun put(factory: FirDiagnosticFactory0, message: String) {
put(factory, SimpleFirDiagnosticRenderer(message))
}
fun <A> put(
factory: FirDiagnosticFactory1<*, A>,
factory: FirDiagnosticFactory1<A>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?
) {
@@ -25,7 +25,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) {
}
fun <A, B> put(
factory: FirDiagnosticFactory2<*, A, B>,
factory: FirDiagnosticFactory2<A, B>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?
@@ -34,7 +34,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) {
}
fun <A, B, C> put(
factory: FirDiagnosticFactory3<*, A, B, C>,
factory: FirDiagnosticFactory3<A, B, C>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
@@ -44,7 +44,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) {
}
fun <A, B, C, D> put(
factory: FirDiagnosticFactory4<*, A, B, C, D>,
factory: FirDiagnosticFactory4<A, B, C, D>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
@@ -54,7 +54,7 @@ class FirDiagnosticFactoryToRendererMap(val name: String) {
put(factory, FirDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
}
private fun put(factory: AbstractFirDiagnosticFactory<*, *>, renderer: FirDiagnosticRenderer<*>) {
private fun put(factory: AbstractFirDiagnosticFactory, renderer: FirDiagnosticRenderer) {
renderersMap[factory] = renderer
}
}
@@ -5,30 +5,34 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.diagnostics.rendering.*
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticParameterRenderer
import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
import org.jetbrains.kotlin.diagnostics.rendering.renderParameter
import java.text.MessageFormat
sealed interface FirDiagnosticRenderer<D : FirDiagnostic<*>> {
fun render(diagnostic: D): String
fun renderParameters(diagnostic: D): Array<out Any?>
sealed interface FirDiagnosticRenderer {
fun render(diagnostic: FirDiagnostic): String
fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?>
}
class SimpleFirDiagnosticRenderer(private val message: String) : FirDiagnosticRenderer<FirSimpleDiagnostic<*>> {
override fun render(diagnostic: FirSimpleDiagnostic<*>): String {
class SimpleFirDiagnosticRenderer(private val message: String) : FirDiagnosticRenderer {
override fun render(diagnostic: FirDiagnostic): String {
require(diagnostic is FirSimpleDiagnostic)
return message
}
override fun renderParameters(diagnostic: FirSimpleDiagnostic<*>): Array<out Any?> {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirSimpleDiagnostic)
return emptyArray()
}
}
sealed class AbstractFirDiagnosticWithParametersRenderer<D : FirDiagnostic<*>>(
sealed class AbstractFirDiagnosticWithParametersRenderer(
protected val message: String
) : FirDiagnosticRenderer<D> {
) : FirDiagnosticRenderer {
private val messageFormat = MessageFormat(message)
final override fun render(diagnostic: D): String {
final override fun render(diagnostic: FirDiagnostic): String {
return messageFormat.format(renderParameters(diagnostic))
}
}
@@ -36,10 +40,12 @@ sealed class AbstractFirDiagnosticWithParametersRenderer<D : FirDiagnostic<*>>(
class FirDiagnosticWithParameters1Renderer<A>(
message: String,
private val rendererForA: DiagnosticParameterRenderer<A>?,
) : AbstractFirDiagnosticWithParametersRenderer<FirDiagnosticWithParameters1<*, A>>(message) {
override fun renderParameters(diagnostic: FirDiagnosticWithParameters1<*, A>): Array<out Any?> {
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters1<*>)
val context = RenderingContext.of(diagnostic.a)
return arrayOf(renderParameter(diagnostic.a, rendererForA, context))
@Suppress("UNCHECKED_CAST")
return arrayOf(renderParameter(diagnostic.a as A, rendererForA, context))
}
}
@@ -47,12 +53,14 @@ class FirDiagnosticWithParameters2Renderer<A, B>(
message: String,
private val rendererForA: DiagnosticParameterRenderer<A>?,
private val rendererForB: DiagnosticParameterRenderer<B>?,
) : AbstractFirDiagnosticWithParametersRenderer<FirDiagnosticWithParameters2<*, A, B>>(message) {
override fun renderParameters(diagnostic: FirDiagnosticWithParameters2<*, A, B>): Array<out Any?> {
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters2<*, *>)
val context = RenderingContext.of(diagnostic.a, diagnostic.b)
@Suppress("UNCHECKED_CAST")
return arrayOf(
renderParameter(diagnostic.a, rendererForA, context),
renderParameter(diagnostic.b, rendererForB, context),
renderParameter(diagnostic.a as A, rendererForA, context),
renderParameter(diagnostic.b as B, rendererForB, context),
)
}
}
@@ -62,13 +70,15 @@ class FirDiagnosticWithParameters3Renderer<A, B, C>(
private val rendererForA: DiagnosticParameterRenderer<A>?,
private val rendererForB: DiagnosticParameterRenderer<B>?,
private val rendererForC: DiagnosticParameterRenderer<C>?,
) : AbstractFirDiagnosticWithParametersRenderer<FirDiagnosticWithParameters3<*, A, B, C>>(message) {
override fun renderParameters(diagnostic: FirDiagnosticWithParameters3<*, A, B, C>): Array<out Any?> {
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters3<*, *, *>)
val context = RenderingContext.of(diagnostic.a, diagnostic.b, diagnostic.c)
@Suppress("UNCHECKED_CAST")
return arrayOf(
renderParameter(diagnostic.a, rendererForA, context),
renderParameter(diagnostic.b, rendererForB, context),
renderParameter(diagnostic.c, rendererForC, context),
renderParameter(diagnostic.a as A, rendererForA, context),
renderParameter(diagnostic.b as B, rendererForB, context),
renderParameter(diagnostic.c as C, rendererForC, context),
)
}
}
@@ -79,14 +89,16 @@ class FirDiagnosticWithParameters4Renderer<A, B, C, D>(
private val rendererForB: DiagnosticParameterRenderer<B>?,
private val rendererForC: DiagnosticParameterRenderer<C>?,
private val rendererForD: DiagnosticParameterRenderer<D>?,
) : AbstractFirDiagnosticWithParametersRenderer<FirDiagnosticWithParameters4<*, A, B, C, D>>(message) {
override fun renderParameters(diagnostic: FirDiagnosticWithParameters4<*, A, B, C, D>): Array<out Any?> {
val context = RenderingContext.of(diagnostic.a, diagnostic.b, diagnostic.c)
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters4<*, *, *, *>)
val context = RenderingContext.of(diagnostic.a, diagnostic.b, diagnostic.c, diagnostic.d)
@Suppress("UNCHECKED_CAST")
return arrayOf(
renderParameter(diagnostic.a, rendererForA, context),
renderParameter(diagnostic.b, rendererForB, context),
renderParameter(diagnostic.c, rendererForC, context),
renderParameter(diagnostic.d, rendererForD, context),
renderParameter(diagnostic.a as A, rendererForA, context),
renderParameter(diagnostic.b as B, rendererForB, context),
renderParameter(diagnostic.c as C, rendererForC, context),
renderParameter(diagnostic.d as D, rendererForD, context),
)
}
}
@@ -11,28 +11,38 @@ import org.jetbrains.kotlin.diagnostics.PositioningStrategy
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
open class SourceElementPositioningStrategy<in E : PsiElement>(
val lightTreeStrategy: LightTreePositioningStrategy,
val psiStrategy: PositioningStrategy<E>
class SourceElementPositioningStrategy(
private val lightTreeStrategy: LightTreePositioningStrategy,
private val psiStrategy: PositioningStrategy<*>
) {
fun markDiagnostic(diagnostic: FirDiagnostic<*>): List<TextRange> {
fun markDiagnostic(diagnostic: FirDiagnostic): List<TextRange> {
val element = diagnostic.element
if (element is FirPsiSourceElement<*>) {
if (element is FirPsiSourceElement) {
@Suppress("UNCHECKED_CAST")
return psiStrategy.mark(element.psi as E)
return psiStrategy.hackyMark(element.psi)
}
return lightTreeStrategy.mark(element.lighterASTNode, element.startOffset, element.endOffset, element.treeStructure)
}
fun isValid(element: FirSourceElement): Boolean {
if (element is FirPsiSourceElement<*>) {
if (element is FirPsiSourceElement) {
@Suppress("UNCHECKED_CAST")
return psiStrategy.isValid(element.psi as E)
return psiStrategy.hackyIsValid(element.psi)
}
return lightTreeStrategy.isValid(element.lighterASTNode, element.treeStructure)
}
private fun PositioningStrategy<*>.hackyMark(psi: PsiElement): List<TextRange> {
@Suppress("UNCHECKED_CAST")
return (this as PositioningStrategy<PsiElement>).mark(psi)
}
private fun PositioningStrategy<*>.hackyIsValid(psi: PsiElement): Boolean {
@Suppress("UNCHECKED_CAST")
return (this as PositioningStrategy<PsiElement>).isValid(psi)
}
companion object {
val DEFAULT: SourceElementPositioningStrategy<PsiElement> = SourceElementPositioningStrategies.DEFAULT
val DEFAULT: SourceElementPositioningStrategy = SourceElementPositioningStrategies.DEFAULT
}
}
@@ -5,7 +5,6 @@
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
@@ -36,7 +35,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
private fun ConeDiagnostic.toFirDiagnostic(
source: FirSourceElement,
qualifiedAccessSource: FirSourceElement?
): FirDiagnostic<FirSourceElement>? = when (this) {
): FirDiagnostic? = when (this) {
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())
@@ -91,7 +90,7 @@ private fun ConeDiagnostic.toFirDiagnostic(
fun ConeDiagnostic.toFirDiagnostics(
source: FirSourceElement,
qualifiedAccessSource: FirSourceElement?
): List<FirDiagnostic<FirSourceElement>> {
): List<FirDiagnostic> {
return when (this) {
is ConeInapplicableCandidateError -> mapInapplicableCandidateError(this, source, qualifiedAccessSource)
is ConeConstraintSystemHasContradiction -> mapSystemHasContradictionError(this, source, qualifiedAccessSource)
@@ -104,7 +103,7 @@ private fun mapUnsafeCallError(
rootCause: UnsafeCall,
source: FirSourceElement,
qualifiedAccessSource: FirSourceElement?,
): FirDiagnostic<*>? {
): FirDiagnostic? {
if (candidate.callInfo.isImplicitInvoke) {
return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.createOn(source, rootCause.actualType)
}
@@ -152,7 +151,7 @@ private fun mapInapplicableCandidateError(
diagnostic: ConeInapplicableCandidateError,
source: FirSourceElement,
qualifiedAccessSource: FirSourceElement?,
): List<FirDiagnostic<FirSourceElement>> {
): List<FirDiagnostic> {
val genericDiagnostic = FirErrors.INAPPLICABLE_CANDIDATE.createOn(source, diagnostic.candidate.symbol)
val diagnostics = diagnostic.candidate.diagnostics.filter { it.applicability == diagnostic.applicability }.mapNotNull { rootCause ->
when (rootCause) {
@@ -207,9 +206,9 @@ private fun mapSystemHasContradictionError(
diagnostic: ConeConstraintSystemHasContradiction,
source: FirSourceElement,
qualifiedAccessSource: FirSourceElement?,
): List<FirDiagnostic<FirSourceElement>> {
): List<FirDiagnostic> {
val errorsToIgnore = mutableSetOf<ConstraintSystemError>()
return buildList<FirDiagnostic<FirSourceElement>> {
return buildList<FirDiagnostic> {
for (error in diagnostic.candidate.system.errors) {
addIfNotNull(
error.toDiagnostic(
@@ -252,7 +251,7 @@ private fun ConstraintSystemError.toDiagnostic(
typeContext: ConeTypeContext,
errorsToIgnore: MutableSet<ConstraintSystemError>,
candidate: Candidate,
): FirDiagnostic<FirSourceElement>? {
): FirDiagnostic? {
return when (this) {
is NewConstraintError -> {
val position = position.from
@@ -329,7 +328,7 @@ private fun ConstraintSystemError.toDiagnostic(
private val NewConstraintError.lowerConeType: ConeKotlinType get() = lowerType as ConeKotlinType
private val NewConstraintError.upperConeType: ConeKotlinType get() = upperType as ConeKotlinType
private fun ConeSimpleDiagnostic.getFactory(source: FirSourceElement): FirDiagnosticFactory0<*> {
private fun ConeSimpleDiagnostic.getFactory(source: FirSourceElement): FirDiagnosticFactory0 {
@Suppress("UNCHECKED_CAST")
return when (kind) {
DiagnosticKind.Syntax -> FirErrors.SYNTAX
@@ -375,35 +374,35 @@ private fun ConeSimpleDiagnostic.getFactory(source: FirSourceElement): FirDiagno
}
@OptIn(InternalDiagnosticFactoryMethod::class)
private fun <P : PsiElement> FirDiagnosticFactory0<P>.createOn(
private fun FirDiagnosticFactory0.createOn(
element: FirSourceElement?
): FirSimpleDiagnostic<*>? {
): FirSimpleDiagnostic? {
return element?.let { on(it, positioningStrategy = null) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
private fun <P : PsiElement, A> FirDiagnosticFactory1<P, A>.createOn(
private fun <A> FirDiagnosticFactory1<A>.createOn(
element: FirSourceElement?,
a: A
): FirDiagnosticWithParameters1<*, 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(
private fun <A, B> FirDiagnosticFactory2<A, B>.createOn(
element: FirSourceElement?,
a: A,
b: B
): FirDiagnosticWithParameters2<*, A, 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(
private fun <A, B, C> FirDiagnosticFactory3<A, B, C>.createOn(
element: FirSourceElement?,
a: A,
b: B,
c: C
): FirDiagnosticWithParameters3<*, A, B, C>? {
): FirDiagnosticWithParameters3<A, B, C>? {
return element?.let { on(it, a, b, c, positioningStrategy = null) }
}
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
abstract class BaseDiagnosticReporter : DiagnosticReporter() {
abstract val diagnostics: List<FirDiagnostic<*>>
abstract val diagnostics: List<FirDiagnostic>
}
@@ -9,11 +9,11 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
class DiagnosticReporterWithSuppress : BaseDiagnosticReporter() {
private val _diagnostics: MutableList<FirDiagnostic<*>> = mutableListOf()
override val diagnostics: List<FirDiagnostic<*>>
private val _diagnostics: MutableList<FirDiagnostic> = mutableListOf()
override val diagnostics: List<FirDiagnostic>
get() = _diagnostics
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) {
if (diagnostic == null) return
if (!context.isDiagnosticSuppressed(diagnostic)) {
_diagnostics += diagnostic
@@ -9,11 +9,11 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
class SimpleDiagnosticReporter : BaseDiagnosticReporter() {
private val _diagnostics: MutableList<FirDiagnostic<*>> = mutableListOf()
override val diagnostics: List<FirDiagnostic<*>>
private val _diagnostics: MutableList<FirDiagnostic> = mutableListOf()
override val diagnostics: List<FirDiagnostic>
get() = _diagnostics
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) {
if (diagnostic == null) return
_diagnostics += diagnostic
}
@@ -26,7 +26,7 @@ class IncrementalPassThroughLookupTrackerComponent(
val path = sourceToFilePathsCache.getOrPut(definedSource) {
sourceToFilePath(definedSource)
}
val position = if (requiresPosition && source != null && source is FirPsiSourceElement<*>) {
val position = if (requiresPosition && source != null && source is FirPsiSourceElement) {
getLineAndColumnInPsiFile(source.psi.containingFile, source.psi.textRange).let { Position(it.line, it.column) }
} else Position.NO_POSITION
@@ -31,7 +31,7 @@ import java.io.File
abstract class AbstractFirAnalyzerFacade {
abstract val scopeSession: ScopeSession
abstract fun runCheckers(): Map<FirFile, List<FirDiagnostic<*>>>
abstract fun runCheckers(): Map<FirFile, List<FirDiagnostic>>
abstract fun runResolution(): List<FirFile>
@@ -50,7 +50,7 @@ class FirAnalyzerFacade(
override val scopeSession: ScopeSession
get() = _scopeSession!!
private var collectedDiagnostics: Map<FirFile, List<FirDiagnostic<*>>>? = null
private var collectedDiagnostics: Map<FirFile, List<FirDiagnostic>>? = null
private fun buildRawFir() {
if (firFiles != null) return
@@ -82,7 +82,7 @@ class FirAnalyzerFacade(
}
@OptIn(ExperimentalStdlibApi::class)
override fun runCheckers(): Map<FirFile, List<FirDiagnostic<*>>> {
override fun runCheckers(): Map<FirFile, List<FirDiagnostic>> {
if (_scopeSession == null) runResolution()
if (collectedDiagnostics != null) return collectedDiagnostics!!
val collector = FirDiagnosticsCollector.create(session, scopeSession)
@@ -72,7 +72,7 @@ fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null) {
register(FirNameConflictsTrackerComponent::class, FirNameConflictsTracker())
if (lookupTracker != null) {
val firFileToPath: (FirSourceElement) -> String = {
val psiSource = (it as? FirPsiSourceElement<*>) ?: TODO("Not implemented for non-FirPsiSourceElement")
val psiSource = (it as? FirPsiSourceElement) ?: TODO("Not implemented for non-FirPsiSourceElement")
((psiSource.psi as? PsiFile) ?: psiSource.psi.containingFile).virtualFile.path
}
register(
@@ -14,12 +14,16 @@ import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.caches.*
import org.jetbrains.kotlin.fir.caches.createCache
import org.jetbrains.kotlin.fir.caches.firCachesFactory
import org.jetbrains.kotlin.fir.caches.getValue
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructedClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.builder.buildEnumEntry
import org.jetbrains.kotlin.fir.declarations.builder.buildOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.defaultType
@@ -549,7 +553,7 @@ class JavaSymbolProvider(
}
private fun buildConstructorForAnnotationClass(
classSource: FirFakeSourceElement<*>?,
classSource: FirFakeSourceElement?,
constructorId: CallableId,
ownerClassBuilder: FirJavaClassBuilder,
valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.fir.types.impl.FirTypeArgumentListImpl
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
@@ -79,7 +78,7 @@ open class RawFirBuilder(
return reference.accept(Visitor(), Unit) as FirTypeRef
}
override fun PsiElement.toFirSourceElement(kind: FirFakeSourceElementKind?): FirPsiSourceElement<*> {
override fun PsiElement.toFirSourceElement(kind: FirFakeSourceElementKind?): FirPsiSourceElement {
val actualKind = kind ?: this@RawFirBuilder.context.forcedElementSourceKind ?: FirRealSourceElementKind
return this.toFirPsiSourceElement(actualKind)
}
@@ -1988,7 +1987,7 @@ open class RawFirBuilder(
private fun splitToCalleeAndReceiver(
calleeExpression: KtExpression?,
defaultSource: FirPsiSourceElement<*>,
defaultSource: FirPsiSourceElement,
): CalleeAndReceiver {
return when (calleeExpression) {
is KtSimpleNameExpression ->
@@ -187,7 +187,7 @@ sealed class FirSourceElement {
// NB: in certain situations, psi.node could be null
// Potentially exceptions can be provoked by elementType / lighterASTNode
sealed class FirPsiSourceElement<out P : PsiElement>(val psi: P) : FirSourceElement() {
sealed class FirPsiSourceElement(val psi: PsiElement) : FirSourceElement() {
override val elementType: IElementType
get() = psi.node.elementType
@@ -268,23 +268,23 @@ sealed class FirPsiSourceElement<out P : PsiElement>(val psi: P) : FirSourceElem
}
}
class FirRealPsiSourceElement<out P : PsiElement>(psi: P) : FirPsiSourceElement<P>(psi) {
class FirRealPsiSourceElement(psi: PsiElement) : FirPsiSourceElement(psi) {
override val kind: FirSourceElementKind get() = FirRealSourceElementKind
}
class FirFakeSourceElement<out P : PsiElement>(psi: P, override val kind: FirFakeSourceElementKind) : FirPsiSourceElement<P>(psi)
class FirFakeSourceElement(psi: PsiElement, override val kind: FirFakeSourceElementKind) : FirPsiSourceElement(psi)
fun FirSourceElement.fakeElement(newKind: FirFakeSourceElementKind): FirSourceElement {
return when (this) {
is FirLightSourceElement -> FirLightSourceElement(lighterASTNode, startOffset, endOffset, treeStructure, newKind)
is FirPsiSourceElement<*> -> FirFakeSourceElement(psi, newKind)
is FirPsiSourceElement -> FirFakeSourceElement(psi, newKind)
}
}
fun FirSourceElement.realElement(): FirSourceElement = when (this) {
is FirRealPsiSourceElement<*> -> this
is FirRealPsiSourceElement -> this
is FirLightSourceElement -> FirLightSourceElement(lighterASTNode, startOffset, endOffset, treeStructure, FirRealSourceElementKind)
is FirPsiSourceElement<*> -> FirRealPsiSourceElement(psi)
is FirPsiSourceElement -> FirRealPsiSourceElement(psi)
}
@@ -305,27 +305,27 @@ class FirLightSourceElement(
* If it is `pure` [FirLightSourceElement], i.e, compiler created it in light tree mode, then return [unwrapToFirPsiSourceElement] `null`.
* Otherwise, return some not-null result.
*/
fun unwrapToFirPsiSourceElement(): FirPsiSourceElement<*>? {
fun unwrapToFirPsiSourceElement(): FirPsiSourceElement? {
if (treeStructure !is FirPsiSourceElement.WrappedTreeStructure) return null
val node = treeStructure.unwrap(lighterASTNode)
return node.psi?.toFirPsiSourceElement(kind)
}
}
val FirSourceElement?.psi: PsiElement? get() = (this as? FirPsiSourceElement<*>)?.psi
val FirSourceElement?.psi: PsiElement? get() = (this as? FirPsiSourceElement)?.psi
val FirSourceElement?.text: CharSequence?
get() = when (this) {
is FirPsiSourceElement<*> -> psi.text
is FirPsiSourceElement -> psi.text
is FirLightSourceElement -> treeStructure.toString(lighterASTNode)
else -> null
}
val FirElement.psi: PsiElement? get() = (source as? FirPsiSourceElement<*>)?.psi
val FirElement.realPsi: PsiElement? get() = (source as? FirRealPsiSourceElement<*>)?.psi
val FirElement.psi: PsiElement? get() = (source as? FirPsiSourceElement)?.psi
val FirElement.realPsi: PsiElement? get() = (source as? FirRealPsiSourceElement)?.psi
@Suppress("NOTHING_TO_INLINE")
inline fun PsiElement.toFirPsiSourceElement(kind: FirSourceElementKind = FirRealSourceElementKind): FirPsiSourceElement<*> = when (kind) {
inline fun PsiElement.toFirPsiSourceElement(kind: FirSourceElementKind = FirRealSourceElementKind): FirPsiSourceElement = when (kind) {
is FirRealSourceElementKind -> FirRealPsiSourceElement(this)
is FirFakeSourceElementKind -> FirFakeSourceElement(this, kind)
}
@@ -68,7 +68,7 @@ fun <R : FirTypeRef> R.copyWithNewSourceKind(newKind: FirFakeSourceElementKind):
fun FirSourceElement.getWholeQualifierSourceIfPossible(stepsToWholeQualifier: Int): FirSourceElement {
if (stepsToWholeQualifier == 0) return this
return when (this) {
is FirRealPsiSourceElement<*> -> {
is FirRealPsiSourceElement -> {
val qualifiersChain = generateSequence(psi) { it.parent }
val wholeQualifier = qualifiersChain.elementAt(stepsToWholeQualifier)
wholeQualifier.toFirPsiSourceElement() as FirRealPsiSourceElement
@@ -82,7 +82,7 @@ fun FirSourceElement.getWholeQualifierSourceIfPossible(stepsToWholeQualifier: In
endOffset = wholeQualifier.endOffset + (this.endOffset - this.lighterASTNode.endOffset)
)
}
is FirFakeSourceElement<*> -> {
is FirFakeSourceElement -> {
this
}
}
@@ -53,6 +53,7 @@ sealed class RenderingContext {
is DiagnosticWithParameters1<*, *> -> listOf(d.a)
is DiagnosticWithParameters2<*, *, *> -> listOf(d.a, d.b)
is DiagnosticWithParameters3<*, *, *, *> -> listOf(d.a, d.b, d.c)
is DiagnosticWithParameters4<*, *, *, *, *> -> listOf(d.a, d.b, d.c, d.d)
is ParametrizedDiagnostic<*> -> error("Unexpected diagnostic: ${d::class.java}")
else -> listOf()
}
@@ -7,11 +7,7 @@ package org.jetbrains.kotlin.test.backend.handlers
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderer
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_FIR_DIAGNOSTICS
@@ -33,7 +29,7 @@ class NoFirCompilationErrorsHandler(testServices: TestServices) : FirAnalysisHan
if (diagnostic.severity == Severity.ERROR) {
hasError = true
if (!ignoreErrors) {
val diagnosticText = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic).hackyRender(diagnostic)
val diagnosticText = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic).render(diagnostic)
val range = diagnostic.textRanges.first()
val locationText = firFile.source?.psi?.containingFile?.let { psiFile ->
PsiDiagnosticUtils.atLocation(psiFile, range)
@@ -48,12 +44,5 @@ class NoFirCompilationErrorsHandler(testServices: TestServices) : FirAnalysisHan
}
}
private fun FirDiagnosticRenderer<*>.hackyRender(diagnostic: FirDiagnostic<*>): String {
@Suppress("UNCHECKED_CAST")
val renderer = this as FirDiagnosticRenderer<FirDiagnostic<FirSourceElement>>
val castedDiagnostic = diagnostic as FirDiagnostic<FirSourceElement>
return renderer.render(castedDiagnostic)
}
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
}
@@ -18,7 +18,7 @@ object FirMetaInfoUtils {
}
class FirDiagnosticCodeMetaInfo(
val diagnostic: FirDiagnostic<*>,
val diagnostic: FirDiagnostic,
renderConfiguration: FirDiagnosticCodeMetaRenderConfiguration
) : CodeMetaInfo {
private val textRangeFromClassicDiagnostic: TextRange = run {
@@ -67,7 +67,7 @@ class FirDiagnosticCodeMetaRenderConfiguration(
@Suppress("UNCHECKED_CAST")
val renderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic)
if (renderer is AbstractFirDiagnosticWithParametersRenderer<*>) {
if (renderer is AbstractFirDiagnosticWithParametersRenderer) {
renderer.renderParameters(diagnostic).mapTo(params, Any?::toString)
}
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.test.model.TestFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.utils.AbstractTwoAttributesMetaInfoProcessor
import org.jetbrains.kotlin.types.SmartcastStability
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -93,7 +92,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
}
}
private fun FirDiagnostic<*>.toMetaInfo(
private fun FirDiagnostic.toMetaInfo(
file: TestFile,
lightTreeEnabled: Boolean,
lightTreeComparingModeEnabled: Boolean,
@@ -139,7 +138,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
lightTreeEnabled: Boolean,
lightTreeComparingModeEnabled: Boolean
) {
val result = mutableListOf<FirDiagnostic<*>>()
val result = mutableListOf<FirDiagnostic>()
val diagnosedRangesToDiagnosticNames = globalMetadataInfoHandler.getExistingMetaInfosForFile(testFile).groupBy(
keySelector = { it.start..it.end },
valueTransform = { it.tag }
@@ -177,7 +176,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
fun createExpressionTypeDiagnosticIfExpected(
element: FirExpression,
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>
): FirDiagnosticWithParameters1<FirSourceElement, String>? =
): FirDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.EXPRESSION_TYPE.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
element.typeRef.renderAsString((element as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.originalType)
}
@@ -194,7 +193,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
element: FirElement,
reference: FirNamedReference,
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>
): FirDiagnosticWithParameters1<FirSourceElement, String>? =
): FirDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.CALL.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
val resolvedSymbol = (reference as? FirResolvedNamedReference)?.resolvedSymbol
val fqName = resolvedSymbol?.fqNameUnsafe()
@@ -205,7 +204,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
return if (this === DebugInfoDiagnosticFactory1.CALL
&& sourceElement.elementType == KtNodeTypes.DOT_QUALIFIED_EXPRESSION
) {
if (sourceElement is FirPsiSourceElement<*>) {
if (sourceElement is FirPsiSourceElement) {
val psi = (sourceElement.psi as KtDotQualifiedExpression).selectorExpression
psi?.let { FirRealPsiSourceElement(it) } ?: sourceElement
} else {
@@ -230,7 +229,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
element: FirElement,
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>,
argument: () -> String,
): FirDiagnosticWithParameters1<FirSourceElement, String>? {
): FirDiagnosticWithParameters1<String>? {
val sourceElement = element.source ?: return null
if (sourceElement.kind !in allowedKindsForDebugInfo) return null
@@ -245,9 +244,9 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
}
val argumentText = argument()
val factory = FirDiagnosticFactory1<PsiElement, String>(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class)
val factory = FirDiagnosticFactory1<String>(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class)
return when (positionedElement) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
is FirPsiSourceElement -> FirPsiDiagnosticWithParameters1(
positionedElement,
argumentText,
severity,
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import java.io.File
import java.util.*
abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
override fun analyzeAndCheck(testDataFile: File, files: List<TestFile>) {
@@ -219,7 +218,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
}
protected fun TestFile.getActualText(
firDiagnostics: Iterable<FirDiagnostic<*>>,
firDiagnostics: Iterable<FirDiagnostic>,
actualText: StringBuilder
): Boolean {
val ktFile = this.ktFile
@@ -331,7 +330,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
return ok[0]
}
private fun Iterable<FirDiagnostic<*>>.toActualDiagnostic(root: PsiElement): List<ActualDiagnostic> {
private fun Iterable<FirDiagnostic>.toActualDiagnostic(root: PsiElement): List<ActualDiagnostic> {
val result = mutableListOf<ActualDiagnostic>()
filterIsInstance<Diagnostic>().mapTo(result) {
ActualDiagnostic(it, null, true)
@@ -117,7 +117,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
for (testFile in testFiles) {
val firFile = firFiles.firstOrNull { it.psi == testFile.ktFile }
if (firFile != null) {
val debugInfoDiagnostics: List<FirDiagnostic<*>> =
val debugInfoDiagnostics: List<FirDiagnostic> =
collectDebugInfoDiagnostics(firFile, testFile.diagnosedRangesToDiagnosticNames)
testFile.getActualText(
diagnostics.getValue(firFile) + debugInfoDiagnostics,
@@ -134,8 +134,8 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
protected fun collectDebugInfoDiagnostics(
firFile: FirFile,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>
): List<FirDiagnostic<*>> {
val result = mutableListOf<FirDiagnostic<*>>()
): List<FirDiagnostic> {
val result = mutableListOf<FirDiagnostic>()
object : FirDefaultVisitorVoid() {
@@ -166,7 +166,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
fun createExpressionTypeDiagnosticIfExpected(
element: FirExpression,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>
): FirDiagnosticWithParameters1<FirSourceElement, String>? =
): FirDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.EXPRESSION_TYPE.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
element.typeRef.renderAsString((element as? FirExpressionWithSmartcast)?.originalType)
}
@@ -183,7 +183,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
element: FirElement,
reference: FirNamedReference,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>
): FirDiagnosticWithParameters1<FirSourceElement, String>? =
): FirDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.CALL.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
val resolvedSymbol = (reference as? FirResolvedNamedReference)?.resolvedSymbol
@@ -195,7 +195,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
element: FirElement,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>,
argument: () -> String,
): FirDiagnosticWithParameters1<FirSourceElement, String>? {
): FirDiagnosticWithParameters1<String>? {
val sourceElement = element.source ?: return null
val sourceKind = sourceElement.kind
if (sourceKind !in allowedKindsForDebugInfo) {
@@ -211,7 +211,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
val argumentText = argument()
return when (sourceElement) {
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
is FirPsiSourceElement -> FirPsiDiagnosticWithParameters1(
sourceElement,
argumentText,
severity,
@@ -264,9 +264,9 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
}
protected fun collectDiagnostics(firFiles: List<FirFile>): Map<FirFile, List<FirDiagnostic<*>>> {
protected fun collectDiagnostics(firFiles: List<FirFile>): Map<FirFile, List<FirDiagnostic>> {
val collectors = mutableMapOf<FirSession, AbstractDiagnosticCollector>()
val result = mutableMapOf<FirFile, List<FirDiagnostic<*>>>()
val result = mutableMapOf<FirFile, List<FirDiagnostic>>()
for (firFile in firFiles) {
val session = firFile.moduleData.session
val collector = collectors.computeIfAbsent(session) { createCollector(session) }
@@ -72,10 +72,10 @@ internal class FirModuleResolveStateDepended(
return null
}
override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic<*>> =
override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic> =
TODO("Diagnostics are not implemented for depended state")
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic<*>> =
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic> =
TODO("Diagnostics are not implemented for depended state")
@OptIn(InternalForInline::class)
@@ -89,4 +89,4 @@ internal class FirModuleResolveStateDepended(
@OptIn(InternalForInline::class)
override fun findSourceFirCompiledDeclaration(ktDeclaration: KtDeclaration) =
originalState.findSourceFirDeclaration(ktDeclaration)
}
}
@@ -73,10 +73,10 @@ internal class FirModuleResolveStateImpl(
override fun tryGetCachedFirFile(declaration: FirDeclaration, cache: ModuleFileCache): FirFile? =
cache.getContainerFirFile(declaration)
override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic<*>> =
override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic> =
diagnosticsCollector.getDiagnosticsFor(element, filter)
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic<*>> =
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic> =
diagnosticsCollector.collectDiagnosticsForFile(ktFile, filter)
@OptIn(InternalForInline::class)
@@ -173,4 +173,4 @@ internal class FirModuleResolveStateImpl(
)
return declaration
}
}
}
@@ -15,7 +15,10 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.ResolveType
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtLambdaExpression
abstract class FirModuleResolveState {
abstract val project: Project
@@ -43,9 +46,9 @@ abstract class FirModuleResolveState {
*/
internal abstract fun tryGetCachedFirFile(declaration: FirDeclaration, cache: ModuleFileCache): FirFile?
internal abstract fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic<*>>
internal abstract fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic>
internal abstract fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic<*>>
internal abstract fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic>
internal inline fun <D : FirDeclaration, R> withLock(declaration: D, declarationLockType: DeclarationLockType, action: (D) -> R): R {
val originalDeclaration = (declaration as? FirCallableDeclaration<*>)?.unwrapFakeOverrides() ?: declaration
@@ -85,4 +88,4 @@ abstract class FirModuleResolveState {
internal abstract fun <D : FirDeclaration> resolveFirToPhase(declaration: D, toPhase: FirResolvePhase): D
internal abstract fun <D : FirDeclaration> resolveFirToResolveType(declaration: D, type: ResolveType): D
}
}
@@ -169,7 +169,7 @@ fun <D : FirDeclaration, R> D.withFirDeclarationInWriteLock(
* Returns a list of Diagnostics compiler finds for given [KtElement]
* This operation could be performance affective because it create FIleStructureElement and resolve non-local declaration into BODY phase
*/
fun KtElement.getDiagnostics(resolveState: FirModuleResolveState, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic<*>> =
fun KtElement.getDiagnostics(resolveState: FirModuleResolveState, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic> =
resolveState.getDiagnostics(this, filter)
/**
@@ -179,7 +179,7 @@ fun KtElement.getDiagnostics(resolveState: FirModuleResolveState, filter: Diagno
fun KtFile.collectDiagnosticsForFile(
resolveState: FirModuleResolveState,
filter: DiagnosticCheckerFilter
): Collection<FirPsiDiagnostic<*>> =
): Collection<FirPsiDiagnostic> =
resolveState.collectDiagnosticsForFile(this, filter)
/**
@@ -16,15 +16,15 @@ internal class DiagnosticsCollector(
private val fileStructureCache: FileStructureCache,
private val cache: ModuleFileCache,
) {
fun getDiagnosticsFor(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic<*>> {
fun getDiagnosticsFor(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic> {
val fileStructure = fileStructureCache.getFileStructure(element.containingKtFile, cache)
val structureElement = fileStructure.getStructureElementFor(element)
val diagnostics = structureElement.diagnostics
return diagnostics.diagnosticsFor(filter, element)
}
fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic<*>> {
fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic> {
val fileStructure = fileStructureCache.getFileStructure(ktFile, cache)
return fileStructure.getAllDiagnosticsForFile(filter)
}
}
}
@@ -9,9 +9,9 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
internal class FileStructureElementDiagnosticList(
private val map: Map<PsiElement, List<FirPsiDiagnostic<*>>>
private val map: Map<PsiElement, List<FirPsiDiagnostic>>
) {
fun diagnosticsFor(element: PsiElement): List<FirPsiDiagnostic<*>> = map[element] ?: emptyList()
fun diagnosticsFor(element: PsiElement): List<FirPsiDiagnostic> = map[element] ?: emptyList()
inline fun forEach(action: (List<FirPsiDiagnostic<*>>) -> Unit) = map.values.forEach(action)
}
inline fun forEach(action: (List<FirPsiDiagnostic>) -> Unit) = map.values.forEach(action)
}
@@ -25,8 +25,8 @@ internal class FileStructureElementDiagnostics(
retriever.retrieve(firFile, FileStructureElementDiagnosticsCollector.EXTENDED_COLLECTOR, lockProvider)
}
fun diagnosticsFor(filter: DiagnosticCheckerFilter, element: PsiElement): List<FirPsiDiagnostic<*>> =
SmartList<FirPsiDiagnostic<*>>().apply {
fun diagnosticsFor(filter: DiagnosticCheckerFilter, element: PsiElement): List<FirPsiDiagnostic> =
SmartList<FirPsiDiagnostic>().apply {
if (filter.runCommonCheckers) {
addAll(diagnosticByCommonCheckers.diagnosticsFor(element))
}
@@ -36,7 +36,7 @@ internal class FileStructureElementDiagnostics(
}
inline fun forEach(filter: DiagnosticCheckerFilter, action: (List<FirPsiDiagnostic<*>>) -> Unit) {
inline fun forEach(filter: DiagnosticCheckerFilter, action: (List<FirPsiDiagnostic>) -> Unit) {
if (filter.runCommonCheckers) {
diagnosticByCommonCheckers.forEach(action)
}
@@ -44,4 +44,4 @@ internal class FileStructureElementDiagnostics(
diagnosticByExtendedCheckers.forEach(action)
}
}
}
}
@@ -11,14 +11,14 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.idea.fir.low.level.api.util.addValueFor
internal class FirIdeDiagnosticReporter : DiagnosticReporter() {
val diagnostics = mutableMapOf<PsiElement, MutableList<FirPsiDiagnostic<*>>>()
val diagnostics = mutableMapOf<PsiElement, MutableList<FirPsiDiagnostic>>()
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) {
if (diagnostic == null) return
if (context.isDiagnosticSuppressed(diagnostic)) return
val psiDiagnostic = when (diagnostic) {
is FirPsiDiagnostic<*> -> diagnostic
is FirPsiDiagnostic -> diagnostic
is FirLightDiagnostic -> diagnostic.toPsiDiagnostic()
else -> error("Unknown diagnostic type ${diagnostic::class.simpleName}")
}
@@ -26,7 +26,7 @@ internal class FirIdeDiagnosticReporter : DiagnosticReporter() {
}
}
private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic {
val psiSourceElement = element.unwrapToFirPsiSourceElement()
?: error("Diagnostic should be created from PSI in IDE")
@Suppress("UNCHECKED_CAST")
@@ -34,7 +34,7 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
is FirLightSimpleDiagnostic -> FirPsiSimpleDiagnostic(
psiSourceElement,
severity,
factory as FirDiagnosticFactory0<PsiElement>,
factory,
positioningStrategy
)
@@ -42,7 +42,7 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
psiSourceElement,
a,
severity,
factory as FirDiagnosticFactory1<PsiElement, Any?>,
factory as FirDiagnosticFactory1<Any?>,
positioningStrategy
)
@@ -50,7 +50,7 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
psiSourceElement,
a, b,
severity,
factory as FirDiagnosticFactory2<PsiElement, Any?, Any?>,
factory as FirDiagnosticFactory2<Any?, Any?>,
positioningStrategy
)
@@ -58,7 +58,7 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
psiSourceElement,
a, b, c,
severity,
factory as FirDiagnosticFactory3<PsiElement, Any?, Any?, Any?>,
factory as FirDiagnosticFactory3<Any?, Any?, Any?>,
positioningStrategy
)
@@ -66,7 +66,7 @@ private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
psiSourceElement,
a, b, c, d,
severity,
factory as FirDiagnosticFactory4<PsiElement, Any?, Any?, Any?, Any?>,
factory as FirDiagnosticFactory4<Any?, Any?, Any?, Any?>,
positioningStrategy
)
else -> error("Unknown diagnostic type ${this::class.simpleName}")
@@ -70,7 +70,7 @@ internal class FileStructure private constructor(
}
@OptIn(ExperimentalStdlibApi::class)
fun getAllDiagnosticsForFile(diagnosticCheckerFilter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic<*>> {
fun getAllDiagnosticsForFile(diagnosticCheckerFilter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic> {
val structureElements = getAllStructureElements()
return buildList {
@@ -78,7 +78,7 @@ internal class FileStructure private constructor(
}
}
private fun MutableCollection<FirPsiDiagnostic<*>>.collectDiagnosticsFromStructureElements(
private fun MutableCollection<FirPsiDiagnostic>.collectDiagnosticsFromStructureElements(
structureElements: Collection<FileStructureElement>,
diagnosticCheckerFilter: DiagnosticCheckerFilter
) {
@@ -25,7 +25,7 @@ internal fun FirDeclaration.getKtDeclarationForFirElement(): KtDeclaration {
require(this !is FirFile)
val ktDeclaration = (psi as? KtDeclaration) ?: run {
(source as? FirFakeSourceElement<*>).psi?.parentOfType()
(source as? FirFakeSourceElement).psi?.parentOfType()
}
check(ktDeclaration is KtDeclaration) {
"FirDeclaration should have a PSI of type KtDeclaration"
@@ -71,4 +71,4 @@ internal fun declarationCanBeLazilyResolved(declaration: KtDeclaration): Boolean
is KtClassLikeDeclaration -> declaration.getClassId() != null
else -> error("Unexpected ${declaration::class.qualifiedName}")
}
}
}
@@ -29,14 +29,13 @@ class LowLevelFirAnalyzerFacade(
) : AbstractFirAnalyzerFacade() {
override val scopeSession: ScopeSession get() = shouldNotBeCalled()
override fun runCheckers(): Map<FirFile, List<FirDiagnostic<*>>> {
override fun runCheckers(): Map<FirFile, List<FirDiagnostic>> {
findSealedInheritors()
return allFirFiles.values.associateWith { firFile ->
val ktFile = firFile.psi as KtFile
val diagnostics = ktFile.collectDiagnosticsForFile(resolveState, diagnosticCheckerFilter)
@Suppress("UNCHECKED_CAST")
diagnostics.toList() as List<FirDiagnostic<*>>
diagnostics.toList() as List<FirDiagnostic>
}
}
@@ -6,7 +6,10 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.generator.rendererrs
import org.jetbrains.kotlin.fir.checkers.generator.inBracketsWithIndent
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.*
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.ConversionContext
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.HLDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.HLDiagnosticList
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.HLDiagnosticParameter
import org.jetbrains.kotlin.util.SmartPrinter
import org.jetbrains.kotlin.util.withIndent
@@ -38,7 +41,7 @@ object FirDiagnosticToKtDiagnosticConverterRenderer : AbstractDiagnosticsDataCla
private fun SmartPrinter.printDiagnosticParameters(diagnostic: HLDiagnostic) {
printCustomParameters(diagnostic)
println("firDiagnostic as FirPsiDiagnostic<*>,")
println("firDiagnostic as FirPsiDiagnostic,")
println("token,")
}
@@ -5,10 +5,12 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.generator.rendererrs
import org.jetbrains.kotlin.fir.checkers.generator.inBracketsWithIndent
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.*
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.printTypeWithShortNames
import org.jetbrains.kotlin.fir.checkers.generator.collectClassNamesTo
import org.jetbrains.kotlin.fir.checkers.generator.inBracketsWithIndent
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.HLDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.HLDiagnosticList
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.HLDiagnosticParameter
import org.jetbrains.kotlin.idea.frontend.api.fir.generator.printTypeWithShortNames
import org.jetbrains.kotlin.util.SmartPrinter
import org.jetbrains.kotlin.util.withIndent
@@ -34,7 +36,7 @@ object KtDiagnosticClassImplementationRenderer : AbstractDiagnosticsDataClassRen
printTypeWithShortNames(diagnostic.original.psiType)
print(">")
inBracketsWithIndent {
println("override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)")
println("override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)")
}
}
@@ -42,7 +44,7 @@ object KtDiagnosticClassImplementationRenderer : AbstractDiagnosticsDataClassRen
for (parameter in diagnostic.parameters) {
printParameter(parameter)
}
println("firDiagnostic: FirPsiDiagnostic<*>,")
println("firDiagnostic: FirPsiDiagnostic,")
println("override val token: ValidityToken,")
}
@@ -134,8 +134,8 @@ private val allowedFakeElementKinds = setOf(
private fun FirElement.getAllowedPsi() = when (val source = source) {
null -> null
is FirRealPsiSourceElement<*> -> source.psi
is FirFakeSourceElement<*> -> if (source.kind in allowedFakeElementKinds) psi else null
is FirRealPsiSourceElement -> source.psi
is FirFakeSourceElement -> if (source.kind in allowedFakeElementKinds) psi else null
else -> null
}
@@ -40,12 +40,12 @@ internal interface KtFirAnalysisSessionComponent {
fun ConeKotlinType.asPsiType(mode: TypeMappingMode, psiContext: PsiElement) =
asPsiType(rootModuleSession, analysisSession.firResolveState, mode, psiContext)
fun FirPsiDiagnostic<*>.asKtDiagnostic(): KtDiagnosticWithPsi<*> =
KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, this as FirDiagnostic<*>)
fun FirPsiDiagnostic.asKtDiagnostic(): KtDiagnosticWithPsi<*> =
KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, this as FirDiagnostic)
fun ConeDiagnostic.asKtDiagnostic(source: FirSourceElement, qualifiedAccessSource: FirSourceElement?): KtDiagnosticWithPsi<*>? {
val firDiagnostic = toFirDiagnostics(source, qualifiedAccessSource).firstOrNull() ?: return null
check(firDiagnostic is FirPsiDiagnostic<*>)
check(firDiagnostic is FirPsiDiagnostic)
return firDiagnostic.asKtDiagnostic()
}
@@ -10,24 +10,20 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderer
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.diagnostics.KtDiagnosticWithPsi
internal interface KtAbstractFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
val firDiagnostic: FirPsiDiagnostic<*>
val firDiagnostic: FirPsiDiagnostic
override val factoryName: String
get() = firDiagnostic.factory.name
override val defaultMessage: String
get() {
val diagnostic = firDiagnostic as FirDiagnostic<*>
val diagnostic = firDiagnostic as FirDiagnostic
@Suppress("UNCHECKED_CAST")
val firDiagnosticRenderer =
FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic) as FirDiagnosticRenderer<FirDiagnostic<*>>
val firDiagnosticRenderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic)
return firDiagnosticRenderer.render(diagnostic)
}
@@ -5,34 +5,33 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
internal interface KtFirDiagnosticCreator
internal fun interface KtFirDiagnostic0Creator : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirSimpleDiagnostic<*>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: FirSimpleDiagnostic): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic1Creator<A> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters1<*, A>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters1<A>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic2Creator<A, B> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters2<*, A, B>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters2<A, B>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic3Creator<A, B, C> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters3<*, A, B, C>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters3<A, B, C>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic4Creator<A, B, C, D> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters4<*, A, B, C, D>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters4<A, B, C, D>): KtFirDiagnostic<*>
}
internal class KtDiagnosticConverter(private val conversions: Map<AbstractFirDiagnosticFactory<*, *>, KtFirDiagnosticCreator>) {
fun convert(analysisSession: KtFirAnalysisSession, diagnostic: FirDiagnostic<*>): KtFirDiagnostic<*> {
internal class KtDiagnosticConverter(private val conversions: Map<AbstractFirDiagnosticFactory, KtFirDiagnosticCreator>) {
fun convert(analysisSession: KtFirAnalysisSession, diagnostic: FirDiagnostic): KtFirDiagnostic<*> {
val creator = conversions[diagnostic.factory]
?: error("No conversion was found for ${diagnostic.factory}")
@@ -40,19 +39,19 @@ internal class KtDiagnosticConverter(private val conversions: Map<AbstractFirDia
return with(analysisSession) {
when (creator) {
is KtFirDiagnostic0Creator -> with(creator) {
create(diagnostic as FirSimpleDiagnostic<*>)
create(diagnostic as FirSimpleDiagnostic)
}
is KtFirDiagnostic1Creator<*> -> with(creator as KtFirDiagnostic1Creator<Any?>) {
create(diagnostic as FirDiagnosticWithParameters1<FirSourceElement, Any?>)
create(diagnostic as FirDiagnosticWithParameters1<Any?>)
}
is KtFirDiagnostic2Creator<*, *> -> with(creator as KtFirDiagnostic2Creator<Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters2<FirSourceElement, Any?, Any?>)
create(diagnostic as FirDiagnosticWithParameters2<Any?, Any?>)
}
is KtFirDiagnostic3Creator<*, *, *> -> with(creator as KtFirDiagnostic3Creator<Any?, Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters3<FirSourceElement, Any?, Any?, Any?>)
create(diagnostic as FirDiagnosticWithParameters3<Any?, Any?, Any?>)
}
is KtFirDiagnostic4Creator<*, *, *, *> -> with(creator as KtFirDiagnostic4Creator<Any?, Any?, Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters4<FirSourceElement, Any?, Any?, Any?, Any?>)
create(diagnostic as FirDiagnosticWithParameters4<Any?, Any?, Any?, Any?>)
}
else -> error("Invalid KtFirDiagnosticCreator ${creator::class.simpleName}")
}
@@ -61,25 +60,25 @@ internal class KtDiagnosticConverter(private val conversions: Map<AbstractFirDia
}
internal class KtDiagnosticConverterBuilder private constructor() {
private val conversions = mutableMapOf<AbstractFirDiagnosticFactory<*, *>, KtFirDiagnosticCreator>()
private val conversions = mutableMapOf<AbstractFirDiagnosticFactory, KtFirDiagnosticCreator>()
fun add(diagnostic: FirDiagnosticFactory0<*>, creator: KtFirDiagnostic0Creator) {
fun add(diagnostic: FirDiagnosticFactory0, creator: KtFirDiagnostic0Creator) {
conversions[diagnostic] = creator
}
fun <A> add(diagnostic: FirDiagnosticFactory1<*, A>, creator: KtFirDiagnostic1Creator<A>) {
fun <A> add(diagnostic: FirDiagnosticFactory1<A>, creator: KtFirDiagnostic1Creator<A>) {
conversions[diagnostic] = creator
}
fun <A, B> add(diagnostic: FirDiagnosticFactory2<*, A, B>, creator: KtFirDiagnostic2Creator<A, B>) {
fun <A, B> add(diagnostic: FirDiagnosticFactory2<A, B>, creator: KtFirDiagnostic2Creator<A, B>) {
conversions[diagnostic] = creator
}
fun <A, B, C> add(diagnostic: FirDiagnosticFactory3<*, A, B, C>, creator: KtFirDiagnostic3Creator<A, B, C>) {
fun <A, B, C> add(diagnostic: FirDiagnosticFactory3<A, B, C>, creator: KtFirDiagnostic3Creator<A, B, C>) {
conversions[diagnostic] = creator
}
fun <A, B, C, D> add(diagnostic: FirDiagnosticFactory4<*, A, B, C, D>, creator: KtFirDiagnostic4Creator<A, B, C, D>) {
fun <A, B, C, D> add(diagnostic: FirDiagnosticFactory4<A, B, C, D>, creator: KtFirDiagnostic4Creator<A, B, C, D>) {
conversions[diagnostic] = creator
}