From aa1a997f8a58e14696aa7c1f6433331771b6676b Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 9 Nov 2023 10:50:34 +0200 Subject: [PATCH] [FIR2IR] Cleanup and reuse utility for creating substitutor from call --- .../kotlin/fir/backend/ConversionUtils.kt | 17 +++++++++++++++++ .../fir/backend/Fir2IrImplicitCastInserter.kt | 16 +--------------- .../generators/CallAndReferenceGenerator.kt | 13 +------------ 3 files changed, 19 insertions(+), 27 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 4d7ef9bf8b6..df5b2b54b71 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 @@ -33,6 +33,8 @@ import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope import org.jetbrains.kotlin.fir.scopes.impl.originalConstructorIfTypeAlias @@ -857,3 +859,18 @@ internal fun implicitCast(original: IrExpression, castType: IrType, typeOperator } return implicitCast(original.argument, castType, typeOperator) } + +context(Fir2IrComponents) +internal fun FirQualifiedAccessExpression.buildSubstitutorByCalledCallable(): ConeSubstitutor { + val typeParameters = when (val declaration = calleeReference.toResolvedCallableSymbol()?.fir) { + is FirFunction -> declaration.typeParameters + is FirProperty -> declaration.typeParameters + else -> return ConeSubstitutor.Empty + } + val map = mutableMapOf() + for ((index, typeParameter) in typeParameters.withIndex()) { + val typeProjection = typeArguments.getOrNull(index) as? FirTypeProjectionWithVariance ?: continue + map[typeParameter.symbol] = typeProjection.typeRef.coneType + } + return ConeSubstitutorByMap(map, session) +} 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 72aa85e274f..49d77bc4450 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 @@ -313,7 +313,7 @@ class Fir2IrImplicitCastInserter( } receiver === extensionReceiver -> { val extensionReceiverType = referencedDeclaration?.receiverParameter?.typeRef?.coneType ?: return null - val substitutor = createSubstitutorFromTypeArguments(selector, referencedDeclaration) + val substitutor = selector.buildSubstitutorByCalledCallable() val substitutedType = substitutor.substituteOrSelf(extensionReceiverType) // Frontend may write captured types as type arguments (by design), so we need to approximate receiver type after substitution val approximatedType = session.typeApproximator.approximateToSuperType( @@ -334,20 +334,6 @@ class Fir2IrImplicitCastInserter( return null } - private fun createSubstitutorFromTypeArguments( - qualifiedAccessExpression: FirQualifiedAccessExpression, - callableDeclaration: FirCallableDeclaration, - ): ConeSubstitutor { - if (qualifiedAccessExpression.typeArguments.isEmpty() || callableDeclaration.typeParameters.isEmpty()) return ConeSubstitutor.Empty - val map = buildMap { - for ((parameter, argument) in callableDeclaration.typeParameters.zip(qualifiedAccessExpression.typeArguments)) { - val argumentType = argument.toConeTypeProjection().type ?: continue - put(parameter.symbol, argumentType) - } - } - return ConeSubstitutorByMap(map, session) - } - private fun implicitCastOrExpression( original: IrExpression, castType: ConeKotlinType, typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT ): IrExpression { 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 ca93bf23d1f..76ffd81649c 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 @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.approximateDeclarationType import org.jetbrains.kotlin.fir.scopes.getDeclaredConstructors import org.jetbrains.kotlin.fir.scopes.impl.originalConstructorIfTypeAlias @@ -839,16 +838,6 @@ class CallAndReferenceGenerator( } } - private fun FirFunctionCall.buildSubstitutorByCalledFunction(function: FirFunction?): ConeSubstitutor? { - if (function == null) return null - val map = mutableMapOf() - for ((index, typeParameter) in function.typeParameters.withIndex()) { - val typeProjection = typeArguments.getOrNull(index) as? FirTypeProjectionWithVariance ?: continue - map[typeParameter.symbol] = typeProjection.typeRef.coneType - } - return ConeSubstitutorByMap(map, session) - } - private fun extractArgumentsMapping( call: FirCall, ): Triple?, Map?, ConeSubstitutor> { @@ -861,7 +850,7 @@ class CallAndReferenceGenerator( val function = ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir val valueParameters = function?.valueParameters val argumentMapping = call.resolvedArgumentMapping - val substitutor = (call as? FirFunctionCall)?.buildSubstitutorByCalledFunction(function) ?: ConeSubstitutor.Empty + val substitutor = (call as? FirFunctionCall)?.buildSubstitutorByCalledCallable() ?: ConeSubstitutor.Empty return Triple(valueParameters, argumentMapping, substitutor) }