FIR: Use more refined names instead of "safe"

^KT-38444 Fixed
This commit is contained in:
Denis Zharkov
2020-06-02 12:42:23 +03:00
parent 6507656496
commit 4a4dce1766
14 changed files with 35 additions and 25 deletions
@@ -432,13 +432,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 hasQuestionMarkAtLHS = 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 QUEST -> hasQuestionMarkAtLHS = 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")
@@ -453,7 +453,7 @@ class ExpressionsConverter(
source = callableReferenceExpression.toFirSourceElement() source = callableReferenceExpression.toFirSourceElement()
calleeReference = firCallableReference.calleeReference as FirNamedReference calleeReference = firCallableReference.calleeReference as FirNamedReference
explicitReceiver = firReceiverExpression explicitReceiver = firReceiverExpression
this.safe = safe this.hasQuestionMarkAtLHS = hasQuestionMarkAtLHS
} }
} }
@@ -487,7 +487,6 @@ class ExpressionsConverter(
return it.wrapWithSafeCall(firReceiver!!) return it.wrapWithSafeCall(firReceiver!!)
} }
it.safe = false
it.explicitReceiver = firReceiver it.explicitReceiver = firReceiver
} }
return firSelector return firSelector
@@ -1812,7 +1812,7 @@ class RawFirBuilder(
name = expression.callableReference.getReferencedNameAsName() name = expression.callableReference.getReferencedNameAsName()
} }
explicitReceiver = expression.receiverExpression?.toFirExpression("Incorrect receiver expression") explicitReceiver = expression.receiverExpression?.toFirExpression("Incorrect receiver expression")
safe = expression.hasQuestionMarks hasQuestionMarkAtLHS = expression.hasQuestionMarks
} }
} }
@@ -71,7 +71,7 @@ class FirDoubleColonExpressionResolver(
private fun shouldTryResolveLHSAsExpression(expression: FirCallableReferenceAccess): Boolean { private fun shouldTryResolveLHSAsExpression(expression: FirCallableReferenceAccess): Boolean {
val lhs = expression.explicitReceiver ?: return false val lhs = expression.explicitReceiver ?: return false
return lhs.canBeConsideredProperExpression() && !expression.safe return lhs.canBeConsideredProperExpression() && !expression.hasQuestionMarkAtLHS
} }
private fun shouldTryResolveLHSAsType(expression: FirCallableReferenceAccess): Boolean { private fun shouldTryResolveLHSAsType(expression: FirCallableReferenceAccess): Boolean {
@@ -172,7 +172,7 @@ class FirDoubleColonExpressionResolver(
else -> ConeStarProjection else -> ConeStarProjection
} }
}, },
isNullable = expression.safe isNullable = resolvedExpression.isNullableLHSForCallableReference
) )
return DoubleColonLHS.Type(type) return DoubleColonLHS.Type(type)
@@ -511,8 +511,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
callableReferenceAccess.annotations.forEach { it.accept(this, data) } callableReferenceAccess.annotations.forEach { it.accept(this, data) }
val explicitReceiver = callableReferenceAccess.explicitReceiver val explicitReceiver = callableReferenceAccess.explicitReceiver
val transformedLHS = explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply { val transformedLHS = explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply {
if (this is FirResolvedQualifier && callableReferenceAccess.safe) { if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
replaceSafe(true) replaceIsNullableLHSForCallableReference(true)
} }
} }
@@ -21,12 +21,12 @@ abstract class FirCallableReferenceAccess : FirQualifiedAccessExpression() {
abstract override val source: FirSourceElement? abstract override val source: FirSourceElement?
abstract override val typeRef: FirTypeRef abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotationCall> abstract override val annotations: List<FirAnnotationCall>
abstract override val safe: Boolean
abstract override val typeArguments: List<FirTypeProjection> abstract override val typeArguments: List<FirTypeProjection>
abstract override val explicitReceiver: FirExpression? abstract override val explicitReceiver: FirExpression?
abstract override val dispatchReceiver: FirExpression abstract override val dispatchReceiver: FirExpression
abstract override val extensionReceiver: FirExpression abstract override val extensionReceiver: FirExpression
abstract override val calleeReference: FirNamedReference abstract override val calleeReference: FirNamedReference
abstract val hasQuestionMarkAtLHS: Boolean
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitCallableReferenceAccess(this, data) override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitCallableReferenceAccess(this, data)
@@ -38,6 +38,8 @@ abstract class FirCallableReferenceAccess : FirQualifiedAccessExpression() {
abstract override fun replaceCalleeReference(newCalleeReference: FirReference) abstract override fun replaceCalleeReference(newCalleeReference: FirReference)
abstract fun replaceHasQuestionMarkAtLHS(newHasQuestionMarkAtLHS: Boolean)
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirCallableReferenceAccess abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirCallableReferenceAccess
abstract override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirCallableReferenceAccess abstract override fun <D> transformTypeArguments(transformer: FirTransformer<D>, data: D): FirCallableReferenceAccess
@@ -26,14 +26,14 @@ abstract class FirResolvedQualifier : FirExpression() {
abstract val relativeClassFqName: FqName? abstract val relativeClassFqName: FqName?
abstract val classId: ClassId? abstract val classId: ClassId?
abstract val symbol: FirClassLikeSymbol<*>? abstract val symbol: FirClassLikeSymbol<*>?
abstract val safe: Boolean abstract val isNullableLHSForCallableReference: Boolean
abstract val typeArguments: List<FirTypeProjection> abstract val typeArguments: List<FirTypeProjection>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedQualifier(this, data) override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedQualifier(this, data)
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef) abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
abstract fun replaceSafe(newSafe: Boolean) abstract fun replaceIsNullableLHSForCallableReference(newIsNullableLHSForCallableReference: Boolean)
abstract fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) abstract fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
@@ -34,24 +34,24 @@ class FirCallableReferenceAccessBuilder : FirQualifiedAccessBuilder, FirAnnotati
override var source: FirSourceElement? = null override var source: FirSourceElement? = null
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
override val annotations: MutableList<FirAnnotationCall> = mutableListOf() override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
override var safe: Boolean = false
override val typeArguments: MutableList<FirTypeProjection> = mutableListOf() override val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
override var explicitReceiver: FirExpression? = null override var explicitReceiver: FirExpression? = null
override var dispatchReceiver: FirExpression = FirNoReceiverExpression override var dispatchReceiver: FirExpression = FirNoReceiverExpression
override var extensionReceiver: FirExpression = FirNoReceiverExpression override var extensionReceiver: FirExpression = FirNoReceiverExpression
lateinit var calleeReference: FirNamedReference lateinit var calleeReference: FirNamedReference
var hasQuestionMarkAtLHS: Boolean = false
override fun build(): FirCallableReferenceAccess { override fun build(): FirCallableReferenceAccess {
return FirCallableReferenceAccessImpl( return FirCallableReferenceAccessImpl(
source, source,
typeRef, typeRef,
annotations, annotations,
safe,
typeArguments, typeArguments,
explicitReceiver, explicitReceiver,
dispatchReceiver, dispatchReceiver,
extensionReceiver, extensionReceiver,
calleeReference, calleeReference,
hasQuestionMarkAtLHS,
) )
} }
@@ -34,7 +34,7 @@ class FirResolvedQualifierBuilder : FirAnnotationContainerBuilder, FirExpression
lateinit var packageFqName: FqName lateinit var packageFqName: FqName
var relativeClassFqName: FqName? = null var relativeClassFqName: FqName? = null
var symbol: FirClassLikeSymbol<*>? = null var symbol: FirClassLikeSymbol<*>? = null
var safe: Boolean by kotlin.properties.Delegates.notNull<Boolean>() var isNullableLHSForCallableReference: Boolean = false
val typeArguments: MutableList<FirTypeProjection> = mutableListOf() val typeArguments: MutableList<FirTypeProjection> = mutableListOf()
override fun build(): FirResolvedQualifier { override fun build(): FirResolvedQualifier {
@@ -45,7 +45,7 @@ class FirResolvedQualifierBuilder : FirAnnotationContainerBuilder, FirExpression
packageFqName, packageFqName,
relativeClassFqName, relativeClassFqName,
symbol, symbol,
safe, isNullableLHSForCallableReference,
typeArguments, typeArguments,
) )
} }
@@ -25,12 +25,12 @@ internal class FirCallableReferenceAccessImpl(
override val source: FirSourceElement?, override val source: FirSourceElement?,
override var typeRef: FirTypeRef, override var typeRef: FirTypeRef,
override val annotations: MutableList<FirAnnotationCall>, override val annotations: MutableList<FirAnnotationCall>,
override var safe: Boolean,
override val typeArguments: MutableList<FirTypeProjection>, override val typeArguments: MutableList<FirTypeProjection>,
override var explicitReceiver: FirExpression?, override var explicitReceiver: FirExpression?,
override var dispatchReceiver: FirExpression, override var dispatchReceiver: FirExpression,
override var extensionReceiver: FirExpression, override var extensionReceiver: FirExpression,
override var calleeReference: FirNamedReference, override var calleeReference: FirNamedReference,
override var hasQuestionMarkAtLHS: Boolean,
) : FirCallableReferenceAccess(), FirModifiableQualifiedAccess { ) : FirCallableReferenceAccess(), FirModifiableQualifiedAccess {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) { override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data) typeRef.accept(visitor, data)
@@ -108,4 +108,8 @@ internal class FirCallableReferenceAccessImpl(
require(newCalleeReference is FirNamedReference) require(newCalleeReference is FirNamedReference)
replaceCalleeReference(newCalleeReference) replaceCalleeReference(newCalleeReference)
} }
override fun replaceHasQuestionMarkAtLHS(newHasQuestionMarkAtLHS: Boolean) {
hasQuestionMarkAtLHS = newHasQuestionMarkAtLHS
}
} }
@@ -27,7 +27,7 @@ internal class FirResolvedQualifierImpl(
override var packageFqName: FqName, override var packageFqName: FqName,
override var relativeClassFqName: FqName?, override var relativeClassFqName: FqName?,
override val symbol: FirClassLikeSymbol<*>?, override val symbol: FirClassLikeSymbol<*>?,
override var safe: Boolean, override var isNullableLHSForCallableReference: Boolean,
override val typeArguments: MutableList<FirTypeProjection>, override val typeArguments: MutableList<FirTypeProjection>,
) : FirResolvedQualifier() { ) : FirResolvedQualifier() {
override val classId: ClassId? get() = relativeClassFqName?.let { override val classId: ClassId? get() = relativeClassFqName?.let {
@@ -61,8 +61,8 @@ internal class FirResolvedQualifierImpl(
typeRef = newTypeRef typeRef = newTypeRef
} }
override fun replaceSafe(newSafe: Boolean) { override fun replaceIsNullableLHSForCallableReference(newIsNullableLHSForCallableReference: Boolean) {
safe = newSafe isNullableLHSForCallableReference = newIsNullableLHSForCallableReference
} }
override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) { override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) {
@@ -1018,7 +1018,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
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 && callableReferenceAccess.explicitReceiver !is FirResolvedQualifier) { if (callableReferenceAccess.hasQuestionMarkAtLHS && callableReferenceAccess.explicitReceiver !is FirResolvedQualifier) {
print("?") print("?")
} }
print("::") print("::")
@@ -1127,7 +1127,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
} else { } else {
print(resolvedQualifier.packageFqName.asString().replace(".", "/")) print(resolvedQualifier.packageFqName.asString().replace(".", "/"))
} }
if (resolvedQualifier.safe) { if (resolvedQualifier.isNullableLHSForCallableReference) {
print("?") print("?")
} }
print("|") print("|")
@@ -111,7 +111,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
parents += qualifiedAccessBuilder parents += qualifiedAccessBuilder
defaultNull("explicitReceiver") defaultNull("explicitReceiver")
defaultNoReceivers() defaultNoReceivers()
defaultFalse("safe") defaultFalse("hasQuestionMarkAtLHS")
} }
builder(componentCall) { builder(componentCall) {
@@ -265,6 +265,10 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
default("symbol", "FirAnonymousInitializerSymbol()") default("symbol", "FirAnonymousInitializerSymbol()")
} }
builder(resolvedQualifier) {
defaultFalse("isNullableLHSForCallableReference")
}
val elementsWithDefaultTypeRef = listOf( val elementsWithDefaultTypeRef = listOf(
thisReceiverExpression, thisReceiverExpression,
callableReferenceAccess, callableReferenceAccess,
@@ -219,7 +219,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
impl(typeOperatorCall) impl(typeOperatorCall)
impl(resolvedQualifier) { impl(resolvedQualifier) {
isMutable("packageFqName", "relativeClassFqName", "safe") isMutable("packageFqName", "relativeClassFqName", "isNullableLHSForCallableReference")
default("classId") { default("classId") {
value = """ value = """
|relativeClassFqName?.let { |relativeClassFqName?.let {
@@ -452,6 +452,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
callableReferenceAccess.configure { callableReferenceAccess.configure {
+field("calleeReference", namedReference, withReplace = true).withTransform() +field("calleeReference", namedReference, withReplace = true).withTransform()
+booleanField("hasQuestionMarkAtLHS", withReplace = true)
} }
getClassCall.configure { getClassCall.configure {
@@ -476,7 +477,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+field("relativeClassFqName", fqNameType, nullable = true) +field("relativeClassFqName", fqNameType, nullable = true)
+field("classId", classIdType, nullable = true) +field("classId", classIdType, nullable = true)
+field("symbol", classLikeSymbolType, nullable = true) +field("symbol", classLikeSymbolType, nullable = true)
+booleanField("safe", withReplace = true) +booleanField("isNullableLHSForCallableReference", withReplace = true)
+typeArguments.withTransform() +typeArguments.withTransform()
} }