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.coneTypeSafe
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.fir.KtFirAnalysisSession
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.withValidityAssertion
import org.jetbrains.kotlin.psi.KtExpression
internal class KtFirSmartcastProvider(
@@ -23,6 +25,7 @@ internal class KtFirSmartcastProvider(
) : KtSmartCastProvider(), KtFirAnalysisSessionComponent {
override fun getSmartCastedToType(expression: KtExpression): KtType? = withValidityAssertion {
expression.getOrBuildFirSafe<FirExpressionWithSmartcast>(analysisSession.firResolveState)
?.takeIf { it.isStable }
?.typeRef
?.coneTypeSafe<ConeKotlinType>()
?.asKtType()
@@ -32,17 +35,19 @@ internal class KtFirSmartcastProvider(
override fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast> = withValidityAssertion {
val qualifiedExpression =
expression.getOrBuildFirSafe<FirQualifiedAccessExpression>(analysisSession.firResolveState) ?: return emptyList()
if (qualifiedExpression.dispatchReceiver !is FirExpressionWithSmartcast
&& qualifiedExpression.extensionReceiver !is FirExpressionWithSmartcast
val dispatchReceiver = qualifiedExpression.dispatchReceiver
val extensionReceiver = qualifiedExpression.extensionReceiver
if ((dispatchReceiver !is FirExpressionWithSmartcast || !dispatchReceiver.isStable) &&
(extensionReceiver !is FirExpressionWithSmartcast || !extensionReceiver.isStable)
) return emptyList()
buildList {
(qualifiedExpression.dispatchReceiver as? FirExpressionWithSmartcast)?.let { smartCasted ->
(dispatchReceiver as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.let { smartCasted ->
ImplicitReceiverSmartCast(
smartCasted.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return@let null,
ImplicitReceiverSmartcastKind.DISPATCH
)
}?.let(::add)
(qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted ->
(extensionReceiver as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.let { smartCasted ->
ImplicitReceiverSmartCast(
smartCasted.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return@let null,
ImplicitReceiverSmartcastKind.EXTENSION