[FIR] Get rid of runCheck in checkers components

This commit is contained in:
Dmitriy Novozhilov
2020-09-04 11:59:16 +03:00
parent 71a855112e
commit a8a5ed3cd3
8 changed files with 62 additions and 76 deletions
@@ -44,7 +44,7 @@ abstract class AbstractDiagnosticCollector(
protected abstract fun initializeCollector() protected abstract fun initializeCollector()
protected abstract fun getCollectedDiagnostics(): Iterable<FirDiagnostic<*>> protected abstract fun getCollectedDiagnostics(): Iterable<FirDiagnostic<*>>
abstract fun runCheck(block: (DiagnosticReporter) -> Unit) abstract val reporter: DiagnosticReporter
private val components: MutableList<AbstractDiagnosticCollectorComponent> = mutableListOf() private val components: MutableList<AbstractDiagnosticCollectorComponent> = mutableListOf()
private var componentsInitialized = false private var componentsInitialized = false
@@ -6,12 +6,12 @@
package org.jetbrains.kotlin.fir.analysis.collectors package org.jetbrains.kotlin.fir.analysis.collectors
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.analysis.diagnostics.SimpleDiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.SimpleDiagnosticReporter
class SimpleDiagnosticsCollector(session: FirSession) : AbstractDiagnosticCollector(session) { class SimpleDiagnosticsCollector(session: FirSession) : AbstractDiagnosticCollector(session) {
private var reporter = SimpleDiagnosticReporter() override var reporter = SimpleDiagnosticReporter()
private set
override fun initializeCollector() { override fun initializeCollector() {
reporter = SimpleDiagnosticReporter() reporter = SimpleDiagnosticReporter()
@@ -20,9 +20,5 @@ class SimpleDiagnosticsCollector(session: FirSession) : AbstractDiagnosticCollec
override fun getCollectedDiagnostics(): Iterable<FirDiagnostic<*>> { override fun getCollectedDiagnostics(): Iterable<FirDiagnostic<*>> {
return reporter.diagnostics return reporter.diagnostics
} }
override fun runCheck(block: (DiagnosticReporter) -> Unit) {
block(reporter)
}
} }
@@ -17,7 +17,6 @@ abstract class AbstractDiagnosticCollectorComponent(private val collector: Abstr
override fun visitElement(element: FirElement, data: CheckerContext) {} override fun visitElement(element: FirElement, data: CheckerContext) {}
protected fun runCheck(block: (DiagnosticReporter) -> Unit) { protected val reporter: DiagnosticReporter
collector.runCheck(block) get() = collector.reporter
} }
}
@@ -31,26 +31,21 @@ class ControlFlowAnalysisDiagnosticComponent(collector: AbstractDiagnosticCollec
data: CheckerContext data: CheckerContext
) { ) {
val graph = controlFlowGraphReference?.controlFlowGraph ?: return val graph = controlFlowGraphReference?.controlFlowGraph ?: return
runCheck { controlFlowAnalyzer.analyzeClassInitializer(klass, graph, data, reporter)
controlFlowAnalyzer.analyzeClassInitializer(klass, graph, data, it)
}
} }
// ------------------------------- Property initializer ------------------------------- // ------------------------------- Property initializer -------------------------------
override fun visitProperty(property: FirProperty, data: CheckerContext) { override fun visitProperty(property: FirProperty, data: CheckerContext) {
val graph = property.controlFlowGraphReference?.controlFlowGraph ?: return val graph = property.controlFlowGraphReference?.controlFlowGraph ?: return
runCheck { controlFlowAnalyzer.analyzePropertyInitializer(property, graph, data, reporter)
controlFlowAnalyzer.analyzePropertyInitializer(property, graph, data, it)
}
} }
// ------------------------------- Function ------------------------------- // ------------------------------- Function -------------------------------
override fun <F : FirFunction<F>> visitFunction(function: FirFunction<F>, data: CheckerContext) { override fun <F : FirFunction<F>> visitFunction(function: FirFunction<F>, data: CheckerContext) {
val graph = function.controlFlowGraphReference?.controlFlowGraph ?: return val graph = function.controlFlowGraphReference?.controlFlowGraph ?: return
runCheck {
controlFlowAnalyzer.analyzeFunction(function, graph, data, it) controlFlowAnalyzer.analyzeFunction(function, graph, data, reporter)
}
} }
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: CheckerContext) { override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: CheckerContext) {
@@ -59,12 +54,11 @@ class ControlFlowAnalysisDiagnosticComponent(collector: AbstractDiagnosticCollec
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: CheckerContext) { override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: CheckerContext) {
val graph = propertyAccessor.controlFlowGraphReference?.controlFlowGraph ?: return val graph = propertyAccessor.controlFlowGraphReference?.controlFlowGraph ?: return
runCheck {
controlFlowAnalyzer.analyzePropertyAccessor(propertyAccessor, graph, data, it) controlFlowAnalyzer.analyzePropertyAccessor(propertyAccessor, graph, data, reporter)
}
} }
override fun visitConstructor(constructor: FirConstructor, data: CheckerContext) { override fun visitConstructor(constructor: FirConstructor, data: CheckerContext) {
visitFunction(constructor, data) visitFunction(constructor, data)
} }
} }
@@ -18,55 +18,55 @@ class DeclarationCheckersDiagnosticComponent(
private val checkers = session.checkersComponent.declarationCheckers private val checkers = session.checkersComponent.declarationCheckers
override fun visitFile(file: FirFile, data: CheckerContext) { override fun visitFile(file: FirFile, data: CheckerContext) {
runCheck { checkers.fileCheckers.check(file, data, it) } checkers.fileCheckers.check(file, data, reporter)
} }
override fun visitProperty(property: FirProperty, data: CheckerContext) { override fun visitProperty(property: FirProperty, data: CheckerContext) {
runCheck { checkers.memberDeclarationCheckers.check(property, data, it) } checkers.memberDeclarationCheckers.check(property, data, reporter)
} }
override fun visitRegularClass(regularClass: FirRegularClass, data: CheckerContext) { override fun visitRegularClass(regularClass: FirRegularClass, data: CheckerContext) {
runCheck { checkers.regularClassCheckers.check(regularClass, data, it) } checkers.regularClassCheckers.check(regularClass, data, reporter)
} }
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: CheckerContext) { override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: CheckerContext) {
runCheck { checkers.memberDeclarationCheckers.check(simpleFunction, data, it) } checkers.memberDeclarationCheckers.check(simpleFunction, data, reporter)
} }
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: CheckerContext) { override fun visitTypeAlias(typeAlias: FirTypeAlias, data: CheckerContext) {
runCheck { checkers.memberDeclarationCheckers.check(typeAlias, data, it) } checkers.memberDeclarationCheckers.check(typeAlias, data, reporter)
} }
override fun visitConstructor(constructor: FirConstructor, data: CheckerContext) { override fun visitConstructor(constructor: FirConstructor, data: CheckerContext) {
runCheck { checkers.constructorCheckers.check(constructor, data, it) } checkers.constructorCheckers.check(constructor, data, reporter)
} }
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: CheckerContext) { override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: CheckerContext) {
runCheck { checkers.declarationCheckers.check(anonymousFunction, data, it) } checkers.declarationCheckers.check(anonymousFunction, data, reporter)
} }
override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: CheckerContext) { override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: CheckerContext) {
runCheck { checkers.declarationCheckers.check(propertyAccessor, data, it) } checkers.declarationCheckers.check(propertyAccessor, data, reporter)
} }
override fun visitValueParameter(valueParameter: FirValueParameter, data: CheckerContext) { override fun visitValueParameter(valueParameter: FirValueParameter, data: CheckerContext) {
runCheck { checkers.declarationCheckers.check(valueParameter, data, it) } checkers.declarationCheckers.check(valueParameter, data, reporter)
} }
override fun visitTypeParameter(typeParameter: FirTypeParameter, data: CheckerContext) { override fun visitTypeParameter(typeParameter: FirTypeParameter, data: CheckerContext) {
runCheck { checkers.declarationCheckers.check(typeParameter, data, it) } checkers.declarationCheckers.check(typeParameter, data, reporter)
} }
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: CheckerContext) { override fun visitEnumEntry(enumEntry: FirEnumEntry, data: CheckerContext) {
runCheck { checkers.declarationCheckers.check(enumEntry, data, it) } checkers.declarationCheckers.check(enumEntry, data, reporter)
} }
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: CheckerContext) { override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: CheckerContext) {
runCheck { checkers.declarationCheckers.check(anonymousObject, data, it) } checkers.declarationCheckers.check(anonymousObject, data, reporter)
} }
override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: CheckerContext) { override fun visitAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: CheckerContext) {
runCheck { checkers.declarationCheckers.check(anonymousInitializer, data, it) } checkers.declarationCheckers.check(anonymousInitializer, data, reporter)
} }
private fun <D : FirDeclaration> List<FirDeclarationChecker<D>>.check( private fun <D : FirDeclaration> List<FirDeclarationChecker<D>>.check(
@@ -78,4 +78,4 @@ class DeclarationCheckersDiagnosticComponent(
checker.check(declaration, context, reporter) checker.check(declaration, context, reporter)
} }
} }
} }
@@ -29,34 +29,34 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) { class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) {
override fun visitErrorLoop(errorLoop: FirErrorLoop, data: CheckerContext) { override fun visitErrorLoop(errorLoop: FirErrorLoop, data: CheckerContext) {
val source = errorLoop.source ?: return val source = errorLoop.source ?: return
runCheck { reportFirDiagnostic(errorLoop.diagnostic, source, it) } reportFirDiagnostic(errorLoop.diagnostic, source, reporter)
} }
override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: CheckerContext) { override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: CheckerContext) {
val source = errorTypeRef.source ?: return val source = errorTypeRef.source ?: return
runCheck { reportFirDiagnostic(errorTypeRef.diagnostic, source, it) } reportFirDiagnostic(errorTypeRef.diagnostic, source, reporter)
} }
override fun visitErrorNamedReference(errorNamedReference: FirErrorNamedReference, data: CheckerContext) { override fun visitErrorNamedReference(errorNamedReference: FirErrorNamedReference, data: CheckerContext) {
val source = errorNamedReference.source ?: return val source = errorNamedReference.source ?: return
// Don't report duplicated unresolved reference on annotation entry (already reported on its type) // Don't report duplicated unresolved reference on annotation entry (already reported on its type)
if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && errorNamedReference.diagnostic is ConeUnresolvedNameError) return if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && errorNamedReference.diagnostic is ConeUnresolvedNameError) return
runCheck { reportFirDiagnostic(errorNamedReference.diagnostic, source, it) } reportFirDiagnostic(errorNamedReference.diagnostic, source, reporter)
} }
override fun visitErrorExpression(errorExpression: FirErrorExpression, data: CheckerContext) { override fun visitErrorExpression(errorExpression: FirErrorExpression, data: CheckerContext) {
val source = errorExpression.source ?: return val source = errorExpression.source ?: return
runCheck { reportFirDiagnostic(errorExpression.diagnostic, source, it) } reportFirDiagnostic(errorExpression.diagnostic, source, reporter)
} }
override fun visitErrorFunction(errorFunction: FirErrorFunction, data: CheckerContext) { override fun visitErrorFunction(errorFunction: FirErrorFunction, data: CheckerContext) {
val source = errorFunction.source ?: return val source = errorFunction.source ?: return
runCheck { reportFirDiagnostic(errorFunction.diagnostic, source, it) } reportFirDiagnostic(errorFunction.diagnostic, source, reporter)
} }
override fun visitErrorResolvedQualifier(errorResolvedQualifier: FirErrorResolvedQualifier, data: CheckerContext) { override fun visitErrorResolvedQualifier(errorResolvedQualifier: FirErrorResolvedQualifier, data: CheckerContext) {
val source = errorResolvedQualifier.source ?: return val source = errorResolvedQualifier.source ?: return
runCheck { reportFirDiagnostic(errorResolvedQualifier.diagnostic, source, it) } reportFirDiagnostic(errorResolvedQualifier.diagnostic, source, reporter)
} }
private fun reportFirDiagnostic(diagnostic: ConeDiagnostic, source: FirSourceElement, reporter: DiagnosticReporter) { private fun reportFirDiagnostic(diagnostic: ConeDiagnostic, source: FirSourceElement, reporter: DiagnosticReporter) {
@@ -16,75 +16,75 @@ class ExpressionCheckersDiagnosticComponent(collector: AbstractDiagnosticCollect
private val checkers = session.checkersComponent.expressionCheckers private val checkers = session.checkersComponent.expressionCheckers
override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: CheckerContext) { override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(typeOperatorCall, data, it) } checkers.expressionCheckers.check(typeOperatorCall, data, reporter)
} }
override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: CheckerContext) { override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(constExpression, data, it) } checkers.expressionCheckers.check(constExpression, data, reporter)
} }
override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: CheckerContext) { override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(annotationCall, data, it) } checkers.expressionCheckers.check(annotationCall, data, reporter)
} }
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: CheckerContext) { override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: CheckerContext) {
runCheck { checkers.qualifiedAccessCheckers.check(qualifiedAccessExpression, data, it) } checkers.qualifiedAccessCheckers.check(qualifiedAccessExpression, data, reporter)
} }
override fun visitFunctionCall(functionCall: FirFunctionCall, data: CheckerContext) { override fun visitFunctionCall(functionCall: FirFunctionCall, data: CheckerContext) {
runCheck { checkers.functionCallCheckers.check(functionCall, data, it) } checkers.functionCallCheckers.check(functionCall, data, reporter)
} }
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: CheckerContext) { override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: CheckerContext) {
runCheck { checkers.qualifiedAccessCheckers.check(callableReferenceAccess, data, it) } checkers.qualifiedAccessCheckers.check(callableReferenceAccess, data, reporter)
} }
override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: CheckerContext) { override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(thisReceiverExpression, data, it) } checkers.expressionCheckers.check(thisReceiverExpression, data, reporter)
} }
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: CheckerContext) { override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(resolvedQualifier, data, it) } checkers.expressionCheckers.check(resolvedQualifier, data, reporter)
} }
override fun visitWhenExpression(whenExpression: FirWhenExpression, data: CheckerContext) { override fun visitWhenExpression(whenExpression: FirWhenExpression, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(whenExpression, data, it) } checkers.expressionCheckers.check(whenExpression, data, reporter)
} }
override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: CheckerContext) { override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(binaryLogicExpression, data, it) } checkers.expressionCheckers.check(binaryLogicExpression, data, reporter)
} }
override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: CheckerContext) { override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(arrayOfCall, data, it) } checkers.expressionCheckers.check(arrayOfCall, data, reporter)
} }
override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: CheckerContext) { override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(stringConcatenationCall, data, it) } checkers.expressionCheckers.check(stringConcatenationCall, data, reporter)
} }
override fun visitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, data: CheckerContext) { override fun visitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(checkNotNullCall, data, it) } checkers.expressionCheckers.check(checkNotNullCall, data, reporter)
} }
override fun visitTryExpression(tryExpression: FirTryExpression, data: CheckerContext) { override fun visitTryExpression(tryExpression: FirTryExpression, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(tryExpression, data, it) } checkers.expressionCheckers.check(tryExpression, data, reporter)
} }
override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression, data: CheckerContext) { override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(classReferenceExpression, data, it) } checkers.expressionCheckers.check(classReferenceExpression, data, reporter)
} }
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: CheckerContext) { override fun visitGetClassCall(getClassCall: FirGetClassCall, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(getClassCall, data, it) } checkers.expressionCheckers.check(getClassCall, data, reporter)
} }
override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: CheckerContext) { override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: CheckerContext) {
runCheck { checkers.expressionCheckers.check(equalityOperatorCall, data, it) } checkers.expressionCheckers.check(equalityOperatorCall, data, reporter)
} }
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: CheckerContext) { override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: CheckerContext) {
runCheck { checkers.variableAssignmentCheckers.check(variableAssignment, data, it) } checkers.variableAssignmentCheckers.check(variableAssignment, data, reporter)
} }
private fun <E : FirStatement> List<FirExpressionChecker<E>>.check(expression: E, context: CheckerContext, reporter: DiagnosticReporter) { private fun <E : FirStatement> List<FirExpressionChecker<E>>.check(expression: E, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -92,4 +92,4 @@ class ExpressionCheckersDiagnosticComponent(collector: AbstractDiagnosticCollect
checker.check(expression, context, reporter) checker.check(expression, context, reporter)
} }
} }
} }
@@ -34,13 +34,19 @@ internal class FirIdeDiagnosticsCollector private constructor(
private inner class Reporter : DiagnosticReporter() { private inner class Reporter : DiagnosticReporter() {
override fun report(diagnostic: FirDiagnostic<*>?) { override fun report(diagnostic: FirDiagnostic<*>?) {
if (diagnostic !is FirPsiDiagnostic<*>) return checkCanceled()
val psi = diagnostic.element.psi as? KtElement ?: return try {
result.addValueFor(psi, diagnostic.asPsiBasedDiagnostic()) if (diagnostic !is FirPsiDiagnostic<*>) return
val psi = diagnostic.element.psi as? KtElement ?: return
result.addValueFor(psi, diagnostic.asPsiBasedDiagnostic())
} catch (e: Throwable) {
LOG.error(e)
}
} }
} }
private lateinit var reporter: Reporter override var reporter: DiagnosticReporter = Reporter()
private set
override fun initializeCollector() { override fun initializeCollector() {
reporter = Reporter() reporter = Reporter()
@@ -51,15 +57,6 @@ internal class FirIdeDiagnosticsCollector private constructor(
return emptyList() return emptyList()
} }
override fun runCheck(block: (DiagnosticReporter) -> Unit) {
checkCanceled()
try {
block(reporter)
} catch (e: Throwable) {
LOG.error(e)
}
}
companion object { companion object {
private val LOG = Logger.getInstance(FirIdeDiagnosticsCollector::class.java) private val LOG = Logger.getInstance(FirIdeDiagnosticsCollector::class.java)