From a9322a01ce5a05827215b977903d8ca74b6d6717 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Sat, 6 Feb 2021 22:59:37 -0800 Subject: [PATCH] FIR checker: avoid redundant casting to resolved type ref --- .../fir/analysis/checkers/FirHelpers.kt | 15 ++++---------- .../FirConflictingProjectionChecker.kt | 2 ++ .../declaration/FirOverrideChecker.kt | 3 +-- .../declaration/FirSealedSupertypeChecker.kt | 19 +++++------------- .../expression/FirCatchParameterChecker.kt | 1 + ...upertypeExtendedByOtherSupertypeChecker.kt | 5 ++--- .../FirSealedClassConstructorCallChecker.kt | 6 +++--- .../FirUpperBoundViolatedChecker.kt | 20 +++++++++---------- .../extended/UselessCallOnNotNullChecker.kt | 5 ++--- 9 files changed, 30 insertions(+), 46 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index ab254cab222..4de8ec9b974 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -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()?.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() - ?.type.safeAs() - ?.lookupTag - ?: continue + for (superTypeRef in superTypeRefs) { + val lookupTag = superTypeRef.coneType.safeAs()?.lookupTag ?: continue val fir = lookupTag.toSymbol(context.session) ?.fir.safeAs>() ?: continue if (fir.classKind != ClassKind.INTERFACE) { - return it + return superTypeRef } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt index 577a93cd63e..b82cb04fc20 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt @@ -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() ?.coneTypeSafe() ?.lookupTag diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt index 094a6426000..8302f1adc3a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt @@ -136,8 +136,7 @@ object FirOverrideChecker : FirRegularClassChecker() { typeCheckerContext: AbstractTypeCheckerContext, context: CheckerContext, ): FirMemberDeclaration? { - val overridingReturnType = returnTypeRef.safeAs()?.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) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt index 73151cf1fc2..91d1c9b3e64 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt @@ -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() - ?.type.safeAs() - ?.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() - ?.type.safeAs() - ?.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() - ?.type.safeAs() - ?.lookupTag?.classId - ?: continue + val classId = it.coneType.classId ?: continue if (classId.isLocal) { continue diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt index b4899e2394b..79970e5eda7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt @@ -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 diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt index 6dd050ad8d1..5a684a64e64 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt @@ -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() - ?.firClassLike(context.session) + val explicitType = superReference.superTypeRef + .firClassLike(context.session) ?.followAllAlias(context.session).safeAs>() ?: return diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt index 3eaf87d9cd9..600d4415e4d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt @@ -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() ?: return - val typeFir = constructorFir.returnTypeRef.safeAs() - ?.type.safeAs() + val typeFir = constructorFir.returnTypeRef.coneType + .safeAs() ?.lookupTag?.toSymbol(context.session) ?.fir as? FirRegularClass ?: return diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt index 1b326fa99da..d469fdeaf28 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt @@ -43,11 +43,11 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { return } - val parameterPairs = mutableMapOf() + val parameterPairs = mutableMapOf() for (it in 0 until count) { expression.typeArguments[it].safeAs() - ?.typeRef.safeAs() + ?.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, T>() - actual.type.safeAs()?.let { + actual.coneType.safeAs()?.let { val errorOccurred = analyzeTypeParameters(it, context, reporter, typeCheckerContext, actual.source) if (errorOccurred) { @@ -125,8 +125,8 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { val actualConstructor = functionCall.calleeReference.safeAs() ?.resolvedSymbol.safeAs() ?.fir.safeAs() - ?.returnTypeRef.safeAs() - ?.type.safeAs() + ?.returnTypeRef?.coneType + ?.safeAs() ?: 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().map { it.type } + proto.fir.bounds.map { it.coneType } ).safeAs() ?: return@forEach intersection = declarationSiteSubstitutor.substituteOrSelf(intersection) @@ -245,7 +245,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { typeCheckerContext: AbstractTypeCheckerContext ): Boolean { var intersection = typeCheckerContext.intersectTypes( - prototypeSymbol.fir.bounds.filterIsInstance().map { it.type } + prototypeSymbol.fir.bounds.map { it.coneType } ).safeAs() ?: return true intersection = substitutor.substituteOrSelf(intersection) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt index 8faa654deff..94b681f2934 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt @@ -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(