FIR: Unify all references to FIR nodes from non-parents

This commit is contained in:
Denis Zharkov
2020-06-02 17:40:09 +03:00
parent 4a4dce1766
commit 7a22827af4
28 changed files with 133 additions and 109 deletions
@@ -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<FirAnnotationCall>
abstract val originalReceiverReference: FirSafeCallOriginalReceiverReference
abstract val originalReceiverRef: FirExpressionRef<FirExpression>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitCheckedSafeCallSubject(this, data)
@@ -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<FirAnnotationCall>
abstract val receiver: FirExpression
abstract val checkedSubject: FirSafeCallCheckedSubjectReference
abstract val checkedSubjectRef: FirExpressionRef<FirCheckedSafeCallSubject>
abstract val regularQualifiedAccess: FirQualifiedAccess
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitSafeCallExpression(this, data)
@@ -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<FirAnnotationCall>
abstract val whenSubject: FirWhenSubject
abstract val whenRef: FirExpressionRef<FirWhenExpression>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitWhenSubjectExpression(this, data)
@@ -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<FirAnnotationCall> = mutableListOf()
lateinit var originalReceiverReference: FirSafeCallOriginalReceiverReference
lateinit var originalReceiverRef: FirExpressionRef<FirExpression>
override fun build(): FirCheckedSafeCallSubject {
return FirCheckedSafeCallSubjectImpl(
source,
typeRef,
annotations,
originalReceiverReference,
originalReceiverRef,
)
}
@@ -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<FirAnnotationCall> = mutableListOf()
lateinit var receiver: FirExpression
lateinit var checkedSubject: FirSafeCallCheckedSubjectReference
lateinit var checkedSubjectRef: FirExpressionRef<FirCheckedSafeCallSubject>
lateinit var regularQualifiedAccess: FirQualifiedAccess
override fun build(): FirSafeCallExpression {
@@ -40,7 +41,7 @@ class FirSafeCallExpressionBuilder : FirAnnotationContainerBuilder, FirExpressio
typeRef,
annotations,
receiver,
checkedSubject,
checkedSubjectRef,
regularQualifiedAccess,
)
}
@@ -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<FirAnnotationCall> = mutableListOf()
lateinit var whenSubject: FirWhenSubject
lateinit var whenRef: FirExpressionRef<FirWhenExpression>
override fun build(): FirWhenSubjectExpression {
return FirWhenSubjectExpressionImpl(
source,
annotations,
whenSubject,
whenRef,
)
}
@@ -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<FirAnnotationCall>,
override val originalReceiverReference: FirSafeCallOriginalReceiverReference,
override val originalReceiverRef: FirExpressionRef<FirExpression>,
) : FirCheckedSafeCallSubject() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
@@ -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<FirAnnotationCall>,
override var receiver: FirExpression,
override val checkedSubject: FirSafeCallCheckedSubjectReference,
override val checkedSubjectRef: FirExpressionRef<FirCheckedSafeCallSubject>,
override var regularQualifiedAccess: FirQualifiedAccess,
) : FirSafeCallExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
@@ -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<FirAnnotationCall>,
override val whenSubject: FirWhenSubject,
override val whenRef: FirExpressionRef<FirWhenExpression>,
) : FirWhenSubjectExpression() {
override val typeRef: FirTypeRef get() = whenSubject.whenExpression.subject!!.typeRef
override val typeRef: FirTypeRef get() = whenRef.value.subject!!.typeRef
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
@@ -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<T : FirExpression> @FirContractViolation constructor () {
lateinit var value: T
fun bind(value: T) {
this.value = value
}
}
@@ -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
}
}
@@ -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
}
}
@@ -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
}
}
@@ -269,6 +269,18 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
defaultFalse("isNullableLHSForCallableReference")
}
// builder(safeCallExpression) {
// useTypes(safeCallCheckedSubjectType)
// }
//
// builder(checkedSafeCallSubject) {
// useTypes(expressionType)
// }
//
// builder(whenSubjectExpression) {
// useTypes(whenExpressionType)
// }
val elementsWithDefaultTypeRef = listOf(
thisReceiverExpression,
callableReferenceAccess,
@@ -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)
}
@@ -441,13 +441,13 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(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<FirTreeBuilder>(FirTreeBuild
}
whenSubjectExpression.configure {
+field("whenSubject", whenSubjectType)
+field("whenRef", whenRefType)
}
wrappedExpression.configure {
@@ -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<FirWhenExpression>")
val safeCallOriginalReceiverReferenceType = generatedType("", "FirExpressionRef<FirExpression>")
val safeCallCheckedSubjectReferenceType = generatedType("", "FirExpressionRef<FirCheckedSafeCallSubject>")
val firSessionType = type("fir", "FirSession")
val emptyCfgReferenceType = generatedType("references.impl", "FirEmptyControlFlowGraphReference")
val noReceiverExpressionType = generatedType("expressions.impl", "FirNoReceiverExpression")