From 8b9e3789b46c6c977d0ede9e77fbaabf92236491 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 24 Aug 2023 11:58:31 +0300 Subject: [PATCH] [FIR2IR] Restrict `FirReference.toSymbolForCall` utility with `FirResolvedNamedReference` only Previously it handled `FirResolvedNamedReference` and `FirThisReceiverReference`, but the second one effectively was never passed to this function. It happened because `FirThisReceiverReference` is present only in `FirThisReceiverExpression`, which is processed separately in `Fir2IrVisitor.visitThisReceiverExpression`, and its implementation don't call `toSymbolForCall` --- .../kotlin/fir/backend/ConversionUtils.kt | 59 +++++++------------ .../generators/CallAndReferenceGenerator.kt | 12 ++-- 2 files changed, 25 insertions(+), 46 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 5e3ff75cd2e..db576ef3d66 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -16,13 +16,11 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.ValueClassRepresentation import org.jetbrains.kotlin.diagnostics.startOffsetSkippingComments import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.backend.unsubstitutedScope import org.jetbrains.kotlin.fir.builder.buildFileAnnotationsContainer import org.jetbrains.kotlin.fir.builder.buildPackageDirective import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildFile import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty -import org.jetbrains.kotlin.fir.declarations.utils.isAbstract import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.declarations.utils.isJava import org.jetbrains.kotlin.fir.declarations.utils.isStatic @@ -58,7 +56,6 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl -import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.StandardClassIds @@ -67,6 +64,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.OperatorNameConventions +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract fun AbstractKtSourceElement?.startOffsetSkippingComments(): Int? { return when (this) { @@ -186,49 +185,33 @@ private fun FirBasedSymbol<*>.toSymbolForCall( } context(Fir2IrComponents) +@OptIn(ExperimentalContracts::class) fun FirReference.toSymbolForCall( dispatchReceiver: FirExpression, - conversionScope: Fir2IrConversionScope, explicitReceiver: FirExpression?, preferGetter: Boolean = true, isDelegate: Boolean = false, isReference: Boolean = false, ): IrSymbol? { - return when (this) { - is FirResolvedNamedReference -> { - var symbol = resolvedSymbol - - if (symbol is FirCallableSymbol<*> && symbol.origin == FirDeclarationOrigin.SubstitutionOverride.CallSite) { - symbol = symbol.fir.unwrapUseSiteSubstitutionOverrides().symbol - } - - symbol.toSymbolForCall( - dispatchReceiver, - preferGetter, - explicitReceiver, - isDelegate, - isReference - ) - } - - is FirThisReference -> { - when (val boundSymbol = boundSymbol) { - is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol) - is FirFunctionSymbol -> { - val firClassSymbol = boundSymbol.receiverParameter?.typeRef?.coneType?.toRegularClassSymbol(session) - firClassSymbol?.let { classifierStorage.getIrClassSymbol(it) } - } - is FirPropertySymbol -> { - val propertySymbol = declarationStorage.getIrPropertySymbol(boundSymbol) as? IrPropertySymbol - propertySymbol?.let { conversionScope.parentAccessorOfPropertyFromStack(it).symbol } - } - is FirScriptSymbol -> declarationStorage.getCachedIrScript(boundSymbol.fir)?.thisReceiver?.symbol - else -> null - } - } - - else -> null + contract { + returnsNotNull() implies (this@toSymbolForCall is FirResolvedNamedReference) } + if (this !is FirResolvedNamedReference) { + return null + } + var symbol = resolvedSymbol + + if (symbol is FirCallableSymbol<*> && symbol.origin == FirDeclarationOrigin.SubstitutionOverride.CallSite) { + symbol = symbol.fir.unwrapUseSiteSubstitutionOverrides().symbol + } + + return symbol.toSymbolForCall( + dispatchReceiver, + preferGetter, + explicitReceiver, + isDelegate, + isReference + ) } private fun FirResolvedQualifier.toLookupTag(session: FirSession): ConeClassLikeLookupTag? = diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index b096ed1ba42..b11ba7951dd 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -84,7 +84,6 @@ class CallAndReferenceGenerator( val symbol = callableReferenceAccess.calleeReference.toSymbolForCall( callableReferenceAccess.dispatchReceiver, - conversionScope, explicitReceiver = callableReferenceAccess.explicitReceiver, isDelegate = isDelegate, isReference = true @@ -392,12 +391,6 @@ class CallAndReferenceGenerator( ) } - val symbol = calleeReference.toSymbolForCall( - dispatchReceiver, - conversionScope, - explicitReceiver = qualifiedAccess.explicitReceiver - ) - // We might have had a dynamic receiver, but resolved // into a non-fake member. For example, we can // resolve into members of `Any`. @@ -423,6 +416,10 @@ class CallAndReferenceGenerator( return@convertWithOffsets visitor.convertToIrExpression(dispatchReceiver) } } + val symbol = calleeReference.toSymbolForCall( + dispatchReceiver, + explicitReceiver = qualifiedAccess.explicitReceiver + ) when (symbol) { is IrConstructorSymbol -> IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, irType, symbol) is IrSimpleFunctionSymbol -> { @@ -600,7 +597,6 @@ class CallAndReferenceGenerator( val symbol = calleeReference.toSymbolForCall( variableAssignment.dispatchReceiver, - conversionScope, explicitReceiver = variableAssignment.explicitReceiver, preferGetter = false, )