FIR: Decouple AbstractDiagnosticCollectorComponent and AbstractDiagnosticCollector
This commit is contained in:
+4
-2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporterFactory
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
@@ -19,7 +20,7 @@ class FirCheckersResolveProcessor(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||
val diagnosticCollector = FirDiagnosticsCollector.create(session, scopeSession)
|
||||
val diagnosticCollector: AbstractDiagnosticCollector = FirDiagnosticsCollector.create(session, scopeSession)
|
||||
|
||||
override val transformer: FirTransformer<Nothing?> = FirCheckersRunnerTransformer(diagnosticCollector)
|
||||
}
|
||||
@@ -30,7 +31,8 @@ class FirCheckersRunnerTransformer(private val diagnosticCollector: AbstractDiag
|
||||
}
|
||||
|
||||
override fun transformFile(file: FirFile, data: Nothing?): FirDeclaration {
|
||||
diagnosticCollector.collectDiagnostics(file)
|
||||
val reporter = DiagnosticReporterFactory.createReporter()
|
||||
diagnosticCollector.collectDiagnostics(file, reporter)
|
||||
return file
|
||||
}
|
||||
}
|
||||
+5
-34
@@ -19,33 +19,15 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
abstract class AbstractDiagnosticCollector(
|
||||
override val session: FirSession,
|
||||
override val scopeSession: ScopeSession = ScopeSession(),
|
||||
protected val createComponents: (DiagnosticReporter) -> List<AbstractDiagnosticCollectorComponent>,
|
||||
) : SessionHolder {
|
||||
fun collectDiagnostics(firDeclaration: FirDeclaration): List<FirDiagnostic<*>> {
|
||||
if (!componentsInitialized) {
|
||||
throw IllegalStateException("Components are not initialized")
|
||||
}
|
||||
initializeCollector()
|
||||
fun collectDiagnostics(firDeclaration: FirDeclaration, reporter: DiagnosticReporter) {
|
||||
val components = createComponents(reporter)
|
||||
val visitor = createVisitor(components)
|
||||
firDeclaration.accept(visitor, null)
|
||||
return getCollectedDiagnostics()
|
||||
}
|
||||
|
||||
protected abstract fun initializeCollector()
|
||||
protected abstract fun getCollectedDiagnostics(): List<FirDiagnostic<*>>
|
||||
abstract val reporter: DiagnosticReporter
|
||||
|
||||
protected val components: MutableList<AbstractDiagnosticCollectorComponent> = mutableListOf()
|
||||
private var componentsInitialized = false
|
||||
|
||||
protected abstract val visitor: CheckerRunningDiagnosticCollectorVisitor
|
||||
|
||||
fun initializeComponents(vararg components: AbstractDiagnosticCollectorComponent) {
|
||||
if (componentsInitialized) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
this.components += components
|
||||
componentsInitialized = true
|
||||
}
|
||||
|
||||
protected abstract fun createVisitor(components: List<AbstractDiagnosticCollectorComponent>): CheckerRunningDiagnosticCollectorVisitor
|
||||
|
||||
companion object {
|
||||
const val SUPPRESS_ALL_INFOS = "infos"
|
||||
@@ -66,14 +48,3 @@ abstract class AbstractDiagnosticCollector(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun AbstractDiagnosticCollector.registerAllComponents() {
|
||||
initializeComponents(
|
||||
DeclarationCheckersDiagnosticComponent(this),
|
||||
ExpressionCheckersDiagnosticComponent(this),
|
||||
TypeCheckersDiagnosticComponent(this),
|
||||
ErrorNodeDiagnosticCollectorComponent(this),
|
||||
ControlFlowAnalysisDiagnosticComponent(this),
|
||||
)
|
||||
}
|
||||
|
||||
+12
-4
@@ -6,12 +6,20 @@
|
||||
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 {
|
||||
fun create(session: FirSession, scopeSession: ScopeSession): SimpleDiagnosticsCollector {
|
||||
val collector = SimpleDiagnosticsCollector(session, scopeSession)
|
||||
collector.registerAllComponents()
|
||||
return collector
|
||||
fun create(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
): SimpleDiagnosticsCollector {
|
||||
return SimpleDiagnosticsCollector(session, scopeSession) { reporter ->
|
||||
DiagnosticComponentsFactory.createAllDiagnosticComponents(session, reporter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-26
@@ -7,42 +7,29 @@ package org.jetbrains.kotlin.fir.analysis.collectors
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.PersistentCheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.BaseDiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.DiagnosticReporterWithSuppress
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.SimpleDiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.SessionHolder
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve
|
||||
|
||||
class SimpleDiagnosticsCollector(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
private val disableSuppress: Boolean = false
|
||||
) : AbstractDiagnosticCollector(session, scopeSession) {
|
||||
override val visitor: CheckerRunningDiagnosticCollectorVisitor = CheckerRunningDiagnosticCollectorVisitor(
|
||||
PersistentCheckerContext(
|
||||
this,
|
||||
ReturnTypeCalculatorForFullBodyResolve()
|
||||
),
|
||||
components
|
||||
)
|
||||
override var reporter = createDiagnosticReporter()
|
||||
private set
|
||||
|
||||
private fun createDiagnosticReporter(): BaseDiagnosticReporter {
|
||||
return if (disableSuppress) {
|
||||
SimpleDiagnosticReporter()
|
||||
} else {
|
||||
DiagnosticReporterWithSuppress()
|
||||
}
|
||||
}
|
||||
|
||||
override fun initializeCollector() {
|
||||
reporter = createDiagnosticReporter()
|
||||
}
|
||||
|
||||
override fun getCollectedDiagnostics(): List<FirDiagnostic<*>> {
|
||||
return reporter.diagnostics
|
||||
createComponents: (DiagnosticReporter) -> List<AbstractDiagnosticCollectorComponent>,
|
||||
) : AbstractDiagnosticCollector(session, scopeSession, createComponents) {
|
||||
override fun createVisitor(components: List<AbstractDiagnosticCollectorComponent>): CheckerRunningDiagnosticCollectorVisitor {
|
||||
return CheckerRunningDiagnosticCollectorVisitor(
|
||||
PersistentCheckerContext(
|
||||
this,
|
||||
ReturnTypeCalculatorForFullBodyResolve()
|
||||
),
|
||||
components
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -12,11 +12,9 @@ import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
abstract class AbstractDiagnosticCollectorComponent(private val collector: AbstractDiagnosticCollector) : FirVisitor<Unit, CheckerContext>() {
|
||||
protected val session: FirSession = collector.session
|
||||
|
||||
abstract class AbstractDiagnosticCollectorComponent(
|
||||
protected val session: FirSession,
|
||||
protected val reporter: DiagnosticReporter,
|
||||
) : FirVisitor<Unit, CheckerContext>() {
|
||||
override fun visitElement(element: FirElement, data: CheckerContext) {}
|
||||
|
||||
protected val reporter: DiagnosticReporter
|
||||
get() = collector.reporter
|
||||
}
|
||||
|
||||
+6
-3
@@ -5,19 +5,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirControlFlowAnalyzer
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
||||
|
||||
class ControlFlowAnalysisDiagnosticComponent(
|
||||
collector: AbstractDiagnosticCollector,
|
||||
declarationCheckers: DeclarationCheckers = collector.session.checkersComponent.declarationCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
session: FirSession,
|
||||
reporter: DiagnosticReporter,
|
||||
declarationCheckers: DeclarationCheckers = session.checkersComponent.declarationCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(session, reporter) {
|
||||
private val controlFlowAnalyzer = FirControlFlowAnalyzer(session, declarationCheckers)
|
||||
|
||||
// ------------------------------- Class initializer -------------------------------
|
||||
|
||||
+5
-3
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
|
||||
@@ -16,9 +17,10 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
|
||||
@OptIn(CheckersComponentInternal::class)
|
||||
class DeclarationCheckersDiagnosticComponent(
|
||||
collector: AbstractDiagnosticCollector,
|
||||
private val checkers: DeclarationCheckers = collector.session.checkersComponent.declarationCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
session: FirSession,
|
||||
reporter: DiagnosticReporter,
|
||||
private val checkers: DeclarationCheckers = session.checkersComponent.declarationCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(session, reporter) {
|
||||
|
||||
override fun visitFile(file: FirFile, data: CheckerContext) {
|
||||
checkers.allFileCheckers.check(file, data, reporter)
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
|
||||
object DiagnosticComponentsFactory {
|
||||
fun createAllDiagnosticComponents(session: FirSession, reporter: DiagnosticReporter): List<AbstractDiagnosticCollectorComponent> {
|
||||
return listOf(
|
||||
DeclarationCheckersDiagnosticComponent(session, reporter),
|
||||
ExpressionCheckersDiagnosticComponent(session, reporter),
|
||||
TypeCheckersDiagnosticComponent(session, reporter),
|
||||
ErrorNodeDiagnosticCollectorComponent(session, reporter),
|
||||
ControlFlowAnalysisDiagnosticComponent(session, reporter),
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
+5
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
@@ -23,7 +24,10 @@ import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
|
||||
class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
class ErrorNodeDiagnosticCollectorComponent(
|
||||
session: FirSession,
|
||||
reporter: DiagnosticReporter,
|
||||
) : AbstractDiagnosticCollectorComponent(session, reporter) {
|
||||
override fun visitErrorLoop(errorLoop: FirErrorLoop, data: CheckerContext) {
|
||||
val source = errorLoop.source ?: return
|
||||
reportFirDiagnostic(errorLoop.diagnostic, source, reporter, data)
|
||||
|
||||
+5
-3
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
|
||||
@@ -17,9 +18,10 @@ import org.jetbrains.kotlin.fir.expressions.*
|
||||
|
||||
@OptIn(CheckersComponentInternal::class)
|
||||
class ExpressionCheckersDiagnosticComponent(
|
||||
collector: AbstractDiagnosticCollector,
|
||||
private val checkers: ExpressionCheckers = collector.session.checkersComponent.expressionCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
session: FirSession,
|
||||
reporter: DiagnosticReporter,
|
||||
private val checkers: ExpressionCheckers = session.checkersComponent.expressionCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(session, reporter) {
|
||||
|
||||
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: CheckerContext) {
|
||||
checkers.allAnonymousFunctionAsExpressionCheckers.check(anonymousFunction, data, reporter)
|
||||
|
||||
+5
-3
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.collectors.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponentInternal
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirTypeChecker
|
||||
@@ -16,9 +17,10 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
|
||||
@OptIn(CheckersComponentInternal::class)
|
||||
class TypeCheckersDiagnosticComponent(
|
||||
collector: AbstractDiagnosticCollector,
|
||||
private val checkers: TypeCheckers = collector.session.checkersComponent.typeCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(collector) {
|
||||
session: FirSession,
|
||||
reporter: DiagnosticReporter,
|
||||
private val checkers: TypeCheckers = session.checkersComponent.typeCheckers,
|
||||
) : AbstractDiagnosticCollectorComponent(session, reporter) {
|
||||
|
||||
override fun visitDynamicTypeRef(dynamicTypeRef: FirDynamicTypeRef, data: CheckerContext) {
|
||||
checkers.allTypeRefCheckers.check(dynamicTypeRef, data, reporter)
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.fir.analysis.diagnostics.impl.BaseDiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.DiagnosticReporterWithSuppress
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.SimpleDiagnosticReporter
|
||||
|
||||
object DiagnosticReporterFactory {
|
||||
fun createReporter(disableSuppress: Boolean = false): BaseDiagnosticReporter {
|
||||
return if (disableSuppress) {
|
||||
SimpleDiagnosticReporter()
|
||||
} else {
|
||||
DiagnosticReporterWithSuppress()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||
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.backend.Fir2IrConverter
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
||||
@@ -78,7 +79,9 @@ class FirAnalyzerFacade(
|
||||
val collector = FirDiagnosticsCollector.create(session, scopeSession)
|
||||
collectedDiagnostics = buildMap {
|
||||
for (file in firFiles!!) {
|
||||
put(file, collector.collectDiagnostics(file))
|
||||
val reporter = DiagnosticReporterFactory.createReporter()
|
||||
collector.collectDiagnostics(file, reporter)
|
||||
put(file, reporter.diagnostics)
|
||||
}
|
||||
}
|
||||
return collectedDiagnostics!!
|
||||
|
||||
@@ -268,7 +268,9 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
|
||||
for (firFile in firFiles) {
|
||||
val session = firFile.declarationSiteSession
|
||||
val collector = collectors.computeIfAbsent(session) { createCollector(session) }
|
||||
result[firFile] = collector.collectDiagnostics(firFile).toList()
|
||||
val reporter = DiagnosticReporterFactory.createReporter()
|
||||
collector.collectDiagnostics(firFile, reporter)
|
||||
result[firFile] = reporter.diagnostics
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
+36
-86
@@ -5,122 +5,72 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.components.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.checkers.*
|
||||
|
||||
internal abstract class AbstractFirIdeDiagnosticsCollector(
|
||||
session: FirSession,
|
||||
useExtendedCheckers: Boolean,
|
||||
) : AbstractDiagnosticCollector(
|
||||
session
|
||||
) {
|
||||
init {
|
||||
val declarationCheckers = CheckersFactory.createDeclarationCheckers(useExtendedCheckers)
|
||||
val expressionCheckers = CheckersFactory.createExpressionCheckers(useExtendedCheckers)
|
||||
val typeCheckers = CheckersFactory.createTypeCheckers(useExtendedCheckers)
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
initializeComponents(
|
||||
DeclarationCheckersDiagnosticComponent(this, declarationCheckers),
|
||||
ExpressionCheckersDiagnosticComponent(this, expressionCheckers),
|
||||
TypeCheckersDiagnosticComponent(this, typeCheckers),
|
||||
ErrorNodeDiagnosticCollectorComponent(this),
|
||||
ControlFlowAnalysisDiagnosticComponent(this, declarationCheckers),
|
||||
)
|
||||
session,
|
||||
createComponents = { reporter ->
|
||||
CheckersFactory.createComponents(session, reporter, useExtendedCheckers)
|
||||
}
|
||||
|
||||
protected abstract fun onDiagnostic(diagnostic: FirPsiDiagnostic<*>)
|
||||
)
|
||||
|
||||
|
||||
private inner class Reporter : DiagnosticReporter() {
|
||||
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
|
||||
if (diagnostic == null) return
|
||||
if (context.isDiagnosticSuppressed(diagnostic)) return
|
||||
private object CheckersFactory {
|
||||
fun createComponents(
|
||||
session: FirSession,
|
||||
reporter: DiagnosticReporter,
|
||||
useExtendedCheckers: Boolean
|
||||
): List<AbstractDiagnosticCollectorComponent> {
|
||||
val declarationCheckers = createDeclarationCheckers(useExtendedCheckers)
|
||||
val expressionCheckers = createExpressionCheckers(useExtendedCheckers)
|
||||
val typeCheckers = createTypeCheckers(useExtendedCheckers)
|
||||
|
||||
val psiDiagnostic = when (diagnostic) {
|
||||
is FirPsiDiagnostic<*> -> diagnostic
|
||||
is FirLightDiagnostic -> diagnostic.toPsiDiagnostic()
|
||||
else -> error("Unknown diagnostic type ${diagnostic::class.simpleName}")
|
||||
}
|
||||
|
||||
onDiagnostic(psiDiagnostic)
|
||||
return if (useExtendedCheckers) {
|
||||
listOf(
|
||||
DeclarationCheckersDiagnosticComponent(session, reporter, declarationCheckers),
|
||||
ExpressionCheckersDiagnosticComponent(session, reporter, expressionCheckers),
|
||||
TypeCheckersDiagnosticComponent(session, reporter, typeCheckers),
|
||||
ControlFlowAnalysisDiagnosticComponent(session, reporter, declarationCheckers),
|
||||
)
|
||||
} else {
|
||||
listOf(
|
||||
DeclarationCheckersDiagnosticComponent(session, reporter, declarationCheckers),
|
||||
ExpressionCheckersDiagnosticComponent(session, reporter, expressionCheckers),
|
||||
TypeCheckersDiagnosticComponent(session, reporter, typeCheckers),
|
||||
ErrorNodeDiagnosticCollectorComponent(session, reporter),
|
||||
ControlFlowAnalysisDiagnosticComponent(session, reporter, declarationCheckers),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override var reporter: DiagnosticReporter = Reporter()
|
||||
|
||||
override fun initializeCollector() {
|
||||
reporter = Reporter()
|
||||
}
|
||||
|
||||
|
||||
override fun getCollectedDiagnostics(): List<FirDiagnostic<*>> {
|
||||
// Not necessary in IDE
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
|
||||
val psiSourceElement = element.unwrapToFirPsiSourceElement()
|
||||
?: error("Diagnostic should be created from PSI in IDE")
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return when (this) {
|
||||
is FirLightSimpleDiagnostic -> FirPsiSimpleDiagnostic(
|
||||
psiSourceElement,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory0<PsiElement>
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters1<*> -> FirPsiDiagnosticWithParameters1(
|
||||
psiSourceElement,
|
||||
a,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory1<PsiElement, Any>
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters2<*, *> -> FirPsiDiagnosticWithParameters2(
|
||||
psiSourceElement,
|
||||
a, b,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory2<PsiElement, Any, Any>
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters3<*, *, *> -> FirPsiDiagnosticWithParameters3(
|
||||
psiSourceElement,
|
||||
a, b, c,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory3<PsiElement, Any, Any, Any>
|
||||
)
|
||||
else -> error("Unknown diagnostic type ${this::class.simpleName}")
|
||||
}
|
||||
}
|
||||
|
||||
private object CheckersFactory {
|
||||
private val extendedDeclarationCheckers = createDeclarationCheckers(ExtendedDeclarationCheckers)
|
||||
private val commonDeclarationCheckers = createDeclarationCheckers(CommonDeclarationCheckers)
|
||||
|
||||
fun createDeclarationCheckers(useExtendedCheckers: Boolean): DeclarationCheckers =
|
||||
private val commonDeclarationCheckers = createDeclarationCheckers(CommonDeclarationCheckers,)
|
||||
|
||||
private fun createDeclarationCheckers(useExtendedCheckers: Boolean): DeclarationCheckers =
|
||||
if (useExtendedCheckers) extendedDeclarationCheckers else commonDeclarationCheckers
|
||||
|
||||
fun createExpressionCheckers(useExtendedCheckers: Boolean): ExpressionCheckers =
|
||||
private fun createExpressionCheckers(useExtendedCheckers: Boolean): ExpressionCheckers =
|
||||
if (useExtendedCheckers) ExtendedExpressionCheckers else CommonExpressionCheckers
|
||||
|
||||
fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers = CommonTypeCheckers
|
||||
private fun createTypeCheckers(useExtendedCheckers: Boolean): TypeCheckers = CommonTypeCheckers
|
||||
|
||||
// TODO hack to have all checkers present in DeclarationCheckers.memberDeclarationCheckers and similar
|
||||
// If use ExtendedDeclarationCheckers directly when DeclarationCheckers.memberDeclarationCheckers will not contain basicDeclarationCheckers
|
||||
@OptIn(SessionConfiguration::class)
|
||||
private fun createDeclarationCheckers(declarationCheckers: DeclarationCheckers): DeclarationCheckers =
|
||||
CheckersComponent().apply { register(declarationCheckers) }.declarationCheckers
|
||||
private fun createDeclarationCheckers(vararg declarationCheckers: DeclarationCheckers): DeclarationCheckers =
|
||||
CheckersComponent().apply { declarationCheckers.forEach(::register) }.declarationCheckers
|
||||
|
||||
}
|
||||
|
||||
+7
-6
@@ -19,13 +19,14 @@ internal class FileStructureElementDiagnosticsCollector private constructor(priv
|
||||
fun collectForStructureElement(
|
||||
firDeclaration: FirDeclaration,
|
||||
createVisitor: (components: List<AbstractDiagnosticCollectorComponent>) -> CheckerRunningDiagnosticCollectorVisitor,
|
||||
): FileStructureElementDiagnosticList =
|
||||
FirIdeStructureElementDiagnosticsCollector(
|
||||
): FileStructureElementDiagnosticList {
|
||||
val reporter = FirIdeDiagnosticReporter()
|
||||
val collector = FirIdeStructureElementDiagnosticsCollector(
|
||||
firDeclaration.declarationSiteSession,
|
||||
createVisitor,
|
||||
useExtendedCheckers,
|
||||
).let { collector ->
|
||||
collector.collectDiagnostics(firDeclaration)
|
||||
FileStructureElementDiagnosticList(collector.result)
|
||||
}
|
||||
)
|
||||
collector.collectDiagnostics(firDeclaration, reporter)
|
||||
return FileStructureElementDiagnosticList(reporter.diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.idea.fir.low.level.api.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.idea.fir.low.level.api.util.addValueFor
|
||||
|
||||
internal class FirIdeDiagnosticReporter : DiagnosticReporter() {
|
||||
val diagnostics = mutableMapOf<PsiElement, MutableList<FirPsiDiagnostic<*>>>()
|
||||
|
||||
override fun report(diagnostic: FirDiagnostic<*>?, context: CheckerContext) {
|
||||
if (diagnostic == null) return
|
||||
if (context.isDiagnosticSuppressed(diagnostic)) return
|
||||
|
||||
val psiDiagnostic = when (diagnostic) {
|
||||
is FirPsiDiagnostic<*> -> diagnostic
|
||||
is FirLightDiagnostic -> diagnostic.toPsiDiagnostic()
|
||||
else -> error("Unknown diagnostic type ${diagnostic::class.simpleName}")
|
||||
}
|
||||
diagnostics.addValueFor(psiDiagnostic.psiElement, psiDiagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirLightDiagnostic.toPsiDiagnostic(): FirPsiDiagnostic<*> {
|
||||
val psiSourceElement = element.unwrapToFirPsiSourceElement()
|
||||
?: error("Diagnostic should be created from PSI in IDE")
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return when (this) {
|
||||
is FirLightSimpleDiagnostic -> FirPsiSimpleDiagnostic(
|
||||
psiSourceElement,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory0<PsiElement>
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters1<*> -> FirPsiDiagnosticWithParameters1(
|
||||
psiSourceElement,
|
||||
a,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory1<PsiElement, Any>
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters2<*, *> -> FirPsiDiagnosticWithParameters2(
|
||||
psiSourceElement,
|
||||
a, b,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory2<PsiElement, Any, Any>
|
||||
)
|
||||
|
||||
is FirLightDiagnosticWithParameters3<*, *, *> -> FirPsiDiagnosticWithParameters3(
|
||||
psiSourceElement,
|
||||
a, b, c,
|
||||
severity,
|
||||
factory as FirDiagnosticFactory3<PsiElement, Any, Any, Any>
|
||||
)
|
||||
else -> error("Unknown diagnostic type ${this::class.simpleName}")
|
||||
}
|
||||
}
|
||||
+3
-10
@@ -5,27 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.fir
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.CheckerRunningDiagnosticCollectorVisitor
|
||||
import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.AbstractFirIdeDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.addValueFor
|
||||
|
||||
internal class FirIdeStructureElementDiagnosticsCollector(
|
||||
session: FirSession,
|
||||
createVisitor: (components: List<AbstractDiagnosticCollectorComponent>) -> CheckerRunningDiagnosticCollectorVisitor,
|
||||
private val doCreateVisitor: (components: List<AbstractDiagnosticCollectorComponent>) -> CheckerRunningDiagnosticCollectorVisitor,
|
||||
useExtendedCheckers: Boolean,
|
||||
) : AbstractFirIdeDiagnosticsCollector(
|
||||
session,
|
||||
useExtendedCheckers,
|
||||
) {
|
||||
override val visitor: CheckerRunningDiagnosticCollectorVisitor = createVisitor(components)
|
||||
|
||||
val result = mutableMapOf<PsiElement, MutableList<FirPsiDiagnostic<*>>>()
|
||||
|
||||
override fun onDiagnostic(diagnostic: FirPsiDiagnostic<*>) {
|
||||
result.addValueFor(diagnostic.psiElement, diagnostic)
|
||||
override fun createVisitor(components: List<AbstractDiagnosticCollectorComponent>): CheckerRunningDiagnosticCollectorVisitor {
|
||||
return doCreateVisitor(components)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user