FIR IDE: ignore smartcast if it's unstable in HL API

This commit is contained in:
Tianyu Geng
2021-06-09 18:21:23 -07:00
committed by TeamCityServer
parent 78401b3ae0
commit baa3a3c81d
@@ -10,11 +10,13 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe
import org.jetbrains.kotlin.idea.frontend.api.* import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartCast
import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind
import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider import org.jetbrains.kotlin.idea.frontend.api.components.KtSmartCastProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
internal class KtFirSmartcastProvider( internal class KtFirSmartcastProvider(
@@ -23,6 +25,7 @@ internal class KtFirSmartcastProvider(
) : KtSmartCastProvider(), KtFirAnalysisSessionComponent { ) : KtSmartCastProvider(), KtFirAnalysisSessionComponent {
override fun getSmartCastedToType(expression: KtExpression): KtType? = withValidityAssertion { override fun getSmartCastedToType(expression: KtExpression): KtType? = withValidityAssertion {
expression.getOrBuildFirSafe<FirExpressionWithSmartcast>(analysisSession.firResolveState) expression.getOrBuildFirSafe<FirExpressionWithSmartcast>(analysisSession.firResolveState)
?.takeIf { it.isStable }
?.typeRef ?.typeRef
?.coneTypeSafe<ConeKotlinType>() ?.coneTypeSafe<ConeKotlinType>()
?.asKtType() ?.asKtType()
@@ -32,17 +35,19 @@ internal class KtFirSmartcastProvider(
override fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast> = withValidityAssertion { override fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast> = withValidityAssertion {
val qualifiedExpression = val qualifiedExpression =
expression.getOrBuildFirSafe<FirQualifiedAccessExpression>(analysisSession.firResolveState) ?: return emptyList() expression.getOrBuildFirSafe<FirQualifiedAccessExpression>(analysisSession.firResolveState) ?: return emptyList()
if (qualifiedExpression.dispatchReceiver !is FirExpressionWithSmartcast val dispatchReceiver = qualifiedExpression.dispatchReceiver
&& qualifiedExpression.extensionReceiver !is FirExpressionWithSmartcast val extensionReceiver = qualifiedExpression.extensionReceiver
if ((dispatchReceiver !is FirExpressionWithSmartcast || !dispatchReceiver.isStable) &&
(extensionReceiver !is FirExpressionWithSmartcast || !extensionReceiver.isStable)
) return emptyList() ) return emptyList()
buildList { buildList {
(qualifiedExpression.dispatchReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> (dispatchReceiver as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.let { smartCasted ->
ImplicitReceiverSmartCast( ImplicitReceiverSmartCast(
smartCasted.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return@let null, smartCasted.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return@let null,
ImplicitReceiverSmartcastKind.DISPATCH ImplicitReceiverSmartcastKind.DISPATCH
) )
}?.let(::add) }?.let(::add)
(qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> (extensionReceiver as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.let { smartCasted ->
ImplicitReceiverSmartCast( ImplicitReceiverSmartCast(
smartCasted.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return@let null, smartCasted.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return@let null,
ImplicitReceiverSmartcastKind.EXTENSION ImplicitReceiverSmartcastKind.EXTENSION