[FIR] Add desugaring of array assignments and resolve of it

#KT-37516 Fixed
This commit is contained in:
Dmitriy Novozhilov
2020-03-16 17:00:08 +03:00
parent 26f919df03
commit 2b986194fb
41 changed files with 608 additions and 233 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.fir.FirPureAbstractElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -16,34 +15,15 @@ import org.jetbrains.kotlin.fir.visitors.*
* DO NOT MODIFY IT MANUALLY
*/
abstract class FirArraySetCall : FirPureAbstractElement(), FirQualifiedAccess, FirCall {
abstract class FirArraySetCall : FirPureAbstractElement(), FirStatement {
abstract override val source: FirSourceElement?
abstract override val annotations: List<FirAnnotationCall>
abstract override val safe: Boolean
abstract override val typeArguments: List<FirTypeProjection>
abstract override val explicitReceiver: FirExpression?
abstract override val dispatchReceiver: FirExpression
abstract override val extensionReceiver: FirExpression
abstract override val calleeReference: FirReference
abstract override val argumentList: FirArgumentList
abstract val rValue: FirExpression
abstract val assignCall: FirFunctionCall
abstract val setGetBlock: FirBlock
abstract val operation: FirOperation
abstract val lValue: FirReference
abstract val indexes: List<FirExpression>
abstract val calleeReference: FirReference
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitArraySetCall(this, data)
abstract override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirArraySetCall
abstract override fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirArraySetCall
abstract override fun <D> transformDispatchReceiver(transformer: FirTransformer<D>, data: D): FirArraySetCall
abstract override fun <D> transformExtensionReceiver(transformer: FirTransformer<D>, data: D): FirArraySetCall
abstract override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirArraySetCall
abstract fun <D> transformRValue(transformer: FirTransformer<D>, data: D): FirArraySetCall
abstract fun <D> transformIndexes(transformer: FirTransformer<D>, data: D): FirArraySetCall
abstract fun replaceCalleeReference(newCalleeReference: FirReference)
}
@@ -10,16 +10,13 @@ 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.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirArraySetCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessBuilder
import org.jetbrains.kotlin.fir.expressions.impl.FirArraySetCallImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirModifiableQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.references.impl.FirStubReference
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -28,34 +25,22 @@ import org.jetbrains.kotlin.fir.visitors.*
*/
@FirBuilderDsl
class FirArraySetCallBuilder : FirQualifiedAccessBuilder, FirAnnotationContainerBuilder {
class FirArraySetCallBuilder : FirAnnotationContainerBuilder {
override var source: FirSourceElement? = null
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
override var safe: Boolean = false
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
override var explicitReceiver: FirExpression? = null
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
override var extensionReceiver: FirExpression = FirNoReceiverExpression
lateinit var calleeReference: FirReference
lateinit var argumentList: FirArgumentList
lateinit var rValue: FirExpression
lateinit var assignCall: FirFunctionCall
lateinit var setGetBlock: FirBlock
lateinit var operation: FirOperation
val indexes: MutableList<FirExpression> = mutableListOf()
var calleeReference: FirReference = FirStubReference
override fun build(): FirArraySetCall {
return FirArraySetCallImpl(
source,
annotations,
safe,
typeArguments,
explicitReceiver,
dispatchReceiver,
extensionReceiver,
calleeReference,
argumentList,
rValue,
assignCall,
setGetBlock,
operation,
indexes,
calleeReference,
)
}
@@ -7,13 +7,11 @@ package org.jetbrains.kotlin.fir.expressions.impl
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirArraySetCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.impl.FirModifiableQualifiedAccess
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -24,97 +22,27 @@ import org.jetbrains.kotlin.fir.visitors.*
internal class FirArraySetCallImpl(
override val source: FirSourceElement?,
override val annotations: MutableList<FirAnnotationCall>,
override var safe: Boolean,
override val typeArguments: MutableList<FirTypeProjection>,
override var explicitReceiver: FirExpression?,
override var dispatchReceiver: FirExpression,
override var extensionReceiver: FirExpression,
override var calleeReference: FirReference,
override var argumentList: FirArgumentList,
override var rValue: FirExpression,
override var assignCall: FirFunctionCall,
override var setGetBlock: FirBlock,
override val operation: FirOperation,
override val indexes: MutableList<FirExpression>,
) : FirArraySetCall(), FirModifiableQualifiedAccess {
override var lValue: FirReference
get() = calleeReference
set(value) {
calleeReference = value
}
override var calleeReference: FirReference,
) : FirArraySetCall() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
typeArguments.forEach { it.accept(visitor, data) }
explicitReceiver?.accept(visitor, data)
if (dispatchReceiver !== explicitReceiver) {
dispatchReceiver.accept(visitor, data)
}
if (extensionReceiver !== explicitReceiver && extensionReceiver !== dispatchReceiver) {
extensionReceiver.accept(visitor, data)
}
assignCall.accept(visitor, data)
setGetBlock.accept(visitor, data)
calleeReference.accept(visitor, data)
argumentList.accept(visitor, data)
rValue.accept(visitor, data)
indexes.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
annotations.transformInplace(transformer, data)
transformTypeArguments(transformer, data)
explicitReceiver = explicitReceiver?.transformSingle(transformer, data)
if (dispatchReceiver !== explicitReceiver) {
dispatchReceiver = dispatchReceiver.transformSingle(transformer, data)
}
if (extensionReceiver !== explicitReceiver && extensionReceiver !== dispatchReceiver) {
extensionReceiver = extensionReceiver.transformSingle(transformer, data)
}
transformCalleeReference(transformer, data)
argumentList = argumentList.transformSingle(transformer, data)
transformRValue(transformer, data)
transformIndexes(transformer, data)
return this
}
override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
typeArguments.transformInplace(transformer, data)
return this
}
override fun <D> transformExplicitReceiver(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
explicitReceiver = explicitReceiver?.transformSingle(transformer, data)
return this
}
override fun <D> transformDispatchReceiver(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
dispatchReceiver = dispatchReceiver.transformSingle(transformer, data)
return this
}
override fun <D> transformExtensionReceiver(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
extensionReceiver = extensionReceiver.transformSingle(transformer, data)
return this
}
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
assignCall = assignCall.transformSingle(transformer, data)
setGetBlock = setGetBlock.transformSingle(transformer, data)
calleeReference = calleeReference.transformSingle(transformer, data)
return this
}
override fun <D> transformRValue(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
rValue = rValue.transformSingle(transformer, data)
return this
}
override fun <D> transformIndexes(transformer: FirTransformer<D>, data: D): FirArraySetCallImpl {
indexes.transformInplace(transformer, data)
return this
}
override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) {
typeArguments.clear()
typeArguments.addAll(newTypeArguments)
}
override fun replaceArgumentList(newArgumentList: FirArgumentList) {
argumentList = newArgumentList
override fun replaceCalleeReference(newCalleeReference: FirReference) {
calleeReference = newCalleeReference
}
}
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.Variance
@@ -1000,12 +999,9 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
override fun visitArraySetCall(arraySetCall: FirArraySetCall) {
arraySetCall.annotations.renderAnnotations()
visitQualifiedAccess(arraySetCall)
arraySetCall.lValue.accept(this)
print("[")
arraySetCall.indexes.renderSeparated()
print("] ")
visitAssignment(arraySetCall.operation, arraySetCall.rValue)
print("ArraySet:[")
arraySetCall.assignCall.accept(this)
print("]")
}
override fun visitFunctionCall(functionCall: FirFunctionCall) {
@@ -112,9 +112,8 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
}
builder(arraySetCall) {
parents += qualifiedAccessBuilder
defaultFalse("safe")
defaultNoReceivers()
default("calleeReference", "FirStubReference")
useTypes(stubReferenceType)
}
builder(callableReferenceAccess) {
@@ -89,7 +89,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val checkNotNullCall = element("CheckNotNullCall", Expression, expression, call, resolvable)
val arrayOfCall = element("ArrayOfCall", Expression, expression, call)
val arraySetCall = element("ArraySetCall", Expression, qualifiedAccess, call)
val arraySetCall = element("ArraySetCall", Expression, statement)
val classReferenceExpression = element("ClassReferenceExpression", Expression, expression)
val errorExpression = element("ErrorExpression", Expression, expression, diagnosticHolder)
val errorFunction = element("ErrorFunction", Declaration, function, diagnosticHolder)
@@ -86,14 +86,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
isMutable("safe")
}
impl(arraySetCall) {
parents += modifiableQualifiedAccess
default("lValue") {
value = "calleeReference"
customSetter = "calleeReference = value"
}
}
impl(callableReferenceAccess) {
parents += modifiableQualifiedAccess
}
@@ -396,10 +396,10 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
}
arraySetCall.configure {
+field("rValue", expression).withTransform()
+field("assignCall", functionCall)
+field("setGetBlock", block)
+field("operation", operationType)
+field("lValue", reference)
+fieldList("indexes", expression).withTransform()
+field("calleeReference", reference, withReplace = true)
}
classReferenceExpression.configure {