[FIR] Speed up CFA-checkers
This commit is contained in:
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.analysis
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirCfaPropertyAssignmentChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
||||
@@ -71,7 +71,7 @@ private class ComposedDeclarationCheckers : DeclarationCheckers() {
|
||||
get() = _constructorCheckers
|
||||
override val controlFlowAnalyserCheckers: List<FirControlFlowChecker>
|
||||
get() = _controlFlowAnalyserCheckers
|
||||
override val variableAssignmentCfaBasedCheckers: List<AbstractFirCfaPropertyAssignmentChecker>
|
||||
override val variableAssignmentCfaBasedCheckers: List<AbstractFirPropertyInitializationChecker>
|
||||
get() = _variableAssignmentCfaBasedCheckers
|
||||
|
||||
private val _fileCheckers: MutableList<FirFileChecker> = mutableListOf()
|
||||
@@ -80,7 +80,7 @@ private class ComposedDeclarationCheckers : DeclarationCheckers() {
|
||||
private val _regularClassCheckers: MutableList<FirRegularClassChecker> = mutableListOf()
|
||||
private val _constructorCheckers: MutableList<FirConstructorChecker> = mutableListOf()
|
||||
private val _controlFlowAnalyserCheckers: MutableList<FirControlFlowChecker> = mutableListOf()
|
||||
private val _variableAssignmentCfaBasedCheckers: MutableList<AbstractFirCfaPropertyAssignmentChecker> = mutableListOf()
|
||||
private val _variableAssignmentCfaBasedCheckers: MutableList<AbstractFirPropertyInitializationChecker> = mutableListOf()
|
||||
|
||||
fun register(checkers: DeclarationCheckers) {
|
||||
_fileCheckers += checkers.allFileCheckers
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
|
||||
abstract class AbstractFirCfaPropertyAssignmentChecker {
|
||||
abstract class AbstractFirPropertyInitializationChecker {
|
||||
abstract fun analyze(
|
||||
graph: ControlFlowGraph,
|
||||
reporter: DiagnosticReporter,
|
||||
|
||||
+21
-8
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.ControlFlowGraph
|
||||
|
||||
class FirControlFlowAnalyzer(session: FirSession) {
|
||||
@@ -20,23 +21,35 @@ class FirControlFlowAnalyzer(session: FirSession) {
|
||||
|
||||
fun analyzeClassInitializer(klass: FirClass<*>, graph: ControlFlowGraph, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (graph.owner != null) return
|
||||
checkers.forEach { it.analyze(graph, reporter) }
|
||||
cfaCheckers.forEach { it.analyze(graph, reporter) }
|
||||
}
|
||||
|
||||
fun analyzeFunction(function: FirFunction<*>, graph: ControlFlowGraph, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (graph.owner != null) return
|
||||
|
||||
cfaCheckers.forEach { it.analyze(graph, reporter) }
|
||||
|
||||
val properties = AbstractFirCfaPropertyAssignmentChecker.LocalPropertyCollector.collect(graph)
|
||||
if (properties.isEmpty()) return
|
||||
val data = AbstractFirCfaPropertyAssignmentChecker.DataCollector(properties).getData(graph)
|
||||
|
||||
variableAssignmentCheckers.forEach { it.analyze(graph, reporter, data, properties) }
|
||||
if (context.containingDeclarations.any { it is FirProperty || it is FirFunction<*> }) return
|
||||
runAssignmentCfaCheckers(graph, reporter)
|
||||
}
|
||||
|
||||
fun analyzePropertyInitializer(property: FirProperty, graph: ControlFlowGraph, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (graph.owner != null) return
|
||||
checkers.forEach { it.analyze(graph, reporter) }
|
||||
|
||||
cfaCheckers.forEach { it.analyze(graph, reporter) }
|
||||
runAssignmentCfaCheckers(graph, reporter)
|
||||
}
|
||||
|
||||
fun analyzePropertyAccessor(accessor: FirPropertyAccessor, graph: ControlFlowGraph, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (graph.owner != null) return
|
||||
|
||||
cfaCheckers.forEach { it.analyze(graph, reporter) }
|
||||
runAssignmentCfaCheckers(graph, reporter)
|
||||
}
|
||||
|
||||
private fun runAssignmentCfaCheckers(graph: ControlFlowGraph, reporter: DiagnosticReporter) {
|
||||
val properties = AbstractFirPropertyInitializationChecker.LocalPropertyCollector.collect(graph)
|
||||
if (properties.isEmpty()) return
|
||||
val data = AbstractFirPropertyInitializationChecker.DataCollector(properties).getData(graph)
|
||||
variableAssignmentCheckers.forEach { it.analyze(graph, reporter, data, properties) }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -18,14 +18,13 @@ import org.jetbrains.kotlin.fir.resolve.dfa.cfg.QualifiedAccessNode
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
|
||||
object FirPropertyInitializationAnalyzer : AbstractFirCfaPropertyAssignmentChecker() {
|
||||
object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChecker() {
|
||||
override fun analyze(
|
||||
graph: ControlFlowGraph,
|
||||
reporter: DiagnosticReporter,
|
||||
data: Map<CFGNode<*>, PropertyInitializationInfo>,
|
||||
properties: Set<FirPropertySymbol>
|
||||
) {
|
||||
// getting symbols of properties without initializers and non-variable symbols
|
||||
val localData = data.filter {
|
||||
val symbolFir = (it.key.fir as? FirVariableSymbol<*>)?.fir
|
||||
symbolFir == null || symbolFir.initializer == null && symbolFir.delegate == null
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirCfaPropertyAssignmentChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
|
||||
|
||||
abstract class DeclarationCheckers {
|
||||
@@ -19,7 +19,7 @@ abstract class DeclarationCheckers {
|
||||
open val regularClassCheckers: List<FirRegularClassChecker> = emptyList()
|
||||
open val constructorCheckers: List<FirConstructorChecker> = emptyList()
|
||||
open val controlFlowAnalyserCheckers: List<FirControlFlowChecker> = emptyList()
|
||||
open val variableAssignmentCfaBasedCheckers: List<AbstractFirCfaPropertyAssignmentChecker> = emptyList()
|
||||
open val variableAssignmentCfaBasedCheckers: List<AbstractFirPropertyInitializationChecker> = emptyList()
|
||||
|
||||
internal val allFileCheckers: List<FirFileChecker> get() = fileCheckers + declarationCheckers
|
||||
internal val allMemberDeclarationCheckers: List<FirMemberDeclarationChecker> get() = memberDeclarationCheckers + declarationCheckers
|
||||
|
||||
+5
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirCallsEffectAnalyzer
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirPropertyInitializationAnalyzer
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer
|
||||
@@ -49,8 +50,11 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
)
|
||||
|
||||
override val controlFlowAnalyserCheckers: List<FirControlFlowChecker> = listOf(
|
||||
FirPropertyInitializationAnalyzer,
|
||||
FirCallsEffectAnalyzer,
|
||||
FirReturnsImpliesAnalyzer
|
||||
)
|
||||
|
||||
override val variableAssignmentCfaBasedCheckers: List<AbstractFirPropertyInitializationChecker> = listOf(
|
||||
FirPropertyInitializationAnalyzer
|
||||
)
|
||||
}
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirCfaPropertyAssignmentChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.extended.*
|
||||
|
||||
object ExtendedDeclarationCheckers : DeclarationCheckers() {
|
||||
@@ -20,7 +20,7 @@ object ExtendedDeclarationCheckers : DeclarationCheckers() {
|
||||
RedundantSetterParameterTypeChecker
|
||||
)
|
||||
|
||||
override val variableAssignmentCfaBasedCheckers: List<AbstractFirCfaPropertyAssignmentChecker> = listOf(
|
||||
override val variableAssignmentCfaBasedCheckers: List<AbstractFirPropertyInitializationChecker> = listOf(
|
||||
VariableAssignmentChecker
|
||||
)
|
||||
}
|
||||
+3
-3
@@ -9,7 +9,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirCfaPropertyAssignmentChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.TraverseDirection
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.traverse
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.fir.toFirPsiSourceElement
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
|
||||
|
||||
object VariableAssignmentChecker : AbstractFirCfaPropertyAssignmentChecker() {
|
||||
object VariableAssignmentChecker : AbstractFirPropertyInitializationChecker() {
|
||||
override fun analyze(
|
||||
graph: ControlFlowGraph,
|
||||
reporter: DiagnosticReporter,
|
||||
@@ -64,7 +64,7 @@ object VariableAssignmentChecker : AbstractFirCfaPropertyAssignmentChecker() {
|
||||
destructuringCanBeVal = false
|
||||
}
|
||||
lastDestructuredVariables--
|
||||
} else if (canBeVal(symbol, value) && symbol.fir.delegate == null) {
|
||||
} else if (canBeVal(symbol, value) && symbol.fir.delegate == null ) {
|
||||
reporter.report(source, FirErrors.CAN_BE_VAL)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user