FIR IDE: always approximate non-denotable types for creating PsiType

This commit is contained in:
Ilya Kirillov
2021-10-28 15:11:33 +02:00
parent bec9cec31c
commit da88ddfc71
4 changed files with 32 additions and 21 deletions
@@ -73,26 +73,34 @@ private fun ConeKotlinType.simplifyType(
currentType = currentType.fullyExpandedType(session)
currentType = currentType.upperBoundIfFlexible()
currentType = substitutor.substituteOrSelf(currentType)
if (shouldHideLocalType(visibilityForApproximation, isInlineFunction)) {
val localTypes: List<ConeKotlinType> = if (isLocal(session)) listOf(this) else {
typeArguments.mapNotNull {
if (it is ConeKotlinTypeProjection && it.type.isLocal(session)) {
it.type
} else null
}
}
val unavailableLocalTypes = localTypes.filterNot { it.isLocalButAvailableAtPosition(session, useSitePosition) }
// Need to approximate if there are local types that are not available in this scope
val needsApproximation = localTypes.isNotEmpty() && unavailableLocalTypes.isNotEmpty()
if (needsApproximation) {
// TODO: can we approximate local types in type arguments *selectively* ?
currentType = PublicTypeApproximator.approximateTypeToPublicDenotable(currentType, session) ?: currentType
}
}
val needLocalTypeApproximation = needLocalTypeApproximation(visibilityForApproximation, isInlineFunction, session, useSitePosition)
// TODO: can we approximate local types in type arguments *selectively* ?
currentType = PublicTypeApproximator.approximateTypeToPublicDenotable(currentType, session, needLocalTypeApproximation)
?: currentType
} while (oldType !== currentType)
return currentType
}
private fun ConeKotlinType.needLocalTypeApproximation(
visibilityForApproximation: Visibility,
isInlineFunction: Boolean,
session: FirSession,
useSitePosition: PsiElement
): Boolean {
if (!shouldHideLocalType(visibilityForApproximation, isInlineFunction)) return false
val localTypes: List<ConeKotlinType> = if (isLocal(session)) listOf(this) else {
typeArguments.mapNotNull {
if (it is ConeKotlinTypeProjection && it.type.isLocal(session)) {
it.type
} else null
}
}
val unavailableLocalTypes = localTypes.filterNot { it.isLocalButAvailableAtPosition(session, useSitePosition) }
// Need to approximate if there are local types that are not available in this scope
return localTypes.isNotEmpty() && unavailableLocalTypes.isNotEmpty()
}
// Mimic FirDeclaration.visibilityForApproximation
private val PsiElement.visibilityForApproximation: Visibility
get() {
@@ -59,7 +59,8 @@ internal class KtFirTypeProvider(
val coneType = type.coneType
val approximatedConeType = PublicTypeApproximator.approximateTypeToPublicDenotable(
coneType,
rootModuleSession
rootModuleSession,
approximateLocalTypes = true,
)
return approximatedConeType?.asKtType()
@@ -50,7 +50,7 @@ internal class FirIdeRenderer private constructor(
require(firRef is FirResolvedTypeRef)
val approximatedIfNeeded = approximate.ifTrue {
PublicTypeApproximator.approximateTypeToPublicDenotable(firRef.coneType, session)
PublicTypeApproximator.approximateTypeToPublicDenotable(firRef.coneType, session, approximateLocalTypes = true)
} ?: firRef.coneType
val annotations = if (RendererModifier.ANNOTATIONS in options.modifiers) {
firRef.annotations
@@ -14,17 +14,19 @@ internal object PublicTypeApproximator {
fun approximateTypeToPublicDenotable(
type: ConeKotlinType,
session: FirSession,
approximateLocalTypes: Boolean
): ConeKotlinType? {
val approximator = session.typeApproximator
return approximator.approximateToSuperType(type, PublicApproximatorConfiguration)
return approximator.approximateToSuperType(type, PublicApproximatorConfiguration(approximateLocalTypes))
}
private object PublicApproximatorConfiguration : TypeApproximatorConfiguration.AllFlexibleSameValue() {
private class PublicApproximatorConfiguration(
override val localTypes: Boolean
) : TypeApproximatorConfiguration.AllFlexibleSameValue() {
override val allFlexible: Boolean get() = false
override val errorType: Boolean get() = true
override val definitelyNotNullType: Boolean get() = false
override val integerLiteralType: Boolean get() = true
override val intersectionTypesInContravariantPositions: Boolean get() = true
override val localTypes: Boolean get() = true
}
}