Support nullable callable references in raw FIR

This commit is contained in:
Mikhail Glukhikh
2020-01-30 19:05:32 +03:00
parent 95122f1d0b
commit a584589665
6 changed files with 12 additions and 1 deletions
@@ -378,11 +378,13 @@ class ExpressionsConverter(
*/ */
private fun convertCallableReferenceExpression(callableReferenceExpression: LighterASTNode): FirExpression { private fun convertCallableReferenceExpression(callableReferenceExpression: LighterASTNode): FirExpression {
var isReceiver = true var isReceiver = true
var safe = false
var firReceiverExpression: FirExpression? = null var firReceiverExpression: FirExpression? = null
lateinit var firCallableReference: FirQualifiedAccess lateinit var firCallableReference: FirQualifiedAccess
callableReferenceExpression.forEachChildren { callableReferenceExpression.forEachChildren {
when (it.tokenType) { when (it.tokenType) {
COLONCOLON -> isReceiver = false COLONCOLON -> isReceiver = false
QUEST -> safe = true
else -> if (it.isExpression()) { else -> if (it.isExpression()) {
if (isReceiver) { if (isReceiver) {
firReceiverExpression = getAsFirExpression(it, "Incorrect receiver expression") firReceiverExpression = getAsFirExpression(it, "Incorrect receiver expression")
@@ -396,6 +398,7 @@ class ExpressionsConverter(
return FirCallableReferenceAccessImpl(null).apply { return FirCallableReferenceAccessImpl(null).apply {
calleeReference = firCallableReference.calleeReference as FirNamedReference calleeReference = firCallableReference.calleeReference as FirNamedReference
explicitReceiver = firReceiverExpression explicitReceiver = firReceiverExpression
this.safe = safe
} }
} }
@@ -1467,6 +1467,7 @@ class RawFirBuilder(session: FirSession, val scopeProvider: FirScopeProvider, va
expression.callableReference.toFirSourceElement(), expression.callableReference.getReferencedNameAsName(), null expression.callableReference.toFirSourceElement(), expression.callableReference.getReferencedNameAsName(), null
) )
explicitReceiver = expression.receiverExpression?.toFirExpression("Incorrect receiver expression") explicitReceiver = expression.receiverExpression?.toFirExpression("Incorrect receiver expression")
safe = expression.hasQuestionMarks
} }
} }
@@ -20,3 +20,5 @@ val test5 = A::bar
val test6 = A::qux val test6 = A::qux
val test7 = ::baz val test7 = ::baz
val test8 = A?::foo
@@ -29,3 +29,5 @@ FILE: callableReferences.kt
public? get(): <implicit> public? get(): <implicit>
public? final? val test7: <implicit> = ::baz# public? final? val test7: <implicit> = ::baz#
public? get(): <implicit> public? get(): <implicit>
public? final? val test8: <implicit> = A#?::foo#
public? get(): <implicit>
@@ -4,7 +4,7 @@ FILE: getOnKProperty.kt
^ Int(42) ^ Int(42)
} }
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/Unit| {
lval f: R|kotlin/reflect/KProperty1<kotlin/Any, kotlin/Int>| = Q|kotlin/Any|::R|/meaning| lval f: R|kotlin/reflect/KProperty1<kotlin/Any, kotlin/Int>| = Q|kotlin/Any|?::R|/meaning|
R|<local>/f|.<Inapplicable(INAPPLICABLE): [kotlin/reflect/KProperty1.get]>#(Null(null)) R|<local>/f|.<Inapplicable(INAPPLICABLE): [kotlin/reflect/KProperty1.get]>#(Null(null))
R|<local>/f|.R|FakeOverride<kotlin/reflect/KProperty1.get: R|kotlin/Int|>|(String()) R|<local>/f|.R|FakeOverride<kotlin/reflect/KProperty1.get: R|kotlin/Int|>|(String())
} }
@@ -944,6 +944,9 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess) { override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess) {
callableReferenceAccess.annotations.renderAnnotations() callableReferenceAccess.annotations.renderAnnotations()
callableReferenceAccess.explicitReceiver?.accept(this) callableReferenceAccess.explicitReceiver?.accept(this)
if (callableReferenceAccess.safe) {
print("?")
}
print("::") print("::")
callableReferenceAccess.calleeReference.accept(this) callableReferenceAccess.calleeReference.accept(this)
} }