From 7a22827af496ab7fd19cfd962d375eca28c4dc75 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 2 Jun 2020 17:40:09 +0300 Subject: [PATCH] FIR: Unify all references to FIR nodes from non-parents --- .../jetbrains/kotlin/fir/dump/HtmlFirDump.kt | 2 +- .../kotlin/fir/builder/BaseFirBuilder.kt | 2 +- .../kotlin/fir/builder/ConversionUtils.kt | 19 ++++++++---- .../converter/ExpressionsConverter.kt | 30 ++++++++++--------- .../kotlin/fir/builder/PsiConversionUtils.kt | 10 +++---- .../kotlin/fir/builder/RawFirBuilder.kt | 7 +++-- .../kotlin/fir/resolve/dfa/VariableStorage.kt | 6 ++-- .../jetbrains/kotlin/fir/resolve/dfa/util.kt | 2 +- ...egerLiteralTypeApproximationTransformer.kt | 2 +- ...ControlFlowStatementsResolveTransformer.kt | 2 +- .../FirExpressionsResolveTransformer.kt | 2 +- .../expressions/FirCheckedSafeCallSubject.kt | 4 +-- .../fir/expressions/FirSafeCallExpression.kt | 4 +-- .../expressions/FirWhenSubjectExpression.kt | 4 +-- .../FirCheckedSafeCallSubjectBuilder.kt | 7 +++-- .../builder/FirSafeCallExpressionBuilder.kt | 7 +++-- .../FirWhenSubjectExpressionBuilder.kt | 7 +++-- .../impl/FirCheckedSafeCallSubjectImpl.kt | 5 ++-- .../impl/FirSafeCallExpressionImpl.kt | 5 ++-- .../impl/FirWhenSubjectExpressionImpl.kt | 7 +++-- .../jetbrains/kotlin/fir/FirExpressionRef.kt | 23 ++++++++++++++ .../fir/FirSafeCallCheckedSubjectReference.kt | 14 --------- .../FirSafeCallOriginalReceiverReference.kt | 14 --------- .../jetbrains/kotlin/fir/FirWhenSubject.kt | 16 ---------- .../fir/tree/generator/BuilderConfigurator.kt | 12 ++++++++ .../generator/ImplementationConfigurator.kt | 11 ++++++- .../fir/tree/generator/NodeConfigurator.kt | 6 ++-- .../kotlin/fir/tree/generator/Types.kt | 12 ++++++-- 28 files changed, 133 insertions(+), 109 deletions(-) create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirExpressionRef.kt delete mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallCheckedSubjectReference.kt delete mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallOriginalReceiverReference.kt delete mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirWhenSubject.kt diff --git a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt index ccd46b93744..2cd4fbbfcb5 100644 --- a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt +++ b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt @@ -1587,7 +1587,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver +"?." val nestedQualifier = safeCallExpression.regularQualifiedAccess - if (nestedQualifier.explicitReceiver == safeCallExpression.checkedSubject.value) { + if (nestedQualifier.explicitReceiver == safeCallExpression.checkedSubjectRef.value) { when (nestedQualifier) { is FirFunctionCall -> { return generate(nestedQualifier, skipReceiver = true) diff --git a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 34a092432ed..48d1cf91a96 100644 --- a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -562,7 +562,7 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte source = baseSource rValue = value calleeReference = nestedAccess.calleeReference - explicitReceiver = safeCallNonAssignment.checkedSubject.value + explicitReceiver = safeCallNonAssignment.checkedSubjectRef.value } safeCallNonAssignment.replaceRegularQualifiedAccess( diff --git a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index 0804c1a9275..3f8f64854d6 100644 --- a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -147,10 +147,12 @@ fun FirExpression.generateNotNullOrOther( ): FirWhenExpression { val subjectName = Name.special("<$caseId>") val subjectVariable = generateTemporaryVariable(session, baseSource, subjectName, this) - val subject = FirWhenSubject() + + @OptIn(FirContractViolation::class) + val ref = FirExpressionRef() val subjectExpression = buildWhenSubjectExpression { source = baseSource - whenSubject = subject + whenRef = ref } return buildWhenExpression { @@ -176,7 +178,7 @@ fun FirExpression.generateNotNullOrOther( result = buildSingleExpressionBlock(generateResolvedAccessExpression(baseSource, subjectVariable)) } }.also { - subject.bind(it) + ref.bind(it) } } @@ -487,6 +489,7 @@ private fun FirExpression.checkReceiver(name: String?): Boolean { return receiverName == name } + fun FirModifiableQualifiedAccess.wrapWithSafeCall(receiver: FirExpression): FirSafeCallExpression { // TODO: Refactor tree to make FirModifiableQualifiedAccess inherit FirQualifiedAccess require(this is FirQualifiedAccess) { @@ -494,13 +497,19 @@ fun FirModifiableQualifiedAccess.wrapWithSafeCall(receiver: FirExpression): FirS } val checkedSafeCallSubject = buildCheckedSafeCallSubject { - this.originalReceiverReference = FirSafeCallOriginalReceiverReference(receiver) + @OptIn(FirContractViolation::class) + this.originalReceiverRef = FirExpressionRef().apply { + bind(receiver) + } } explicitReceiver = checkedSafeCallSubject return buildSafeCallExpression { this.receiver = receiver - this.checkedSubject = FirSafeCallCheckedSubjectReference(checkedSafeCallSubject) + @OptIn(FirContractViolation::class) + this.checkedSubjectRef = FirExpressionRef().apply { + bind(checkedSafeCallSubject) + } this.regularQualifiedAccess = this@wrapWithSafeCall this.source = this@wrapWithSafeCall.source } diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt index 489f3813f5b..32006123929 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt @@ -636,7 +636,9 @@ class ExpressionsConverter( } subjectExpression = subjectVariable?.initializer ?: subjectExpression val hasSubject = subjectExpression != null - val subject = FirWhenSubject() + + @OptIn(FirContractViolation::class) + val subject = FirExpressionRef() whenEntryNodes.mapTo(whenEntries) { convertWhenEntry(it, subject.takeIf { hasSubject }) } return buildWhenExpression { source = whenExpression.toFirSourceElement() @@ -676,15 +678,15 @@ class ExpressionsConverter( * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseWhenEntry * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseWhenEntryNotElse */ - private fun convertWhenEntry(whenEntry: LighterASTNode, subject: FirWhenSubject?): WhenEntry { + private fun convertWhenEntry(whenEntry: LighterASTNode, whenRefWithSubject: FirExpressionRef?): WhenEntry { var isElse = false var firBlock: FirBlock = buildEmptyExpressionBlock() val conditions = mutableListOf() whenEntry.forEachChildren { when (it.tokenType) { - WHEN_CONDITION_EXPRESSION -> conditions += convertWhenConditionExpression(it, subject) - WHEN_CONDITION_IN_RANGE -> conditions += convertWhenConditionInRange(it, subject) - WHEN_CONDITION_IS_PATTERN -> conditions += convertWhenConditionIsPattern(it, subject) + WHEN_CONDITION_EXPRESSION -> conditions += convertWhenConditionExpression(it, whenRefWithSubject) + WHEN_CONDITION_IN_RANGE -> conditions += convertWhenConditionInRange(it, whenRefWithSubject) + WHEN_CONDITION_IS_PATTERN -> conditions += convertWhenConditionIsPattern(it, whenRefWithSubject) ELSE_KEYWORD -> isElse = true BLOCK -> firBlock = declarationsConverter.convertBlock(it) else -> if (it.isExpression()) firBlock = declarationsConverter.convertBlock(it) @@ -694,20 +696,20 @@ class ExpressionsConverter( return WhenEntry(conditions, firBlock, isElse) } - private fun convertWhenConditionExpression(whenCondition: LighterASTNode, subject: FirWhenSubject?): FirExpression { + private fun convertWhenConditionExpression(whenCondition: LighterASTNode, whenRefWithSubject: FirExpressionRef?): FirExpression { var firExpression: FirExpression = buildErrorExpression(null, ConeSimpleDiagnostic("No expression in condition with expression", DiagnosticKind.Syntax)) whenCondition.forEachChildren { when (it.tokenType) { else -> if (it.isExpression()) firExpression = getAsFirExpression(it, "No expression in condition with expression") } } - return if (subject != null) { + return if (whenRefWithSubject != null) { buildOperatorCall { source = whenCondition.toFirSourceElement() operation = FirOperation.EQ argumentList = buildBinaryArgumentList( buildWhenSubjectExpression { - whenSubject = subject + whenRef = whenRefWithSubject }, firExpression ) } @@ -717,7 +719,7 @@ class ExpressionsConverter( } } - private fun convertWhenConditionInRange(whenCondition: LighterASTNode, subject: FirWhenSubject?): FirExpression { + private fun convertWhenConditionInRange(whenCondition: LighterASTNode, whenRefWithSubject: FirExpressionRef?): FirExpression { var isNegate = false var firExpression: FirExpression = buildErrorExpression(null, ConeSimpleDiagnostic("No range in condition with range", DiagnosticKind.Syntax)) var conditionSource: FirLightSourceElement? = null @@ -731,9 +733,9 @@ class ExpressionsConverter( } } - val subjectExpression = if (subject != null) { + val subjectExpression = if (whenRefWithSubject != null) { buildWhenSubjectExpression { - whenSubject = subject + whenRef = whenRefWithSubject } } else { return buildErrorExpression { @@ -750,7 +752,7 @@ class ExpressionsConverter( ) } - private fun convertWhenConditionIsPattern(whenCondition: LighterASTNode, subject: FirWhenSubject?): FirExpression { + private fun convertWhenConditionIsPattern(whenCondition: LighterASTNode, whenRefWithSubject: FirExpressionRef?): FirExpression { lateinit var firOperation: FirOperation lateinit var firType: FirTypeRef whenCondition.forEachChildren { @@ -761,9 +763,9 @@ class ExpressionsConverter( } } - val subjectExpression = if (subject != null) { + val subjectExpression = if (whenRefWithSubject != null) { buildWhenSubjectExpression { - whenSubject = subject + whenRef = whenRefWithSubject } } else { return buildErrorExpression { diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt index 8bf9177a35a..009128b582b 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiConversionUtils.kt @@ -7,9 +7,9 @@ package org.jetbrains.kotlin.fir.builder import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.fir.FirWhenSubject import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.builder.buildProperty @@ -24,14 +24,14 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.psi.* internal fun KtWhenCondition.toFirWhenCondition( - subject: FirWhenSubject, + whenRefWithSibject: FirExpressionRef, convert: KtExpression?.(String) -> FirExpression, toFirOrErrorTypeRef: KtTypeReference?.() -> FirTypeRef, ): FirExpression { val baseSource = this.toFirPsiSourceElement() val firSubjectExpression = buildWhenSubjectExpression { source = baseSource - whenSubject = subject + whenRef = whenRefWithSibject } return when (this) { is KtWhenConditionWithExpression -> { @@ -68,7 +68,7 @@ internal fun KtWhenCondition.toFirWhenCondition( internal fun Array.toFirWhenCondition( baseSource: FirSourceElement?, - subject: FirWhenSubject, + subject: FirExpressionRef, convert: KtExpression?.(String) -> FirExpression, toFirOrErrorTypeRef: KtTypeReference?.() -> FirTypeRef, ): FirExpression { @@ -121,4 +121,4 @@ internal fun generateDestructuringBlock( } } } -} \ No newline at end of file +} diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index b03e7284bbd..d64e38f7112 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1343,7 +1343,8 @@ class RawFirBuilder( else -> null } val hasSubject = subjectExpression != null - val subject = FirWhenSubject() + @OptIn(FirContractViolation::class) + val ref = FirExpressionRef() return buildWhenExpression { source = expression.toFirSourceElement() this.subject = subjectExpression @@ -1358,7 +1359,7 @@ class RawFirBuilder( source = entrySource condition = entry.conditions.toFirWhenCondition( entrySource, - subject, + ref, { toFirExpression(it) }, { toFirOrErrorType() }, ) @@ -1382,7 +1383,7 @@ class RawFirBuilder( } }.also { if (hasSubject) { - subject.bind(it) + ref.bind(it) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorage.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorage.kt index 79062e922e3..2ff918ac0f6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorage.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorage.kt @@ -43,10 +43,10 @@ class VariableStorage(private val session: FirSession) { } private fun FirElement.unwrapElement(): FirElement = when (this) { - is FirWhenSubjectExpression -> whenSubject.whenExpression.let { it.subjectVariable ?: it.subject }?.unwrapElement() ?: this + is FirWhenSubjectExpression -> whenRef.value.let { it.subjectVariable ?: it.subject }?.unwrapElement() ?: this is FirExpressionWithSmartcast -> originalExpression.unwrapElement() is FirSafeCallExpression -> regularQualifiedAccess.unwrapElement() - is FirCheckedSafeCallSubject -> originalReceiverReference.value.unwrapElement() + is FirCheckedSafeCallSubject -> originalReceiverRef.value.unwrapElement() else -> this } @@ -71,7 +71,7 @@ class VariableStorage(private val session: FirSession) { val isThisReference: Boolean val expression: FirQualifiedAccess? = when (originalFir) { is FirQualifiedAccessExpression -> originalFir - is FirWhenSubjectExpression -> originalFir.whenSubject.whenExpression.subject as? FirQualifiedAccessExpression + is FirWhenSubjectExpression -> originalFir.whenRef.value.subject as? FirQualifiedAccessExpression is FirVariableAssignment -> originalFir else -> null } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/util.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/util.kt index 8019384c44d..5c6dd927878 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/util.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/util.kt @@ -122,7 +122,7 @@ internal val FirElement.symbol: AbstractFirBasedSymbol<*>? get() = when (this) { is FirResolvable -> symbol is FirSymbolOwner<*> -> symbol - is FirWhenSubjectExpression -> whenSubject.whenExpression.subject?.symbol + is FirWhenSubjectExpression -> whenRef.value.subject?.symbol is FirSafeCallExpression -> regularQualifiedAccess.symbol else -> null }?.takeIf { this is FirThisReceiverExpression || (it !is FirFunctionSymbol<*> && it !is FirAccessorSymbol) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt index 206d30be8c6..8a5d7b59662 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt @@ -136,7 +136,7 @@ class IntegerLiteralTypeApproximationTransformer( data: ConeKotlinType? ): CompositeTransformResult { val newReceiver = - checkedSafeCallSubject.originalReceiverReference.value.transform(this, data).single + checkedSafeCallSubject.originalReceiverRef.value.transform(this, data).single checkedSafeCallSubject.propagateTypeFromOriginalReceiver(newReceiver, session) return super.transformCheckedSafeCallSubject(checkedSafeCallSubject, data) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 1ee42e89384..ca92b03346b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -125,7 +125,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran whenSubjectExpression: FirWhenSubjectExpression, data: ResolutionMode ): CompositeTransformResult { - val parentWhen = whenSubjectExpression.whenSubject.whenExpression + val parentWhen = whenSubjectExpression.whenRef.value val subjectType = parentWhen.subject?.resultType ?: parentWhen.subjectVariable?.returnTypeRef if (subjectType != null) { whenSubjectExpression.resultType = subjectType diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 201d84e07a9..a157503e3d3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -177,7 +177,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : dataFlowAnalyzer.enterSafeCallAfterNullCheck(safeCallExpression) safeCallExpression.apply { - checkedSubject.value.propagateTypeFromOriginalReceiver(receiver, components.session) + checkedSubjectRef.value.propagateTypeFromOriginalReceiver(receiver, components.session) transformRegularQualifiedAccess(this@FirExpressionsResolveTransformer, data) propagateTypeFromQualifiedAccessAfterNullCheck(receiver, session) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirCheckedSafeCallSubject.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirCheckedSafeCallSubject.kt index 4734cbdbbb6..28a176521ee 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirCheckedSafeCallSubject.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirCheckedSafeCallSubject.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.expressions -import org.jetbrains.kotlin.fir.FirSafeCallOriginalReceiverReference +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.* @@ -19,7 +19,7 @@ abstract class FirCheckedSafeCallSubject : FirExpression() { abstract override val source: FirSourceElement? abstract override val typeRef: FirTypeRef abstract override val annotations: List - abstract val originalReceiverReference: FirSafeCallOriginalReceiverReference + abstract val originalReceiverRef: FirExpressionRef override fun accept(visitor: FirVisitor, data: D): R = visitor.visitCheckedSafeCallSubject(this, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirSafeCallExpression.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirSafeCallExpression.kt index 365ad07b8f3..29e9089e6d6 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirSafeCallExpression.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirSafeCallExpression.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.expressions -import org.jetbrains.kotlin.fir.FirSafeCallCheckedSubjectReference +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.* @@ -20,7 +20,7 @@ abstract class FirSafeCallExpression : FirExpression() { abstract override val typeRef: FirTypeRef abstract override val annotations: List abstract val receiver: FirExpression - abstract val checkedSubject: FirSafeCallCheckedSubjectReference + abstract val checkedSubjectRef: FirExpressionRef abstract val regularQualifiedAccess: FirQualifiedAccess override fun accept(visitor: FirVisitor, data: D): R = visitor.visitSafeCallExpression(this, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenSubjectExpression.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenSubjectExpression.kt index f22a697142b..7eaf6d48f0c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenSubjectExpression.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenSubjectExpression.kt @@ -5,8 +5,8 @@ package org.jetbrains.kotlin.fir.expressions +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.fir.FirWhenSubject import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.* @@ -19,7 +19,7 @@ abstract class FirWhenSubjectExpression : FirExpression() { abstract override val source: FirSourceElement? abstract override val typeRef: FirTypeRef abstract override val annotations: List - abstract val whenSubject: FirWhenSubject + abstract val whenRef: FirExpressionRef override fun accept(visitor: FirVisitor, data: D): R = visitor.visitWhenSubjectExpression(this, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirCheckedSafeCallSubjectBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirCheckedSafeCallSubjectBuilder.kt index 5c84324486a..e7c86e31bd8 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirCheckedSafeCallSubjectBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirCheckedSafeCallSubjectBuilder.kt @@ -6,12 +6,13 @@ package org.jetbrains.kotlin.fir.expressions.builder import kotlin.contracts.* -import org.jetbrains.kotlin.fir.FirSafeCallOriginalReceiverReference +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.impl.FirCheckedSafeCallSubjectImpl import org.jetbrains.kotlin.fir.types.FirTypeRef @@ -28,14 +29,14 @@ class FirCheckedSafeCallSubjectBuilder : FirAnnotationContainerBuilder, FirExpre override var source: FirSourceElement? = null override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) override val annotations: MutableList = mutableListOf() - lateinit var originalReceiverReference: FirSafeCallOriginalReceiverReference + lateinit var originalReceiverRef: FirExpressionRef override fun build(): FirCheckedSafeCallSubject { return FirCheckedSafeCallSubjectImpl( source, typeRef, annotations, - originalReceiverReference, + originalReceiverRef, ) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirSafeCallExpressionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirSafeCallExpressionBuilder.kt index d884de8aee8..0b337328a35 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirSafeCallExpressionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirSafeCallExpressionBuilder.kt @@ -6,11 +6,12 @@ package org.jetbrains.kotlin.fir.expressions.builder import kotlin.contracts.* -import org.jetbrains.kotlin.fir.FirSafeCallCheckedSubjectReference +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression @@ -31,7 +32,7 @@ class FirSafeCallExpressionBuilder : FirAnnotationContainerBuilder, FirExpressio override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) override val annotations: MutableList = mutableListOf() lateinit var receiver: FirExpression - lateinit var checkedSubject: FirSafeCallCheckedSubjectReference + lateinit var checkedSubjectRef: FirExpressionRef lateinit var regularQualifiedAccess: FirQualifiedAccess override fun build(): FirSafeCallExpression { @@ -40,7 +41,7 @@ class FirSafeCallExpressionBuilder : FirAnnotationContainerBuilder, FirExpressio typeRef, annotations, receiver, - checkedSubject, + checkedSubjectRef, regularQualifiedAccess, ) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenSubjectExpressionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenSubjectExpressionBuilder.kt index 3c686fcb190..1531a0d4fd8 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenSubjectExpressionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenSubjectExpressionBuilder.kt @@ -6,11 +6,12 @@ package org.jetbrains.kotlin.fir.expressions.builder import kotlin.contracts.* +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.fir.FirWhenSubject import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirWhenExpression import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder import org.jetbrains.kotlin.fir.expressions.impl.FirWhenSubjectExpressionImpl @@ -26,13 +27,13 @@ import org.jetbrains.kotlin.fir.visitors.* class FirWhenSubjectExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder { override var source: FirSourceElement? = null override val annotations: MutableList = mutableListOf() - lateinit var whenSubject: FirWhenSubject + lateinit var whenRef: FirExpressionRef override fun build(): FirWhenSubjectExpression { return FirWhenSubjectExpressionImpl( source, annotations, - whenSubject, + whenRef, ) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirCheckedSafeCallSubjectImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirCheckedSafeCallSubjectImpl.kt index 110f449993a..74ac2f500bc 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirCheckedSafeCallSubjectImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirCheckedSafeCallSubjectImpl.kt @@ -5,10 +5,11 @@ package org.jetbrains.kotlin.fir.expressions.impl -import org.jetbrains.kotlin.fir.FirSafeCallOriginalReceiverReference +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.* @@ -21,7 +22,7 @@ internal class FirCheckedSafeCallSubjectImpl( override val source: FirSourceElement?, override var typeRef: FirTypeRef, override val annotations: MutableList, - override val originalReceiverReference: FirSafeCallOriginalReceiverReference, + override val originalReceiverRef: FirExpressionRef, ) : FirCheckedSafeCallSubject() { override fun acceptChildren(visitor: FirVisitor, data: D) { typeRef.accept(visitor, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirSafeCallExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirSafeCallExpressionImpl.kt index a5008414005..a55983423aa 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirSafeCallExpressionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirSafeCallExpressionImpl.kt @@ -5,9 +5,10 @@ package org.jetbrains.kotlin.fir.expressions.impl -import org.jetbrains.kotlin.fir.FirSafeCallCheckedSubjectReference +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression @@ -24,7 +25,7 @@ internal class FirSafeCallExpressionImpl( override var typeRef: FirTypeRef, override val annotations: MutableList, override var receiver: FirExpression, - override val checkedSubject: FirSafeCallCheckedSubjectReference, + override val checkedSubjectRef: FirExpressionRef, override var regularQualifiedAccess: FirQualifiedAccess, ) : FirSafeCallExpression() { override fun acceptChildren(visitor: FirVisitor, data: D) { diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenSubjectExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenSubjectExpressionImpl.kt index c109c88fb87..86f4403d1a5 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenSubjectExpressionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenSubjectExpressionImpl.kt @@ -5,9 +5,10 @@ package org.jetbrains.kotlin.fir.expressions.impl +import org.jetbrains.kotlin.fir.FirExpressionRef import org.jetbrains.kotlin.fir.FirSourceElement -import org.jetbrains.kotlin.fir.FirWhenSubject import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirWhenExpression import org.jetbrains.kotlin.fir.expressions.FirWhenSubjectExpression import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.* @@ -20,9 +21,9 @@ import org.jetbrains.kotlin.fir.visitors.* internal class FirWhenSubjectExpressionImpl( override val source: FirSourceElement?, override val annotations: MutableList, - override val whenSubject: FirWhenSubject, + override val whenRef: FirExpressionRef, ) : FirWhenSubjectExpression() { - override val typeRef: FirTypeRef get() = whenSubject.whenExpression.subject!!.typeRef + override val typeRef: FirTypeRef get() = whenRef.value.subject!!.typeRef override fun acceptChildren(visitor: FirVisitor, data: D) { annotations.forEach { it.accept(visitor, data) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirExpressionRef.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirExpressionRef.kt new file mode 100644 index 00000000000..21604e534a8 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirExpressionRef.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir + +import org.jetbrains.kotlin.fir.expressions.FirExpression + +@RequiresOptIn(level = RequiresOptIn.Level.ERROR) +annotation class FirContractViolation + +/** + * This class is created to implicitly overcome FIR contract that some node may only be referenced once from its parents (not from any other node) + * Thus, these kinds of secondary references may not be common FIR nodes since it would lead to visiting them twice during usual traversal + * And this class is used to wrap such references + */ +class FirExpressionRef @FirContractViolation constructor () { + lateinit var value: T + fun bind(value: T) { + this.value = value + } +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallCheckedSubjectReference.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallCheckedSubjectReference.kt deleted file mode 100644 index e9e6930730c..00000000000 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallCheckedSubjectReference.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir - -import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject - -class FirSafeCallCheckedSubjectReference(var value: FirCheckedSafeCallSubject) { - fun bind(subject: FirCheckedSafeCallSubject) { - this.value = subject - } -} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallOriginalReceiverReference.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallOriginalReceiverReference.kt deleted file mode 100644 index 83afa4dc15a..00000000000 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSafeCallOriginalReceiverReference.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir - -import org.jetbrains.kotlin.fir.expressions.FirExpression - -class FirSafeCallOriginalReceiverReference(var value: FirExpression) { - fun bind(realReceiver: FirExpression) { - this.value = realReceiver - } -} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirWhenSubject.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirWhenSubject.kt deleted file mode 100644 index 616752ae706..00000000000 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirWhenSubject.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir - -import org.jetbrains.kotlin.fir.expressions.FirWhenExpression - -class FirWhenSubject { - lateinit var whenExpression: FirWhenExpression - - fun bind(expression: FirWhenExpression) { - whenExpression = expression - } -} \ No newline at end of file diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index 55209bb302e..64480d89a7d 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -269,6 +269,18 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree defaultFalse("isNullableLHSForCallableReference") } +// builder(safeCallExpression) { +// useTypes(safeCallCheckedSubjectType) +// } +// +// builder(checkedSafeCallSubject) { +// useTypes(expressionType) +// } +// +// builder(whenSubjectExpression) { +// useTypes(whenExpressionType) +// } + val elementsWithDefaultTypeRef = listOf( thisReceiverExpression, callableReferenceAccess, diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 077fdb0aae1..e1a513449a4 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -286,9 +286,10 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() impl(whenSubjectExpression) { default("typeRef") { - value = "whenSubject.whenExpression.subject!!.typeRef" + value = "whenRef.value.subject!!.typeRef" withGetter = true } + useTypes(whenExpressionType) } impl(wrappedDelegateExpression) { @@ -443,6 +444,14 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() } } + impl(safeCallExpression) { + useTypes(safeCallCheckedSubjectType) + } + + impl(checkedSafeCallSubject) { + useTypes(expressionType) + } + noImpl(userTypeRef) } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index a0651b3fe82..4daf0fab5da 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -441,13 +441,13 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild safeCallExpression.configure { +field("receiver", expression).withTransform() // Special node that might be used as a reference to receiver of a safe call after null check - +field("checkedSubject", safeCallCheckedSubjectReferenceType) + +field("checkedSubjectRef", safeCallCheckedSubjectReferenceType) // One that uses checkedReceiver as a receiver +field("regularQualifiedAccess", qualifiedAccess, withReplace = true).withTransform() } checkedSafeCallSubject.configure { - +field("originalReceiverReference", safeCallReceiverReferenceType) + +field("originalReceiverRef", safeCallOriginalReceiverReferenceType) } callableReferenceAccess.configure { @@ -498,7 +498,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } whenSubjectExpression.configure { - +field("whenSubject", whenSubjectType) + +field("whenRef", whenRefType) } wrappedExpression.configure { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index 60aa07aa57f..f91006fb090 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -37,9 +37,15 @@ val classIdType = type(ClassId::class) val annotationUseSiteTargetType = type(AnnotationUseSiteTarget::class) val operationKindType = type("fir.expressions", "LogicOperationKind") val coneKotlinTypeType = type(ConeKotlinType::class) -val whenSubjectType = type("fir", "FirWhenSubject") -val safeCallReceiverReferenceType = type("fir", "FirSafeCallOriginalReceiverReference") -val safeCallCheckedSubjectReferenceType = type("fir", "FirSafeCallCheckedSubjectReference") + +val whenExpressionType = generatedType("expressions", "FirWhenExpression") +val expressionType = generatedType("expressions", "FirExpression") +val safeCallCheckedSubjectType = generatedType("expressions", "FirCheckedSafeCallSubject") + +val whenRefType = generatedType("", "FirExpressionRef") +val safeCallOriginalReceiverReferenceType = generatedType("", "FirExpressionRef") +val safeCallCheckedSubjectReferenceType = generatedType("", "FirExpressionRef") + val firSessionType = type("fir", "FirSession") val emptyCfgReferenceType = generatedType("references.impl", "FirEmptyControlFlowGraphReference") val noReceiverExpressionType = generatedType("expressions.impl", "FirNoReceiverExpression")