[FIR] Support dispatch & extension receiver in component calls

This commit is contained in:
Mikhail Glukhikh
2020-04-08 17:08:03 +03:00
parent a93c7a39e0
commit cd5a4900e6
35 changed files with 25 additions and 45 deletions
@@ -37,6 +37,8 @@ class FirComponentCallBuilder : FirCallBuilder, FirAnnotationContainerBuilder, F
override var source: FirSourceElement? = null
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
var dispatchReceiver: FirExpression = FirNoReceiverExpression
var extensionReceiver: FirExpression = FirNoReceiverExpression
override var argumentList: FirArgumentList = FirEmptyArgumentList
lateinit var explicitReceiver: FirExpression
var componentIndex: Int by kotlin.properties.Delegates.notNull<Int>()
@@ -46,6 +48,8 @@ class FirComponentCallBuilder : FirCallBuilder, FirAnnotationContainerBuilder, F
source,
annotations,
typeArguments,
dispatchReceiver,
extensionReceiver,
argumentList,
explicitReceiver,
componentIndex,
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirArgumentList
import org.jetbrains.kotlin.fir.expressions.FirComponentCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.types.FirTypeProjection
@@ -30,14 +29,14 @@ internal class FirComponentCallImpl(
override val source: FirSourceElement?,
override val annotations: MutableList<FirAnnotationCall>,
override val typeArguments: MutableList<FirTypeProjection>,
override var dispatchReceiver: FirExpression,
override var extensionReceiver: FirExpression,
override var argumentList: FirArgumentList,
override var explicitReceiver: FirExpression,
override val componentIndex: Int,
) : FirComponentCall() {
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
override val safe: Boolean get() = false
override val dispatchReceiver: FirExpression get() = FirNoReceiverExpression
override val extensionReceiver: FirExpression get() = FirNoReceiverExpression
override var calleeReference: FirNamedReference = FirSimpleNamedReference(source, Name.identifier("component$componentIndex"), null)
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
@@ -62,6 +61,12 @@ internal class FirComponentCallImpl(
argumentList = argumentList.transformSingle(transformer, data)
transformCalleeReference(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)
}
return this
}
@@ -76,10 +81,12 @@ internal class FirComponentCallImpl(
}
override fun <D> transformDispatchReceiver(transformer: FirTransformer<D>, data: D): FirComponentCallImpl {
dispatchReceiver = dispatchReceiver.transformSingle(transformer, data)
return this
}
override fun <D> transformExtensionReceiver(transformer: FirTransformer<D>, data: D): FirComponentCallImpl {
extensionReceiver = extensionReceiver.transformSingle(transformer, data)
return this
}
@@ -125,6 +125,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
builder(componentCall) {
parents += callBuilder
defaultNoReceivers(notNullExplicitReceiver = true)
default("argumentList") {
value = "FirEmptyArgumentList"
}
@@ -97,14 +97,8 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
value = "false"
withGetter = true
}
listOf("dispatchReceiver", "extensionReceiver").forEach {
default(it) {
value = "FirNoReceiverExpression"
withGetter = true
}
}
default("calleeReference", "FirSimpleNamedReference(source, Name.identifier(\"component\$componentIndex\"), null)")
useTypes(simpleNamedReferenceType, nameType, noReceiverExpressionType)
useTypes(simpleNamedReferenceType, nameType)
optInToInternals()
}
@@ -23,8 +23,10 @@ abstract class AbstractBuilderConfigurator<T : AbstractFirTreeBuilder>(val firTr
types.forEach { builder.usedTypes += it }
}
fun defaultNoReceivers() {
defaultNull("explicitReceiver")
fun defaultNoReceivers(notNullExplicitReceiver: Boolean = false) {
if (!notNullExplicitReceiver) {
defaultNull("explicitReceiver")
}
default("dispatchReceiver", "FirNoReceiverExpression")
default("extensionReceiver", "FirNoReceiverExpression")
useTypes(noReceiverExpressionType)