[FIR] Add infrastructure for call checkers

This commit is contained in:
Dmitriy Novozhilov
2020-02-27 15:08:33 +03:00
parent 9cee2962db
commit f6a23ea441
5 changed files with 119 additions and 14 deletions
@@ -0,0 +1,14 @@
/*
* 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.resolve.diagnostics.checkers.call
import org.jetbrains.kotlin.fir.expressions.FirExpression
object CallCheckers {
val EXPRESSIONS: List<FirExpressionChecker<FirExpression>> = listOf()
val QUALIFIED_ACCESS: List<FirQualifiedAccessChecker> = listOf<FirQualifiedAccessChecker>() + EXPRESSIONS
val FUNCTION_CALLS: List<FirFunctionCallChecker> = listOf<FirFunctionCallChecker>() + QUALIFIED_ACCESS
}
@@ -1,13 +0,0 @@
/*
* Copyright 2010-2019 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.resolve.diagnostics.checkers.call
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.resolve.diagnostics.DiagnosticReporter
abstract class FirCallChecker {
abstract fun check(functionCall: FirFunctionCall, reporter: DiagnosticReporter)
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 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.resolve.diagnostics.checkers.call
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.resolve.diagnostics.DiagnosticReporter
abstract class FirExpressionChecker<in E : FirExpression> {
abstract fun check(functionCall: E, reporter: DiagnosticReporter)
}
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccessExpression>
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.resolve.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.resolve.diagnostics.collectors.components.AbstractDiagnosticCollectorComponent
import org.jetbrains.kotlin.fir.resolve.diagnostics.collectors.components.ExpressionCheckersDiagnosticComponent
import org.jetbrains.kotlin.fir.resolve.diagnostics.collectors.components.DeclarationCheckersDiagnosticComponent
import org.jetbrains.kotlin.fir.resolve.diagnostics.collectors.components.ErrorNodeDiagnosticCollectorComponent
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
@@ -57,6 +58,7 @@ abstract class AbstractDiagnosticCollector {
fun AbstractDiagnosticCollector.registerAllComponents() {
initializeComponents(
DeclarationCheckersDiagnosticComponent(this),
ErrorNodeDiagnosticCollectorComponent(this)
ExpressionCheckersDiagnosticComponent(this),
ErrorNodeDiagnosticCollectorComponent(this),
)
}
@@ -0,0 +1,84 @@
/*
* 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.resolve.diagnostics.collectors.components
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.resolve.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.resolve.diagnostics.checkers.call.CallCheckers
import org.jetbrains.kotlin.fir.resolve.diagnostics.checkers.call.FirExpressionChecker
import org.jetbrains.kotlin.fir.resolve.diagnostics.collectors.AbstractDiagnosticCollector
class ExpressionCheckersDiagnosticComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) {
override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall) {
runCheck { CallCheckers.EXPRESSIONS.check(typeOperatorCall, it) }
}
override fun <T> visitConstExpression(constExpression: FirConstExpression<T>) {
runCheck { CallCheckers.EXPRESSIONS.check(constExpression, it) }
}
override fun visitAnnotationCall(annotationCall: FirAnnotationCall) {
runCheck { CallCheckers.EXPRESSIONS.check(annotationCall, it) }
}
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) {
runCheck { CallCheckers.QUALIFIED_ACCESS.check(qualifiedAccessExpression, it) }
}
override fun visitFunctionCall(functionCall: FirFunctionCall) {
runCheck { CallCheckers.FUNCTION_CALLS.check(functionCall, it) }
}
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess) {
runCheck { CallCheckers.QUALIFIED_ACCESS.check(callableReferenceAccess, it) }
}
override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression) {
runCheck { CallCheckers.EXPRESSIONS.check(thisReceiverExpression, it) }
}
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier) {
runCheck { CallCheckers.EXPRESSIONS.check(resolvedQualifier, it) }
}
override fun visitWhenExpression(whenExpression: FirWhenExpression) {
runCheck { CallCheckers.EXPRESSIONS.check(whenExpression, it) }
}
override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression) {
runCheck { CallCheckers.EXPRESSIONS.check(binaryLogicExpression, it) }
}
override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall) {
runCheck { CallCheckers.EXPRESSIONS.check(arrayOfCall, it) }
}
override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall) {
runCheck { CallCheckers.EXPRESSIONS.check(stringConcatenationCall, it) }
}
override fun visitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall) {
runCheck { CallCheckers.EXPRESSIONS.check(checkNotNullCall, it) }
}
override fun visitTryExpression(tryExpression: FirTryExpression) {
runCheck { CallCheckers.EXPRESSIONS.check(tryExpression, it) }
}
override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression) {
runCheck { CallCheckers.EXPRESSIONS.check(classReferenceExpression, it) }
}
override fun visitGetClassCall(getClassCall: FirGetClassCall) {
runCheck { CallCheckers.EXPRESSIONS.check(getClassCall, it) }
}
private fun <E : FirExpression> List<FirExpressionChecker<E>>.check(expression: E, reporter: DiagnosticReporter) {
for (checker in this) {
checker.check(expression, reporter)
}
}
}