FIR: distinguish qualified access / qualified access expression checkers
This commit is contained in:
+2
-1
@@ -27,7 +27,8 @@ fun main(args: Array<String>) {
|
||||
val expressionPackage = "$basePackage.checkers.expression"
|
||||
generateCheckersComponents(generationPath, expressionPackage, "FirExpressionChecker") {
|
||||
alias<FirStatement>("BasicExpressionChecker")
|
||||
alias<FirQualifiedAccessExpression>("QualifiedAccessChecker")
|
||||
alias<FirQualifiedAccess>("QualifiedAccessChecker")
|
||||
alias<FirQualifiedAccessExpression>("QualifiedAccessExpressionChecker")
|
||||
alias<FirFunctionCall>("FunctionCallChecker")
|
||||
alias<FirVariableAssignment>("VariableAssignmentChecker")
|
||||
alias<FirTryExpression>("TryExpressionChecker")
|
||||
|
||||
+4
@@ -17,6 +17,8 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
||||
get() = _basicExpressionCheckers
|
||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
|
||||
get() = _qualifiedAccessCheckers
|
||||
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
||||
get() = _qualifiedAccessExpressionCheckers
|
||||
override val functionCallCheckers: Set<FirFunctionCallChecker>
|
||||
get() = _functionCallCheckers
|
||||
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
|
||||
@@ -56,6 +58,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
||||
|
||||
private val _basicExpressionCheckers: MutableSet<FirBasicExpressionChecker> = mutableSetOf()
|
||||
private val _qualifiedAccessCheckers: MutableSet<FirQualifiedAccessChecker> = mutableSetOf()
|
||||
private val _qualifiedAccessExpressionCheckers: MutableSet<FirQualifiedAccessExpressionChecker> = mutableSetOf()
|
||||
private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf()
|
||||
private val _variableAssignmentCheckers: MutableSet<FirVariableAssignmentChecker> = mutableSetOf()
|
||||
private val _tryExpressionCheckers: MutableSet<FirTryExpressionChecker> = mutableSetOf()
|
||||
@@ -79,6 +82,7 @@ class ComposedExpressionCheckers : ExpressionCheckers() {
|
||||
fun register(checkers: ExpressionCheckers) {
|
||||
_basicExpressionCheckers += checkers.basicExpressionCheckers
|
||||
_qualifiedAccessCheckers += checkers.qualifiedAccessCheckers
|
||||
_qualifiedAccessExpressionCheckers += checkers.qualifiedAccessExpressionCheckers
|
||||
_functionCallCheckers += checkers.functionCallCheckers
|
||||
_variableAssignmentCheckers += checkers.variableAssignmentCheckers
|
||||
_tryExpressionCheckers += checkers.tryExpressionCheckers
|
||||
|
||||
+4
-2
@@ -19,6 +19,7 @@ abstract class ExpressionCheckers {
|
||||
|
||||
open val basicExpressionCheckers: Set<FirBasicExpressionChecker> = emptySet()
|
||||
open val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker> = emptySet()
|
||||
open val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> = emptySet()
|
||||
open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet()
|
||||
open val variableAssignmentCheckers: Set<FirVariableAssignmentChecker> = emptySet()
|
||||
open val tryExpressionCheckers: Set<FirTryExpressionChecker> = emptySet()
|
||||
@@ -40,8 +41,9 @@ abstract class ExpressionCheckers {
|
||||
|
||||
@CheckersComponentInternal internal val allBasicExpressionCheckers: Set<FirBasicExpressionChecker> get() = basicExpressionCheckers
|
||||
@CheckersComponentInternal internal val allQualifiedAccessCheckers: Set<FirQualifiedAccessChecker> get() = qualifiedAccessCheckers + basicExpressionCheckers
|
||||
@CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> get() = functionCallCheckers + qualifiedAccessCheckers + basicExpressionCheckers
|
||||
@CheckersComponentInternal internal val allVariableAssignmentCheckers: Set<FirVariableAssignmentChecker> get() = variableAssignmentCheckers + basicExpressionCheckers
|
||||
@CheckersComponentInternal internal val allQualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker> get() = qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers
|
||||
@CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> get() = functionCallCheckers + qualifiedAccessExpressionCheckers + basicExpressionCheckers + qualifiedAccessCheckers
|
||||
@CheckersComponentInternal internal val allVariableAssignmentCheckers: Set<FirVariableAssignmentChecker> get() = variableAssignmentCheckers + qualifiedAccessCheckers + basicExpressionCheckers
|
||||
@CheckersComponentInternal internal val allTryExpressionCheckers: Set<FirTryExpressionChecker> get() = tryExpressionCheckers + basicExpressionCheckers
|
||||
@CheckersComponentInternal internal val allWhenExpressionCheckers: Set<FirWhenExpressionChecker> get() = whenExpressionCheckers + basicExpressionCheckers
|
||||
@CheckersComponentInternal internal val allLoopExpressionCheckers: Set<FirLoopExpressionChecker> get() = loopExpressionCheckers + basicExpressionCheckers
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
@@ -32,7 +33,8 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||
|
||||
typealias FirBasicExpressionChecker = FirExpressionChecker<FirStatement>
|
||||
typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccessExpression>
|
||||
typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccess>
|
||||
typealias FirQualifiedAccessExpressionChecker = FirExpressionChecker<FirQualifiedAccessExpression>
|
||||
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
|
||||
typealias FirVariableAssignmentChecker = FirExpressionChecker<FirVariableAssignment>
|
||||
typealias FirTryExpressionChecker = FirExpressionChecker<FirTryExpression>
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirExpressionAnnotationChecker,
|
||||
)
|
||||
|
||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
|
||||
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
||||
get() = setOf(
|
||||
FirCallableReferenceChecker,
|
||||
FirSuperNotAvailableChecker,
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ object ExtendedExpressionCheckers : ExpressionCheckers() {
|
||||
CanBeReplacedWithOperatorAssignmentChecker,
|
||||
)
|
||||
|
||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker>
|
||||
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
|
||||
get() = setOf(
|
||||
RedundantCallOfConversionMethod,
|
||||
UselessCallOnNotNullChecker,
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirAbstractSuperCallChecker : FirQualifiedAccessChecker() {
|
||||
object FirAbstractSuperCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
// require the receiver to be the super reference
|
||||
expression.explicitReceiver.safeAs<FirQualifiedAccessExpression>()
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.getContainingClass
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
||||
|
||||
object FirCallableReferenceChecker : FirQualifiedAccessChecker() {
|
||||
object FirCallableReferenceChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (expression !is FirCallableReferenceAccess) return
|
||||
// [FirGetClassCallChecker] will check [FirGetClassCall].
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.isFun
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
|
||||
object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessChecker() {
|
||||
object FirFunInterfaceConstructorReferenceChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (expression !is FirCallableReferenceAccess || expression is FirGetClassCall) return
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirNotASupertypeChecker : FirQualifiedAccessChecker() {
|
||||
object FirNotASupertypeChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val superReference = expression.calleeReference.safeAs<FirSuperReference>()?.takeIf { it.hadExplicitTypeInSource() }
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.types.FirStarProjection
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
object FirProjectionsOnNonClassTypeArgumentChecker : FirQualifiedAccessChecker() {
|
||||
object FirProjectionsOnNonClassTypeArgumentChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (it in expression.typeArguments) {
|
||||
when (it) {
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccessChecker() {
|
||||
object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
// require to be called over a super reference
|
||||
val superReference = expression.calleeReference.safeAs<FirSuperReference>()
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirSealedClassConstructorCallChecker : FirQualifiedAccessChecker() {
|
||||
object FirSealedClassConstructorCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val constructorFir = expression.calleeReference.safeAs<FirResolvedNamedReference>()
|
||||
?.resolvedSymbol
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirSuperNotAvailableChecker : FirQualifiedAccessChecker() {
|
||||
object FirSuperNotAvailableChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (expression.calleeReference.safeAs<FirSuperReference>()?.hadExplicitTypeInSource() != true) return
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessChecker() {
|
||||
object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
expression.explicitReceiver.safeAs<FirQualifiedAccessExpression>()
|
||||
?.calleeReference.safeAs<FirSuperReference>()
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
|
||||
object FirTypeArgumentsNotAllowedExpressionChecker : FirQualifiedAccessChecker() {
|
||||
object FirTypeArgumentsNotAllowedExpressionChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
// analyze type parameters near
|
||||
// package names
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualified
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
|
||||
object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessChecker() {
|
||||
object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
checkExplicitReceiver(expression, context, reporter)
|
||||
checkExpressionItself(expression, context, reporter)
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
|
||||
object FirUninitializedEnumChecker : FirQualifiedAccessChecker() {
|
||||
object FirUninitializedEnumChecker : FirQualifiedAccessExpressionChecker() {
|
||||
// Initialization order: member property initializers, enum entries, companion object (including members in it).
|
||||
//
|
||||
// When JVM loads a class, the corresponding class initializer, a.k.a. <clinit>, is executed first.
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
object FirUpperBoundViolatedChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
// something that contains the type parameters
|
||||
// declarations with their declared bounds.
|
||||
|
||||
+2
-3
@@ -5,9 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
@@ -24,7 +23,7 @@ import org.jetbrains.kotlin.fir.types.isMarkedNullable
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
|
||||
|
||||
object RedundantCallOfConversionMethod : FirQualifiedAccessChecker() {
|
||||
object RedundantCallOfConversionMethod : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (expression !is FirFunctionCall) return
|
||||
val functionName = expression.calleeReference.name.asString()
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
|
||||
object UselessCallOnNotNullChecker : FirQualifiedAccessChecker() {
|
||||
object UselessCallOnNotNullChecker : FirQualifiedAccessExpressionChecker() {
|
||||
// todo: add 'call may be reduced' in cases like 's?.isNullOrEmpty()' where 's: String? = ""'
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val method = expression.getCallableId() ?: return
|
||||
|
||||
+2
-2
@@ -39,7 +39,7 @@ class ExpressionCheckersDiagnosticComponent(
|
||||
}
|
||||
|
||||
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: CheckerContext) {
|
||||
checkers.allQualifiedAccessCheckers.check(qualifiedAccessExpression, data, reporter)
|
||||
checkers.allQualifiedAccessExpressionCheckers.check(qualifiedAccessExpression, data, reporter)
|
||||
}
|
||||
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: CheckerContext) {
|
||||
@@ -47,7 +47,7 @@ class ExpressionCheckersDiagnosticComponent(
|
||||
}
|
||||
|
||||
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: CheckerContext) {
|
||||
checkers.allQualifiedAccessCheckers.check(callableReferenceAccess, data, reporter)
|
||||
checkers.allQualifiedAccessExpressionCheckers.check(callableReferenceAccess, data, reporter)
|
||||
}
|
||||
|
||||
override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: CheckerContext) {
|
||||
|
||||
Reference in New Issue
Block a user