Rearrange fir diagnostic for further reuse

This commit is contained in:
Ilya Chernikov
2021-09-17 22:13:23 +02:00
parent a5bf8f5f91
commit 31c58767cf
61 changed files with 1972 additions and 1944 deletions
@@ -16,8 +16,8 @@ import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
@@ -41,17 +41,17 @@ internal interface KtFirAnalysisSessionComponent {
fun ConeKotlinType.asKtType() = analysisSession.firSymbolBuilder.typeBuilder.buildKtType(this)
fun FirPsiDiagnostic.asKtDiagnostic(): KtDiagnosticWithPsi<*> =
KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, this as FirDiagnostic)
fun KtPsiDiagnostic.asKtDiagnostic(): KtDiagnosticWithPsi<*> =
KT_DIAGNOSTIC_CONVERTER.convert(analysisSession, this as KtDiagnostic)
fun ConeDiagnostic.asKtDiagnostic(
source: KtSourceElement,
qualifiedAccessSource: KtSourceElement?,
diagnosticCache: MutableList<FirDiagnostic>
diagnosticCache: MutableList<KtDiagnostic>
): KtDiagnosticWithPsi<*>? {
val firDiagnostic = toFirDiagnostics(analysisSession.rootModuleSession, source, qualifiedAccessSource).firstOrNull() ?: return null
diagnosticCache += firDiagnostic
check(firDiagnostic is FirPsiDiagnostic)
check(firDiagnostic is KtPsiDiagnostic)
return firDiagnostic.asKtDiagnostic()
}
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.realPsi
@@ -49,7 +49,7 @@ internal class KtFirCallResolver(
override val analysisSession: KtFirAnalysisSession,
override val token: ValidityToken,
) : AbstractKtCallResolver(), KtFirAnalysisSessionComponent {
private val diagnosticCache = mutableListOf<FirDiagnostic>()
private val diagnosticCache = mutableListOf<KtDiagnostic>()
private val cache: ConcurrentHashMap<KtElement, KtCall?> = ConcurrentHashMap()
override fun resolveAccessorCall(call: KtSimpleNameExpression): KtCall? = withValidityAssertion {
@@ -5,16 +5,15 @@
package org.jetbrains.kotlin.analysis.api.fir.components
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getDiagnostics
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.components.KtDiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.api.components.KtDiagnosticProvider
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getDiagnostics
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
@@ -8,22 +8,22 @@ package org.jetbrains.kotlin.analysis.api.fir.diagnostics
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
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.FirPsiDiagnostic
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
internal interface KtAbstractFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI>, ValidityTokenOwner {
val firDiagnostic: FirPsiDiagnostic
val firDiagnostic: KtPsiDiagnostic
override val factoryName: String
get() = withValidityAssertion { firDiagnostic.factory.name }
override val defaultMessage: String
get() = withValidityAssertion {
val diagnostic = firDiagnostic as FirDiagnostic
val diagnostic = firDiagnostic as KtDiagnostic
val firDiagnosticRenderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic)
return firDiagnosticRenderer.render(diagnostic)
@@ -5,33 +5,33 @@
package org.jetbrains.kotlin.analysis.api.fir.diagnostics
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
internal interface KtFirDiagnosticCreator
internal fun interface KtFirDiagnostic0Creator : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirSimpleDiagnostic): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: KtSimpleDiagnostic): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic1Creator<A> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters1<A>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: KtDiagnosticWithParameters1<A>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic2Creator<A, B> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters2<A, B>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: KtDiagnosticWithParameters2<A, B>): KtFirDiagnostic<*>
}
internal fun interface KtFirDiagnostic3Creator<A, B, C> : KtFirDiagnosticCreator {
fun KtFirAnalysisSession.create(diagnostic: FirDiagnosticWithParameters3<A, B, C>): KtFirDiagnostic<*>
fun KtFirAnalysisSession.create(diagnostic: KtDiagnosticWithParameters3<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: KtDiagnosticWithParameters4<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<AbstractKtDiagnosticFactory, KtFirDiagnosticCreator>) {
fun convert(analysisSession: KtFirAnalysisSession, diagnostic: KtDiagnostic): KtFirDiagnostic<*> {
val creator = conversions[diagnostic.factory]
?: error("No conversion was found for ${diagnostic.factory}")
@@ -39,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 KtSimpleDiagnostic)
}
is KtFirDiagnostic1Creator<*> -> with(creator as KtFirDiagnostic1Creator<Any?>) {
create(diagnostic as FirDiagnosticWithParameters1<Any?>)
create(diagnostic as KtDiagnosticWithParameters1<Any?>)
}
is KtFirDiagnostic2Creator<*, *> -> with(creator as KtFirDiagnostic2Creator<Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters2<Any?, Any?>)
create(diagnostic as KtDiagnosticWithParameters2<Any?, Any?>)
}
is KtFirDiagnostic3Creator<*, *, *> -> with(creator as KtFirDiagnostic3Creator<Any?, Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters3<Any?, Any?, Any?>)
create(diagnostic as KtDiagnosticWithParameters3<Any?, Any?, Any?>)
}
is KtFirDiagnostic4Creator<*, *, *, *> -> with(creator as KtFirDiagnostic4Creator<Any?, Any?, Any?, Any?>) {
create(diagnostic as FirDiagnosticWithParameters4<Any?, Any?, Any?, Any?>)
create(diagnostic as KtDiagnosticWithParameters4<Any?, Any?, Any?, Any?>)
}
else -> error("Invalid KtFirDiagnosticCreator ${creator::class.simpleName}")
}
@@ -60,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<AbstractKtDiagnosticFactory, KtFirDiagnosticCreator>()
fun add(diagnostic: FirDiagnosticFactory0, creator: KtFirDiagnostic0Creator) {
fun add(diagnostic: KtDiagnosticFactory0, creator: KtFirDiagnostic0Creator) {
conversions[diagnostic] = creator
}
fun <A> add(diagnostic: FirDiagnosticFactory1<A>, creator: KtFirDiagnostic1Creator<A>) {
fun <A> add(diagnostic: KtDiagnosticFactory1<A>, creator: KtFirDiagnostic1Creator<A>) {
conversions[diagnostic] = creator
}
fun <A, B> add(diagnostic: FirDiagnosticFactory2<A, B>, creator: KtFirDiagnostic2Creator<A, B>) {
fun <A, B> add(diagnostic: KtDiagnosticFactory2<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: KtDiagnosticFactory3<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: KtDiagnosticFactory4<A, B, C, D>, creator: KtFirDiagnostic4Creator<A, B, C, D>) {
conversions[diagnostic] = creator
}
@@ -18,6 +18,7 @@ dependencies {
api(project(":compiler:backend.common.jvm"))
api(project(":analysis:analysis-api-impl-barebone"))
testApi(project(":analysis:analysis-api-fir"))
implementation(project(":compiler:frontend.common"))
implementation(project(":compiler:ir.psi2ir"))
implementation(project(":compiler:fir:entrypoint"))
implementation(project(":analysis:analysis-api-providers"))
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalKtFile
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
@@ -75,10 +75,10 @@ internal class FirModuleResolveStateDepended(
return null
}
override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<FirPsiDiagnostic> =
override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<KtPsiDiagnostic> =
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<KtPsiDiagnostic> =
TODO("Diagnostics are not implemented for depended state")
@OptIn(InternalForInline::class)
@@ -7,15 +7,6 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.InternalForInline
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.DiagnosticsCollector
@@ -37,6 +28,15 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.psi.*
@@ -78,10 +78,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<KtPsiDiagnostic> =
diagnosticsCollector.getDiagnosticsFor(element, filter)
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic> =
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<KtPsiDiagnostic> =
diagnosticsCollector.collectDiagnosticsForFile(ktFile, filter)
@OptIn(InternalForInline::class)
@@ -13,6 +13,9 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
@@ -44,9 +47,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<KtPsiDiagnostic>
internal abstract fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic>
internal abstract fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<KtPsiDiagnostic>
@InternalForInline
abstract fun findSourceFirDeclaration(
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
@@ -148,7 +148,7 @@ fun <D : FirDeclaration, R> D.withFirDeclaration(
* 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<KtPsiDiagnostic> =
resolveState.getDiagnostics(this, filter)
/**
@@ -158,7 +158,7 @@ fun KtElement.getDiagnostics(resolveState: FirModuleResolveState, filter: Diagno
fun KtFile.collectDiagnosticsForFile(
resolveState: FirModuleResolveState,
filter: DiagnosticCheckerFilter
): Collection<FirPsiDiagnostic> =
): Collection<KtPsiDiagnostic> =
resolveState.collectDiagnosticsForFile(this, filter)
/**
@@ -5,10 +5,10 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCache
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureCache
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
@@ -16,14 +16,14 @@ 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<KtPsiDiagnostic> {
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<KtPsiDiagnostic> {
val fileStructure = fileStructureCache.getFileStructure(ktFile, cache)
return fileStructure.getAllDiagnosticsForFile(filter)
}
@@ -6,12 +6,12 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
internal class FileStructureElementDiagnosticList(
private val map: Map<PsiElement, List<FirPsiDiagnostic>>
private val map: Map<PsiElement, List<KtPsiDiagnostic>>
) {
fun diagnosticsFor(element: PsiElement): List<FirPsiDiagnostic> = map[element] ?: emptyList()
fun diagnosticsFor(element: PsiElement): List<KtPsiDiagnostic> = map[element] ?: emptyList()
inline fun forEach(action: (List<FirPsiDiagnostic>) -> Unit) = map.values.forEach(action)
inline fun forEach(action: (List<KtPsiDiagnostic>) -> Unit) = map.values.forEach(action)
}
@@ -7,10 +7,10 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
import com.intellij.psi.PsiElement
import com.intellij.util.SmartList
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LockProvider
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirFile
internal class FileStructureElementDiagnostics(
private val firFile: FirFile,
@@ -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<KtPsiDiagnostic> =
SmartList<KtPsiDiagnostic>().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<KtPsiDiagnostic>) -> Unit) {
if (filter.runCommonCheckers) {
diagnosticByCommonCheckers.forEach(action)
}
@@ -6,67 +6,66 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
internal class FirIdeDiagnosticReporter : DiagnosticReporter() {
val diagnostics = mutableMapOf<PsiElement, MutableList<FirPsiDiagnostic>>()
val diagnostics = mutableMapOf<PsiElement, MutableList<KtPsiDiagnostic>>()
override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) {
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) {
if (diagnostic == null) return
if (context.isDiagnosticSuppressed(diagnostic)) return
val psiDiagnostic = when (diagnostic) {
is FirPsiDiagnostic -> diagnostic
is FirLightDiagnostic -> diagnostic.toPsiDiagnostic()
is KtPsiDiagnostic -> diagnostic
is KtLightDiagnostic -> diagnostic.toPsiDiagnostic()
else -> error("Unknown diagnostic type ${diagnostic::class.simpleName}")
}
diagnostics.addValueFor(psiDiagnostic.psiElement, psiDiagnostic)
}
}
private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic {
private fun KtLightDiagnostic.toPsiDiagnostic(): KtPsiDiagnostic {
val psiSourceElement = element.unwrapToKtPsiSourceElement()
?: error("Diagnostic should be created from PSI in IDE")
@Suppress("UNCHECKED_CAST")
return when (this) {
is FirLightSimpleDiagnostic -> FirPsiSimpleDiagnostic(
is KtLightSimpleDiagnostic -> KtPsiSimpleDiagnostic(
psiSourceElement,
severity,
factory,
positioningStrategy
)
is FirLightDiagnosticWithParameters1<*> -> FirPsiDiagnosticWithParameters1(
is KtLightDiagnosticWithParameters1<*> -> KtPsiDiagnosticWithParameters1(
psiSourceElement,
a,
severity,
factory as FirDiagnosticFactory1<Any?>,
factory as KtDiagnosticFactory1<Any?>,
positioningStrategy
)
is FirLightDiagnosticWithParameters2<*, *> -> FirPsiDiagnosticWithParameters2(
is KtLightDiagnosticWithParameters2<*, *> -> KtPsiDiagnosticWithParameters2(
psiSourceElement,
a, b,
severity,
factory as FirDiagnosticFactory2<Any?, Any?>,
factory as KtDiagnosticFactory2<Any?, Any?>,
positioningStrategy
)
is FirLightDiagnosticWithParameters3<*, *, *> -> FirPsiDiagnosticWithParameters3(
is KtLightDiagnosticWithParameters3<*, *, *> -> KtPsiDiagnosticWithParameters3(
psiSourceElement,
a, b, c,
severity,
factory as FirDiagnosticFactory3<Any?, Any?, Any?>,
factory as KtDiagnosticFactory3<Any?, Any?, Any?>,
positioningStrategy
)
is FirLightDiagnosticWithParameters4<*, *, *, *> -> FirPsiDiagnosticWithParameters4(
is KtLightDiagnosticWithParameters4<*, *, *, *> -> KtPsiDiagnosticWithParameters4(
psiSourceElement,
a, b, c, d,
severity,
factory as FirDiagnosticFactory4<Any?, Any?, Any?, Any?>,
factory as KtDiagnosticFactory4<Any?, Any?, Any?, Any?>,
positioningStrategy
)
else -> error("Unknown diagnostic type ${this::class.simpleName}")
@@ -6,10 +6,6 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.FirFileBuilder
@@ -18,6 +14,10 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyDecla
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.firIdeProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.psi.*
import java.util.concurrent.ConcurrentHashMap
@@ -70,7 +70,7 @@ internal class FileStructure private constructor(
}
@OptIn(ExperimentalStdlibApi::class)
fun getAllDiagnosticsForFile(diagnosticCheckerFilter: DiagnosticCheckerFilter): Collection<FirPsiDiagnostic> {
fun getAllDiagnosticsForFile(diagnosticCheckerFilter: DiagnosticCheckerFilter): Collection<KtPsiDiagnostic> {
val structureElements = getAllStructureElements()
return buildList {
@@ -78,7 +78,7 @@ internal class FileStructure private constructor(
}
}
private fun MutableCollection<FirPsiDiagnostic>.collectDiagnosticsFromStructureElements(
private fun MutableCollection<KtPsiDiagnostic>.collectDiagnosticsFromStructureElements(
structureElements: Collection<FileStructureElement>,
diagnosticCheckerFilter: DiagnosticCheckerFilter
) {
@@ -10,13 +10,12 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolvedFirToPhase
import org.jetbrains.kotlin.fir.analysis.AbstractFirAnalyzerFacade
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
import org.jetbrains.kotlin.test.model.TestFile
@@ -28,13 +27,13 @@ class LowLevelFirAnalyzerFacade(
) : AbstractFirAnalyzerFacade() {
override val scopeSession: ScopeSession get() = shouldNotBeCalled()
override fun runCheckers(): Map<FirFile, List<FirDiagnostic>> {
override fun runCheckers(): Map<FirFile, List<KtDiagnostic>> {
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<KtDiagnostic>
}
}
@@ -14,10 +14,10 @@ import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
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.KtDiagnostic
object FirDiagnosticsCompilerResultsReporter {
fun reportDiagnostics(diagnostics: Collection<FirDiagnostic>, reporter: MessageCollector): Boolean {
fun reportDiagnostics(diagnostics: Collection<KtDiagnostic>, 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<KtDiagnostic>) {
/*
* 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: KtDiagnostic, reporter: MessageCollector): Boolean {
if (!diagnostic.isValid) return false
diagnostic.location()?.let { location ->
val severity = AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity)
@@ -48,24 +48,24 @@ object FirDiagnosticsCompilerResultsReporter {
return diagnostic.severity == Severity.ERROR
}
private fun FirDiagnostic.location(): CompilerMessageSourceLocation? = when (val element = element) {
private fun KtDiagnostic.location(): CompilerMessageSourceLocation? = when (val element = element) {
is KtPsiSourceElement -> element.location(this)
is KtLightSourceElement -> element.location(this)
}
private fun KtPsiSourceElement.location(diagnostic: FirDiagnostic): CompilerMessageSourceLocation? {
private fun KtPsiSourceElement.location(diagnostic: KtDiagnostic): CompilerMessageSourceLocation? {
val file = psi.containingFile
return MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumnRange(file, diagnostic.textRanges))
}
@Suppress("UNUSED_PARAMETER")
private fun KtLightSourceElement.location(diagnostic: FirDiagnostic): CompilerMessageSourceLocation? {
private fun KtLightSourceElement.location(diagnostic: KtDiagnostic): CompilerMessageSourceLocation? {
// TODO: support light tree
return null
}
private object DiagnosticComparator : Comparator<FirDiagnostic> {
override fun compare(o1: FirDiagnostic, o2: FirDiagnostic): Int {
private object DiagnosticComparator : Comparator<KtDiagnostic> {
override fun compare(o1: KtDiagnostic, o2: KtDiagnostic): Int {
val element1 = o1.element
val element2 = o1.element
// TODO: support light tree
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.codegen.CodegenFactory
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
@@ -244,16 +244,16 @@ object FirKotlinToJvmBytecodeCompiler {
val commonRawFir = commonSession?.buildFirFromKtFiles(commonKtFiles)
val rawFir = session.buildFirFromKtFiles(ktFiles)
val allFirDiagnostics = mutableListOf<FirDiagnostic>()
val allKtDiagnostics = mutableListOf<KtDiagnostic>()
commonSession?.apply {
val (commonScopeSession, commonFir) = runResolution(commonRawFir!!)
runCheckers(commonScopeSession, commonFir).values.flattenTo(allFirDiagnostics)
runCheckers(commonScopeSession, commonFir).values.flattenTo(allKtDiagnostics)
}
val (scopeSession, fir) = session.runResolution(rawFir)
session.runCheckers(scopeSession, fir).values.flattenTo(allFirDiagnostics)
session.runCheckers(scopeSession, fir).values.flattenTo(allKtDiagnostics)
val hasErrors = FirDiagnosticsCompilerResultsReporter.reportDiagnostics(allFirDiagnostics, messageCollector)
val hasErrors = FirDiagnosticsCompilerResultsReporter.reportDiagnostics(allKtDiagnostics, messageCollector)
return if (syntaxErrors || hasErrors) null else FirResult(session, scopeSession, fir)
}
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.TO_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.CONCURRENT_HASH_MAP_CONTAINS_OPERATOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.CONFLICTING_JVM_DECLARATIONS
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.DEFAULT_METHOD_CALL_FROM_JAVA6_TARGET
@@ -5,21 +5,24 @@
package org.jetbrains.kotlin.fir.analysis.checkers.context
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.name.Name
abstract class CheckerContext {
abstract class CheckerContext : DiagnosticContext {
// Services
abstract val sessionHolder: SessionHolder
abstract val returnTypeCalculator: ReturnTypeCalculator
@@ -40,13 +43,6 @@ abstract class CheckerContext {
val session: FirSession
get() = sessionHolder.session
abstract fun addSuppressedDiagnostics(
diagnosticNames: Collection<String>,
allInfosSuppressed: Boolean,
allWarningsSuppressed: Boolean,
allErrorsSuppressed: Boolean
): CheckerContext
abstract fun addImplicitReceiver(name: Name?, value: ImplicitReceiverValue<*>): CheckerContext
abstract fun addDeclaration(declaration: FirDeclaration): CheckerContext
@@ -74,7 +70,7 @@ abstract class CheckerContext {
abstract fun dropAnnotationContainer()
fun isDiagnosticSuppressed(diagnostic: FirDiagnostic): Boolean {
override fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean {
val factory = diagnostic.factory
val name = factory.name
val suppressedByAll = when (factory.severity) {
@@ -85,6 +81,9 @@ abstract class CheckerContext {
return suppressedByAll || name in suppressedDiagnostics
}
override val languageVersionSettings: LanguageVersionSettings
get() = session.languageVersionSettings
}
/**
@@ -6,16 +6,19 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory0
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.types.type
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirDelegateUsesExtensionPropertyTypeParameterChecker : FirPropertyChecker() {
@@ -31,7 +34,7 @@ object FirDelegateUsesExtensionPropertyTypeParameterChecker : FirPropertyChecker
}
}
private fun getProperDiagnostic(context: CheckerContext): FirDiagnosticFactory0 {
private fun getProperDiagnostic(context: CheckerContext): KtDiagnosticFactory0 {
val reportAsError = context.session.languageVersionSettings.supportsFeature(
LanguageFeature.ForbidUsingExtensionPropertyTypeParameterInDelegate
)
@@ -9,8 +9,8 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticFactory0
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirBackingField
import org.jetbrains.kotlin.fir.declarations.FirResolvedDeclarationStatus
@@ -44,7 +44,7 @@ object FirExplicitBackingFieldForbiddenChecker : FirBackingFieldChecker() {
}
}
private fun getProperDiagnostic(context: CheckerContext): FirDiagnosticFactory0 {
private fun getProperDiagnostic(context: CheckerContext): KtDiagnosticFactory0 {
return if (context.findClosestClassOrObject()?.classKind == ClassKind.INTERFACE) {
FirErrors.EXPLICIT_BACKING_FIELD_IN_INTERFACE
} else {
@@ -16,8 +16,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.checkers.getActualTargetList
import org.jetbrains.kotlin.fir.analysis.checkers.getModifierList
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory2
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticFactory2
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
@@ -174,7 +174,7 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
context: CheckerContext,
reporter: DiagnosticReporter
): Boolean {
fun checkModifier(factory: FirDiagnosticFactory2<KtModifierKeywordToken, String>): Boolean {
fun checkModifier(factory: KtDiagnosticFactory2<KtModifierKeywordToken, String>): Boolean {
val map = when (factory) {
FirErrors.WRONG_MODIFIER_TARGET -> possibleTargetMap
FirErrors.DEPRECATED_MODIFIER_FOR_TARGET -> deprecatedTargetMap
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.ConstantArgumentKind
import org.jetbrains.kotlin.fir.analysis.checkers.checkConstantArguments
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticFactory0
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.findArgumentByName
import org.jetbrains.kotlin.fir.expressions.*
@@ -58,9 +58,9 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
session: FirSession,
reporter: DiagnosticReporter,
context: CheckerContext
): FirDiagnosticFactory0? {
): KtDiagnosticFactory0? {
fun checkArgumentList(args: FirArgumentList): FirDiagnosticFactory0? {
fun checkArgumentList(args: FirArgumentList): KtDiagnosticFactory0? {
var usedNonConst = false
for (arg in args.arguments) {
@@ -93,10 +93,10 @@ object FirForLoopChecker : FirBlockChecker() {
reporter: DiagnosticReporter,
reportSource: KtSourceElement?,
context: CheckerContext,
ambiguityFactory: FirDiagnosticFactory1<Collection<FirBasedSymbol<*>>>,
missingFactory: FirDiagnosticFactory0,
noneApplicableFactory: FirDiagnosticFactory1<Collection<FirBasedSymbol<*>>>? = null,
unsafeCallFactory: FirDiagnosticFactory0? = null,
ambiguityFactory: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>>,
missingFactory: KtDiagnosticFactory0,
noneApplicableFactory: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>>? = null,
unsafeCallFactory: KtDiagnosticFactory0? = null,
): Boolean {
when (val calleeReference = call.calleeReference) {
is FirErrorNamedReference -> {
@@ -52,7 +52,7 @@ object FirReifiedChecker : FirQualifiedAccessExpressionChecker() {
return
}
var factory: FirDiagnosticFactory1<FirTypeParameterSymbol>? = null
var factory: KtDiagnosticFactory1<FirTypeParameterSymbol>? = null
lateinit var symbol: FirTypeParameterSymbol
if (typeArgument is ConeTypeParameterType) {
@@ -5,16 +5,18 @@
package org.jetbrains.kotlin.fir.analysis.checkers.syntax
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtRealSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.config.ExplicitApiMode
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
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.analysis.getChild
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
@@ -31,16 +33,16 @@ object FirExplicitApiDeclarationChecker : FirDeclarationSyntaxChecker<FirDeclara
override fun checkPsiOrLightTree(
element: FirDeclaration,
source: FirSourceElement,
source: KtSourceElement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
if ((source.kind !is FirRealSourceElementKind && source.kind != FirFakeSourceElementKind.PropertyFromParameter) ||
if ((source.kind !is KtRealSourceElementKind && source.kind != KtFakeSourceElementKind.PropertyFromParameter) ||
element !is FirMemberDeclaration
) {
return
}
val state = context.session.languageVersionSettings.getFlag(AnalysisFlags.explicitApiMode)
val state = context.languageVersionSettings.getFlag(AnalysisFlags.explicitApiMode)
if (state == ExplicitApiMode.DISABLED) return
// Enum entries do not have visibilities
if (element is FirEnumEntry) return
@@ -53,7 +55,7 @@ object FirExplicitApiDeclarationChecker : FirDeclarationSyntaxChecker<FirDeclara
private fun checkVisibilityModifier(
state: ExplicitApiMode,
declaration: FirMemberDeclaration,
source: FirSourceElement,
source: KtSourceElement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
@@ -111,7 +113,7 @@ object FirExplicitApiDeclarationChecker : FirDeclarationSyntaxChecker<FirDeclara
private fun checkExplicitReturnType(
state: ExplicitApiMode,
declaration: FirMemberDeclaration,
source: FirSourceElement,
source: KtSourceElement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
@@ -129,7 +131,7 @@ object FirExplicitApiDeclarationChecker : FirDeclarationSyntaxChecker<FirDeclara
}
}
private fun returnTypeCheckIsApplicable(source: FirSourceElement, context: CheckerContext): Boolean {
private fun returnTypeCheckIsApplicable(source: KtSourceElement, context: CheckerContext): Boolean {
// Note that by default getChild uses `depth = -1`, which would find all descendents.
if (source.getChild(KtNodeTypes.TYPE_REFERENCE, depth = 1) != null) return false
// Do not check if the containing file is not a physical file.
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.syntax
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.config.LanguageFeature
@@ -32,7 +33,7 @@ object FirLocalVariableTypeParametersSyntaxChecker : FirDeclarationSyntaxChecker
) {
if (psi is KtProperty && psi.typeParameterList != null) {
val diagnostic =
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTypeParametersForLocalVariables))
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTypeParametersForLocalVariables))
FirErrors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS else FirErrors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING
reporter.reportOn(source, diagnostic, context)
}
@@ -46,7 +47,7 @@ object FirLocalVariableTypeParametersSyntaxChecker : FirDeclarationSyntaxChecker
) {
source.treeStructure.typeParametersList(source.lighterASTNode)?.let { _ ->
val diagnostic =
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTypeParametersForLocalVariables))
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTypeParametersForLocalVariables))
FirErrors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS else FirErrors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING
reporter.reportOn(source, diagnostic, context)
@@ -9,13 +9,17 @@ import com.intellij.lang.LighterASTNode
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.findChildByType
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.diagnostics.unwrapParenthesesLabelsAndAnnotations
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.buildChildSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
import org.jetbrains.kotlin.fir.expressions.FirBlock
@@ -26,14 +30,14 @@ import org.jetbrains.kotlin.psi.*
object FirRedundantLabelChecker : FirDeclarationSyntaxChecker<FirDeclaration, PsiElement>() {
override fun checkLightTree(
element: FirDeclaration,
source: FirLightSourceElement,
source: KtLightSourceElement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
// Local declarations are already checked when the containing declaration is checked.
if (!isRootLabelContainer(element)) return
val allTraversalRoots = mutableSetOf<FirSourceElement>()
val allTraversalRoots = mutableSetOf<KtSourceElement>()
// First collect all labels in the declaration
element.accept(object : FirVisitorVoid() {
@@ -68,22 +72,22 @@ object FirRedundantLabelChecker : FirDeclarationSyntaxChecker<FirDeclaration, Ps
private fun markTraversalRoot(elem: FirElement) {
val elemSource = elem.source
if (elemSource?.kind is FirRealSourceElementKind) {
if (elemSource?.kind is KtRealSourceElementKind) {
allTraversalRoots.add(elemSource)
}
}
})
for (root in allTraversalRoots) {
root.treeStructure.reportRedundantLabels(reporter, context, root as FirLightSourceElement, allTraversalRoots)
root.treeStructure.reportRedundantLabels(reporter, context, root as KtLightSourceElement, allTraversalRoots)
}
}
private fun FlyweightCapableTreeStructure<LighterASTNode>.reportRedundantLabels(
reporter: DiagnosticReporter,
context: CheckerContext,
source: FirLightSourceElement,
allTraversalRoots: Set<FirSourceElement>,
source: KtLightSourceElement,
allTraversalRoots: Set<KtSourceElement>,
isChildNode: Boolean = false,
) {
if (isChildNode && source in allTraversalRoots) return // Prevent double traversal
@@ -113,7 +117,7 @@ object FirRedundantLabelChecker : FirDeclarationSyntaxChecker<FirDeclaration, Ps
override fun checkPsi(
element: FirDeclaration,
source: FirPsiSourceElement,
source: KtPsiSourceElement,
psi: PsiElement,
context: CheckerContext,
reporter: DiagnosticReporter
@@ -132,7 +136,7 @@ object FirRedundantLabelChecker : FirDeclarationSyntaxChecker<FirDeclaration, Ps
deparenthesizedBaseExpression !is KtLoopExpression &&
deparenthesizedBaseExpression !is KtNamedFunction
) {
reporter.reportOn(labelNameExpression.toFirPsiSourceElement(), FirErrors.REDUNDANT_LABEL_WARNING, context)
reporter.reportOn(labelNameExpression.toKtPsiSourceElement(), FirErrors.REDUNDANT_LABEL_WARNING, context)
}
}
super.visitLabeledExpression(expression)
@@ -141,7 +145,7 @@ object FirRedundantLabelChecker : FirDeclarationSyntaxChecker<FirDeclaration, Ps
}
private fun isRootLabelContainer(element: FirDeclaration): Boolean {
if (element.source?.kind is FirFakeSourceElementKind) return false
if (element.source?.kind is KtFakeSourceElementKind) return false
if (element is FirCallableDeclaration && element.effectiveVisibility == EffectiveVisibility.Local) return false
return when (element) {
is FirAnonymousFunction -> false
@@ -341,6 +341,6 @@ abstract class AbstractDiagnosticCollectorVisitor(
allInfosSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_INFOS in arguments,
allWarningsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_WARNINGS in arguments,
allErrorsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_ERRORS in arguments
)
) as CheckerContext
}
}
@@ -7,10 +7,6 @@ package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.collectors.components.DiagnosticComponentsFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.DiagnosticReporterWithSuppress
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.SimpleDiagnosticReporter
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.ScopeSession
object FirDiagnosticsCollector {
@@ -5,226 +5,21 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettings
interface DiagnosticContext {
fun isDiagnosticSuppressed(diagnostic: KtDiagnostic): Boolean
fun addSuppressedDiagnostics(
diagnosticNames: Collection<String>,
allInfosSuppressed: Boolean,
allWarningsSuppressed: Boolean,
allErrorsSuppressed: Boolean
): DiagnosticContext
val languageVersionSettings: LanguageVersionSettings
}
abstract class DiagnosticReporter {
abstract fun report(diagnostic: FirDiagnostic?, context: CheckerContext)
abstract fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactory0,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactory1<A>,
a: A,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactory2<A, B>,
a: A,
b: B,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactory3<A, B, C>,
a: A,
b: B,
c: C,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, c, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactory4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, c, d, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactoryForDeprecation0,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactoryForDeprecation1<A>,
a: A,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactoryForDeprecation2<A, B>,
a: A,
b: B,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactoryForDeprecation3<A, B, C>,
a: A,
b: B,
c: C,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, c, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: FirDiagnosticFactoryForDeprecation4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, c, d, context, positioningStrategy)
}
fun <F : AbstractFirDiagnosticFactory> FirDiagnosticFactoryForDeprecation<F>.chooseFactory(context: CheckerContext): F {
return if (context.session.languageVersionSettings.supportsFeature(deprecatingFeature)) {
errorFactory
} else {
warningFactory
}
}
fun DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: FirDiagnosticFactory0,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, it, positioningStrategy)
}
}
fun <A : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: FirDiagnosticFactory1<A>,
a: A,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, it, positioningStrategy)
}
}
fun <A : Any, B : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: FirDiagnosticFactory2<A, B>,
a: A,
b: B,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, it, positioningStrategy)
}
}
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: FirDiagnosticFactory3<A, B, C>,
a: A,
b: B,
c: C,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, it, positioningStrategy)
}
}
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: FirDiagnosticFactory4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, d, it, positioningStrategy)
}
}
inline fun withSuppressedDiagnostics(
annotationContainer: FirAnnotationContainer,
context: CheckerContext,
f: (CheckerContext) -> Unit
) {
val arguments = AbstractDiagnosticCollector.getDiagnosticsSuppressedForContainer(annotationContainer)
if (arguments != null) {
f(
context.addSuppressedDiagnostics(
arguments,
allInfosSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_INFOS in arguments,
allWarningsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_WARNINGS in arguments,
allErrorsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_ERRORS in arguments
)
)
return
}
f(context)
}
@@ -11,25 +11,18 @@ import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING
import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.commaSeparated
import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.COLLECTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.EMPTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTION_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.MODULE_DATA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME_OF_CONTAINING_DECLARATION_OR_FILE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_COLLECTION_OF_TYPES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.VARIABLE_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.VISIBILITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.WHEN_MISSING_CASES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED
@@ -521,21 +514,28 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_PARAMETER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETURN_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.COLLECTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.EMPTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.FUNCTION_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.NOT_RENDERED
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.NULLABLE_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.TO_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnosticRenderers.VISIBILITY
@Suppress("unused")
class FirDefaultErrorMessages {
companion object {
fun getRendererForDiagnostic(diagnostic: FirDiagnostic): FirDiagnosticRenderer {
fun getRendererForDiagnostic(diagnostic: KtDiagnostic): KtDiagnosticRenderer {
val factory = diagnostic.factory
@Suppress("UNCHECKED_CAST")
return (MAP[factory] ?: factory.firRenderer)
return (MAP[factory] ?: factory.ktRenderer)
}
// * - The old FE reports these diagnostics with additional parameters
// & - New diagnostic that has no analogues in the old FE
// + - Better message required
// # - The new diagnostic differs from the old FE's one
val MAP = FirDiagnosticFactoryToRendererMap("FIR").also { map ->
val MAP = KtDiagnosticFactoryToRendererMap("FIR").also { map ->
// Meta-errors
map.put(UNSUPPORTED, "Unsupported [{0}]", TO_STRING)
map.put(UNSUPPORTED_FEATURE, "{0}", LanguageFeatureMessageRenderer(LanguageFeatureMessageRenderer.Type.UNSUPPORTED))
@@ -1,10 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.diagnostics
fun interface FirDiagnosticParameterRenderer<in O> {
fun render(obj: O): String
}
@@ -5,9 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.diagnostics.rendering.ContextIndependentParameterRenderer
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
@@ -24,8 +22,6 @@ import org.jetbrains.kotlin.fir.types.render
import org.jetbrains.kotlin.name.CallableId
object FirDiagnosticRenderers {
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
val SYMBOL = Renderer { symbol: FirBasedSymbol<*> ->
when (symbol) {
is FirClassLikeSymbol<*> -> symbol.classId.asString()
@@ -35,7 +31,7 @@ object FirDiagnosticRenderers {
}
}
val SYMBOLS = COLLECTION(SYMBOL)
val SYMBOLS = KtDiagnosticRenderers.COLLECTION(SYMBOL)
val RENDER_COLLECTION_OF_TYPES = Renderer { types: Collection<ConeKotlinType> ->
types.joinToString(separator = ", ") { type ->
@@ -43,12 +39,6 @@ object FirDiagnosticRenderers {
}
}
val TO_STRING = Renderer { element: Any? ->
element.toString()
}
val EMPTY = Renderer { _: Any? -> "" }
val VARIABLE_NAME = Renderer { symbol: FirVariableSymbol<*> ->
symbol.name.asString()
}
@@ -57,10 +47,6 @@ object FirDiagnosticRenderers {
element.render()
}
val VISIBILITY = Renderer { visibility: Visibility ->
visibility.externalDisplayName
}
val DECLARATION_NAME = Renderer { symbol: FirBasedSymbol<*> ->
val name = when (symbol) {
is FirCallableSymbol<*> -> symbol.name
@@ -127,12 +113,6 @@ object FirDiagnosticRenderers {
}
}
val NOT_RENDERED = Renderer<Any?> {
""
}
val FUNCTION_PARAMETERS = Renderer { hasValueParameters: Boolean -> if (hasValueParameters) "..." else "" }
val MODULE_DATA = Renderer<FirModuleData> {
"Module ${it.name}"
}
@@ -0,0 +1,224 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
@OptIn(InternalDiagnosticFactoryMethod::class)
fun DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactory0,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactory1<A>,
a: A,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactory2<A, B>,
a: A,
b: B,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactory3<A, B, C>,
a: A,
b: B,
c: C,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, c, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactory4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
source?.let { report(factory.on(it, a, b, c, d, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation0,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation1<A>,
a: A,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation2<A, B>,
a: A,
b: B,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation3<A, B, C>,
a: A,
b: B,
c: C,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, c, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: KtSourceElement?,
factory: KtDiagnosticFactoryForDeprecation4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, c, d, context, positioningStrategy)
}
fun <F : AbstractKtDiagnosticFactory> KtDiagnosticFactoryForDeprecation<F>.chooseFactory(context: DiagnosticContext): F {
return if (context.languageVersionSettings.supportsFeature(deprecatingFeature)) {
errorFactory
} else {
warningFactory
}
}
fun DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory0,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, it, positioningStrategy)
}
}
fun <A : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory1<A>,
a: A,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, it, positioningStrategy)
}
}
fun <A : Any, B : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory2<A, B>,
a: A,
b: B,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, it, positioningStrategy)
}
}
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory3<A, B, C>,
a: A,
b: B,
c: C,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, it, positioningStrategy)
}
}
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: DiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, d, it, positioningStrategy)
}
}
inline fun <reified C : DiagnosticContext> withSuppressedDiagnostics(
annotationContainer: FirAnnotationContainer,
context: C,
f: (C) -> Unit
) {
val arguments = AbstractDiagnosticCollector.getDiagnosticsSuppressedForContainer(annotationContainer)
if (arguments != null) {
f(
context.addSuppressedDiagnostics(
arguments,
allInfosSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_INFOS in arguments,
allWarningsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_WARNINGS in arguments,
allErrorsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_ERRORS in arguments
) as C
)
return
}
f(context)
}
@@ -15,10 +15,10 @@ import org.jetbrains.kotlin.diagnostics.*
// ------------------------------ diagnostics ------------------------------
sealed class FirDiagnostic : DiagnosticMarker {
sealed class KtDiagnostic : DiagnosticMarker {
abstract val element: KtSourceElement
abstract val severity: Severity
abstract val factory: AbstractFirDiagnosticFactory
abstract val factory: AbstractKtDiagnosticFactory
abstract val positioningStrategy: SourceElementPositioningStrategy
val textRanges: List<TextRange>
@@ -31,40 +31,40 @@ sealed class FirDiagnostic : DiagnosticMarker {
get() = factory.name
}
sealed class FirSimpleDiagnostic : FirDiagnostic() {
abstract override val factory: FirDiagnosticFactory0
sealed class KtSimpleDiagnostic : KtDiagnostic() {
abstract override val factory: KtDiagnosticFactory0
}
sealed class FirDiagnosticWithParameters1<A> : FirDiagnostic(), DiagnosticWithParameters1Marker<A> {
sealed class KtDiagnosticWithParameters1<A> : KtDiagnostic(), DiagnosticWithParameters1Marker<A> {
abstract override val a: A
abstract override val factory: FirDiagnosticFactory1<A>
abstract override val factory: KtDiagnosticFactory1<A>
}
sealed class FirDiagnosticWithParameters2<A, B> : FirDiagnostic(), DiagnosticWithParameters2Marker<A, B> {
sealed class KtDiagnosticWithParameters2<A, B> : KtDiagnostic(), DiagnosticWithParameters2Marker<A, B> {
abstract override val a: A
abstract override val b: B
abstract override val factory: FirDiagnosticFactory2<A, B>
abstract override val factory: KtDiagnosticFactory2<A, B>
}
sealed class FirDiagnosticWithParameters3<A, B, C> : FirDiagnostic(), DiagnosticWithParameters3Marker<A, B, C> {
sealed class KtDiagnosticWithParameters3<A, B, C> : KtDiagnostic(), DiagnosticWithParameters3Marker<A, B, C> {
abstract override val a: A
abstract override val b: B
abstract override val c: C
abstract override val factory: FirDiagnosticFactory3<A, B, C>
abstract override val factory: KtDiagnosticFactory3<A, B, C>
}
sealed class FirDiagnosticWithParameters4<A, B, C, D> : FirDiagnostic(), DiagnosticWithParameters4Marker<A, B, C, D> {
sealed class KtDiagnosticWithParameters4<A, B, C, D> : KtDiagnostic(), DiagnosticWithParameters4Marker<A, B, C, D> {
abstract override val a: A
abstract override val b: B
abstract override val c: C
abstract override val d: D
abstract override val factory: FirDiagnosticFactory4<A, B, C, D>
abstract override val factory: KtDiagnosticFactory4<A, B, C, D>
}
// ------------------------------ psi diagnostics ------------------------------
interface FirPsiDiagnostic : DiagnosticMarker {
val factory: AbstractFirDiagnosticFactory
interface KtPsiDiagnostic : DiagnosticMarker {
val factory: AbstractKtDiagnosticFactory
val element: KtPsiSourceElement
val textRanges: List<TextRange>
val severity: Severity
@@ -78,7 +78,7 @@ interface FirPsiDiagnostic : DiagnosticMarker {
private const val CHECK_PSI_CONSISTENCY_IN_DIAGNOSTICS = true
private fun FirPsiDiagnostic.checkPsiTypeConsistency() {
private fun KtPsiDiagnostic.checkPsiTypeConsistency() {
if (CHECK_PSI_CONSISTENCY_IN_DIAGNOSTICS) {
require(factory.psiType.isInstance(element.psi)) {
"${element.psi::class} is not a subtype of ${factory.psiType} for factory $factory"
@@ -86,67 +86,67 @@ private fun FirPsiDiagnostic.checkPsiTypeConsistency() {
}
}
data class FirPsiSimpleDiagnostic(
data class KtPsiSimpleDiagnostic(
override val element: KtPsiSourceElement,
override val severity: Severity,
override val factory: FirDiagnosticFactory0,
override val factory: KtDiagnosticFactory0,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirSimpleDiagnostic(), FirPsiDiagnostic {
) : KtSimpleDiagnostic(), KtPsiDiagnostic {
init {
checkPsiTypeConsistency()
}
}
data class FirPsiDiagnosticWithParameters1<A>(
data class KtPsiDiagnosticWithParameters1<A>(
override val element: KtPsiSourceElement,
override val a: A,
override val severity: Severity,
override val factory: FirDiagnosticFactory1<A>,
override val factory: KtDiagnosticFactory1<A>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters1<A>(), FirPsiDiagnostic {
) : KtDiagnosticWithParameters1<A>(), KtPsiDiagnostic {
init {
checkPsiTypeConsistency()
}
}
data class FirPsiDiagnosticWithParameters2<A, B>(
data class KtPsiDiagnosticWithParameters2<A, B>(
override val element: KtPsiSourceElement,
override val a: A,
override val b: B,
override val severity: Severity,
override val factory: FirDiagnosticFactory2<A, B>,
override val factory: KtDiagnosticFactory2<A, B>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters2<A, B>(), FirPsiDiagnostic {
) : KtDiagnosticWithParameters2<A, B>(), KtPsiDiagnostic {
init {
checkPsiTypeConsistency()
}
}
data class FirPsiDiagnosticWithParameters3<A, B, C>(
data class KtPsiDiagnosticWithParameters3<A, B, C>(
override val element: KtPsiSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val severity: Severity,
override val factory: FirDiagnosticFactory3<A, B, C>,
override val factory: KtDiagnosticFactory3<A, B, C>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters3<A, B, C>(), FirPsiDiagnostic {
) : KtDiagnosticWithParameters3<A, B, C>(), KtPsiDiagnostic {
init {
checkPsiTypeConsistency()
}
}
data class FirPsiDiagnosticWithParameters4<A, B, C, D>(
data class KtPsiDiagnosticWithParameters4<A, B, C, D>(
override val element: KtPsiSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val d: D,
override val severity: Severity,
override val factory: FirDiagnosticFactory4<A, B, C, D>,
override val factory: KtDiagnosticFactory4<A, B, C, D>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters4<A, B, C, D>(), FirPsiDiagnostic {
) : KtDiagnosticWithParameters4<A, B, C, D>(), KtPsiDiagnostic {
init {
checkPsiTypeConsistency()
}
@@ -154,55 +154,55 @@ data class FirPsiDiagnosticWithParameters4<A, B, C, D>(
// ------------------------------ light tree diagnostics ------------------------------
interface FirLightDiagnostic : DiagnosticMarker {
interface KtLightDiagnostic : DiagnosticMarker {
val element: KtLightSourceElement
@Deprecated("Should not be called", level = DeprecationLevel.HIDDEN)
override val psiElement: PsiElement
get() = error("psiElement should not be called on FirLightDiagnostic")
get() = error("psiElement should not be called on KtLightDiagnostic")
}
data class FirLightSimpleDiagnostic(
data class KtLightSimpleDiagnostic(
override val element: KtLightSourceElement,
override val severity: Severity,
override val factory: FirDiagnosticFactory0,
override val factory: KtDiagnosticFactory0,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirSimpleDiagnostic(), FirLightDiagnostic
) : KtSimpleDiagnostic(), KtLightDiagnostic
data class FirLightDiagnosticWithParameters1<A>(
data class KtLightDiagnosticWithParameters1<A>(
override val element: KtLightSourceElement,
override val a: A,
override val severity: Severity,
override val factory: FirDiagnosticFactory1<A>,
override val factory: KtDiagnosticFactory1<A>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters1<A>(), FirLightDiagnostic
) : KtDiagnosticWithParameters1<A>(), KtLightDiagnostic
data class FirLightDiagnosticWithParameters2<A, B>(
data class KtLightDiagnosticWithParameters2<A, B>(
override val element: KtLightSourceElement,
override val a: A,
override val b: B,
override val severity: Severity,
override val factory: FirDiagnosticFactory2<A, B>,
override val factory: KtDiagnosticFactory2<A, B>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters2<A, B>(), FirLightDiagnostic
) : KtDiagnosticWithParameters2<A, B>(), KtLightDiagnostic
data class FirLightDiagnosticWithParameters3<A, B, C>(
data class KtLightDiagnosticWithParameters3<A, B, C>(
override val element: KtLightSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val severity: Severity,
override val factory: FirDiagnosticFactory3<A, B, C>,
override val factory: KtDiagnosticFactory3<A, B, C>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters3<A, B, C>(), FirLightDiagnostic
) : KtDiagnosticWithParameters3<A, B, C>(), KtLightDiagnostic
data class FirLightDiagnosticWithParameters4<A, B, C, D>(
data class KtLightDiagnosticWithParameters4<A, B, C, D>(
override val element: KtLightSourceElement,
override val a: A,
override val b: B,
override val c: C,
override val d: D,
override val severity: Severity,
override val factory: FirDiagnosticFactory4<A, B, C, D>,
override val factory: KtDiagnosticFactory4<A, B, C, D>,
override val positioningStrategy: SourceElementPositioningStrategy
) : FirDiagnosticWithParameters4<A, B, C, D>(), FirLightDiagnostic
) : KtDiagnosticWithParameters4<A, B, C, D>(), KtLightDiagnostic
@@ -12,51 +12,51 @@ import kotlin.reflect.KClass
@RequiresOptIn("Please use DiagnosticReporter.reportOn method if possible")
annotation class InternalDiagnosticFactoryMethod
sealed class AbstractFirDiagnosticFactory(
sealed class AbstractKtDiagnosticFactory(
val name: String,
val severity: Severity,
val defaultPositioningStrategy: SourceElementPositioningStrategy,
val psiType: KClass<*>
) {
abstract val firRenderer: FirDiagnosticRenderer
abstract val ktRenderer: KtDiagnosticRenderer
override fun toString(): String {
return name
}
}
class FirDiagnosticFactory0(
class KtDiagnosticFactory0(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = SimpleFirDiagnosticRenderer("")
) : AbstractKtDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val ktRenderer: KtDiagnosticRenderer = SimpleKtDiagnosticRenderer("")
@InternalDiagnosticFactoryMethod
fun on(
element: KtSourceElement,
positioningStrategy: SourceElementPositioningStrategy?
): FirSimpleDiagnostic {
): KtSimpleDiagnostic {
return when (element) {
is KtPsiSourceElement -> FirPsiSimpleDiagnostic(
is KtPsiSourceElement -> KtPsiSimpleDiagnostic(
element, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is KtLightSourceElement -> FirLightSimpleDiagnostic(element, severity, this, positioningStrategy ?: defaultPositioningStrategy)
is KtLightSourceElement -> KtLightSimpleDiagnostic(element, severity, this, positioningStrategy ?: defaultPositioningStrategy)
else -> incorrectElement(element)
}
}
}
class FirDiagnosticFactory1<A>(
class KtDiagnosticFactory1<A>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters1Renderer(
) : AbstractKtDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val ktRenderer: KtDiagnosticRenderer = KtDiagnosticWithParameters1Renderer(
"{0}",
FirDiagnosticRenderers.TO_STRING
KtDiagnosticRenderers.TO_STRING
)
@InternalDiagnosticFactoryMethod
@@ -64,12 +64,12 @@ class FirDiagnosticFactory1<A>(
element: KtSourceElement,
a: A,
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters1<A> {
): KtDiagnosticWithParameters1<A> {
return when (element) {
is KtPsiSourceElement -> FirPsiDiagnosticWithParameters1(
is KtPsiSourceElement -> KtPsiDiagnosticWithParameters1(
element, a, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is KtLightSourceElement -> FirLightDiagnosticWithParameters1(
is KtLightSourceElement -> KtLightDiagnosticWithParameters1(
element,
a,
severity,
@@ -81,16 +81,16 @@ class FirDiagnosticFactory1<A>(
}
}
class FirDiagnosticFactory2<A, B>(
class KtDiagnosticFactory2<A, B>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters2Renderer(
) : AbstractKtDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val ktRenderer: KtDiagnosticRenderer = KtDiagnosticWithParameters2Renderer(
"{0}, {1}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
KtDiagnosticRenderers.TO_STRING,
KtDiagnosticRenderers.TO_STRING
)
@InternalDiagnosticFactoryMethod
@@ -99,12 +99,12 @@ class FirDiagnosticFactory2<A, B>(
a: A,
b: B,
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters2<A, B> {
): KtDiagnosticWithParameters2<A, B> {
return when (element) {
is KtPsiSourceElement -> FirPsiDiagnosticWithParameters2(
is KtPsiSourceElement -> KtPsiDiagnosticWithParameters2(
element, a, b, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is KtLightSourceElement -> FirLightDiagnosticWithParameters2(
is KtLightSourceElement -> KtLightDiagnosticWithParameters2(
element,
a,
b,
@@ -117,17 +117,17 @@ class FirDiagnosticFactory2<A, B>(
}
}
class FirDiagnosticFactory3<A, B, C>(
class KtDiagnosticFactory3<A, B, C>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters3Renderer(
) : AbstractKtDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val ktRenderer: KtDiagnosticRenderer = KtDiagnosticWithParameters3Renderer(
"{0}, {1}, {2}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
KtDiagnosticRenderers.TO_STRING,
KtDiagnosticRenderers.TO_STRING,
KtDiagnosticRenderers.TO_STRING
)
@InternalDiagnosticFactoryMethod
@@ -137,12 +137,12 @@ class FirDiagnosticFactory3<A, B, C>(
b: B,
c: C,
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters3<A, B, C> {
): KtDiagnosticWithParameters3<A, B, C> {
return when (element) {
is KtPsiSourceElement -> FirPsiDiagnosticWithParameters3(
is KtPsiSourceElement -> KtPsiDiagnosticWithParameters3(
element, a, b, c, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is KtLightSourceElement -> FirLightDiagnosticWithParameters3(
is KtLightSourceElement -> KtLightDiagnosticWithParameters3(
element,
a,
b,
@@ -156,18 +156,18 @@ class FirDiagnosticFactory3<A, B, C>(
}
}
class FirDiagnosticFactory4<A, B, C, D>(
class KtDiagnosticFactory4<A, B, C, D>(
name: String,
severity: Severity,
defaultPositioningStrategy: SourceElementPositioningStrategy,
psiType: KClass<*>
) : AbstractFirDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val firRenderer: FirDiagnosticRenderer = FirDiagnosticWithParameters4Renderer(
) : AbstractKtDiagnosticFactory(name, severity, defaultPositioningStrategy, psiType) {
override val ktRenderer: KtDiagnosticRenderer = KtDiagnosticWithParameters4Renderer(
"{0}, {1}, {2}, {3}",
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING,
FirDiagnosticRenderers.TO_STRING
KtDiagnosticRenderers.TO_STRING,
KtDiagnosticRenderers.TO_STRING,
KtDiagnosticRenderers.TO_STRING,
KtDiagnosticRenderers.TO_STRING
)
@InternalDiagnosticFactoryMethod
@@ -178,12 +178,12 @@ class FirDiagnosticFactory4<A, B, C, D>(
c: C,
d: D,
positioningStrategy: SourceElementPositioningStrategy?
): FirDiagnosticWithParameters4<A, B, C, D> {
): KtDiagnosticWithParameters4<A, B, C, D> {
return when (element) {
is KtPsiSourceElement -> FirPsiDiagnosticWithParameters4(
is KtPsiSourceElement -> KtPsiDiagnosticWithParameters4(
element, a, b, c, d, severity, this, positioningStrategy ?: defaultPositioningStrategy
)
is KtLightSourceElement -> FirLightDiagnosticWithParameters4(
is KtLightSourceElement -> KtLightDiagnosticWithParameters4(
element,
a,
b,
@@ -204,38 +204,38 @@ private fun incorrectElement(element: KtSourceElement): Nothing {
// ------------------------------ factories for deprecation ------------------------------
sealed class FirDiagnosticFactoryForDeprecation<F : AbstractFirDiagnosticFactory>(
sealed class KtDiagnosticFactoryForDeprecation<F : AbstractKtDiagnosticFactory>(
val deprecatingFeature: LanguageFeature,
val warningFactory: F,
val errorFactory: F
)
class FirDiagnosticFactoryForDeprecation0(
class KtDiagnosticFactoryForDeprecation0(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory0,
errorFactory: FirDiagnosticFactory0
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory0>(featureForError, warningFactory, errorFactory)
warningFactory: KtDiagnosticFactory0,
errorFactory: KtDiagnosticFactory0
) : KtDiagnosticFactoryForDeprecation<KtDiagnosticFactory0>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation1<A>(
class KtDiagnosticFactoryForDeprecation1<A>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory1<A>,
errorFactory: FirDiagnosticFactory1<A>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory1<A>>(featureForError, warningFactory, errorFactory)
warningFactory: KtDiagnosticFactory1<A>,
errorFactory: KtDiagnosticFactory1<A>
) : KtDiagnosticFactoryForDeprecation<KtDiagnosticFactory1<A>>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation2<A, B>(
class KtDiagnosticFactoryForDeprecation2<A, B>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory2<A, B>,
errorFactory: FirDiagnosticFactory2<A, B>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory2<A, B>>(featureForError, warningFactory, errorFactory)
warningFactory: KtDiagnosticFactory2<A, B>,
errorFactory: KtDiagnosticFactory2<A, B>
) : KtDiagnosticFactoryForDeprecation<KtDiagnosticFactory2<A, B>>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation3<A, B, C>(
class KtDiagnosticFactoryForDeprecation3<A, B, C>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory3<A, B, C>,
errorFactory: FirDiagnosticFactory3<A, B, C>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory3<A, B, C>>(featureForError, warningFactory, errorFactory)
warningFactory: KtDiagnosticFactory3<A, B, C>,
errorFactory: KtDiagnosticFactory3<A, B, C>
) : KtDiagnosticFactoryForDeprecation<KtDiagnosticFactory3<A, B, C>>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation4<A, B, C, D>(
class KtDiagnosticFactoryForDeprecation4<A, B, C, D>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory4<A, B, C, D>,
errorFactory: FirDiagnosticFactory4<A, B, C, D>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory4<A, B, C, D>>(featureForError, warningFactory, errorFactory)
warningFactory: KtDiagnosticFactory4<A, B, C, D>,
errorFactory: KtDiagnosticFactory4<A, B, C, D>
) : KtDiagnosticFactoryForDeprecation<KtDiagnosticFactory4<A, B, C, D>>(featureForError, warningFactory, errorFactory)
@@ -114,8 +114,8 @@ class DiagnosticFactory0DelegateProvider(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory0> {
return DummyDelegate(FirDiagnosticFactory0(prop.name, severity, positioningStrategy, psiType))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactory0> {
return DummyDelegate(KtDiagnosticFactory0(prop.name, severity, positioningStrategy, psiType))
}
}
@@ -124,8 +124,8 @@ class DiagnosticFactory1DelegateProvider<A>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory1<A>> {
return DummyDelegate(FirDiagnosticFactory1(prop.name, severity, positioningStrategy, psiType))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactory1<A>> {
return DummyDelegate(KtDiagnosticFactory1(prop.name, severity, positioningStrategy, psiType))
}
}
@@ -134,8 +134,8 @@ class DiagnosticFactory2DelegateProvider<A, B>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory2<A, B>> {
return DummyDelegate(FirDiagnosticFactory2(prop.name, severity, positioningStrategy, psiType))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactory2<A, B>> {
return DummyDelegate(KtDiagnosticFactory2(prop.name, severity, positioningStrategy, psiType))
}
}
@@ -144,8 +144,8 @@ class DiagnosticFactory3DelegateProvider<A, B, C>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory3<A, B, C>> {
return DummyDelegate(FirDiagnosticFactory3(prop.name, severity, positioningStrategy, psiType))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactory3<A, B, C>> {
return DummyDelegate(KtDiagnosticFactory3(prop.name, severity, positioningStrategy, psiType))
}
}
@@ -154,8 +154,8 @@ class DiagnosticFactory4DelegateProvider<A, B, C, D>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactory4<A, B, C, D>> {
return DummyDelegate(FirDiagnosticFactory4(prop.name, severity, positioningStrategy, psiType))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactory4<A, B, C, D>> {
return DummyDelegate(KtDiagnosticFactory4(prop.name, severity, positioningStrategy, psiType))
}
}
@@ -167,10 +167,10 @@ class DeprecationDiagnosticFactory0DelegateProvider(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation0> {
val errorFactory = FirDiagnosticFactory0("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory0("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation0(featureForError, warningFactory, errorFactory))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactoryForDeprecation0> {
val errorFactory = KtDiagnosticFactory0("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = KtDiagnosticFactory0("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(KtDiagnosticFactoryForDeprecation0(featureForError, warningFactory, errorFactory))
}
}
@@ -179,10 +179,10 @@ class DeprecationDiagnosticFactory1DelegateProvider<A>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation1<A>> {
val errorFactory = FirDiagnosticFactory1<A>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory1<A>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation1(featureForError, warningFactory, errorFactory))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactoryForDeprecation1<A>> {
val errorFactory = KtDiagnosticFactory1<A>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = KtDiagnosticFactory1<A>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(KtDiagnosticFactoryForDeprecation1(featureForError, warningFactory, errorFactory))
}
}
@@ -191,10 +191,10 @@ class DeprecationDiagnosticFactory2DelegateProvider<A, B>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation2<A, B>> {
val errorFactory = FirDiagnosticFactory2<A, B>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory2<A, B>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation2(featureForError, warningFactory, errorFactory))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactoryForDeprecation2<A, B>> {
val errorFactory = KtDiagnosticFactory2<A, B>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = KtDiagnosticFactory2<A, B>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(KtDiagnosticFactoryForDeprecation2(featureForError, warningFactory, errorFactory))
}
}
@@ -203,10 +203,10 @@ class DeprecationDiagnosticFactory3DelegateProvider<A, B, C>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation3<A, B, C>> {
val errorFactory = FirDiagnosticFactory3<A, B, C>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory3<A, B, C>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation3(featureForError, warningFactory, errorFactory))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactoryForDeprecation3<A, B, C>> {
val errorFactory = KtDiagnosticFactory3<A, B, C>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = KtDiagnosticFactory3<A, B, C>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(KtDiagnosticFactoryForDeprecation3(featureForError, warningFactory, errorFactory))
}
}
@@ -215,10 +215,10 @@ class DeprecationDiagnosticFactory4DelegateProvider<A, B, C, D>(
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation4<A, B, C, D>> {
val errorFactory = FirDiagnosticFactory4<A, B, C, D>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory4<A, B, C, D>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation4(featureForError, warningFactory, errorFactory))
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, KtDiagnosticFactoryForDeprecation4<A, B, C, D>> {
val errorFactory = KtDiagnosticFactory4<A, B, C, D>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = KtDiagnosticFactory4<A, B, C, D>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(KtDiagnosticFactoryForDeprecation4(featureForError, warningFactory, errorFactory))
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -7,105 +7,105 @@ 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()
class KtDiagnosticFactoryToRendererMap(val name: String) {
private val renderersMap: MutableMap<AbstractKtDiagnosticFactory, KtDiagnosticRenderer> = mutableMapOf()
operator fun get(factory: AbstractFirDiagnosticFactory): FirDiagnosticRenderer? = renderersMap[factory]
operator fun get(factory: AbstractKtDiagnosticFactory): KtDiagnosticRenderer? = renderersMap[factory]
fun put(factory: FirDiagnosticFactory0, message: String) {
put(factory, SimpleFirDiagnosticRenderer(message))
fun put(factory: KtDiagnosticFactory0, message: String) {
put(factory, SimpleKtDiagnosticRenderer(message))
}
fun <A> put(
factory: FirDiagnosticFactory1<A>,
factory: KtDiagnosticFactory1<A>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?
) {
put(factory, FirDiagnosticWithParameters1Renderer(message, rendererA))
put(factory, KtDiagnosticWithParameters1Renderer(message, rendererA))
}
fun <A, B> put(
factory: FirDiagnosticFactory2<A, B>,
factory: KtDiagnosticFactory2<A, B>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?
) {
put(factory, FirDiagnosticWithParameters2Renderer(message, rendererA, rendererB))
put(factory, KtDiagnosticWithParameters2Renderer(message, rendererA, rendererB))
}
fun <A, B, C> put(
factory: FirDiagnosticFactory3<A, B, C>,
factory: KtDiagnosticFactory3<A, B, C>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
rendererC: DiagnosticParameterRenderer<C>?
) {
put(factory, FirDiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC))
put(factory, KtDiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC))
}
fun <A, B, C, D> put(
factory: FirDiagnosticFactory4<A, B, C, D>,
factory: KtDiagnosticFactory4<A, B, C, D>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
rendererC: DiagnosticParameterRenderer<C>?,
rendererD: DiagnosticParameterRenderer<D>?
) {
put(factory, FirDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
put(factory, KtDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
}
fun put(factory: FirDiagnosticFactoryForDeprecation0, message: String) {
put(factory.errorFactory, SimpleFirDiagnosticRenderer(message))
put(factory.warningFactory, SimpleFirDiagnosticRenderer(factory.warningMessage(message)))
fun put(factory: KtDiagnosticFactoryForDeprecation0, message: String) {
put(factory.errorFactory, SimpleKtDiagnosticRenderer(message))
put(factory.warningFactory, SimpleKtDiagnosticRenderer(factory.warningMessage(message)))
}
fun <A> put(
factory: FirDiagnosticFactoryForDeprecation1<A>,
factory: KtDiagnosticFactoryForDeprecation1<A>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters1Renderer(message, rendererA))
put(factory.warningFactory, FirDiagnosticWithParameters1Renderer(factory.warningMessage(message), rendererA))
put(factory.errorFactory, KtDiagnosticWithParameters1Renderer(message, rendererA))
put(factory.warningFactory, KtDiagnosticWithParameters1Renderer(factory.warningMessage(message), rendererA))
}
fun <A, B> put(
factory: FirDiagnosticFactoryForDeprecation2<A, B>,
factory: KtDiagnosticFactoryForDeprecation2<A, B>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters2Renderer(message, rendererA, rendererB))
put(factory.warningFactory, FirDiagnosticWithParameters2Renderer(factory.warningMessage(message), rendererA, rendererB))
put(factory.errorFactory, KtDiagnosticWithParameters2Renderer(message, rendererA, rendererB))
put(factory.warningFactory, KtDiagnosticWithParameters2Renderer(factory.warningMessage(message), rendererA, rendererB))
}
fun <A, B, C> put(
factory: FirDiagnosticFactoryForDeprecation3<A, B, C>,
factory: KtDiagnosticFactoryForDeprecation3<A, B, C>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
rendererC: DiagnosticParameterRenderer<C>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC))
put(factory.warningFactory, FirDiagnosticWithParameters3Renderer(factory.warningMessage(message), rendererA, rendererB, rendererC))
put(factory.errorFactory, KtDiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC))
put(factory.warningFactory, KtDiagnosticWithParameters3Renderer(factory.warningMessage(message), rendererA, rendererB, rendererC))
}
fun <A, B, C, D> put(
factory: FirDiagnosticFactoryForDeprecation4<A, B, C, D>,
factory: KtDiagnosticFactoryForDeprecation4<A, B, C, D>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
rendererC: DiagnosticParameterRenderer<C>?,
rendererD: DiagnosticParameterRenderer<D>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
put(factory.warningFactory, FirDiagnosticWithParameters4Renderer(factory.warningMessage(message), rendererA, rendererB, rendererC, rendererD))
put(factory.errorFactory, KtDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
put(factory.warningFactory, KtDiagnosticWithParameters4Renderer(factory.warningMessage(message), rendererA, rendererB, rendererC, rendererD))
}
private fun put(factory: AbstractFirDiagnosticFactory, renderer: FirDiagnosticRenderer) {
private fun put(factory: AbstractKtDiagnosticFactory, renderer: KtDiagnosticRenderer) {
renderersMap[factory] = renderer
}
private fun FirDiagnosticFactoryForDeprecation<*>.warningMessage(errorMessage: String): String {
private fun KtDiagnosticFactoryForDeprecation<*>.warningMessage(errorMessage: String): String {
return buildString {
append(errorMessage)
append(". This will become an error")
@@ -10,52 +10,52 @@ import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
import org.jetbrains.kotlin.diagnostics.rendering.renderParameter
import java.text.MessageFormat
sealed interface FirDiagnosticRenderer {
fun render(diagnostic: FirDiagnostic): String
fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?>
sealed interface KtDiagnosticRenderer {
fun render(diagnostic: KtDiagnostic): String
fun renderParameters(diagnostic: KtDiagnostic): Array<out Any?>
}
class SimpleFirDiagnosticRenderer(private val message: String) : FirDiagnosticRenderer {
override fun render(diagnostic: FirDiagnostic): String {
require(diagnostic is FirSimpleDiagnostic)
class SimpleKtDiagnosticRenderer(private val message: String) : KtDiagnosticRenderer {
override fun render(diagnostic: KtDiagnostic): String {
require(diagnostic is KtSimpleDiagnostic)
return message
}
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirSimpleDiagnostic)
override fun renderParameters(diagnostic: KtDiagnostic): Array<out Any?> {
require(diagnostic is KtSimpleDiagnostic)
return emptyArray()
}
}
sealed class AbstractFirDiagnosticWithParametersRenderer(
sealed class AbstractKtDiagnosticWithParametersRenderer(
protected val message: String
) : FirDiagnosticRenderer {
) : KtDiagnosticRenderer {
private val messageFormat = MessageFormat(message)
final override fun render(diagnostic: FirDiagnostic): String {
final override fun render(diagnostic: KtDiagnostic): String {
return messageFormat.format(renderParameters(diagnostic))
}
}
class FirDiagnosticWithParameters1Renderer<A>(
class KtDiagnosticWithParameters1Renderer<A>(
message: String,
private val rendererForA: DiagnosticParameterRenderer<A>?,
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters1<*>)
) : AbstractKtDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: KtDiagnostic): Array<out Any?> {
require(diagnostic is KtDiagnosticWithParameters1<*>)
val context = RenderingContext.of(diagnostic.a)
@Suppress("UNCHECKED_CAST")
return arrayOf(renderParameter(diagnostic.a as A, rendererForA, context))
}
}
class FirDiagnosticWithParameters2Renderer<A, B>(
class KtDiagnosticWithParameters2Renderer<A, B>(
message: String,
private val rendererForA: DiagnosticParameterRenderer<A>?,
private val rendererForB: DiagnosticParameterRenderer<B>?,
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters2<*, *>)
) : AbstractKtDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: KtDiagnostic): Array<out Any?> {
require(diagnostic is KtDiagnosticWithParameters2<*, *>)
val context = RenderingContext.of(diagnostic.a, diagnostic.b)
@Suppress("UNCHECKED_CAST")
return arrayOf(
@@ -65,14 +65,14 @@ class FirDiagnosticWithParameters2Renderer<A, B>(
}
}
class FirDiagnosticWithParameters3Renderer<A, B, C>(
class KtDiagnosticWithParameters3Renderer<A, B, C>(
message: String,
private val rendererForA: DiagnosticParameterRenderer<A>?,
private val rendererForB: DiagnosticParameterRenderer<B>?,
private val rendererForC: DiagnosticParameterRenderer<C>?,
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters3<*, *, *>)
) : AbstractKtDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: KtDiagnostic): Array<out Any?> {
require(diagnostic is KtDiagnosticWithParameters3<*, *, *>)
val context = RenderingContext.of(diagnostic.a, diagnostic.b, diagnostic.c)
@Suppress("UNCHECKED_CAST")
return arrayOf(
@@ -83,15 +83,15 @@ class FirDiagnosticWithParameters3Renderer<A, B, C>(
}
}
class FirDiagnosticWithParameters4Renderer<A, B, C, D>(
class KtDiagnosticWithParameters4Renderer<A, B, C, D>(
message: String,
private val rendererForA: DiagnosticParameterRenderer<A>?,
private val rendererForB: DiagnosticParameterRenderer<B>?,
private val rendererForC: DiagnosticParameterRenderer<C>?,
private val rendererForD: DiagnosticParameterRenderer<D>?,
) : AbstractFirDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: FirDiagnostic): Array<out Any?> {
require(diagnostic is FirDiagnosticWithParameters4<*, *, *, *>)
) : AbstractKtDiagnosticWithParametersRenderer(message) {
override fun renderParameters(diagnostic: KtDiagnostic): Array<out Any?> {
require(diagnostic is KtDiagnosticWithParameters4<*, *, *, *>)
val context = RenderingContext.of(diagnostic.a, diagnostic.b, diagnostic.c, diagnostic.d)
@Suppress("UNCHECKED_CAST")
return arrayOf(
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.rendering.ContextIndependentParameterRenderer
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
object KtDiagnosticRenderers {
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
val TO_STRING = Renderer { element: Any? ->
element.toString()
}
val EMPTY = Renderer { _: Any? -> "" }
val VISIBILITY = Renderer { visibility: Visibility ->
visibility.externalDisplayName
}
val NOT_RENDERED = Renderer<Any?> {
""
}
val FUNCTION_PARAMETERS = Renderer { hasValueParameters: Boolean -> if (hasValueParameters) "..." else "" }
@Suppress("FunctionName")
fun <T> COLLECTION(renderer: ContextIndependentParameterRenderer<T>): ContextIndependentParameterRenderer<Collection<T>> {
return Renderer { list ->
list.joinToString(prefix = "[", postfix = "]", separator = ", ", limit = 3, truncated = "...") {
renderer.render(it)
}
}
}
}
@@ -11,9 +11,9 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.KtNodeType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS
@@ -968,21 +968,21 @@ object LightTreePositioningStrategies {
}
val UNREACHABLE_CODE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun markFirDiagnostic(element: KtSourceElement, diagnostic: FirDiagnostic): List<TextRange> {
override fun markKtDiagnostic(element: KtSourceElement, diagnostic: KtDiagnostic): List<TextRange> {
@Suppress("UNCHECKED_CAST")
val typed = diagnostic as FirDiagnosticWithParameters2<Set<KtSourceElement>, Set<KtSourceElement>>
val typed = diagnostic as KtDiagnosticWithParameters2<Set<KtSourceElement>, Set<KtSourceElement>>
with(UnreachableCodeLightTreeHelper(element.treeStructure)) {
val reachable = typed.a.map { it.lighterASTNode }.toSet()
val unreachable = typed.b.map { it.lighterASTNode }.toSet()
if (!element.lighterASTNode.hasChildrenInSet(reachable)) {
return super.markFirDiagnostic(element, diagnostic)
return super.markKtDiagnostic(element, diagnostic)
}
val nodesToMark = element.lighterASTNode.getLeavesOrReachableChildren(reachable, unreachable)
.removeReachableElementsWithMeaninglessSiblings(reachable)
if (nodesToMark.isEmpty()) {
return super.markFirDiagnostic(element, diagnostic)
return super.markKtDiagnostic(element, diagnostic)
}
val ranges = nodesToMark.flatMap {
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.WHITE_SPACE
open class LightTreePositioningStrategy {
open fun markFirDiagnostic(element: KtSourceElement, diagnostic: FirDiagnostic): List<TextRange> {
open fun markKtDiagnostic(element: KtSourceElement, diagnostic: KtDiagnostic): List<TextRange> {
return mark(element.lighterASTNode, element.startOffset, element.endOffset, element.treeStructure)
}
@@ -17,12 +17,12 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedDeclaration
object FirPsiPositioningStrategies {
object PsiPositioningStrategies {
val UNREACHABLE_CODE = object : PositioningStrategy<PsiElement>() {
override fun markDiagnostic(diagnostic: DiagnosticMarker): List<TextRange> {
//todo it is better to implement arguments extraction in FirDiagnosticFactory, but kotlin struggle with checking types in it atm
//todo it is better to implement arguments extraction in KtDiagnosticFactory, but kotlin struggle with checking types in it atm
@Suppress("UNCHECKED_CAST")
val typed = diagnostic as FirDiagnosticWithParameters2<Set<KtSourceElement>, Set<KtSourceElement>>
val typed = diagnostic as KtDiagnosticWithParameters2<Set<KtSourceElement>, Set<KtSourceElement>>
val source = diagnostic.element as KtPsiSourceElement
return UnreachableCode.getUnreachableTextRanges(
source.psi as KtElement,
@@ -34,7 +34,7 @@ object FirPsiPositioningStrategies {
val ACTUAL_DECLARATION_NAME = object : PositioningStrategy<PsiElement>() {
override fun markDiagnostic(diagnostic: DiagnosticMarker): List<TextRange> {
require(diagnostic is FirDiagnostic)
require(diagnostic is KtDiagnostic)
val element = diagnostic.element.psi ?: return emptyList()
(element as? KtNamedDeclaration)?.nameIdentifier?.let { nameIdentifier ->
return mark(nameIdentifier)
@@ -279,12 +279,12 @@ object SourceElementPositioningStrategies {
val UNREACHABLE_CODE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.UNREACHABLE_CODE,
FirPsiPositioningStrategies.UNREACHABLE_CODE
PsiPositioningStrategies.UNREACHABLE_CODE
)
val ACTUAL_DECLARATION_NAME = SourceElementPositioningStrategy(
LightTreePositioningStrategies.ACTUAL_DECLARATION_NAME,
FirPsiPositioningStrategies.ACTUAL_DECLARATION_NAME
PsiPositioningStrategies.ACTUAL_DECLARATION_NAME
)
val LABEL = SourceElementPositioningStrategy(
@@ -16,10 +16,10 @@ class SourceElementPositioningStrategy(
private val lightTreeStrategy: LightTreePositioningStrategy,
private val psiStrategy: PositioningStrategy<*>
) {
fun markDiagnostic(diagnostic: FirDiagnostic): List<TextRange> {
fun markDiagnostic(diagnostic: KtDiagnostic): List<TextRange> {
return when (val element = diagnostic.element) {
is KtPsiSourceElement -> psiStrategy.markDiagnostic(diagnostic)
is KtLightSourceElement -> lightTreeStrategy.markFirDiagnostic(element, diagnostic)
is KtLightSourceElement -> lightTreeStrategy.markKtDiagnostic(element, diagnostic)
}
}
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
import org.jetbrains.kotlin.fir.analysis.getChild
@@ -35,10 +35,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
private fun ConeDiagnostic.toFirDiagnostic(
private fun ConeDiagnostic.toKtDiagnostic(
source: KtSourceElement,
qualifiedAccessSource: KtSourceElement?
): FirDiagnostic? = when (this) {
): KtDiagnostic? = when (this) {
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.createOn(
source,
(this.name ?: SpecialNames.NO_NAME_PROVIDED).asString()
@@ -119,11 +119,11 @@ fun ConeDiagnostic.toFirDiagnostics(
session: FirSession,
source: KtSourceElement,
qualifiedAccessSource: KtSourceElement?
): List<FirDiagnostic> {
): List<KtDiagnostic> {
return when (this) {
is ConeInapplicableCandidateError -> mapInapplicableCandidateError(session, this, source, qualifiedAccessSource)
is ConeConstraintSystemHasContradiction -> mapSystemHasContradictionError(session, this, source, qualifiedAccessSource)
else -> listOfNotNull(toFirDiagnostic(source, qualifiedAccessSource))
else -> listOfNotNull(toKtDiagnostic(source, qualifiedAccessSource))
}
}
@@ -132,7 +132,7 @@ private fun mapUnsafeCallError(
rootCause: UnsafeCall,
source: KtSourceElement,
qualifiedAccessSource: KtSourceElement?,
): FirDiagnostic? {
): KtDiagnostic? {
if (candidate.callInfo.isImplicitInvoke) {
return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.createOn(source, rootCause.actualType)
}
@@ -181,7 +181,7 @@ private fun mapInapplicableCandidateError(
diagnostic: ConeInapplicableCandidateError,
source: KtSourceElement,
qualifiedAccessSource: KtSourceElement?,
): List<FirDiagnostic> {
): List<KtDiagnostic> {
val genericDiagnostic = FirErrors.INAPPLICABLE_CANDIDATE.createOn(source, diagnostic.candidate.symbol)
val diagnostics = diagnostic.candidate.diagnostics.filter { it.applicability == diagnostic.applicability }.mapNotNull { rootCause ->
when (rootCause) {
@@ -245,9 +245,9 @@ private fun mapSystemHasContradictionError(
diagnostic: ConeConstraintSystemHasContradiction,
source: KtSourceElement,
qualifiedAccessSource: KtSourceElement?,
): List<FirDiagnostic> {
): List<KtDiagnostic> {
val errorsToIgnore = mutableSetOf<ConstraintSystemError>()
return buildList<FirDiagnostic> {
return buildList<KtDiagnostic> {
for (error in diagnostic.candidate.system.errors) {
addIfNotNull(
error.toDiagnostic(
@@ -290,7 +290,7 @@ private fun ConstraintSystemError.toDiagnostic(
typeContext: ConeTypeContext,
errorsToIgnore: MutableSet<ConstraintSystemError>,
candidate: AbstractCandidate,
): FirDiagnostic? {
): KtDiagnostic? {
return when (this) {
is NewConstraintError -> {
val position = position.from
@@ -365,7 +365,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: KtSourceElement): FirDiagnosticFactory0 {
private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement): KtDiagnosticFactory0 {
@Suppress("UNCHECKED_CAST")
return when (kind) {
DiagnosticKind.Syntax -> FirErrors.SYNTAX
@@ -416,46 +416,46 @@ private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement): FirDiagnos
@OptIn(InternalDiagnosticFactoryMethod::class)
private fun FirDiagnosticFactory0.createOn(
private fun KtDiagnosticFactory0.createOn(
element: KtSourceElement?
): FirSimpleDiagnostic? {
): KtSimpleDiagnostic? {
return element?.let { on(it, positioningStrategy = null) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
private fun <A> FirDiagnosticFactory1<A>.createOn(
private fun <A> KtDiagnosticFactory1<A>.createOn(
element: KtSourceElement?,
a: A
): FirDiagnosticWithParameters1<A>? {
): KtDiagnosticWithParameters1<A>? {
return element?.let { on(it, a, positioningStrategy = null) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
private fun <A, B> FirDiagnosticFactory2<A, B>.createOn(
private fun <A, B> KtDiagnosticFactory2<A, B>.createOn(
element: KtSourceElement?,
a: A,
b: B
): FirDiagnosticWithParameters2<A, B>? {
): KtDiagnosticWithParameters2<A, B>? {
return element?.let { on(it, a, b, positioningStrategy = null) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
private fun <A, B, C> FirDiagnosticFactory3<A, B, C>.createOn(
private fun <A, B, C> KtDiagnosticFactory3<A, B, C>.createOn(
element: KtSourceElement?,
a: A,
b: B,
c: C
): FirDiagnosticWithParameters3<A, B, C>? {
): KtDiagnosticWithParameters3<A, B, C>? {
return element?.let { on(it, a, b, c, positioningStrategy = null) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
private fun <A, B, C, D> FirDiagnosticFactory4<A, B, C, D>.createOn(
private fun <A, B, C, D> KtDiagnosticFactory4<A, B, C, D>.createOn(
element: KtSourceElement?,
a: A,
b: B,
c: C,
d: D
): FirDiagnosticWithParameters4<A, B, C, D>? {
): KtDiagnosticWithParameters4<A, B, C, D>? {
return element?.let { on(it, a, b, c, d, positioningStrategy = null) }
}
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics.impl
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
abstract class BaseDiagnosticReporter : DiagnosticReporter() {
abstract val diagnostics: List<FirDiagnostic>
abstract val diagnostics: List<KtDiagnostic>
}
@@ -6,16 +6,16 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics.impl
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.AbstractFirDiagnosticFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.AbstractKtDiagnosticFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
class DeduplicatingDiagnosticReporter(private val inner: DiagnosticReporter) : DiagnosticReporter() {
private val reported = mutableSetOf<Pair<KtSourceElement, AbstractFirDiagnosticFactory>>()
private val reported = mutableSetOf<Pair<KtSourceElement, AbstractKtDiagnosticFactory>>()
override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) {
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) {
if (diagnostic != null && reported.add(Pair(diagnostic.element, diagnostic.factory))) {
inner.report(diagnostic, context)
}
@@ -5,15 +5,15 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics.impl
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
class DiagnosticReporterWithSuppress : BaseDiagnosticReporter() {
private val _diagnostics: MutableList<FirDiagnostic> = mutableListOf()
override val diagnostics: List<FirDiagnostic>
private val _diagnostics: MutableList<KtDiagnostic> = mutableListOf()
override val diagnostics: List<KtDiagnostic>
get() = _diagnostics
override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) {
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) {
if (diagnostic == null) return
if (!context.isDiagnosticSuppressed(diagnostic)) {
_diagnostics += diagnostic
@@ -5,15 +5,15 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics.impl
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
class SimpleDiagnosticReporter : BaseDiagnosticReporter() {
private val _diagnostics: MutableList<FirDiagnostic> = mutableListOf()
override val diagnostics: List<FirDiagnostic>
private val _diagnostics: MutableList<KtDiagnostic> = mutableListOf()
override val diagnostics: List<KtDiagnostic>
get() = _diagnostics
override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) {
override fun report(diagnostic: KtDiagnostic?, context: DiagnosticContext) {
if (diagnostic == null) return
_diagnostics += diagnostic
}
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider
@@ -34,7 +34,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<KtDiagnostic>>
abstract fun runResolution(): List<FirFile>
@@ -55,7 +55,7 @@ class FirAnalyzerFacade(
override val scopeSession: ScopeSession
get() = _scopeSession!!
private var collectedDiagnostics: Map<FirFile, List<FirDiagnostic>>? = null
private var collectedDiagnostics: Map<FirFile, List<KtDiagnostic>>? = null
private fun buildRawFir() {
if (firFiles != null) return
@@ -87,7 +87,7 @@ class FirAnalyzerFacade(
}
@OptIn(ExperimentalStdlibApi::class)
override fun runCheckers(): Map<FirFile, List<FirDiagnostic>> {
override fun runCheckers(): Map<FirFile, List<KtDiagnostic>> {
if (_scopeSession == null) runResolution()
if (collectedDiagnostics != null) return collectedDiagnostics!!
val collector = FirDiagnosticsCollector.create(session, scopeSession)
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.pipeline
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor
@@ -20,7 +20,7 @@ fun FirSession.runResolution(firFiles: List<FirFile>): Pair<ScopeSession, List<F
}
@OptIn(ExperimentalStdlibApi::class)
fun FirSession.runCheckers(scopeSession: ScopeSession, firFiles: List<FirFile>): Map<FirFile, List<FirDiagnostic>> {
fun FirSession.runCheckers(scopeSession: ScopeSession, firFiles: List<FirFile>): Map<FirFile, List<KtDiagnostic>> {
val collector = FirDiagnosticsCollector.create(this, scopeSession)
return buildMap {
for (file in firFiles) {
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.test.frontend.fir.handlers
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.codeMetaInfo.model.CodeMetaInfo
import org.jetbrains.kotlin.codeMetaInfo.renderConfigurations.AbstractCodeMetaInfoRenderConfiguration
import org.jetbrains.kotlin.fir.analysis.diagnostics.AbstractFirDiagnosticWithParametersRenderer
import org.jetbrains.kotlin.fir.analysis.diagnostics.AbstractKtDiagnosticWithParametersRenderer
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDefaultErrorMessages
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
object FirMetaInfoUtils {
val renderDiagnosticNoArgs = FirDiagnosticCodeMetaRenderConfiguration().apply { renderParams = false }
@@ -18,7 +18,7 @@ object FirMetaInfoUtils {
}
class FirDiagnosticCodeMetaInfo(
val diagnostic: FirDiagnostic,
val diagnostic: KtDiagnostic,
renderConfiguration: FirDiagnosticCodeMetaRenderConfiguration,
private val range: TextRange
) : CodeMetaInfo {
@@ -64,7 +64,7 @@ class FirDiagnosticCodeMetaRenderConfiguration(
@Suppress("UNCHECKED_CAST")
val renderer = FirDefaultErrorMessages.getRendererForDiagnostic(diagnostic)
if (renderer is AbstractFirDiagnosticWithParametersRenderer) {
if (renderer is AbstractKtDiagnosticWithParametersRenderer) {
renderer.renderParameters(diagnostic).mapTo(params, Any?::toString)
}
@@ -102,7 +102,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
}
}
private fun FirDiagnostic.toMetaInfos(
private fun KtDiagnostic.toMetaInfos(
file: TestFile,
lightTreeEnabled: Boolean,
lightTreeComparingModeEnabled: Boolean,
@@ -151,7 +151,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
lightTreeEnabled: Boolean,
lightTreeComparingModeEnabled: Boolean
) {
val result = mutableListOf<FirDiagnostic>()
val result = mutableListOf<KtDiagnostic>()
val diagnosedRangesToDiagnosticNames = globalMetadataInfoHandler.getExistingMetaInfosForFile(testFile).groupBy(
keySelector = { it.start..it.end },
valueTransform = { it.tag }
@@ -201,7 +201,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
fun createExpressionTypeDiagnosticIfExpected(
element: FirExpression,
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>
): FirDiagnosticWithParameters1<String>? =
): KtDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.EXPRESSION_TYPE.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
element.typeRef.renderAsString((element as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.originalType)
}
@@ -218,7 +218,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
element: FirElement,
reference: FirNamedReference,
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>
): FirDiagnosticWithParameters1<String>? =
): KtDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.CALL.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
val resolvedSymbol = (reference as? FirResolvedNamedReference)?.resolvedSymbol
val fqName = resolvedSymbol?.fqNameUnsafe()
@@ -255,7 +255,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
element: FirElement,
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>,
argument: () -> String,
): FirDiagnosticWithParameters1<String>? {
): KtDiagnosticWithParameters1<String>? {
val sourceElement = element.source ?: return null
if (sourceElement.kind !in allowedKindsForDebugInfo) return null
@@ -270,16 +270,16 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
}
val argumentText = argument()
val factory = FirDiagnosticFactory1<String>(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class)
val factory = KtDiagnosticFactory1<String>(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class)
return when (positionedElement) {
is KtPsiSourceElement -> FirPsiDiagnosticWithParameters1(
is KtPsiSourceElement -> KtPsiDiagnosticWithParameters1(
positionedElement,
argumentText,
severity,
factory,
factory.defaultPositioningStrategy
)
is KtLightSourceElement -> FirLightDiagnosticWithParameters1(
is KtLightSourceElement -> KtLightDiagnosticWithParameters1(
positionedElement,
argumentText,
severity,
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
import org.jetbrains.kotlin.fir.builder.PsiHandlingMode
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
@@ -226,7 +226,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
}
protected fun TestFile.getActualText(
firDiagnostics: Iterable<FirDiagnostic>,
ktDiagnostics: Iterable<KtDiagnostic>,
actualText: StringBuilder
): Boolean {
val ktFile = this.ktFile
@@ -241,7 +241,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
// TODO: report JVM signature diagnostics also for implementing modules
val ok = booleanArrayOf(true)
val diagnostics = firDiagnostics.toActualDiagnostic(ktFile)
val diagnostics = ktDiagnostics.toActualDiagnostic(ktFile)
val filteredDiagnostics = diagnostics // TODO
actualDiagnostics.addAll(filteredDiagnostics)
@@ -338,7 +338,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
return ok[0]
}
private fun Iterable<FirDiagnostic>.toActualDiagnostic(root: PsiElement): List<ActualDiagnostic> {
private fun Iterable<KtDiagnostic>.toActualDiagnostic(root: PsiElement): List<ActualDiagnostic> {
val result = mutableListOf<ActualDiagnostic>()
filterIsInstance<Diagnostic>().mapTo(result) {
ActualDiagnostic(it, null, true)
@@ -57,7 +57,7 @@ import java.io.File
* and it will opens xdot with dump for that test
*/
@OptIn(SymbolInternals::class)
abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
abstract class AbstractKtDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
companion object {
const val DUMP_CFG_DIRECTIVE = "DUMP_CFG"
@@ -118,7 +118,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<KtDiagnostic> =
collectDebugInfoDiagnostics(firFile, testFile.diagnosedRangesToDiagnosticNames)
testFile.getActualText(
diagnostics.getValue(firFile) + debugInfoDiagnostics,
@@ -135,8 +135,8 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
protected fun collectDebugInfoDiagnostics(
firFile: FirFile,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>
): List<FirDiagnostic> {
val result = mutableListOf<FirDiagnostic>()
): List<KtDiagnostic> {
val result = mutableListOf<KtDiagnostic>()
object : FirDefaultVisitorVoid() {
@@ -167,7 +167,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
fun createExpressionTypeDiagnosticIfExpected(
element: FirExpression,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>
): FirDiagnosticWithParameters1<String>? =
): KtDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.EXPRESSION_TYPE.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
element.typeRef.renderAsString((element as? FirExpressionWithSmartcast)?.originalType)
}
@@ -184,7 +184,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
element: FirElement,
reference: FirNamedReference,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>
): FirDiagnosticWithParameters1<String>? =
): KtDiagnosticWithParameters1<String>? =
DebugInfoDiagnosticFactory1.CALL.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
val resolvedSymbol = (reference as? FirResolvedNamedReference)?.resolvedSymbol
@@ -196,7 +196,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
element: FirElement,
diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>>,
argument: () -> String,
): FirDiagnosticWithParameters1<String>? {
): KtDiagnosticWithParameters1<String>? {
val sourceElement = element.source ?: return null
val sourceKind = sourceElement.kind
if (sourceKind !in allowedKindsForDebugInfo) {
@@ -212,18 +212,18 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
val argumentText = argument()
return when (sourceElement) {
is KtPsiSourceElement -> FirPsiDiagnosticWithParameters1(
is KtPsiSourceElement -> KtPsiDiagnosticWithParameters1(
sourceElement,
argumentText,
severity,
FirDiagnosticFactory1(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class),
KtDiagnosticFactory1(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class),
SourceElementPositioningStrategy.DEFAULT
)
is KtLightSourceElement -> FirLightDiagnosticWithParameters1(
is KtLightSourceElement -> KtLightDiagnosticWithParameters1(
sourceElement,
argumentText,
severity,
FirDiagnosticFactory1(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class),
KtDiagnosticFactory1(name, severity, SourceElementPositioningStrategy.DEFAULT, PsiElement::class),
SourceElementPositioningStrategy.DEFAULT
)
}
@@ -263,9 +263,9 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
}
protected fun collectDiagnostics(firFiles: List<FirFile>): Map<FirFile, List<FirDiagnostic>> {
protected fun collectDiagnostics(firFiles: List<FirFile>): Map<FirFile, List<KtDiagnostic>> {
val collectors = mutableMapOf<FirSession, AbstractDiagnosticCollector>()
val result = mutableMapOf<FirFile, List<FirDiagnostic>>()
val result = mutableMapOf<FirFile, List<KtDiagnostic>>()
for (firFile in firFiles) {
val session = firFile.moduleData.session
val collector = collectors.computeIfAbsent(session) { createCollector(session) }
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.createAllCompilerResolvePro
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
abstract class AbstractFirOldFrontendDiagnosticsTest : AbstractFirDiagnosticsTest() {
abstract class AbstractFirOldFrontendDiagnosticsTest : AbstractKtDiagnosticsTest() {
override fun createTestFileFromPath(filePath: String): File {
val newPath = if (File(filePath).readText().contains("// FIR_IDENTICAL")) filePath else filePath.replace(".kt", ".fir.kt")
return File(newPath).also {