[FIR IDE] Make KtSmartcastProvider report resolved smartcast type
This commit is contained in:
committed by
Ilya Kirillov
parent
d97a2b13c0
commit
58d903c638
+12
-16
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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<KtType>, val kind: ImplicitReceiverSmartcastKind)
|
||||
data class ImplicitReceiverSmartCast(val type: KtType, val kind: ImplicitReceiverSmartcastKind)
|
||||
|
||||
enum class ImplicitReceiverSmartcastKind {
|
||||
DISPATCH, EXTENSION
|
||||
|
||||
+3
-3
@@ -61,10 +61,10 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali
|
||||
fun KtCallableSymbol.getIntersectionOverriddenSymbols(): Collection<KtCallableSymbol> =
|
||||
symbolDeclarationOverridesProvider.getIntersectionOverriddenSymbols(this)
|
||||
|
||||
fun KtExpression.getSmartCasts(): Collection<KtType> = smartCastProvider.getSmartCastedToTypes(this)
|
||||
fun KtExpression.getSmartCast(): KtType? = smartCastProvider.getSmartCastedToType(this)
|
||||
|
||||
fun KtExpression.getImplicitReceiverSmartCasts(): Collection<ImplicitReceiverSmartCast> =
|
||||
smartCastProvider.getImplicitReceiverSmartCasts(this)
|
||||
fun KtExpression.getImplicitReceiverSmartCast(): Collection<ImplicitReceiverSmartCast> =
|
||||
smartCastProvider.getImplicitReceiverSmartCast(this)
|
||||
|
||||
fun KtExpression.getKtType(): KtType = expressionTypeProvider.getKtExpressionType(this)
|
||||
|
||||
|
||||
+2
-2
@@ -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<KtType>
|
||||
abstract fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection<ImplicitReceiverSmartCast>
|
||||
abstract fun getSmartCastedToType(expression: KtExpression): KtType?
|
||||
abstract fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast>
|
||||
}
|
||||
+10
-10
@@ -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<KtType> = withValidityAssertion {
|
||||
// TODO filter out not used smartcasts
|
||||
) : KtSmartCastProvider(), KtFirAnalysisSessionComponent {
|
||||
override fun getSmartCastedToType(expression: KtExpression): KtType? = withValidityAssertion {
|
||||
expression.getOrBuildFirSafe<FirExpressionWithSmartcast>(analysisSession.firResolveState)
|
||||
?.typesFromSmartCast
|
||||
?.map { it.asKtType() }
|
||||
?: emptyList()
|
||||
?.typeRef
|
||||
?.coneTypeSafe<ConeKotlinType>()
|
||||
?.asKtType()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
override fun getImplicitReceiverSmartCasts(expression: KtExpression): Collection<ImplicitReceiverSmartCast> = withValidityAssertion {
|
||||
// TODO filter out not used smartcasts
|
||||
override fun getImplicitReceiverSmartCast(expression: KtExpression): Collection<ImplicitReceiverSmartCast> = withValidityAssertion {
|
||||
val qualifiedExpression =
|
||||
expression.getOrBuildFirSafe<FirQualifiedAccessExpression>(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<ConeKotlinType>()?.asKtType() ?: return@let null,
|
||||
ImplicitReceiverSmartcastKind.DISPATCH
|
||||
)
|
||||
}?.let(::add)
|
||||
(qualifiedExpression.extensionReceiver as? FirExpressionWithSmartcast)?.let { smartCasted ->
|
||||
ImplicitReceiverSmartCast(
|
||||
smartCasted.typesFromSmartCast.map { it.asKtType() },
|
||||
smartCasted.typeRef.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return@let null,
|
||||
ImplicitReceiverSmartcastKind.EXTENSION
|
||||
)
|
||||
}?.let(::add)
|
||||
|
||||
Reference in New Issue
Block a user