[FIR] Make FirRegularClass.companionObject companionObjectSymbol field

This is needed for two reasons:
1. Before this change companion object appeared in FirRegularClass
  twice: in declarations list and in companionObject field. This may
  trigger twice transform of it
2. It's very hard to implement generation of companion object by plugins
  because if it is part of the tree then generated declaration must be
  registered in FirProvider, which is inconsistent with other generated
  declarations. Replacing FIR with symbol and removing custom logic of
  visiting/transforming companion FIR allows us to just replace companionSymbol
  in FirClass if plugin wants to generate it without any additional work
This commit is contained in:
Dmitriy Novozhilov
2021-10-18 18:37:14 +03:00
committed by teamcityserver
parent 01deac5e5c
commit 75b6f7ca00
29 changed files with 50 additions and 67 deletions
@@ -38,8 +38,8 @@ abstract class FirRegularClass : FirClass(), FirControlFlowGraphOwner {
abstract override val controlFlowGraphReference: FirControlFlowGraphReference?
abstract val name: Name
abstract override val symbol: FirRegularClassSymbol
abstract val companionObject: FirRegularClass?
abstract val hasLazyNestedClassifiers: Boolean
abstract val companionObjectSymbol: FirRegularClassSymbol?
abstract override val superTypeRefs: List<FirTypeRef>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitRegularClass(this, data)
@@ -54,6 +54,8 @@ abstract class FirRegularClass : FirClass(), FirControlFlowGraphOwner {
abstract override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?)
abstract fun replaceCompanionObjectSymbol(newCompanionObjectSymbol: FirRegularClassSymbol?)
abstract override fun replaceSuperTypeRefs(newSuperTypeRefs: List<FirTypeRef>)
abstract override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirRegularClass
@@ -64,7 +66,5 @@ abstract class FirRegularClass : FirClass(), FirControlFlowGraphOwner {
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirRegularClass
abstract fun <D> transformCompanionObject(transformer: FirTransformer<D>, data: D): FirRegularClass
abstract override fun <D> transformSuperTypeRefs(transformer: FirTransformer<D>, data: D): FirRegularClass
}
@@ -51,7 +51,7 @@ open class FirRegularClassBuilder : FirClassBuilder, FirTypeParameterRefsOwnerBu
override lateinit var scopeProvider: FirScopeProvider
open lateinit var name: Name
open lateinit var symbol: FirRegularClassSymbol
open var companionObject: FirRegularClass? = null
open var companionObjectSymbol: FirRegularClassSymbol? = null
override val superTypeRefs: MutableList<FirTypeRef> = mutableListOf()
override fun build(): FirRegularClass {
@@ -70,7 +70,7 @@ open class FirRegularClassBuilder : FirClassBuilder, FirTypeParameterRefsOwnerBu
scopeProvider,
name,
symbol,
companionObject,
companionObjectSymbol,
superTypeRefs,
)
}
@@ -105,7 +105,7 @@ inline fun buildRegularClassCopy(original: FirRegularClass, init: FirRegularClas
copyBuilder.scopeProvider = original.scopeProvider
copyBuilder.name = original.name
copyBuilder.symbol = original.symbol
copyBuilder.companionObject = original.companionObject
copyBuilder.companionObjectSymbol = original.companionObjectSymbol
copyBuilder.superTypeRefs.addAll(original.superTypeRefs)
return copyBuilder.apply(init).build()
}
@@ -45,7 +45,7 @@ internal class FirRegularClassImpl(
override val scopeProvider: FirScopeProvider,
override val name: Name,
override val symbol: FirRegularClassSymbol,
override var companionObject: FirRegularClass?,
override var companionObjectSymbol: FirRegularClassSymbol?,
override val superTypeRefs: MutableList<FirTypeRef>,
) : FirRegularClass() {
override var controlFlowGraphReference: FirControlFlowGraphReference? = null
@@ -70,7 +70,6 @@ internal class FirRegularClassImpl(
transformDeclarations(transformer, data)
transformAnnotations(transformer, data)
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
companionObject = declarations.asSequence().filterIsInstance<FirRegularClass>().firstOrNull { it.status.isCompanion }
transformSuperTypeRefs(transformer, data)
return this
}
@@ -95,11 +94,6 @@ internal class FirRegularClassImpl(
return this
}
override fun <D> transformCompanionObject(transformer: FirTransformer<D>, data: D): FirRegularClassImpl {
companionObject = companionObject?.transform(transformer, data)
return this
}
override fun <D> transformSuperTypeRefs(transformer: FirTransformer<D>, data: D): FirRegularClassImpl {
superTypeRefs.transformInplace(transformer, data)
return this
@@ -117,6 +111,10 @@ internal class FirRegularClassImpl(
controlFlowGraphReference = newControlFlowGraphReference
}
override fun replaceCompanionObjectSymbol(newCompanionObjectSymbol: FirRegularClassSymbol?) {
companionObjectSymbol = newCompanionObjectSymbol
}
override fun replaceSuperTypeRefs(newSuperTypeRefs: List<FirTypeRef>) {
superTypeRefs.clear()
superTypeRefs.addAll(newSuperTypeRefs)
@@ -36,7 +36,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 var resolvedToCompanionObject: Boolean = (symbol?.fir as? FirRegularClass)?.companionObjectSymbol != null
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
@@ -21,9 +21,6 @@ fun FirTypeParameterBuilder.addDefaultBoundIfNecessary() {
fun FirRegularClassBuilder.addDeclaration(declaration: FirDeclaration) {
declarations += declaration
if (companionObject == null && declaration is FirRegularClass && declaration.isCompanion) {
companionObject = declaration
}
}
fun FirRegularClassBuilder.addDeclarations(declarations: Collection<FirDeclaration>) {
@@ -66,7 +66,7 @@ class FirRegularClassSymbol(classId: ClassId) : FirClassSymbol<FirRegularClass>(
}
val companionObjectSymbol: FirRegularClassSymbol?
get() = fir.companionObject?.symbol
get() = fir.companionObjectSymbol
}
val ANONYMOUS_CLASS_ID = ClassId(FqName.ROOT, FqName.topLevel(SpecialNames.ANONYMOUS), true)
@@ -40,7 +40,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
builder(regularClass) {
parents += classBuilder
parents += typeParameterRefsOwnerBuilder
defaultNull("companionObject")
defaultNull("companionObjectSymbol")
openBuilder()
withCopy()
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.tree.generator
import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFirTreeImplementationConfigurator
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.Object
import org.jetbrains.kotlin.fir.tree.generator.model.Implementation.Kind.OpenClass
import org.jetbrains.kotlin.fir.tree.generator.model.Type
object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() {
fun configureImplementations() {
@@ -496,7 +497,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
//
// 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")
default("resolvedToCompanionObject", "(symbol?.fir as? FirRegularClass)?.companionObjectSymbol != null")
useTypes(regularClass)
}
@@ -251,8 +251,8 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
regularClass.configure {
+name
+symbol("FirRegularClassSymbol")
+field("companionObject", regularClass, nullable = true).withTransform()
+booleanField("hasLazyNestedClassifiers")
+field("companionObjectSymbol", regularClassSymbolType, nullable = true, withReplace = true)
+superTypeRefs(withReplace = true)
}
@@ -70,6 +70,7 @@ val backingFieldSymbolType = type("fir.symbols.impl", "FirBackingFieldSymbol")
val delegateFieldSymbolType = type("fir.symbols.impl", "FirDelegateFieldSymbol")
val classSymbolType = type("fir.symbols.impl", "FirClassSymbol")
val classLikeSymbolType = type("fir.symbols.impl", "FirClassLikeSymbol<*>")
val regularClassSymbolType = type("fir.symbols.impl", "FirRegularClassSymbol")
val typeParameterSymbolType = type("fir.symbols.impl", "FirTypeParameterSymbol")
val emptyArgumentListType = type("fir.expressions", "FirEmptyArgumentList")
val firScopeProviderType = type("fir.scopes", "FirScopeProvider")
@@ -105,7 +105,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
element.allFields.filter {
it.withBindThis && it.type.contains("Symbol") && it !is FieldList
it.withBindThis && it.type.contains("Symbol") && it !is FieldList && it.name != "companionObjectSymbol"
}.takeIf {
it.isNotEmpty() && !isInterface && !isAbstract &&
!element.type.contains("Reference")
@@ -225,10 +225,6 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
field.name in setOf("dispatchReceiver", "extensionReceiver") -> {}
field.name == "companionObject" -> {
println("companionObject = declarations.asSequence().filterIsInstance<FirRegularClass>().firstOrNull { it.status.isCompanion }")
}
field.needsSeparateTransform -> {
if (!(element.needTransformOtherChildren && field.needTransformInOtherChildren)) {
println("transform${field.name.replaceFirstChar(Char::uppercaseChar)}(transformer, data)")