FIR. Refactor smart-cast representation in FIR tree

Make smart-casts non-transparent expression without delegation
to underlying FirQualifiedAccessExpression, as children delegation in
fir tree has unclear semantics
Remove two different kinds of tree nodes for smart-casts
This commit is contained in:
Simon Ogorodnik
2022-08-02 00:49:24 +02:00
committed by teamcity
parent bc9db58b3c
commit 513af2dfbc
154 changed files with 9573 additions and 9320 deletions
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcastToNothing
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
@@ -25,17 +24,16 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.ClassId
fun FirExpressionWithSmartcast.smartcastScope(
fun FirSmartCastExpression.smartcastScope(
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirTypeScope? {
val smartcastType =
if (this is FirExpressionWithSmartcastToNothing) smartcastTypeWithoutNullableNothing.coneType else smartcastType.coneType
val smartcastType = smartcastTypeWithoutNullableNothing?.coneType ?: smartcastType.coneType
val smartcastScope = smartcastType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
if (isStable) {
return smartcastScope
}
val originalScope = originalType.coneType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
val originalScope = originalExpression.typeRef.coneType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
?: return smartcastScope
if (smartcastScope == null) {
@@ -5,10 +5,13 @@
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.builder.buildSmartCastExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildThisReceiverExpression
import org.jetbrains.kotlin.fir.references.builder.buildImplicitThisReference
import org.jetbrains.kotlin.fir.renderWithType
@@ -66,7 +69,7 @@ open class ExpressionReceiverValue(
if (receiverExpr is FirCheckNotNullCall) {
receiverExpr = receiverExpr.arguments.firstOrNull()
}
if (receiverExpr is FirExpressionWithSmartcast) {
if (receiverExpr is FirSmartCastExpression) {
return receiverExpr.smartcastScope(useSiteSession, scopeSession)
}
return type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
@@ -107,11 +110,16 @@ sealed class ImplicitReceiverValue<S : FirBasedSymbol<*>>(
receiverExpression = if (type == originalReceiverExpression.typeRef.coneType) {
originalReceiverExpression
} else {
buildExpressionWithSmartcast {
buildSmartCastExpression {
originalExpression = originalReceiverExpression
smartcastType = originalReceiverExpression.typeRef.resolvedTypeFromPrototype(type)
this.source = originalExpression.source?.fakeElement(KtFakeSourceElementKind.SmartCastExpression)
smartcastType = buildResolvedTypeRef {
source = originalReceiverExpression.typeRef.source?.fakeElement(KtFakeSourceElementKind.SmartCastedTypeRef)
this.type = type
}
typesFromSmartCast = listOf(type)
smartcastStability = SmartcastStability.STABLE_VALUE
typeRef = smartcastType.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef)
}
}
implicitScope = type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)