FIR tree: add dispatch & extension receivers
This commit is contained in:
+4
-2
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirWrappedDelegateExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
@@ -80,6 +81,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
val childElement = property.getter.apply { isAccessible = true }.call(this)
|
||||
|
||||
when (childElement) {
|
||||
is FirNoReceiverExpression -> continue@propertyLoop
|
||||
is FirElement -> childElement.traverseChildren(result)
|
||||
is List<*> -> childElement.filterIsInstance<FirElement>().forEach { it.traverseChildren(result) }
|
||||
else -> continue@propertyLoop
|
||||
@@ -129,7 +131,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
override fun visitElement(element: FirElement) {
|
||||
// NB: types are reused sometimes (e.g. in accessors)
|
||||
if (!result.add(element)) {
|
||||
if (element !is FirTypeRef) {
|
||||
if (element !is FirTypeRef && element !is FirNoReceiverExpression) {
|
||||
val elementDump = StringBuilder().also { element.accept(FirRenderer(it)) }.toString()
|
||||
throw AssertionError("FirElement ${element.javaClass} is visited twice: $elementDump")
|
||||
}
|
||||
@@ -146,7 +148,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
|
||||
override fun <E : FirElement> transformElement(element: E, data: Unit): CompositeTransformResult<E> {
|
||||
if (!result.add(element)) {
|
||||
if (element !is FirTypeRef) {
|
||||
if (element !is FirTypeRef && element !is FirNoReceiverExpression) {
|
||||
val elementDump = StringBuilder().also { element.accept(FirRenderer(it)) }.toString()
|
||||
throw AssertionError("FirElement ${element.javaClass} is visited twice: $elementDump")
|
||||
}
|
||||
|
||||
@@ -10,10 +10,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirLoopJump
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
@@ -827,13 +824,29 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
||||
|
||||
override fun visitQualifiedAccess(qualifiedAccess: FirQualifiedAccess) {
|
||||
val explicitReceiver = qualifiedAccess.explicitReceiver
|
||||
val dispatchReceiver = qualifiedAccess.dispatchReceiver
|
||||
val extensionReceiver = qualifiedAccess.extensionReceiver
|
||||
if (dispatchReceiver !is FirNoReceiverExpression) {
|
||||
print("D|")
|
||||
dispatchReceiver.accept(this)
|
||||
print("|")
|
||||
}
|
||||
if (extensionReceiver !is FirNoReceiverExpression) {
|
||||
print("E|")
|
||||
extensionReceiver.accept(this)
|
||||
print("|")
|
||||
}
|
||||
if (explicitReceiver != null) {
|
||||
explicitReceiver.accept(this)
|
||||
if (explicitReceiver !== dispatchReceiver && explicitReceiver !== extensionReceiver) {
|
||||
explicitReceiver.accept(this)
|
||||
}
|
||||
if (qualifiedAccess.safe) {
|
||||
print("?.")
|
||||
} else {
|
||||
print(".")
|
||||
}
|
||||
} else if (dispatchReceiver !is FirNoReceiverExpression || extensionReceiver !is FirNoReceiverExpression) {
|
||||
print(".")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
@@ -13,6 +14,10 @@ interface FirQualifiedAccess : FirResolvable {
|
||||
|
||||
val explicitReceiver: FirExpression? get() = null
|
||||
|
||||
val dispatchReceiver: FirExpression get() = FirNoReceiverExpression
|
||||
|
||||
val extensionReceiver: FirExpression get() = FirNoReceiverExpression
|
||||
|
||||
fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirQualifiedAccess
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
|
||||
@@ -21,6 +26,8 @@ interface FirQualifiedAccess : FirResolvable {
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
calleeReference.accept(visitor, data)
|
||||
explicitReceiver?.accept(visitor, data)
|
||||
dispatchReceiver.accept(visitor, data)
|
||||
extensionReceiver.accept(visitor, data)
|
||||
super.acceptChildren(visitor, data)
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -19,6 +19,8 @@ abstract class FirQualifiedAccessExpression(
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
calleeReference.accept(visitor, data)
|
||||
explicitReceiver?.accept(visitor, data)
|
||||
dispatchReceiver.accept(visitor, data)
|
||||
extensionReceiver.accept(visitor, data)
|
||||
super<FirUnknownTypeExpression>.acceptChildren(visitor, data)
|
||||
}
|
||||
}
|
||||
+7
@@ -19,9 +19,16 @@ abstract class FirAbstractQualifiedAccess(
|
||||
|
||||
final override var explicitReceiver: FirExpression? = null
|
||||
|
||||
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
||||
|
||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
calleeReference = calleeReference.transformSingle(transformer, data)
|
||||
explicitReceiver = explicitReceiver?.transformSingle(transformer, data)
|
||||
dispatchReceiver = dispatchReceiver.transformSingle(transformer, data)
|
||||
extensionReceiver = extensionReceiver.transformSingle(transformer, data)
|
||||
|
||||
return super<FirAnnotatedStatement>.transformChildren(transformer, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,17 @@ class FirFunctionCallImpl(
|
||||
|
||||
override var explicitReceiver: FirExpression? = null
|
||||
|
||||
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
||||
|
||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
typeArguments.transformInplace(transformer, data)
|
||||
calleeReference = calleeReference.transformSingle(transformer, data)
|
||||
explicitReceiver = explicitReceiver?.transformSingle(transformer, data)
|
||||
dispatchReceiver = dispatchReceiver.transformSingle(transformer, data)
|
||||
extensionReceiver = extensionReceiver.transformSingle(transformer, data)
|
||||
|
||||
return super<FirFunctionCall>.transformChildren(transformer, data)
|
||||
}
|
||||
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
|
||||
object FirNoReceiverExpression : FirExpression(null) {
|
||||
override val typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||
|
||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) {}
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||
}
|
||||
+6
@@ -21,9 +21,15 @@ class FirQualifiedAccessExpressionImpl(
|
||||
|
||||
override var explicitReceiver: FirExpression? = null
|
||||
|
||||
override var dispatchReceiver: FirExpression = FirNoReceiverExpression
|
||||
|
||||
override var extensionReceiver: FirExpression = FirNoReceiverExpression
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
calleeReference = calleeReference.transformSingle(transformer, data)
|
||||
explicitReceiver = explicitReceiver?.transformSingle(transformer, data)
|
||||
dispatchReceiver = dispatchReceiver.transformSingle(transformer, data)
|
||||
extensionReceiver = extensionReceiver.transformSingle(transformer, data)
|
||||
|
||||
return super<FirQualifiedAccessExpression>.transformChildren(transformer, data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user