[FIR2IR] Cleanup and reuse utility for creating substitutor from call
This commit is contained in:
committed by
Space Team
parent
5f5daa0e06
commit
aa1a997f8a
@@ -33,6 +33,8 @@ import org.jetbrains.kotlin.fir.resolve.*
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
|
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.originalConstructorIfTypeAlias
|
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)
|
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<FirTypeParameterSymbol, ConeKotlinType>()
|
||||||
|
for ((index, typeParameter) in typeParameters.withIndex()) {
|
||||||
|
val typeProjection = typeArguments.getOrNull(index) as? FirTypeProjectionWithVariance ?: continue
|
||||||
|
map[typeParameter.symbol] = typeProjection.typeRef.coneType
|
||||||
|
}
|
||||||
|
return ConeSubstitutorByMap(map, session)
|
||||||
|
}
|
||||||
|
|||||||
+1
-15
@@ -313,7 +313,7 @@ class Fir2IrImplicitCastInserter(
|
|||||||
}
|
}
|
||||||
receiver === extensionReceiver -> {
|
receiver === extensionReceiver -> {
|
||||||
val extensionReceiverType = referencedDeclaration?.receiverParameter?.typeRef?.coneType ?: return null
|
val extensionReceiverType = referencedDeclaration?.receiverParameter?.typeRef?.coneType ?: return null
|
||||||
val substitutor = createSubstitutorFromTypeArguments(selector, referencedDeclaration)
|
val substitutor = selector.buildSubstitutorByCalledCallable()
|
||||||
val substitutedType = substitutor.substituteOrSelf(extensionReceiverType)
|
val substitutedType = substitutor.substituteOrSelf(extensionReceiverType)
|
||||||
// Frontend may write captured types as type arguments (by design), so we need to approximate receiver type after substitution
|
// Frontend may write captured types as type arguments (by design), so we need to approximate receiver type after substitution
|
||||||
val approximatedType = session.typeApproximator.approximateToSuperType(
|
val approximatedType = session.typeApproximator.approximateToSuperType(
|
||||||
@@ -334,20 +334,6 @@ class Fir2IrImplicitCastInserter(
|
|||||||
return null
|
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(
|
private fun implicitCastOrExpression(
|
||||||
original: IrExpression, castType: ConeKotlinType, typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT
|
original: IrExpression, castType: ConeKotlinType, typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
|
|||||||
+1
-12
@@ -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.FirSyntheticFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType
|
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
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.resolve.transformers.body.resolve.approximateDeclarationType
|
||||||
import org.jetbrains.kotlin.fir.scopes.getDeclaredConstructors
|
import org.jetbrains.kotlin.fir.scopes.getDeclaredConstructors
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.originalConstructorIfTypeAlias
|
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<FirTypeParameterSymbol, ConeKotlinType>()
|
|
||||||
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(
|
private fun extractArgumentsMapping(
|
||||||
call: FirCall,
|
call: FirCall,
|
||||||
): Triple<List<FirValueParameter>?, Map<FirExpression, FirValueParameter>?, ConeSubstitutor> {
|
): Triple<List<FirValueParameter>?, Map<FirExpression, FirValueParameter>?, ConeSubstitutor> {
|
||||||
@@ -861,7 +850,7 @@ class CallAndReferenceGenerator(
|
|||||||
val function = ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
val function = ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
||||||
val valueParameters = function?.valueParameters
|
val valueParameters = function?.valueParameters
|
||||||
val argumentMapping = call.resolvedArgumentMapping
|
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)
|
return Triple(valueParameters, argumentMapping, substitutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user