FIR checker: avoid redundant casting to resolved type ref
This commit is contained in:
committed by
Dmitriy Novozhilov
parent
37a702b962
commit
a9322a01ce
@@ -22,23 +22,19 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.typeCheckerContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -132,7 +128,7 @@ fun ConeKotlinType.toRegularClass(session: FirSession): FirRegularClass? {
|
||||
* or null of something goes wrong.
|
||||
*/
|
||||
fun FirTypeRef.toRegularClass(session: FirSession): FirRegularClass? {
|
||||
return safeAs<FirResolvedTypeRef>()?.type?.toRegularClass(session)
|
||||
return coneType.toRegularClass(session)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,18 +285,15 @@ private fun FirDeclaration.hasBody(): Boolean = when (this) {
|
||||
* or null if couldn't find any.
|
||||
*/
|
||||
fun FirClass<*>.findNonInterfaceSupertype(context: CheckerContext): FirTypeRef? {
|
||||
for (it in superTypeRefs) {
|
||||
val lookupTag = it.safeAs<FirResolvedTypeRef>()
|
||||
?.type.safeAs<ConeClassLikeType>()
|
||||
?.lookupTag
|
||||
?: continue
|
||||
for (superTypeRef in superTypeRefs) {
|
||||
val lookupTag = superTypeRef.coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: continue
|
||||
|
||||
val fir = lookupTag.toSymbol(context.session)
|
||||
?.fir.safeAs<FirClass<*>>()
|
||||
?: continue
|
||||
|
||||
if (fir.classKind != ClassKind.INTERFACE) {
|
||||
return it
|
||||
return superTypeRef
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -44,6 +44,8 @@ object FirConflictingProjectionChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
|
||||
private fun checkTypeRef(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
// TODO: remaining implicit types should be resolved as an error type, along with proper error kind,
|
||||
// e.g., type mismatch, can't infer parameter type, syntax error, etc.
|
||||
val declaration = typeRef.safeAs<FirResolvedTypeRef>()
|
||||
?.coneTypeSafe<ConeClassLikeType>()
|
||||
?.lookupTag
|
||||
|
||||
+1
-2
@@ -136,8 +136,7 @@ object FirOverrideChecker : FirRegularClassChecker() {
|
||||
typeCheckerContext: AbstractTypeCheckerContext,
|
||||
context: CheckerContext,
|
||||
): FirMemberDeclaration? {
|
||||
val overridingReturnType = returnTypeRef.safeAs<FirResolvedTypeRef>()?.type
|
||||
?: return null
|
||||
val overridingReturnType = returnTypeRef.coneType
|
||||
|
||||
// Don't report *_ON_OVERRIDE diagnostics according to an error return type. That should be reported separately.
|
||||
if (overridingReturnType is ConeKotlinErrorType) {
|
||||
|
||||
+5
-14
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
|
||||
@@ -41,10 +41,7 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
|
||||
|
||||
private fun checkTopLevelDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (it in declaration.superTypeRefs) {
|
||||
val classId = it.safeAs<FirResolvedTypeRef>()
|
||||
?.type.safeAs<ConeClassLikeType>()
|
||||
?.lookupTag?.classId
|
||||
?: continue
|
||||
val classId = it.coneType.classId ?: continue
|
||||
|
||||
if (classId.isLocal) {
|
||||
continue
|
||||
@@ -63,10 +60,7 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
|
||||
|
||||
private fun checkLocalDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (it in declaration.superTypeRefs) {
|
||||
val classId = it.safeAs<FirResolvedTypeRef>()
|
||||
?.type.safeAs<ConeClassLikeType>()
|
||||
?.lookupTag?.classId
|
||||
?: continue
|
||||
val classId = it.coneType.classId ?: continue
|
||||
|
||||
if (classId.isLocal) {
|
||||
continue
|
||||
@@ -85,10 +79,7 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() {
|
||||
|
||||
private fun checkInnerDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (it in declaration.superTypeRefs) {
|
||||
val classId = it.safeAs<FirResolvedTypeRef>()
|
||||
?.type.safeAs<ConeClassLikeType>()
|
||||
?.lookupTag?.classId
|
||||
?: continue
|
||||
val classId = it.coneType.classId ?: continue
|
||||
|
||||
if (classId.isLocal) {
|
||||
continue
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
}
|
||||
|
||||
val typeRef = catchParameter.returnTypeRef
|
||||
// TODO: remaining implicit types should be resolved as an error type, along with proper error kind, most likely syntax error.
|
||||
if (typeRef !is FirResolvedTypeRef) return
|
||||
|
||||
val coneType = typeRef.type
|
||||
|
||||
+2
-3
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccessChecker() {
|
||||
@@ -26,8 +25,8 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess
|
||||
?.takeIf { it.hadExplicitTypeInSource() }
|
||||
?: return
|
||||
|
||||
val explicitType = superReference.superTypeRef.safeAs<FirResolvedTypeRef>()
|
||||
?.firClassLike(context.session)
|
||||
val explicitType = superReference.superTypeRef
|
||||
.firClassLike(context.session)
|
||||
?.followAllAlias(context.session).safeAs<FirClass<*>>()
|
||||
?: return
|
||||
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirSealedClassConstructorCallChecker : FirQualifiedAccessChecker() {
|
||||
@@ -26,8 +26,8 @@ object FirSealedClassConstructorCallChecker : FirQualifiedAccessChecker() {
|
||||
?.fir.safeAs<FirConstructor>()
|
||||
?: return
|
||||
|
||||
val typeFir = constructorFir.returnTypeRef.safeAs<FirResolvedTypeRef>()
|
||||
?.type.safeAs<ConeClassLikeType>()
|
||||
val typeFir = constructorFir.returnTypeRef.coneType
|
||||
.safeAs<ConeClassLikeType>()
|
||||
?.lookupTag?.toSymbol(context.session)
|
||||
?.fir as? FirRegularClass
|
||||
?: return
|
||||
|
||||
+10
-10
@@ -43,11 +43,11 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
return
|
||||
}
|
||||
|
||||
val parameterPairs = mutableMapOf<FirTypeParameterSymbol, FirResolvedTypeRef>()
|
||||
val parameterPairs = mutableMapOf<FirTypeParameterSymbol, FirTypeRef>()
|
||||
|
||||
for (it in 0 until count) {
|
||||
expression.typeArguments[it].safeAs<FirTypeProjectionWithVariance>()
|
||||
?.typeRef.safeAs<FirResolvedTypeRef>()
|
||||
?.typeRef
|
||||
?.let { that ->
|
||||
if (that !is FirErrorTypeRef) {
|
||||
parameterPairs[calleeFir.typeParameters[it].symbol] = that
|
||||
@@ -60,7 +60,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
// we substitute actual values to the
|
||||
// type parameters from the declaration
|
||||
val substitutor = substitutorByMap(
|
||||
parameterPairs.mapValues { it.value.type }
|
||||
parameterPairs.mapValues { it.value.coneType }
|
||||
)
|
||||
|
||||
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext(
|
||||
@@ -74,14 +74,14 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
if (!satisfiesBounds(proto, actual.type, substitutor, typeCheckerContext)) {
|
||||
reporter.reportOn(actual.source, proto, actual.type, context)
|
||||
if (!satisfiesBounds(proto, actual.coneType, substitutor, typeCheckerContext)) {
|
||||
reporter.reportOn(actual.source, proto, actual.coneType, context)
|
||||
return
|
||||
}
|
||||
|
||||
// we must analyze nested things like
|
||||
// S<S<K, L>, T<K, L>>()
|
||||
actual.type.safeAs<ConeClassLikeType>()?.let {
|
||||
actual.coneType.safeAs<ConeClassLikeType>()?.let {
|
||||
val errorOccurred = analyzeTypeParameters(it, context, reporter, typeCheckerContext, actual.source)
|
||||
|
||||
if (errorOccurred) {
|
||||
@@ -125,8 +125,8 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
val actualConstructor = functionCall.calleeReference.safeAs<FirResolvedNamedReference>()
|
||||
?.resolvedSymbol.safeAs<FirConstructorSymbol>()
|
||||
?.fir.safeAs<FirConstructor>()
|
||||
?.returnTypeRef.safeAs<FirResolvedTypeRef>()
|
||||
?.type.safeAs<ConeClassLikeType>()
|
||||
?.returnTypeRef?.coneType
|
||||
?.safeAs<ConeClassLikeType>()
|
||||
?: return
|
||||
|
||||
val count = min(protoConstructor.typeParameters.size, actualConstructor.typeArguments.size)
|
||||
@@ -158,7 +158,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
constructorsParameterPairs.forEach { (proto, actual) ->
|
||||
// just in case
|
||||
var intersection = typeCheckerContext.intersectTypes(
|
||||
proto.fir.bounds.filterIsInstance<FirResolvedTypeRef>().map { it.type }
|
||||
proto.fir.bounds.map { it.coneType }
|
||||
).safeAs<ConeKotlinType>() ?: return@forEach
|
||||
|
||||
intersection = declarationSiteSubstitutor.substituteOrSelf(intersection)
|
||||
@@ -245,7 +245,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
|
||||
typeCheckerContext: AbstractTypeCheckerContext
|
||||
): Boolean {
|
||||
var intersection = typeCheckerContext.intersectTypes(
|
||||
prototypeSymbol.fir.bounds.filterIsInstance<FirResolvedTypeRef>().map { it.type }
|
||||
prototypeSymbol.fir.bounds.map { it.coneType }
|
||||
).safeAs<ConeKotlinType>() ?: return true
|
||||
|
||||
intersection = substitutor.substituteOrSelf(intersection)
|
||||
|
||||
+2
-3
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
|
||||
@@ -37,9 +36,9 @@ object UselessCallOnNotNullChecker : FirQualifiedAccessChecker() {
|
||||
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol)?.callableId
|
||||
|
||||
private fun FirExpression.getPackage() =
|
||||
(typeRef as? FirResolvedTypeRef)?.coneType?.classId?.packageFqName.toString()
|
||||
typeRef.coneType.classId?.packageFqName.toString()
|
||||
|
||||
private fun FirExpression.getNullability() = (typeRef as FirResolvedTypeRef).type.nullability
|
||||
private fun FirExpression.getNullability() = typeRef.coneType.nullability
|
||||
|
||||
|
||||
private val triggerOn = setOf(
|
||||
|
||||
Reference in New Issue
Block a user