FIR: add helper to check if a smartcast expressioin is stable
This commit is contained in:
committed by
TeamCityServer
parent
3c8693758b
commit
78401b3ae0
+1
-1
@@ -271,7 +271,7 @@ class Fir2IrImplicitCastInserter(
|
||||
}
|
||||
|
||||
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: IrElement): IrExpression {
|
||||
return if (expressionWithSmartcast.smartcastStability == SmartcastStability.STABLE_VALUE) {
|
||||
return if (expressionWithSmartcast.isStable) {
|
||||
implicitCastOrExpression(data as IrExpression, expressionWithSmartcast.typeRef)
|
||||
} else {
|
||||
data as IrExpression
|
||||
|
||||
@@ -35,7 +35,7 @@ fun FirExpressionWithSmartcast.smartcastScope(
|
||||
): FirTypeScope? {
|
||||
val smartcastType = smartcastType.coneType
|
||||
val smartcastScope = smartcastType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
if (smartcastStability == SmartcastStability.STABLE_VALUE) {
|
||||
if (isStable) {
|
||||
return smartcastScope
|
||||
}
|
||||
val originalScope = originalType.coneType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ abstract class FirExpressionWithSmartcast : FirQualifiedAccessExpression() {
|
||||
abstract val typesFromSmartCast: Collection<ConeKotlinType>
|
||||
abstract val originalType: FirTypeRef
|
||||
abstract val smartcastType: FirTypeRef
|
||||
abstract val isStable: Boolean
|
||||
abstract val smartcastStability: SmartcastStability
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitExpressionWithSmartcast(this, data)
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ abstract class FirExpressionWithSmartcastToNull : FirExpressionWithSmartcast() {
|
||||
abstract override val explicitReceiver: FirExpression?
|
||||
abstract override val dispatchReceiver: FirExpression
|
||||
abstract override val extensionReceiver: FirExpression
|
||||
abstract override val isStable: Boolean
|
||||
abstract override val originalExpression: FirQualifiedAccessExpression
|
||||
abstract override val typesFromSmartCast: Collection<ConeKotlinType>
|
||||
abstract override val originalType: FirTypeRef
|
||||
|
||||
+3
-1
@@ -39,10 +39,12 @@ internal class FirExpressionWithSmartcastImpl(
|
||||
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
||||
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
||||
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
||||
override val isStable: Boolean get() = smartcastStability == SmartcastStability.STABLE_VALUE
|
||||
|
||||
// A FirExpressionWithSmartcast is only an effective smartcast if `smartcastStability == SmartcastStability.STABLE_VALUE`. Otherwise,
|
||||
// it's the same as the `originalExpression` under the hood. The reason we still create such a smartcast expression is for diagnostics
|
||||
// purpose only.
|
||||
override val typeRef: FirTypeRef get() = if (smartcastStability == SmartcastStability.STABLE_VALUE) smartcastType else originalType
|
||||
override val typeRef: FirTypeRef get() = if (isStable) smartcastType else originalType
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcast {
|
||||
originalExpression = originalExpression.transformSingle(transformer, data)
|
||||
|
||||
+7
-2
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.fir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcastToNull
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
@@ -34,12 +37,14 @@ class FirExpressionWithSmartcastToNullImpl(
|
||||
override val explicitReceiver: FirExpression? get() = originalExpression.explicitReceiver
|
||||
override val dispatchReceiver: FirExpression get() = originalExpression.dispatchReceiver
|
||||
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
||||
override val isStable: Boolean get() = smartcastStability == SmartcastStability.STABLE_VALUE
|
||||
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
||||
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
||||
|
||||
// A FirExpressionWithSmartcast is only an effective smartcast if `smartcastStability == SmartcastStability.STABLE_VALUE`. Otherwise,
|
||||
// it's the same as the `originalExpression` under the hood. The reason we still create such a smartcast expression is for diagnostics
|
||||
// purpose only.
|
||||
override val typeRef: FirTypeRef get() = if (smartcastStability == SmartcastStability.STABLE_VALUE) smartcastType else originalType
|
||||
override val typeRef: FirTypeRef get() = if (isStable) smartcastType else originalType
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcastToNull {
|
||||
originalExpression = originalExpression.transformSingle(transformer, data)
|
||||
|
||||
+1
@@ -464,6 +464,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+field("typesFromSmartCast", "Collection<ConeKotlinType>", null, customType = coneKotlinTypeType)
|
||||
+field("originalType", typeRef)
|
||||
+field("smartcastType", typeRef)
|
||||
+booleanField("isStable")
|
||||
+smartcastStability
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>
|
||||
): FirDiagnosticWithParameters1<FirSourceElement, String>? =
|
||||
DebugInfoDiagnosticFactory1.EXPRESSION_TYPE.createDebugInfoDiagnostic(element, diagnosedRangesToDiagnosticNames) {
|
||||
element.typeRef.renderAsString((element as? FirExpressionWithSmartcast)?.takeIf { it.smartcastStability == SmartcastStability.STABLE_VALUE }?.originalType)
|
||||
element.typeRef.renderAsString((element as? FirExpressionWithSmartcast)?.takeIf { it.isStable }?.originalType)
|
||||
}
|
||||
|
||||
private fun FirTypeRef.renderAsString(originalTypeRef: FirTypeRef?): String {
|
||||
|
||||
Reference in New Issue
Block a user