From 58d903c63869029a4181cbad922a2a2fbb4c0072 Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Thu, 4 Feb 2021 11:59:23 -0800 Subject: [PATCH] [FIR IDE] Make KtSmartcastProvider report resolved smartcast type --- ...ExpressionsSmartcastHighlightingVisitor.kt | 28 ++++++++----------- .../frontend/api/ImplicitReceiverSmartCast.kt | 2 +- .../idea/frontend/api/KtAnalysisSession.kt | 6 ++-- .../api/components/KtSmartCastProvider.kt | 4 +-- .../fir/components/KtFirSmartcastProvider.kt | 20 ++++++------- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt index eb8c0166d41..26b8020cd11 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/ExpressionsSmartcastHighlightingVisitor.kt @@ -8,8 +8,8 @@ package org.jetbrains.kotlin.idea.fir.highlighter.visitors import com.intellij.lang.annotation.AnnotationHolder import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.KotlinIdeaAnalysisBundle -import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors import org.jetbrains.kotlin.psi.* @@ -18,25 +18,23 @@ internal class ExpressionsSmartcastHighlightingVisitor( holder: AnnotationHolder ) : FirAfterResolveHighlightingVisitor(analysisSession, holder) { override fun visitExpression(expression: KtExpression) = with(analysisSession) { - expression.getImplicitReceiverSmartCasts().forEach { (types, kind) -> + expression.getImplicitReceiverSmartCast().forEach { (type, kind) -> val receiverName = when (kind) { ImplicitReceiverSmartcastKind.EXTENSION -> KotlinIdeaAnalysisBundle.message("extension.implicit.receiver") ImplicitReceiverSmartcastKind.DISPATCH -> KotlinIdeaAnalysisBundle.message("implicit.receiver") } - types.forEach { type -> - createInfoAnnotation( - expression, - KotlinIdeaAnalysisBundle.message( - "0.smart.cast.to.1", - receiverName, - type.asStringForDebugging() - ), - KotlinHighlightingColors.SMART_CAST_RECEIVER - ) - } + createInfoAnnotation( + expression, + KotlinIdeaAnalysisBundle.message( + "0.smart.cast.to.1", + receiverName, + type.asStringForDebugging() + ), + KotlinHighlightingColors.SMART_CAST_RECEIVER + ) } - expression.getSmartCasts()?.forEach { type -> + expression.getSmartCast()?.let { type -> createInfoAnnotation( getSmartCastTarget(expression), KotlinIdeaAnalysisBundle.message( @@ -47,8 +45,6 @@ internal class ExpressionsSmartcastHighlightingVisitor( ) } - //todo smartcast to null - super.visitExpression(expression) } } diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt index 5e63a8a034b..09de7bbdb92 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/ImplicitReceiverSmartCast.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api import org.jetbrains.kotlin.idea.frontend.api.types.KtType -data class ImplicitReceiverSmartCast(val types: Collection, val kind: ImplicitReceiverSmartcastKind) +data class ImplicitReceiverSmartCast(val type: KtType, val kind: ImplicitReceiverSmartcastKind) enum class ImplicitReceiverSmartcastKind { DISPATCH, EXTENSION diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt index a768ed8d6d5..f06355cd03a 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt @@ -61,10 +61,10 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali fun KtCallableSymbol.getIntersectionOverriddenSymbols(): Collection = symbolDeclarationOverridesProvider.getIntersectionOverriddenSymbols(this) - fun KtExpression.getSmartCasts(): Collection = smartCastProvider.getSmartCastedToTypes(this) + fun KtExpression.getSmartCast(): KtType? = smartCastProvider.getSmartCastedToType(this) - fun KtExpression.getImplicitReceiverSmartCasts(): Collection = - smartCastProvider.getImplicitReceiverSmartCasts(this) + fun KtExpression.getImplicitReceiverSmartCast(): Collection = + smartCastProvider.getImplicitReceiverSmartCast(this) fun KtExpression.getKtType(): KtType = expressionTypeProvider.getKtExpressionType(this) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSmartCastProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSmartCastProvider.kt index 1c80a97dcb8..415804c1af2 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSmartCastProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtSmartCastProvider.kt @@ -10,6 +10,6 @@ import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.psi.KtExpression abstract class KtSmartCastProvider : KtAnalysisSessionComponent() { - abstract fun getSmartCastedToTypes(expression: KtExpression): Collection - abstract fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection + abstract fun getSmartCastedToType(expression: KtExpression): KtType? + abstract fun getImplicitReceiverSmartCast(expression: KtExpression): Collection } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt index 7e6bb935144..25dc4adc57f 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSmartcastProvider.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast 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.ImplicitReceiverSmartCast import org.jetbrains.kotlin.idea.frontend.api.ImplicitReceiverSmartcastKind @@ -20,18 +22,16 @@ import org.jetbrains.kotlin.psi.KtExpression internal class KtFirSmartcastProvider( override val analysisSession: KtFirAnalysisSession, override val token: ValidityToken, - ) : KtSmartCastProvider(), KtFirAnalysisSessionComponent { - override fun getSmartCastedToTypes(expression: KtExpression): Collection = withValidityAssertion { - // TODO filter out not used smartcasts +) : KtSmartCastProvider(), KtFirAnalysisSessionComponent { + override fun getSmartCastedToType(expression: KtExpression): KtType? = withValidityAssertion { expression.getOrBuildFirSafe(analysisSession.firResolveState) - ?.typesFromSmartCast - ?.map { it.asKtType() } - ?: emptyList() + ?.typeRef + ?.coneTypeSafe() + ?.asKtType() } @OptIn(ExperimentalStdlibApi::class) - override fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection = withValidityAssertion { - // TODO filter out not used smartcasts + override fun getImplicitReceiverSmartCast(expression: KtExpression): Collection = withValidityAssertion { val qualifiedExpression = expression.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() if (qualifiedExpression.dispatchReceiver !is FirExpressionWithSmartcast @@ -40,13 +40,13 @@ internal class KtFirSmartcastProvider( buildList { (qualifiedExpression.dispatchReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> ImplicitReceiverSmartCast( - smartCasted.typesFromSmartCast.map { it.asKtType() }, + smartCasted.typeRef.coneTypeSafe()?.asKtType() ?: return@let null, ImplicitReceiverSmartcastKind.DISPATCH ) }?.let(::add) (qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted -> ImplicitReceiverSmartCast( - smartCasted.typesFromSmartCast.map { it.asKtType() }, + smartCasted.typeRef.coneTypeSafe()?.asKtType() ?: return@let null, ImplicitReceiverSmartcastKind.EXTENSION ) }?.let(::add)