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
@@ -9,8 +9,8 @@ import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -103,7 +103,7 @@ object LowerPriorityForDynamic : ResolutionDiagnostic(K2_SYNTHETIC_RESOLVED)
object CandidateChosenUsingOverloadResolutionByLambdaAnnotation : ResolutionDiagnostic(RESOLVED)
class UnstableSmartCast(val argument: FirExpressionWithSmartcast, val targetType: ConeKotlinType, val isCastToNotNull: Boolean) :
class UnstableSmartCast(val argument: FirSmartCastExpression, val targetType: ConeKotlinType, val isCastToNotNull: Boolean) :
ResolutionDiagnostic(UNSTABLE_SMARTCAST)
class ArgumentTypeMismatch(
@@ -62,7 +62,7 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
private fun FirElement.unwrapElement(): FirElement = when (this) {
is FirWhenSubjectExpression -> whenRef.value.let { it.subjectVariable ?: it.subject }?.unwrapElement() ?: this
is FirExpressionWithSmartcast -> originalExpression.unwrapElement()
is FirSmartCastExpression -> originalExpression.unwrapElement()
is FirSafeCallExpression -> selector.unwrapElement()
is FirCheckedSafeCallSubject -> originalReceiverRef.value.unwrapElement()
is FirCheckNotNullCall -> argument.unwrapElement()
@@ -857,3 +857,12 @@ object FirStub : FirElement {
return this
}
}
// ----------------------------------- Smart-cast node -----------------------------------
class SmartCastExpressionExitNode(owner: ControlFlowGraph, override val fir: FirSmartCastExpression, level: Int, id: Int) : CFGNode<FirSmartCastExpression>(owner, level, id) {
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
return visitor.visitSmartCastExpressionExitNode(this, data)
}
}
@@ -44,6 +44,7 @@ fun CFGNode<*>.render(): String =
is ResolvedQualifierNode -> "Access qualifier ${fir.classId}"
is ComparisonExpressionNode -> "Comparison ${fir.operation.operator}"
is TypeOperatorCallNode -> "Type operator: \"${CfgRenderer.renderElementAsString(fir)}\""
is SmartCastExpressionExitNode -> "Smart cast: \"${CfgRenderer.renderElementAsString(fir)}\""
is EqualityOperatorCallNode -> "Equality operator ${fir.operation.operator}"
is JumpNode -> "Jump: ${fir.render()}"
is StubNode -> "Stub"
@@ -386,4 +386,8 @@ abstract class ControlFlowGraphVisitor<out R, in D> {
open fun visitAnnotationExitNode(node: AnnotationExitNode, data: D): R {
return visitNode(node, data)
}
open fun visitSmartCastExpressionExitNode(node: SmartCastExpressionExitNode, data: D): R {
return visitNode(node, data)
}
}
@@ -99,6 +99,7 @@ val FirElement.symbol: FirBasedSymbol<*>?
is FirDeclaration -> symbol
is FirWhenSubjectExpression -> whenRef.value.subject?.symbol
is FirSafeCallExpression -> selector.symbol
is FirSmartCastExpression -> originalExpression.symbol
else -> null
}?.takeIf {
(this as? FirExpression)?.unwrapSmartcastExpression() is FirThisReceiverExpression ||
@@ -116,6 +117,6 @@ internal val FirResolvable.symbol: FirBasedSymbol<*>?
fun FirExpression.unwrapSmartcastExpression(): FirExpression =
when (this) {
is FirExpressionWithSmartcast -> originalExpression
is FirSmartCastExpression -> originalExpression
else -> this
}