From b3b1eb57ae6727d4fcd46ec5693268ce5af48d45 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 27 Jan 2021 18:11:04 +0300 Subject: [PATCH] FIR2IR: Simplify Fir2IrImplicitCastInserter::convertToImplicitCastExpression Use dispatchReceiverType instead of looking into scopes --- .../fir/backend/Fir2IrImplicitCastInserter.kt | 80 +++++-------------- 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt index 5db2dbb6fa6..04e7d2b1c84 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt @@ -6,9 +6,9 @@ package org.jetbrains.kotlin.fir.backend import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.baseForIntersectionOverride import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject +import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirTypeAlias import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement @@ -16,15 +16,8 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.render -import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope -import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol -import org.jetbrains.kotlin.fir.resolve.scope -import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator -import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.ir.IrElement @@ -36,7 +29,7 @@ import org.jetbrains.kotlin.ir.types.withHasQuestionMark import org.jetbrains.kotlin.ir.util.classId import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded import org.jetbrains.kotlin.ir.util.parentAsClass -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.AbstractTypeChecker class Fir2IrImplicitCastInserter( private val components: Fir2IrComponents, @@ -292,61 +285,26 @@ class Fir2IrImplicitCastInserter( ): IrExpression { val originalExpression = expressionWithSmartcast.originalExpression val value = visitor.convertToIrExpression(originalExpression) - val castTypeRef = expressionWithSmartcast.typeRef - if (calleeReference !is FirResolvedNamedReference) { - return implicitCastOrExpression(value, castTypeRef) - } - val referencedSymbol = calleeReference.resolvedSymbol - if (referencedSymbol !is FirPropertySymbol && referencedSymbol !is FirFunctionSymbol && referencedSymbol !is FirFieldSymbol) { - return implicitCastOrExpression(value, castTypeRef) - } - if (castTypeRef is FirResolvedTypeRef) { - val castType = castTypeRef.type - if (castType is ConeIntersectionType) { - val unwrappedSymbol = (referencedSymbol as? FirCallableSymbol)?.baseForIntersectionOverride ?: referencedSymbol - castType.intersectedTypes.forEach { - if (it.doesContainReferencedSymbolInScope(unwrappedSymbol, calleeReference.name)) { - return implicitCastOrExpression(value, it) - } - } + val typeRef = expressionWithSmartcast.typeRef + val referencedDeclaration = + ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirCallableSymbol<*>)?.unwrapCallRepresentative() + ?.fir as FirCallableMemberDeclaration<*> + + val dispatchReceiverType = + referencedDeclaration.dispatchReceiverType as? ConeClassLikeType + ?: return implicitCastOrExpression(value, typeRef) + + val starProjectedDispatchReceiver = dispatchReceiverType.replaceArgumentsWithStarProjections() + + val castType = typeRef.coneTypeSafe() + castType?.intersectedTypes?.forEach { type -> + if (AbstractTypeChecker.isSubtypeOf(session.typeContext, type, starProjectedDispatchReceiver)) { + return implicitCastOrExpression(value, type) } } - return implicitCastOrExpression(value, castTypeRef.toIrType()) - } - private fun ConeKotlinType.doesContainReferencedSymbolInScope( - referencedSymbol: AbstractFirBasedSymbol<*>, name: Name - ): Boolean { - val scope = scope(session, components.scopeSession, FakeOverrideTypeCalculator.Forced) ?: return false - if (referencedSymbol is SyntheticPropertySymbol) { - return doesContainReferencedSyntheticSymbolInScope(referencedSymbol, name, scope) - } - var result = false - val processor = { it: FirCallableSymbol<*> -> - if (!result && it == referencedSymbol) { - result = true - } - } - when (referencedSymbol) { - is FirPropertySymbol, is FirFieldSymbol -> scope.processPropertiesByName(name, processor) - is FirFunctionSymbol -> scope.processFunctionsByName(name, processor) - } - return result - } - - private fun doesContainReferencedSyntheticSymbolInScope( - referencedSymbol: SyntheticPropertySymbol, name: Name, baseScope: FirTypeScope - ): Boolean { - val scope = FirSyntheticPropertiesScope(session, baseScope) - var result = false - val processor = { it: FirCallableSymbol<*> -> - if (!result && it.callableId == referencedSymbol.callableId) { - result = true - } - } - scope.processPropertiesByName(name, processor) - return result + return implicitCastOrExpression(value, typeRef) } private fun implicitCastOrExpression(original: IrExpression, castType: ConeKotlinType): IrExpression {