[FIR] Use resolvedType instead of coneTypeOrNull in checkers

#KT-61367
This commit is contained in:
Kirill Rakhman
2023-09-08 17:45:31 +02:00
committed by Space Team
parent e8731f3f31
commit c3abe28049
13 changed files with 34 additions and 31 deletions
@@ -12,11 +12,11 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirPropertyChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
import org.jetbrains.kotlin.fir.types.resolvedType
object FirJsPropertyDelegationByDynamicChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration.delegate?.coneTypeOrNull is ConeDynamicType) {
if (declaration.delegate?.resolvedType is ConeDynamicType) {
reporter.reportOn(declaration.delegate?.source, FirJsErrors.PROPERTY_DELEGATION_BY_DYNAMIC, context)
}
}
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirCall
import org.jetbrains.kotlin.fir.expressions.resolvedArgumentMapping
import org.jetbrains.kotlin.fir.expressions.unwrapArgument
import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.name.JsStandardClassIds.Annotations.JsExternalArgument
@@ -26,7 +26,7 @@ object FirJsExternalArgumentCallChecker : FirCallChecker() {
for ((argument, parameter) in arguments) {
if (parameter.hasAnnotation(JsExternalArgument, context.session)) {
val unwrappedArg = argument.unwrapArgument()
val type = unwrappedArg.coneTypeOrNull ?: continue
val type = unwrappedArg.resolvedType
val symbol = type.toRegularClassSymbol(context.session)
if (symbol?.isEffectivelyExternal(context.session) == false || type is ConeDynamicType) {
reporter.reportOn(
@@ -10,13 +10,13 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirGetClassCallChecker
import org.jetbrains.kotlin.fir.analysis.js.checkers.checkJsModuleUsage
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toSymbol
object FirJsModuleGetClassCallChecker : FirGetClassCallChecker() {
override fun check(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) {
val callee = expression.argument.coneTypeOrNull?.toSymbol(context.session) ?: return
val callee = expression.argument.resolvedType.toSymbol(context.session) ?: return
checkJsModuleUsage(callee, context, reporter, expression.source)
}
}
@@ -8,14 +8,19 @@ package org.jetbrains.kotlin.fir.analysis.native.checkers
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
@@ -179,7 +184,7 @@ object FirNativeThrowsChecker : FirBasicDeclarationChecker() {
val arguments = argumentList.arguments
return (arguments.firstOrNull() as? FirVarargArgumentsExpression)?.arguments
?.filterIsInstance<FirGetClassCall>()
?.mapNotNull { it.arguments.first().coneTypeOrNull?.fullyExpandedType(session) }
?.map { it.arguments.first().resolvedType.fullyExpandedType(session) }
?: emptyList()
}
@@ -237,7 +237,7 @@ private fun FirFunctionCall.isCompileTimeBuiltinCall(): Boolean {
val symbol = calleeReference.resolvedSymbol as? FirCallableSymbol
if (!symbol.fromKotlin()) return false
val coneType = this.dispatchReceiver?.coneTypeSafe<ConeKotlinType>()
val coneType = this.dispatchReceiver?.resolvedType
val receiverClassId = coneType?.lowerBoundIfFlexible()?.classId
if (receiverClassId in StandardClassIds.unsignedTypes) return false
@@ -125,7 +125,7 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() {
val (hint, type) = when (annotation.useSiteTarget) {
FIELD -> "fields" to ((declaration as? FirBackingField)?.returnTypeRef ?: return)
PROPERTY_DELEGATE_FIELD -> "delegate fields" to ((declaration as? FirBackingField)?.propertySymbol?.delegate?.coneTypeOrNull
PROPERTY_DELEGATE_FIELD -> "delegate fields" to ((declaration as? FirBackingField)?.propertySymbol?.delegate?.resolvedType
?: return)
RECEIVER -> "receivers" to ((declaration as? FirCallableDeclaration)?.receiverParameter?.typeRef ?: return)
FILE, PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, CONSTRUCTOR_PARAMETER, SETTER_PARAMETER, null -> when {
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -42,7 +42,7 @@ abstract class AbstractFirReflectionApiCallChecker : FirBasicExpressionChecker()
val resolvedReference = expression.calleeReference?.resolved ?: return
val referencedSymbol = resolvedReference.resolvedSymbol as? FirCallableSymbol ?: return
val containingClassId = (expression as? FirQualifiedAccessExpression)?.dispatchReceiver?.coneTypeOrNull?.classId
val containingClassId = (expression as? FirQualifiedAccessExpression)?.dispatchReceiver?.resolvedType?.classId
if (containingClassId == null || containingClassId.packageFqName != StandardNames.KOTLIN_REFLECT_FQ_NAME) return
if (!isAllowedReflectionApi(referencedSymbol.name, containingClassId, context)) {
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.unwrapSmartcastExpression
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConePropertyAsOperator
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
@@ -44,7 +45,7 @@ object FirConventionFunctionCallChecker : FirFunctionCallChecker() {
context: CheckerContext,
reporter: DiagnosticReporter
) {
if (callExpression.dispatchReceiver?.coneTypeOrNull is ConeDynamicType) return
if (callExpression.dispatchReceiver?.resolvedType is ConeDynamicType) return
// KT-61905: TODO: Return also in case of error type.
val sourceKind = callExpression.source?.kind
if (sourceKind !is KtRealSourceElementKind &&
@@ -46,9 +46,9 @@ object FirMissingDependencyClassChecker : FirFunctionCallChecker() {
}
}
expression.coneTypeOrNull?.let(::consider)
expression.extensionReceiver?.coneTypeOrNull?.let(::consider)
expression.argumentList.arguments.forEach { it.coneTypeOrNull?.let(::consider) }
consider(expression.resolvedType)
expression.extensionReceiver?.resolvedType?.let(::consider)
expression.argumentList.arguments.forEach { consider(it.resolvedType) }
}
private fun ConeKotlinType.forEachClassLikeType(action: (ConeClassLikeType) -> Unit) {
@@ -36,7 +36,7 @@ object FirNamedVarargChecker : FirCallChecker() {
else LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
)
fun checkArgument(argument: FirExpression, isVararg: Boolean, expectedArrayType: ConeKotlinType?) {
fun checkArgument(argument: FirExpression, isVararg: Boolean, expectedArrayType: ConeKotlinType) {
if (argument !is FirNamedArgumentExpression) return
if (argument.isSpread) {
if (isVararg && (expression as? FirResolvable)?.calleeReference !is FirErrorNamedReference) {
@@ -44,11 +44,11 @@ object FirNamedVarargChecker : FirCallChecker() {
}
return
}
val type = argument.expression.coneTypeOrNull
val type = argument.expression.resolvedType
if (type is ConeErrorType) return
if (argument.expression is FirArrayLiteral) return
if (allowAssignArray && type?.isArrayType == true) return
if (allowAssignArray && type.isArrayType) return
if (isAnnotation) {
reporter.reportOn(
@@ -57,7 +57,6 @@ object FirNamedVarargChecker : FirCallChecker() {
context
)
} else {
require(expectedArrayType != null) { "expectedArrayType must be passed for function call" }
reporter.reportOn(
argument.expression.source,
FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION,
@@ -69,7 +68,7 @@ object FirNamedVarargChecker : FirCallChecker() {
if (expression is FirArrayLiteral) {
// FirArrayLiteral has the `vararg` argument expression pre-flattened and doesn't have an argument mapping.
expression.arguments.forEach { checkArgument(it, it is FirNamedArgumentExpression, expression.coneTypeOrNull) }
expression.arguments.forEach { checkArgument(it, it is FirNamedArgumentExpression, expression.resolvedType) }
} else {
val argumentMap = expression.resolvedArgumentMapping ?: return
for ((argument, parameter) in argumentMap) {
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvedReifiedParameterReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.resolvedType
object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessExpressionChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -36,7 +37,7 @@ object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessExpressionCh
val secondLast = context.callsOrAssignments.elementAtOrNull(context.callsOrAssignments.size - 2)
if (secondLast is FirQualifiedAccessExpression && secondLast.explicitReceiver == expression) return
val diagnostic = expression.coneTypeOrNull?.coneTypeParameterInQualifiedAccess ?: return
val diagnostic = expression.resolvedType.coneTypeParameterInQualifiedAccess ?: return
val source = expression.calleeReference.source ?: return
reporter.reportOn(source, FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION, diagnostic.symbol, context)
}
@@ -49,7 +50,7 @@ object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessExpressionCh
val explicitReceiver = expression.explicitReceiver
val typeParameterSymbol =
(explicitReceiver as? FirResolvedReifiedParameterReference)?.symbol
?: explicitReceiver?.coneTypeOrNull?.coneTypeParameterInQualifiedAccess?.symbol
?: explicitReceiver?.resolvedType?.coneTypeParameterInQualifiedAccess?.symbol
?: return
if (expression is FirCallableReferenceAccess) {
reporter.reportOn(expression.source, FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS, context)
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.renderForDebugging
import org.jetbrains.kotlin.fir.types.*
class ErrorNodeDiagnosticCollectorComponent(
session: FirSession,
@@ -89,7 +86,7 @@ class ErrorNodeDiagnosticCollectorComponent(
}
private fun FirExpression?.cannotBeResolved(): Boolean {
return when (val diagnostic = (this?.coneTypeOrNull as? ConeErrorType)?.diagnostic) {
return when (val diagnostic = (this?.resolvedType as? ConeErrorType)?.diagnostic) {
is ConeUnresolvedNameError, is ConeInstanceAccessBeforeSuperCall, is ConeAmbiguousSuper -> true
is ConeSimpleDiagnostic -> diagnostic.kind == DiagnosticKind.NotASupertype ||
diagnostic.kind == DiagnosticKind.SuperNotAvailable ||
@@ -22,8 +22,8 @@ import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithSingleCandidate
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
import org.jetbrains.kotlin.fir.types.isUnit
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.types.expressions.OperatorConventions.ASSIGN_METHOD
@@ -59,7 +59,7 @@ object FirAssignmentPluginFunctionCallChecker : FirFunctionCallChecker() {
calleeReference.name == ASSIGN_METHOD && isAnnotated(session)
private fun FirFunctionCall.isAnnotated(session: FirSession): Boolean =
session.annotationMatchingService.isAnnotated(explicitReceiver?.coneTypeOrNull?.toRegularClassSymbol(session))
session.annotationMatchingService.isAnnotated(explicitReceiver?.resolvedType?.toRegularClassSymbol(session))
private fun FirFunctionCall.isReturnTypeUnit() = toResolvedCallableSymbol()?.resolvedReturnType?.isUnit ?: false
}