FIR: Prepare tree structure for safe-call refactoring

^KT-38444 In Progress
This commit is contained in:
Denis Zharkov
2020-06-01 15:06:18 +03:00
parent 14a41d91f6
commit cb1c3f87f0
16 changed files with 381 additions and 4 deletions
@@ -0,0 +1,29 @@
/*
* 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.expressions
import org.jetbrains.kotlin.fir.FirSafeCallOriginalReceiverReference
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
abstract class FirCheckedSafeCallSubject : FirExpression() {
abstract override val source: FirSourceElement?
abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotationCall>
abstract val originalReceiverReference: FirSafeCallOriginalReceiverReference
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitCheckedSafeCallSubject(this, data)
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirCheckedSafeCallSubject
}
@@ -0,0 +1,37 @@
/*
* 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.expressions
import org.jetbrains.kotlin.fir.FirSafeCallCheckedSubjectReference
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
abstract class FirSafeCallExpression : FirExpression() {
abstract override val source: FirSourceElement?
abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotationCall>
abstract val receiver: FirExpression
abstract val checkedSubject: FirSafeCallCheckedSubjectReference
abstract val regularQualifiedAccess: FirQualifiedAccess
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitSafeCallExpression(this, data)
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
abstract fun replaceRegularQualifiedAccess(newRegularQualifiedAccess: FirQualifiedAccess)
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirSafeCallExpression
abstract fun <D> transformReceiver(transformer: FirTransformer<D>, data: D): FirSafeCallExpression
abstract fun <D> transformRegularQualifiedAccess(transformer: FirTransformer<D>, data: D): FirSafeCallExpression
}
@@ -0,0 +1,50 @@
/*
* 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.expressions.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.fir.FirSafeCallOriginalReceiverReference
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.builder.FirExpressionBuilder
import org.jetbrains.kotlin.fir.expressions.impl.FirCheckedSafeCallSubjectImpl
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
@FirBuilderDsl
class FirCheckedSafeCallSubjectBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
override var source: FirSourceElement? = null
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
lateinit var originalReceiverReference: FirSafeCallOriginalReceiverReference
override fun build(): FirCheckedSafeCallSubject {
return FirCheckedSafeCallSubjectImpl(
source,
typeRef,
annotations,
originalReceiverReference,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildCheckedSafeCallSubject(init: FirCheckedSafeCallSubjectBuilder.() -> Unit): FirCheckedSafeCallSubject {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
return FirCheckedSafeCallSubjectBuilder().apply(init).build()
}
@@ -0,0 +1,56 @@
/*
* 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.expressions.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.fir.FirSafeCallCheckedSubjectReference
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.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
import org.jetbrains.kotlin.fir.expressions.impl.FirSafeCallExpressionImpl
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
@FirBuilderDsl
class FirSafeCallExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
override var source: FirSourceElement? = null
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
lateinit var receiver: FirExpression
lateinit var checkedSubject: FirSafeCallCheckedSubjectReference
lateinit var regularQualifiedAccess: FirQualifiedAccess
override fun build(): FirSafeCallExpression {
return FirSafeCallExpressionImpl(
source,
typeRef,
annotations,
receiver,
checkedSubject,
regularQualifiedAccess,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildSafeCallExpression(init: FirSafeCallExpressionBuilder.() -> Unit): FirSafeCallExpression {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
return FirSafeCallExpressionBuilder().apply(init).build()
}
@@ -0,0 +1,45 @@
/*
* 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.expressions.impl
import org.jetbrains.kotlin.fir.FirSafeCallOriginalReceiverReference
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.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
internal class FirCheckedSafeCallSubjectImpl(
override val source: FirSourceElement?,
override var typeRef: FirTypeRef,
override val annotations: MutableList<FirAnnotationCall>,
override val originalReceiverReference: FirSafeCallOriginalReceiverReference,
) : FirCheckedSafeCallSubject() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
annotations.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirCheckedSafeCallSubjectImpl {
typeRef = typeRef.transformSingle(transformer, data)
transformAnnotations(transformer, data)
return this
}
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirCheckedSafeCallSubjectImpl {
annotations.transformInplace(transformer, data)
return this
}
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
typeRef = newTypeRef
}
}
@@ -0,0 +1,67 @@
/*
* 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.expressions.impl
import org.jetbrains.kotlin.fir.FirSafeCallCheckedSubjectReference
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
internal class FirSafeCallExpressionImpl(
override val source: FirSourceElement?,
override var typeRef: FirTypeRef,
override val annotations: MutableList<FirAnnotationCall>,
override var receiver: FirExpression,
override val checkedSubject: FirSafeCallCheckedSubjectReference,
override var regularQualifiedAccess: FirQualifiedAccess,
) : FirSafeCallExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
annotations.forEach { it.accept(visitor, data) }
receiver.accept(visitor, data)
regularQualifiedAccess.accept(visitor, data)
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirSafeCallExpressionImpl {
typeRef = typeRef.transformSingle(transformer, data)
transformAnnotations(transformer, data)
transformReceiver(transformer, data)
transformRegularQualifiedAccess(transformer, data)
return this
}
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirSafeCallExpressionImpl {
annotations.transformInplace(transformer, data)
return this
}
override fun <D> transformReceiver(transformer: FirTransformer<D>, data: D): FirSafeCallExpressionImpl {
receiver = receiver.transformSingle(transformer, data)
return this
}
override fun <D> transformRegularQualifiedAccess(transformer: FirTransformer<D>, data: D): FirSafeCallExpressionImpl {
regularQualifiedAccess = regularQualifiedAccess.transformSingle(transformer, data)
return this
}
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
typeRef = newTypeRef
}
override fun replaceRegularQualifiedAccess(newRegularQualifiedAccess: FirQualifiedAccess) {
regularQualifiedAccess = newRegularQualifiedAccess
}
}
@@ -87,6 +87,8 @@ import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirWrappedExpression
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
@@ -459,6 +461,14 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformElement(expressionWithSmartcast, data)
}
open fun transformSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: D): CompositeTransformResult<FirStatement> {
return transformElement(safeCallExpression, data)
}
open fun transformCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject, data: D): CompositeTransformResult<FirStatement> {
return transformElement(checkedSafeCallSubject, data)
}
open fun transformGetClassCall(getClassCall: FirGetClassCall, data: D): CompositeTransformResult<FirStatement> {
return transformElement(getClassCall, data)
}
@@ -935,6 +945,14 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformExpressionWithSmartcast(expressionWithSmartcast, data)
}
final override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: D): CompositeTransformResult<FirStatement> {
return transformSafeCallExpression(safeCallExpression, data)
}
final override fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject, data: D): CompositeTransformResult<FirStatement> {
return transformCheckedSafeCallSubject(checkedSafeCallSubject, data)
}
final override fun visitGetClassCall(getClassCall: FirGetClassCall, data: D): CompositeTransformResult<FirStatement> {
return transformGetClassCall(getClassCall, data)
}
@@ -87,6 +87,8 @@ import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirWrappedExpression
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
@@ -295,6 +297,10 @@ abstract class FirVisitor<out R, in D> {
open fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: D): R = visitElement(expressionWithSmartcast, data)
open fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: D): R = visitElement(safeCallExpression, data)
open fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject, data: D): R = visitElement(checkedSafeCallSubject, data)
open fun visitGetClassCall(getClassCall: FirGetClassCall, data: D): R = visitElement(getClassCall, data)
open fun visitWrappedExpression(wrappedExpression: FirWrappedExpression, data: D): R = visitElement(wrappedExpression, data)
@@ -87,6 +87,8 @@ import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
import org.jetbrains.kotlin.fir.expressions.FirCheckedSafeCallSubject
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirWrappedExpression
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
@@ -457,6 +459,14 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitElement(expressionWithSmartcast)
}
open fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression) {
visitElement(safeCallExpression)
}
open fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject) {
visitElement(checkedSafeCallSubject)
}
open fun visitGetClassCall(getClassCall: FirGetClassCall) {
visitElement(getClassCall)
}
@@ -933,6 +943,14 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitExpressionWithSmartcast(expressionWithSmartcast)
}
final override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: Nothing?) {
visitSafeCallExpression(safeCallExpression)
}
final override fun visitCheckedSafeCallSubject(checkedSafeCallSubject: FirCheckedSafeCallSubject, data: Nothing?) {
visitCheckedSafeCallSubject(checkedSafeCallSubject)
}
final override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Nothing?) {
visitGetClassCall(getClassCall)
}
@@ -0,0 +1,14 @@
/*
* 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
}
}
@@ -0,0 +1,14 @@
/*
* 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
}
}
@@ -280,7 +280,9 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
resolvedQualifier,
resolvedReifiedParameterReference,
expression to "FirExpressionStub",
varargArgumentsExpression
varargArgumentsExpression,
checkedSafeCallSubject,
safeCallExpression
)
elementsWithDefaultTypeRef.forEach {
val (element, name) = when (it) {
@@ -375,4 +377,4 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
}
}
}
}
@@ -102,6 +102,8 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val callableReferenceAccess = element("CallableReferenceAccess", Expression, qualifiedAccessExpression)
val thisReceiverExpression = element("ThisReceiverExpression", Expression, qualifiedAccessExpression)
val expressionWithSmartcast = element("ExpressionWithSmartcast", Expression, qualifiedAccessExpression)
val safeCallExpression = element("SafeCallExpression", Expression, expression)
val checkedSafeCallSubject = element("CheckedSafeCallSubject", Expression, expression)
val getClassCall = element("GetClassCall", Expression, expression, call)
val wrappedExpression = element("WrappedExpression", Expression, expression)
val wrappedArgumentExpression = element("WrappedArgumentExpression", Expression, wrappedExpression)
@@ -481,6 +481,8 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
"FirResolvedReifiedParameterReferenceImpl",
"FirExpressionStub",
"FirVarargArgumentsExpressionImpl",
"FirSafeCallExpressionImpl",
"FirCheckedSafeCallSubjectImpl",
)
configureFieldInAllImplementations(
field = "typeRef",
@@ -439,6 +439,18 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+field("originalType", typeRef)
}
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)
// One that uses checkedReceiver as a receiver
+field("regularQualifiedAccess", qualifiedAccess, withReplace = true).withTransform()
}
checkedSafeCallSubject.configure {
+field("originalReceiverReference", safeCallReceiverReferenceType)
}
callableReferenceAccess.configure {
+field("calleeReference", namedReference, withReplace = true).withTransform()
}
@@ -6,7 +6,10 @@
package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.contracts.description.InvocationKind
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.tree.generator.context.generatedType
import org.jetbrains.kotlin.fir.tree.generator.context.type
@@ -35,6 +38,8 @@ 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 firSessionType = type("fir", "FirSession")
val emptyCfgReferenceType = generatedType("references.impl", "FirEmptyControlFlowGraphReference")
val noReceiverExpressionType = generatedType("expressions.impl", "FirNoReceiverExpression")
@@ -71,4 +76,4 @@ val coneStubDiagnosticType = generatedType("diagnostics", "ConeStubDiagnostic")
val dslBuilderAnnotationType = generatedType("builder", "FirBuilderDsl")
val firImplementationDetailType = generatedType("FirImplementationDetail")
val declarationOriginType = generatedType("declarations", "FirDeclarationOrigin")
val declarationAttributesType = generatedType("declarations", "FirDeclarationAttributes")
val declarationAttributesType = generatedType("declarations", "FirDeclarationAttributes")