FIR: add a boolean tracking if a class ref resolves to the companion object

This commit is contained in:
Tianyu Geng
2021-06-08 17:58:29 -07:00
committed by Ilya Kirillov
parent 45ccec3b64
commit a537074e1e
12 changed files with 82 additions and 0 deletions
@@ -30,6 +30,7 @@ abstract class FirErrorResolvedQualifier : FirResolvedQualifier(), FirDiagnostic
abstract override val classId: ClassId?
abstract override val symbol: FirClassLikeSymbol<*>?
abstract override val isNullableLHSForCallableReference: Boolean
abstract override val resolvedToCompanionObject: Boolean
abstract override val typeArguments: List<FirTypeProjection>
abstract override val diagnostic: ConeDiagnostic
@@ -43,6 +44,8 @@ abstract class FirErrorResolvedQualifier : FirResolvedQualifier(), FirDiagnostic
abstract override fun replaceIsNullableLHSForCallableReference(newIsNullableLHSForCallableReference: Boolean)
abstract override fun replaceResolvedToCompanionObject(newResolvedToCompanionObject: Boolean)
abstract override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirErrorResolvedQualifier
@@ -28,6 +28,7 @@ abstract class FirResolvedQualifier : FirExpression() {
abstract val classId: ClassId?
abstract val symbol: FirClassLikeSymbol<*>?
abstract val isNullableLHSForCallableReference: Boolean
abstract val resolvedToCompanionObject: Boolean
abstract val typeArguments: List<FirTypeProjection>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedQualifier(this, data)
@@ -40,6 +41,8 @@ abstract class FirResolvedQualifier : FirExpression() {
abstract fun replaceIsNullableLHSForCallableReference(newIsNullableLHSForCallableReference: Boolean)
abstract fun replaceResolvedToCompanionObject(newResolvedToCompanionObject: Boolean)
abstract fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>)
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirResolvedQualifier
@@ -31,6 +31,7 @@ interface FirAbstractResolvedQualifierBuilder {
abstract var classId: ClassId?
abstract var symbol: FirClassLikeSymbol<*>?
abstract var isNullableLHSForCallableReference: Boolean
abstract var resolvedToCompanionObject: Boolean
abstract val typeArguments: MutableList<FirTypeProjection>
fun build(): FirResolvedQualifier
@@ -61,6 +61,13 @@ class FirErrorResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, Fi
set(_) {
throw IllegalStateException()
}
@Deprecated("Modification of 'resolvedToCompanionObject' has no impact for FirErrorResolvedQualifierBuilder", level = DeprecationLevel.HIDDEN)
override var resolvedToCompanionObject: Boolean
get() = throw IllegalStateException()
set(_) {
throw IllegalStateException()
}
}
@OptIn(ExperimentalContracts::class)
@@ -9,6 +9,7 @@ import kotlin.contracts.*
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.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.builder.FirAbstractResolvedQualifierBuilder
@@ -58,6 +59,13 @@ class FirResolvedQualifierBuilder : FirAbstractResolvedQualifierBuilder, FirAnno
set(_) {
throw IllegalStateException()
}
@Deprecated("Modification of 'resolvedToCompanionObject' has no impact for FirResolvedQualifierBuilder", level = DeprecationLevel.HIDDEN)
override var resolvedToCompanionObject: Boolean
get() = throw IllegalStateException()
set(_) {
throw IllegalStateException()
}
}
@OptIn(ExperimentalContracts::class)
@@ -34,6 +34,7 @@ internal class FirErrorResolvedQualifierImpl(
override val diagnostic: ConeDiagnostic,
) : FirErrorResolvedQualifier() {
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
override val resolvedToCompanionObject: Boolean get() = false
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
@@ -66,6 +67,8 @@ internal class FirErrorResolvedQualifierImpl(
isNullableLHSForCallableReference = newIsNullableLHSForCallableReference
}
override fun replaceResolvedToCompanionObject(newResolvedToCompanionObject: Boolean) {}
override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) {
typeArguments.clear()
typeArguments.addAll(newTypeArguments)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.expressions.impl
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
@@ -33,6 +34,7 @@ internal class FirResolvedQualifierImpl(
override val classId: ClassId? get() = relativeClassFqName?.let {
ClassId(packageFqName, it, false)
}
override var resolvedToCompanionObject: Boolean = (symbol?.fir as? FirRegularClass)?.companionObject != null
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
@@ -65,6 +67,10 @@ internal class FirResolvedQualifierImpl(
isNullableLHSForCallableReference = newIsNullableLHSForCallableReference
}
override fun replaceResolvedToCompanionObject(newResolvedToCompanionObject: Boolean) {
resolvedToCompanionObject = newResolvedToCompanionObject
}
override fun replaceTypeArguments(newTypeArguments: List<FirTypeProjection>) {
typeArguments.clear()
typeArguments.addAll(newTypeArguments)
@@ -469,6 +469,27 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
useTypes(expressionType)
}
impl(resolvedQualifier) {
// Initialize the value to true if only the companion object is present. This makes a standalone class reference expression
// correctly resolve to the companion object. For example
// ```
// class A {
// companion object
// }
//
// val companionOfA = A // This standalone class reference `A` here should resolve to the companion object.
// ```
//
// If this `FirResolvedQualifier` is a receiver expression of some other qualified access, the value is updated in
// `FirCallResolver` according to the resolution result.
default("resolvedToCompanionObject", "(symbol?.fir as? FirRegularClass)?.companionObject != null")
useTypes(regularClass)
}
impl(errorResolvedQualifier) {
defaultFalse("resolvedToCompanionObject", withGetter = true)
}
noImpl(userTypeRef)
}
@@ -516,6 +516,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+field("classId", classIdType, nullable = true)
+field("symbol", classLikeSymbolType, nullable = true)
+booleanField("isNullableLHSForCallableReference", withReplace = true)
+booleanField("resolvedToCompanionObject", withReplace = true)
+typeArguments.withTransform()
}