[FIR] Replace FirExpression.typeRef.coneType (and variants) with FirExpression.coneType

#KT-59855
This commit is contained in:
Kirill Rakhman
2023-07-31 17:36:01 +02:00
committed by Space Team
parent 1472b21993
commit 9ec814b7ad
108 changed files with 289 additions and 299 deletions
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.fir.declarations.resolvePhase
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.unwrapAndFlattenArgument
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.types.coneTypeOrNull
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
@@ -50,7 +51,7 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirEx
checkWithAttachment(annotation.resolved, { "By now the annotations argument mapping should have been resolved" }) {
withFirEntry("annotation", annotation)
withClassEntry("annotationTypeRef", annotation.annotationTypeRef)
withClassEntry("typeRef", annotation.typeRef)
withClassEntry("coneTypeOrNull", annotation.coneTypeOrNull)
}
return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name }
@@ -215,4 +216,4 @@ internal fun hasAnnotation(
}
private fun FirBasedSymbol<*>.isFromCompilerRequiredAnnotationsPhase(classId: ClassId): Boolean =
fir.resolvePhase < FirResolvePhase.TYPES && classId in CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS
fir.resolvePhase < FirResolvePhase.TYPES && classId in CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS
@@ -413,7 +413,7 @@ internal class KtFirCallResolver(
}
// Specially handle @ExtensionFunctionType
if (dispatchReceiver.typeRef.coneTypeSafe<ConeKotlinType>()?.isExtensionFunctionType == true) {
if (dispatchReceiver.coneTypeSafe<ConeKotlinType>()?.isExtensionFunctionType == true) {
firstArgIsExtensionReceiver = true
}
@@ -421,7 +421,7 @@ internal class KtFirCallResolver(
val extensionReceiverValue: KtReceiverValue?
if (explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER) {
dispatchReceiverValue =
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.typeRef.coneType.asKtType(), false, token)
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.coneType.asKtType(), false, token)
if (firstArgIsExtensionReceiver) {
extensionReceiverValue = (fir as FirFunctionCall).arguments.firstOrNull()?.toKtReceiverValue()
} else {
@@ -430,7 +430,7 @@ internal class KtFirCallResolver(
} else {
dispatchReceiverValue = dispatchReceiver.toKtReceiverValue()
extensionReceiverValue =
KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.typeRef.coneType.asKtType(), false, token)
KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.coneType.asKtType(), false, token)
}
return KtPartiallyAppliedSymbol(
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
@@ -777,12 +777,12 @@ internal class KtFirCallResolver(
(calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol ?: return null
val substitutor = createConeSubstitutorFromTypeArguments() ?: return null
val dispatchReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == dispatchReceiver) {
explicitReceiverPsiSupplement.toExplicitReceiverValue(dispatchReceiver.typeRef.coneType.asKtType())
explicitReceiverPsiSupplement.toExplicitReceiverValue(dispatchReceiver.coneType.asKtType())
} else {
dispatchReceiver.toKtReceiverValue()
}
val extensionReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == extensionReceiver) {
explicitReceiverPsiSupplement.toExplicitReceiverValue(extensionReceiver.typeRef.coneType.asKtType())
explicitReceiverPsiSupplement.toExplicitReceiverValue(extensionReceiver.coneType.asKtType())
} else {
extensionReceiver.toKtReceiverValue()
}
@@ -811,12 +811,12 @@ internal class KtFirCallResolver(
?: return null
else -> return null
}
KtImplicitReceiverValue(implicitPartiallyAppliedSymbol, typeRef.coneType.asKtType())
KtImplicitReceiverValue(implicitPartiallyAppliedSymbol, coneType.asKtType())
}
else -> {
val psi = psi
if (psi !is KtExpression) return null
psi.toExplicitReceiverValue(typeRef.coneType.asKtType())
psi.toExplicitReceiverValue(coneType.asKtType())
}
}
}
@@ -875,7 +875,7 @@ internal class KtFirCallResolver(
private fun FirArrayLiteral.toTypeArgumentsMapping(
partiallyAppliedSymbol: KtPartiallyAppliedSymbol<*, *>
): Map<KtTypeParameterSymbol, KtType> {
val elementType = typeRef.coneTypeSafe<ConeClassLikeType>()?.arrayElementType()?.asKtType() ?: return emptyMap()
val elementType = coneTypeSafe<ConeClassLikeType>()?.arrayElementType()?.asKtType() ?: return emptyMap()
val typeParameter = partiallyAppliedSymbol.symbol.typeParameters.singleOrNull() ?: return emptyMap()
return mapOf(typeParameter to elementType)
}
@@ -1109,7 +1109,7 @@ internal class KtFirCallResolver(
private fun FirArrayLiteral.toKtCallInfo(): KtCallInfo? {
val arrayOfSymbol = with(analysisSession) {
val type = typeRef.coneTypeSafe<ConeClassLikeType>()
val type = coneTypeSafe<ConeClassLikeType>()
?: return run {
val defaultArrayOfSymbol = arrayOfSymbol(arrayOf) ?: return null
val substitutor = createSubstitutorFromTypeArguments(defaultArrayOfSymbol)
@@ -1154,7 +1154,7 @@ internal class KtFirCallResolver(
val firSymbol = arrayOfSymbol.firSymbol
// No type parameter means this is an arrayOf call of primitives, in which case there is no type arguments
val typeParameter = firSymbol.fir.typeParameters.singleOrNull() ?: return KtSubstitutor.Empty(token)
val elementType = typeRef.coneTypeSafe<ConeClassLikeType>()?.arrayElementType() ?: return KtSubstitutor.Empty(token)
val elementType = coneTypeSafe<ConeClassLikeType>()?.arrayElementType() ?: return KtSubstitutor.Empty(token)
val coneSubstitutor = substitutorByMap(mapOf(typeParameter.symbol to elementType), rootModuleSession)
return firSymbolBuilder.typeBuilder.buildSubstitutor(coneSubstitutor)
}
@@ -1169,7 +1169,7 @@ internal class KtFirCallResolver(
val equalsSymbolInAny = equalsSymbolInAny
val leftOperand = arguments.firstOrNull() ?: return null
val session = analysisSession.useSiteSession
val leftOperandType = leftOperand.typeRef.coneType
val leftOperandType = leftOperand.coneType
val classSymbol = leftOperandType.fullyExpandedType(session).toSymbol(session) as? FirClassSymbol<*>
val equalsSymbol = classSymbol?.getEqualsSymbol(equalsSymbolInAny) ?: equalsSymbolInAny
@@ -67,7 +67,7 @@ internal class KtFirExpressionTypeProvider(
}
private fun getKtExpressionType(expression: KtExpression, fir: FirElement): KtType? = when (fir) {
is FirFunctionCall -> getReturnTypeForArrayStyleAssignmentTarget(expression, fir) ?: fir.typeRef.coneType.asKtType()
is FirFunctionCall -> getReturnTypeForArrayStyleAssignmentTarget(expression, fir) ?: fir.coneType.asKtType()
is FirPropertyAccessExpression -> {
// For unresolved `super`, we manually create an intersection type so that IDE features like completion can work correctly.
val containingClass = (fir.dispatchReceiver as? FirThisReceiverExpression)?.calleeReference?.boundSymbol as? FirClassSymbol<*>
@@ -80,19 +80,19 @@ internal class KtFirExpressionTypeProvider(
else -> ConeIntersectionType(superTypes).asKtType()
}
} else {
fir.typeRef.coneType.asKtType()
fir.coneType.asKtType()
}
}
is FirVariableAssignment -> {
if (fir.lValue.source?.psi == expression) {
fir.lValue.typeRef.coneType.asKtType()
fir.lValue.coneType.asKtType()
} else if (expression is KtUnaryExpression && expression.operationToken in KtTokens.INCREMENT_AND_DECREMENT) {
fir.rValue.typeRef.coneType.asKtType()
fir.rValue.coneType.asKtType()
} else {
analysisSession.builtinTypes.UNIT
}
}
is FirExpression -> fir.typeRef.coneType.asKtType()
is FirExpression -> fir.coneType.asKtType()
is FirNamedReference -> fir.getCorrespondingTypeIfPossible()?.asKtType()
is FirStatement -> with(analysisSession) { builtinTypes.UNIT }
is FirTypeRef, is FirImport, is FirPackageDirective, is FirLabel, is FirTypeParameterRef -> null
@@ -123,7 +123,7 @@ internal class KtFirExpressionTypeProvider(
* of the whole expression instead, and that is not what he wants.
*/
private fun FirNamedReference.getCorrespondingTypeIfPossible(): ConeKotlinType? =
findOuterPropertyAccessExpression()?.typeRef?.coneType
findOuterPropertyAccessExpression()?.coneType
/**
* Finds an outer expression for [this] named reference in cases when it is a part of a property access.
@@ -427,7 +427,7 @@ internal class KtFirExpressionTypeProvider(
private fun getDefiniteNullability(expression: KtExpression): DefiniteNullability {
fun FirExpression.isNotNullable() = with(analysisSession.useSiteSession.typeContext) {
!typeRef.coneType.isNullableType()
!coneType.isNullableType()
}
when (val fir = expression.getOrBuildFir(analysisSession.firResolveSession)) {
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerC
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildImport
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
@@ -326,8 +325,8 @@ private class FirShorteningContext(val analysisSession: KtFirAnalysisSession) {
}
}
fun getRegularClass(typeRef: FirTypeRef): FirRegularClass? {
return typeRef.toRegularClassSymbol(firSession)?.fir
fun getRegularClass(type: ConeKotlinType?): FirRegularClass? {
return type?.toRegularClassSymbol(firSession)?.fir
}
fun toClassSymbol(classId: ClassId) =
@@ -1314,4 +1313,4 @@ private fun KtElement.getQualifier(): KtElement? = when (this) {
is KtUserType -> qualifier
is KtDotQualifiedExpression -> receiverExpression
else -> null
}
}
@@ -105,7 +105,7 @@ internal class KtFirSmartcastProvider(
if (receiver == firExpression.explicitReceiver) return null
if (!receiver.isStableSmartcast()) return null
val type = receiver.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return null
val type = receiver.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return null
return KtImplicitReceiverSmartCast(type, kind, token)
}
}
@@ -172,9 +172,9 @@ internal class KtFirTypeProvider(
override fun getReceiverTypeForDoubleColonExpression(expression: KtDoubleColonExpression): KtType? {
return when (val fir = expression.getOrBuildFir(firResolveSession)) {
is FirGetClassCall ->
fir.typeRef.coneType.getReceiverOfReflectionType()?.asKtType()
fir.coneType.getReceiverOfReflectionType()?.asKtType()
is FirCallableReferenceAccess ->
fir.typeRef.coneType.getReceiverOfReflectionType()?.asKtType()
fir.coneType.getReceiverOfReflectionType()?.asKtType()
else -> throwUnexpectedFirElementError(fir, expression)
}
}
@@ -45,7 +45,7 @@ internal object FirAnnotationValueConverter {
private fun <T> FirConstExpression<T>.convertConstantExpression(): KtConstantAnnotationValue? {
val expression = psi as? KtElement
val type = (typeRef as? FirResolvedTypeRef)?.type
val type = coneTypeOrNull
val constantValue = when {
value == null -> KtConstantValue.KtNullConstantValue(expression)
type == null -> KtConstantValueFactory.createConstantValue(value, psi as? KtElement)
@@ -179,7 +179,7 @@ internal object FirAnnotationValueConverter {
val qualifierParts = mutableListOf<String?>()
fun process(expression: FirExpression) {
val errorType = expression.typeRef.coneType as? ConeErrorType
val errorType = expression.coneType as? ConeErrorType
val unresolvedName = when (val diagnostic = errorType?.diagnostic) {
is ConeUnresolvedTypeQualifierError -> diagnostic.qualifier
is ConeUnresolvedNameError -> diagnostic.qualifier
@@ -178,19 +178,19 @@ internal object FirCompileTimeConstantEvaluator {
val opr1 = evaluate(functionCall.explicitReceiver, mode) ?: return null
opr1.evaluate(function)?.let {
return it.adjustType(functionCall.typeRef)
return it.adjustType(functionCall.type)
}
val argument = functionCall.arguments.firstOrNull() ?: return null
val opr2 = evaluate(argument, mode) ?: return null
opr1.evaluate(function, opr2)?.let {
return it.adjustType(functionCall.typeRef)
return it.adjustType(functionCall.type)
}
return null
}
private fun FirConstExpression<*>.adjustType(expectedType: FirTypeRef): FirConstExpression<*> {
val expectedKind = expectedType.toConstantValueKind()
private fun FirConstExpression<*>.adjustType(expectedType: ConeKotlinType?): FirConstExpression<*> {
val expectedKind = expectedType?.toConstantValueKind()
// Note that the resolved type for the const expression is not always matched with the const kind. For example,
// fun foo(x: Int) {
// when (x) {
@@ -207,7 +207,7 @@ internal object FirCompileTimeConstantEvaluator {
}
// Lastly, we should preserve the resolved type of the original function call.
return expression.apply {
replaceTypeRef(expectedType)
replaceType(expectedType)
}
}
@@ -304,25 +304,6 @@ internal object FirCompileTimeConstantEvaluator {
////// KINDS
private fun FirTypeRef.toConstantValueKind(): ConstantValueKind<*>? =
when (this) {
!is FirResolvedTypeRef -> null
!is FirImplicitBuiltinTypeRef -> type.toConstantValueKind()
is FirImplicitByteTypeRef -> ConstantValueKind.Byte
is FirImplicitDoubleTypeRef -> ConstantValueKind.Double
is FirImplicitFloatTypeRef -> ConstantValueKind.Float
is FirImplicitIntTypeRef -> ConstantValueKind.Int
is FirImplicitLongTypeRef -> ConstantValueKind.Long
is FirImplicitShortTypeRef -> ConstantValueKind.Short
is FirImplicitCharTypeRef -> ConstantValueKind.Char
is FirImplicitStringTypeRef -> ConstantValueKind.String
is FirImplicitBooleanTypeRef -> ConstantValueKind.Boolean
else -> null
}
private fun ConeKotlinType.toConstantValueKind(): ConstantValueKind<*>? =
when (this) {
is ConeErrorType -> null
@@ -58,12 +58,20 @@ import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
internal object FirReferenceResolveHelper {
fun FirResolvedTypeRef.toTargetSymbol(session: FirSession, symbolBuilder: KtSymbolByFirBuilder): KtSymbol? {
val type = getDeclaredType() as? ConeLookupTagBasedType
return type?.toTargetSymbol(session, symbolBuilder) ?: run {
val diagnostic = (this as? FirErrorTypeRef)?.diagnostic
(diagnostic as? ConeUnmatchedTypeArgumentsError)?.symbol?.fir?.buildSymbol(symbolBuilder)
}
}
private fun ConeKotlinType.toTargetSymbol(session: FirSession, symbolBuilder: KtSymbolByFirBuilder): KtSymbol? {
val type = this as? ConeLookupTagBasedType
val resolvedSymbol = type?.lookupTag?.toSymbol(session) as? FirBasedSymbol<*>
val symbol = resolvedSymbol ?: run {
val diagnostic = (this as? FirErrorTypeRef)?.diagnostic
val diagnostic = (this as? ConeErrorType)?.diagnostic
(diagnostic as? ConeUnmatchedTypeArgumentsError)?.symbol
}
@@ -253,7 +261,7 @@ internal object FirReferenceResolveHelper {
symbolBuilder: KtSymbolByFirBuilder
): Collection<KtSymbol> {
val lhs = expression.arguments.firstOrNull() ?: return emptyList()
val scope = lhs.typeRef.coneType.scope(
val scope = lhs.coneType.scope(
session,
analysisSession.getScopeSessionFor(analysisSession.useSiteSession),
FakeOverrideTypeCalculator.DoNothing,
@@ -414,7 +422,7 @@ internal object FirReferenceResolveHelper {
// accessing the `super` property on `this`, hence this weird looking if condition. In addition, the current class type is available
// from the dispatch receiver `this`.
if (expression is KtLabelReferenceExpression && fir is FirPropertyAccessExpression && fir.calleeReference is FirSuperReference) {
return listOfNotNull((fir.dispatchReceiver.typeRef as? FirResolvedTypeRef)?.toTargetSymbol(session, symbolBuilder))
return listOfNotNull(fir.dispatchReceiver.type?.toTargetSymbol(session, symbolBuilder))
}
val receiverOrImplicitInvoke = if (fir is FirImplicitInvokeCall) {
fir.explicitReceiver?.unwrapSmartcastExpression()
@@ -725,7 +733,7 @@ internal object FirReferenceResolveHelper {
session: FirSession,
symbolBuilder: KtSymbolByFirBuilder
): Collection<KtSymbol> {
val type = fir.typeRef as? FirResolvedTypeRef ?: return emptyList()
val type = fir.type ?: return emptyList()
return listOfNotNull(type.toTargetSymbol(session, symbolBuilder))
}
@@ -24,7 +24,7 @@ class KtFirCollectionLiteralReference(
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
check(this is KtFirAnalysisSession)
val fir = element.getOrBuildFirSafe<FirArrayLiteral>(firResolveSession) ?: return emptyList()
val type = fir.typeRef.coneTypeSafe<ConeClassLikeType>() ?: return listOfNotNull(arrayOfSymbol(arrayOf))
val type = fir.coneTypeSafe<ConeClassLikeType>() ?: return listOfNotNull(arrayOfSymbol(arrayOf))
val call = arrayTypeToArrayOfCall[type.lookupTag.classId] ?: arrayOf
return listOfNotNull(arrayOfSymbol(call))
}