[FIR2IR] Part 1. Cleanup Fir2IrClassifierStorage API (classes)

This commit cleans up API related to referencing classes and their symbols,
  to make it more similar with similar API in Fir2IrDeclarationStorage
This commit is contained in:
Dmitriy Novozhilov
2024-02-21 10:03:22 +02:00
committed by Space Team
parent 3bf0a11ced
commit 9c21c2214a
17 changed files with 90 additions and 84 deletions
@@ -21,7 +21,7 @@ class FirJvmBackendClassResolver(val components: Fir2IrComponents) : JvmBackendC
val symbol = components.session.symbolProvider.getClassLikeSymbolByClassId(type.classId) ?: return emptyList() val symbol = components.session.symbolProvider.getClassLikeSymbolByClassId(type.classId) ?: return emptyList()
require(symbol is FirClassSymbol<*>) require(symbol is FirClassSymbol<*>)
return listOf(components.classifierStorage.getOrCreateIrClass(symbol).symbol.descriptor) return listOf(components.classifierStorage.getIrClassSymbol(symbol).descriptor)
} }
} }
@@ -23,9 +23,10 @@ class FirJvmElementAwareStringTable(
private val localPoppedUpClasses: List<IrAttributeContainer>, private val localPoppedUpClasses: List<IrAttributeContainer>,
nameResolver: JvmNameResolver? = null nameResolver: JvmNameResolver? = null
) : JvmStringTable(nameResolver), FirElementAwareStringTable { ) : JvmStringTable(nameResolver), FirElementAwareStringTable {
override fun getLocalClassIdReplacement(firClass: FirClass): ClassId = override fun getLocalClassIdReplacement(firClass: FirClass): ClassId {
components.classifierStorage.getCachedIrClass(firClass)?.getLocalClassIdReplacement() // TODO: should call getCachedIrLocalClass, see KT-66018
?: throw AssertionError("not a local class: ${firClass.symbol.classId}") return components.classifierStorage.getIrClass(firClass).getLocalClassIdReplacement()
}
private fun IrClass.getLocalClassIdReplacement(): ClassId { private fun IrClass.getLocalClassIdReplacement(): ClassId {
// This convoluted implementation aims to reproduce K1 behaviour (see JvmCodegenStringTable::getLocalClassIdReplacement). // This convoluted implementation aims to reproduce K1 behaviour (see JvmCodegenStringTable::getLocalClassIdReplacement).
@@ -188,7 +188,7 @@ fun FirClassifierSymbol<*>.toSymbol(
} }
is FirClassSymbol -> { is FirClassSymbol -> {
classifierStorage.getOrCreateIrClass(this).symbol classifierStorage.getIrClassSymbol(this)
} }
else -> error("Unknown symbol: $this") else -> error("Unknown symbol: $this")
@@ -914,4 +914,4 @@ val incOrDeclSourceKindToIrStatementOrigin = mapOf(
KtFakeSourceElementKind.DesugaredPostfixDec to IrStatementOrigin.POSTFIX_DECR, KtFakeSourceElementKind.DesugaredPostfixDec to IrStatementOrigin.POSTFIX_DECR,
KtFakeSourceElementKind.DesugaredPrefixIncSecondGetReference to IrStatementOrigin.PREFIX_INCR, KtFakeSourceElementKind.DesugaredPrefixIncSecondGetReference to IrStatementOrigin.PREFIX_INCR,
KtFakeSourceElementKind.DesugaredPrefixDecSecondGetReference to IrStatementOrigin.PREFIX_DECR KtFakeSourceElementKind.DesugaredPrefixDecSecondGetReference to IrStatementOrigin.PREFIX_DECR
) )
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.backend.generators.isExternalParent
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
@@ -26,13 +27,14 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.utils.addToStdlib.runIf
class Fir2IrClassifierStorage( class Fir2IrClassifierStorage(
private val components: Fir2IrComponents, private val components: Fir2IrComponents,
commonMemberStorage: Fir2IrCommonMemberStorage, commonMemberStorage: Fir2IrCommonMemberStorage,
private val conversionScope: Fir2IrConversionScope, private val conversionScope: Fir2IrConversionScope,
) : Fir2IrComponents by components { ) : Fir2IrComponents by components {
private val classCache: MutableMap<FirRegularClass, IrClass> = commonMemberStorage.classCache private val classCache: MutableMap<FirRegularClass, IrClassSymbol> = commonMemberStorage.classCache
private val typeAliasCache: MutableMap<FirTypeAlias, IrTypeAlias> = mutableMapOf() private val typeAliasCache: MutableMap<FirTypeAlias, IrTypeAlias> = mutableMapOf()
@@ -61,7 +63,7 @@ class Fir2IrClassifierStorage(
*/ */
@DelicateDeclarationStorageApi @DelicateDeclarationStorageApi
fun forEachCachedDeclarationSymbol(block: (IrSymbol) -> Unit) { fun forEachCachedDeclarationSymbol(block: (IrSymbol) -> Unit) {
classCache.values.forEach { block(it.symbol) } classCache.values.forEach { block(it) }
typeAliasCache.values.forEach { block(it.symbol) } typeAliasCache.values.forEach { block(it.symbol) }
enumEntryCache.values.forEach { block(it.symbol) } enumEntryCache.values.forEach { block(it.symbol) }
fieldsForContextReceivers.values.forEach { fields -> fieldsForContextReceivers.values.forEach { fields ->
@@ -195,58 +197,62 @@ class Fir2IrClassifierStorage(
if (regularClass.visibility == Visibilities.Local) { if (regularClass.visibility == Visibilities.Local) {
localStorage[regularClass] = irClass localStorage[regularClass] = irClass
} else { } else {
classCache[regularClass] = irClass classCache[regularClass] = irClass.symbol
} }
} }
fun getCachedIrClass(klass: FirClass): IrClass? { /**
return if (klass is FirAnonymousObject || klass is FirRegularClass && klass.visibility == Visibilities.Local) { * FIR2IR looks over all non-local source classes and creates IR for them using [createAndCacheIrClass]
localStorage[klass] * This means that after this phase all classes are either created and bound to their symbols or external classes,
} else { * which are created and bound at the first access anyway
classCache[klass] *
} * So, unlike callable declarations, it's safe to expose an API, which returns not just IrClassSymbol, but IrClass itself
} *
* But on the first FIR2IR stage this API should not be used
fun findIrClass(lookupTag: ConeClassLikeLookupTag): IrClass? { */
return if (lookupTag.classId.isLocal) { fun getIrClass(firClass: FirClass): IrClass {
getCachedLocalClass(lookupTag) getCachedIrClass(firClass)?.let { return it }
} else {
val firSymbol = lookupTag.toSymbol(session)
if (firSymbol is FirClassSymbol) {
getOrCreateIrClass(firSymbol)
} else {
null
}
}
}
private fun getCachedLocalClass(lookupTag: ConeClassLikeLookupTag): IrClass? {
return localStorage[lookupTag.toSymbol(session)!!.fir as FirClass]
}
fun getOrCreateIrClass(firClassSymbol: FirClassSymbol<*>): IrClass {
val firClass = firClassSymbol.fir
classifierStorage.getCachedIrClass(firClass)?.let { return it }
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.Local) { if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.Local) {
return createAndCacheLocalIrClassOnTheFly(firClass) return createAndCacheLocalIrClassOnTheFly(firClass)
} }
firClass as FirRegularClass require(firClass is FirRegularClass)
val classId = firClassSymbol.classId val symbol = createClassSymbol(signature = null)
val classId = firClass.symbol.classId
val parentId = classId.outerClassId val parentId = classId.outerClassId
val parentClass = parentId?.let { session.symbolProvider.getClassLikeSymbolByClassId(it) } val parentClass = parentId?.let { session.symbolProvider.getClassLikeSymbolByClassId(it) }
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentClass?.toLookupTag(), firClassSymbol, firClass.origin)!! val irParent = declarationStorage.findIrParent(classId.packageFqName, parentClass?.toLookupTag(), firClass.symbol, firClass.origin)!!
// firClass may be referenced by some parent's type parameters as a bound. In that case, getIrClassSymbol will be called recursively. classCache[firClass] = symbol
classifierStorage.getCachedIrClass(firClass)?.let { return it } check(irParent.isExternalParent()) { "Source classes should be created separately before referencing" }
val symbol = createClassSymbol(signature = null)
val irClass = lazyDeclarationsGenerator.createIrLazyClass(firClass, irParent, symbol) val irClass = lazyDeclarationsGenerator.createIrLazyClass(firClass, irParent, symbol)
classCache[firClass] = irClass
// NB: this is needed to prevent recursions in case of self bounds // NB: this is needed to prevent recursions in case of self bounds
irClass.prepareTypeParameters() irClass.prepareTypeParameters()
return irClass return irClass
}
fun getIrClass(lookupTag: ConeClassLikeLookupTag): IrClass? {
val firClassSymbol = lookupTag.toSymbol(session) as? FirClassSymbol<*> ?: return null
return getIrClass(firClassSymbol.fir)
}
fun getCachedIrLocalClass(klass: FirClass): IrClass? {
return runIf(klass is FirAnonymousObject || klass is FirRegularClass && klass.visibility == Visibilities.Local) {
localStorage[klass]
}
}
private fun getCachedIrClass(klass: FirClass): IrClass? {
@OptIn(UnsafeDuringIrConstructionAPI::class)
return getCachedIrLocalClass(klass) ?: classCache[klass]?.owner
}
fun getIrClassSymbol(firClassSymbol: FirClassSymbol<*>): IrClassSymbol {
return getIrClass(firClassSymbol.fir).symbol
}
fun getIrClassSymbol(lookupTag: ConeClassLikeLookupTag): IrClassSymbol? {
return getIrClass(lookupTag)?.symbol
} }
fun getFieldsWithContextReceiversForClass(irClass: IrClass, klass: FirClass): List<IrField> { fun getFieldsWithContextReceiversForClass(irClass: IrClass, klass: FirClass): List<IrField> {
@@ -328,7 +334,7 @@ class Fir2IrClassifierStorage(
fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass { fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass {
localStorage[anonymousObject]?.let { return it } localStorage[anonymousObject]?.let { return it }
val irAnonymousObject = classifierStorage.createAndCacheAnonymousObject(anonymousObject, Visibilities.Private, name, irParent) val irAnonymousObject = createAndCacheAnonymousObject(anonymousObject, Visibilities.Private, name, irParent)
classifiersGenerator.processClassHeader(anonymousObject, irAnonymousObject) classifiersGenerator.processClassHeader(anonymousObject, irAnonymousObject)
return irAnonymousObject return irAnonymousObject
} }
@@ -26,7 +26,7 @@ class Fir2IrCommonMemberStorage(firMangler: FirMangler) {
val symbolTable = SymbolTable(signaturer = null, irFactory = IrFactoryImpl) val symbolTable = SymbolTable(signaturer = null, irFactory = IrFactoryImpl)
val classCache: MutableMap<FirRegularClass, IrClass> = mutableMapOf() val classCache: MutableMap<FirRegularClass, IrClassSymbol> = mutableMapOf()
val typeParameterCache: MutableMap<FirTypeParameter, IrTypeParameter> = mutableMapOf() val typeParameterCache: MutableMap<FirTypeParameter, IrTypeParameter> = mutableMapOf()
@@ -434,13 +434,12 @@ class Fir2IrConverter(
private fun registerClassAndNestedClasses(klass: FirClass, parent: IrDeclarationParent): IrClass { private fun registerClassAndNestedClasses(klass: FirClass, parent: IrDeclarationParent): IrClass {
// Local classes might be referenced before they declared (see usages of Fir2IrClassifierStorage.createLocalIrClassOnTheFly) // Local classes might be referenced before they declared (see usages of Fir2IrClassifierStorage.createLocalIrClassOnTheFly)
// So, we only need to set its parent properly // So, we only need to set its parent properly
val irClass = val irClass = classifierStorage.getCachedIrLocalClass(klass)?.apply {
classifierStorage.getCachedIrClass(klass)?.apply { this.parent = parent
this.parent = parent } ?: when (klass) {
} ?: when (klass) { is FirRegularClass -> classifierStorage.createAndCacheIrClass(klass, parent)
is FirRegularClass -> classifierStorage.createAndCacheIrClass(klass, parent) is FirAnonymousObject -> classifierStorage.createAndCacheAnonymousObject(klass, irParent = parent)
is FirAnonymousObject -> classifierStorage.createAndCacheAnonymousObject(klass, irParent = parent) }
}
registerNestedClasses(klass, irClass) registerNestedClasses(klass, irClass)
return irClass return irClass
} }
@@ -463,7 +462,7 @@ class Fir2IrConverter(
private fun processClassAndNestedClassHeaders(klass: FirClass) { private fun processClassAndNestedClassHeaders(klass: FirClass) {
classifiersGenerator.processClassHeader(klass) classifiersGenerator.processClassHeader(klass)
processNestedClassHeaders(klass) processNestedClassHeaders(klass)
val irClass = classifierStorage.getCachedIrClass(klass)!! val irClass = classifierStorage.getIrClass(klass)!!
/* /*
* This is needed to preserve the source order of declarations in the class * This is needed to preserve the source order of declarations in the class
* IrClass should contain declarations in the source order, but creating of nested IrClass automatically adds created class to the list * IrClass should contain declarations in the source order, but creating of nested IrClass automatically adds created class to the list
@@ -522,7 +521,7 @@ class Fir2IrConverter(
val isInLocalClass = containingClass != null && (containingClass !is FirRegularClass || containingClass.isLocal) val isInLocalClass = containingClass != null && (containingClass !is FirRegularClass || containingClass.isLocal)
when (declaration) { when (declaration) {
is FirRegularClass -> { is FirRegularClass -> {
val irClass = classifierStorage.getCachedIrClass(declaration)!! val irClass = classifierStorage.getIrClass(declaration)!!
addDeclarationToParentIfNeeded(irClass) addDeclarationToParentIfNeeded(irClass)
processClassMembers(declaration, irClass) processClassMembers(declaration, irClass)
} }
@@ -410,7 +410,7 @@ class Fir2IrDeclarationStorage(
else -> shouldNotBeCalled() else -> shouldNotBeCalled()
} }
requireNotNull(containingClassLookupTag) { "Containing class not found for ${callable.render()}"} requireNotNull(containingClassLookupTag) { "Containing class not found for ${callable.render()}"}
return classifierStorage.findIrClass(containingClassLookupTag)?.symbol return classifierStorage.getIrClassSymbol(containingClassLookupTag)
?: error("IR class for $containingClassLookupTag not found") ?: error("IR class for $containingClassLookupTag not found")
} }
@@ -994,7 +994,7 @@ class Fir2IrDeclarationStorage(
return when (val firDeclaration = firVariableSymbol.fir) { return when (val firDeclaration = firVariableSymbol.fir) {
is FirEnumEntry -> { is FirEnumEntry -> {
classifierStorage.getCachedIrEnumEntry(firDeclaration)?.let { return it.symbol } classifierStorage.getCachedIrEnumEntry(firDeclaration)?.let { return it.symbol }
val irParentClass = firDeclaration.containingClassLookupTag()?.let { classifierStorage.findIrClass(it) }!! val irParentClass = firDeclaration.containingClassLookupTag()?.let { classifierStorage.getIrClass(it) }!!
val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol) val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol)
@@ -1247,9 +1247,9 @@ class Fir2IrDeclarationStorage(
} }
private fun generateLazyFakeOverrides(name: Name, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?) { private fun generateLazyFakeOverrides(name: Name, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?) {
val firClassSymbol = fakeOverrideOwnerLookupTag?.toSymbol(session) as? FirClassSymbol val firClassSymbol = fakeOverrideOwnerLookupTag?.toSymbol(session) as? FirClassSymbol<*>
if (firClassSymbol != null) { if (firClassSymbol != null) {
val irClass = classifierStorage.getOrCreateIrClass(firClassSymbol) val irClass = classifierStorage.getIrClass(firClassSymbol.fir)
if (irClass is Fir2IrLazyClass) { if (irClass is Fir2IrLazyClass) {
irClass.getFakeOverridesByName(name) irClass.getFakeOverridesByName(name)
} }
@@ -1427,7 +1427,9 @@ class Fir2IrDeclarationStorage(
firOrigin: FirDeclarationOrigin firOrigin: FirDeclarationOrigin
): IrDeclarationParent? { ): IrDeclarationParent? {
if (parentLookupTag != null) { if (parentLookupTag != null) {
return classifierStorage.findIrClass(parentLookupTag) // At this point all source classes should be already created and bound to symbols
@OptIn(UnsafeDuringIrConstructionAPI::class)
return classifierStorage.getIrClassSymbol(parentLookupTag)?.owner
} }
@@ -74,7 +74,7 @@ class Fir2IrPluginContext(
override fun referenceClass(classId: ClassId): IrClassSymbol? { override fun referenceClass(classId: ClassId): IrClassSymbol? {
val firSymbol = symbolProvider.getClassLikeSymbolByClassId(classId) as? FirClassSymbol<*> ?: return null val firSymbol = symbolProvider.getClassLikeSymbolByClassId(classId) as? FirClassSymbol<*> ?: return null
return components.classifierStorage.getOrCreateIrClass(firSymbol).symbol return components.classifierStorage.getIrClassSymbol(firSymbol)
} }
override fun referenceTypeAlias(classId: ClassId): IrTypeAliasSymbol? { override fun referenceTypeAlias(classId: ClassId): IrTypeAliasSymbol? {
@@ -191,7 +191,7 @@ class Fir2IrVisitor(
if (regularClass.visibility == Visibilities.Local) { if (regularClass.visibility == Visibilities.Local) {
val irParent = conversionScope.parentFromStack() val irParent = conversionScope.parentFromStack()
// NB: for implicit types it is possible that local class is already cached // NB: for implicit types it is possible that local class is already cached
val irClass = classifierStorage.getCachedIrClass(regularClass)?.apply { this.parent = irParent } val irClass = classifierStorage.getIrClass(regularClass)?.apply { this.parent = irParent }
if (irClass != null) { if (irClass != null) {
conversionScope.withParent(irClass) { conversionScope.withParent(irClass) {
memberGenerator.convertClassContent(irClass, regularClass) memberGenerator.convertClassContent(irClass, regularClass)
@@ -200,7 +200,7 @@ class Fir2IrVisitor(
} }
converter.processLocalClassAndNestedClasses(regularClass, irParent) converter.processLocalClassAndNestedClasses(regularClass, irParent)
} }
val irClass = classifierStorage.getCachedIrClass(regularClass)!! val irClass = classifierStorage.getIrClass(regularClass)!!
if (regularClass.isSealed) { if (regularClass.isSealed) {
irClass.sealedSubclasses = regularClass.getIrSymbolsForSealedSubclasses() irClass.sealedSubclasses = regularClass.getIrSymbolsForSealedSubclasses()
} }
@@ -350,7 +350,7 @@ class Fir2IrVisitor(
) { ) {
val irParent = conversionScope.parentFromStack() val irParent = conversionScope.parentFromStack()
// NB: for implicit types it is possible that anonymous object is already cached // NB: for implicit types it is possible that anonymous object is already cached
val irAnonymousObject = classifierStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent } val irAnonymousObject = classifierStorage.getCachedIrLocalClass(anonymousObject)?.apply { this.parent = irParent }
?: converter.processLocalClassAndNestedClasses(anonymousObject, irParent) ?: converter.processLocalClassAndNestedClasses(anonymousObject, irParent)
conversionScope.withParent(irAnonymousObject) { conversionScope.withParent(irAnonymousObject) {
@@ -711,7 +711,7 @@ class Fir2IrVisitor(
// We anyway can use 'else' branch as fallback, but // We anyway can use 'else' branch as fallback, but
// this is an additional check of FIR2IR invariants // this is an additional check of FIR2IR invariants
// (source classes should be already built when we analyze bodies) // (source classes should be already built when we analyze bodies)
classifierStorage.getCachedIrClass(firClass)!!.symbol classifierStorage.getIrClass(firClass)!!.symbol
} else { } else {
/* /*
* The only case when we can refer to non-source this is resolution to companion object of parent * The only case when we can refer to non-source this is resolution to companion object of parent
@@ -729,7 +729,7 @@ class Fir2IrVisitor(
* val x: Int = foo() // this: Base.Companion * val x: Int = foo() // this: Base.Companion
* ) : Base() * ) : Base()
*/ */
classifierStorage.getOrCreateIrClass(firClassSymbol).symbol classifierStorage.getIrClassSymbol(firClassSymbol)
} }
if (firClass.classKind.isObject && shouldGenerateReceiverAsSingletonReference(irClassSymbol)) { if (firClass.classKind.isObject && shouldGenerateReceiverAsSingletonReference(irClassSymbol)) {
@@ -1560,7 +1560,7 @@ class Fir2IrVisitor(
is FirResolvedQualifier -> { is FirResolvedQualifier -> {
when (val symbol = argument.symbol) { when (val symbol = argument.symbol) {
is FirClassSymbol -> { is FirClassSymbol -> {
classifierStorage.getOrCreateIrClass(symbol).symbol classifierStorage.getIrClassSymbol(symbol)
} }
is FirTypeAliasSymbol -> { is FirTypeAliasSymbol -> {
symbol.fir.fullyExpandedConeType(session).toIrClassSymbol() symbol.fir.fullyExpandedConeType(session).toIrClassSymbol()
@@ -1594,7 +1594,7 @@ class Fir2IrVisitor(
private fun ConeClassLikeType?.toIrClassSymbol(): IrClassSymbol? = private fun ConeClassLikeType?.toIrClassSymbol(): IrClassSymbol? =
(this?.lookupTag?.toSymbol(session) as? FirClassSymbol<*>)?.let { (this?.lookupTag?.toSymbol(session) as? FirClassSymbol<*>)?.let {
classifierStorage.getOrCreateIrClass(it).symbol classifierStorage.getIrClassSymbol(it)
} }
private fun convertToArrayLiteral( private fun convertToArrayLiteral(
@@ -92,7 +92,7 @@ class FirIrProvider(val components: Fir2IrComponents) : IrProvider {
val scope = with(components) { firClass.unsubstitutedScope() } val scope = with(components) { firClass.unsubstitutedScope() }
fun findIrClass(firClass: FirRegularClass): IrClass { fun findIrClass(firClass: FirRegularClass): IrClass {
val irClassSymbol = classifierStorage.getOrCreateIrClass(firClass.symbol).symbol val irClassSymbol = classifierStorage.getIrClassSymbol(firClass.symbol)
return getDeclaration(irClassSymbol) as IrClass return getDeclaration(irClassSymbol) as IrClass
} }
@@ -176,7 +176,7 @@ class FirIrProvider(val components: Fir2IrComponents) : IrProvider {
return when (kind) { return when (kind) {
SymbolKind.CLASS_SYMBOL -> { SymbolKind.CLASS_SYMBOL -> {
classifierStorage.getOrCreateIrClass((firDeclaration as FirRegularClass).symbol) shouldNotBeCalled()
} }
SymbolKind.ENUM_ENTRY_SYMBOL -> classifierStorage.getOrCreateIrEnumEntry( SymbolKind.ENUM_ENTRY_SYMBOL -> classifierStorage.getOrCreateIrEnumEntry(
firDeclaration as FirEnumEntry, parent as IrClass firDeclaration as FirEnumEntry, parent as IrClass
@@ -596,7 +596,7 @@ class IrBuiltInsOverFir(
private fun loadClassSafe(classId: ClassId): IrClassSymbol? { private fun loadClassSafe(classId: ClassId): IrClassSymbol? {
val firClassSymbol = symbolProvider.getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol ?: return null val firClassSymbol = symbolProvider.getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol ?: return null
return components.classifierStorage.getOrCreateIrClass(firClassSymbol).symbol return components.classifierStorage.getIrClassSymbol(firClassSymbol)
} }
@OptIn(UnsafeDuringIrConstructionAPI::class) @OptIn(UnsafeDuringIrConstructionAPI::class)
@@ -285,7 +285,7 @@ class CallAndReferenceGenerator(
val coneSuperType = superTypeRef.coneTypeSafe<ConeClassLikeType>() ?: return null val coneSuperType = superTypeRef.coneTypeSafe<ConeClassLikeType>() ?: return null
val firClassSymbol = coneSuperType.fullyExpandedType(session).lookupTag.toSymbol(session) as? FirClassSymbol<*> val firClassSymbol = coneSuperType.fullyExpandedType(session).lookupTag.toSymbol(session) as? FirClassSymbol<*>
if (firClassSymbol != null) { if (firClassSymbol != null) {
return classifierStorage.getOrCreateIrClass(firClassSymbol).symbol return classifierStorage.getIrClassSymbol(firClassSymbol)
} }
return null return null
} }
@@ -82,7 +82,7 @@ internal class ClassMemberGenerator(
declaration is FirConstructor && declaration.isPrimary -> { declaration is FirConstructor && declaration.isPrimary -> {
} }
declaration is FirRegularClass && declaration.visibility == Visibilities.Local -> { declaration is FirRegularClass && declaration.visibility == Visibilities.Local -> {
val irNestedClass = classifierStorage.getCachedIrClass(declaration)!! val irNestedClass = classifierStorage.getIrClass(declaration)
irNestedClass.parent = irClass irNestedClass.parent = irClass
conversionScope.withParent(irNestedClass) { conversionScope.withParent(irNestedClass) {
convertClassContent(irNestedClass, declaration) convertClassContent(irNestedClass, declaration)
@@ -101,7 +101,7 @@ internal class ClassMemberGenerator(
dataClassMembersGenerator.generateBodiesForMultiFieldValueClassMembers(klass, irClass) dataClassMembersGenerator.generateBodiesForMultiFieldValueClassMembers(klass, irClass)
} }
if (irClass.isData) { if (irClass.isData) {
dataClassMembersGenerator.generateBodiesForDataClassMembers(klass, irClass) dataClassMembersGenerator.generateBodiesForDataClassMembers(klass, irClass)
} }
} }
@@ -337,7 +337,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
// dispatch receiver of the target method. Therefore, we need to check if a cast must be inserted. // dispatch receiver of the target method. Therefore, we need to check if a cast must be inserted.
val superFunctionDispatchReceiverType = originalFirDeclaration.dispatchReceiverType val superFunctionDispatchReceiverType = originalFirDeclaration.dispatchReceiverType
val superFunctionDispatchReceiverLookupTag = (superFunctionDispatchReceiverType as? ConeClassLikeType)?.lookupTag val superFunctionDispatchReceiverLookupTag = (superFunctionDispatchReceiverType as? ConeClassLikeType)?.lookupTag
val superFunctionParentSymbol = superFunctionDispatchReceiverLookupTag?.let { classifierStorage.findIrClass(it)?.symbol } val superFunctionParentSymbol = superFunctionDispatchReceiverLookupTag?.let { classifierStorage.getIrClassSymbol(it) }
dispatchReceiver = if (superFunctionParentSymbol == null || irField.type.isSubtypeOfClass(superFunctionParentSymbol)) { dispatchReceiver = if (superFunctionParentSymbol == null || irField.type.isSubtypeOfClass(superFunctionParentSymbol)) {
getField getField
} else { } else {
@@ -593,7 +593,7 @@ class FakeOverrideGenerator(
@OptIn(UnsafeDuringIrConstructionAPI::class) @OptIn(UnsafeDuringIrConstructionAPI::class)
val overriddenContainingIrClass = val overriddenContainingIrClass =
declarationStorage.classifierStorage.getOrCreateIrClass(overriddenContainingClass.symbol).symbol.owner declarationStorage.classifierStorage.getIrClassSymbol(overriddenContainingClass.symbol).owner
return superClasses.mapNotNull { superClass -> return superClasses.mapNotNull { superClass ->
if (superClass == overriddenContainingIrClass || if (superClass == overriddenContainingIrClass ||
@@ -733,9 +733,8 @@ internal fun FirSimpleFunction.generateOverriddenFunctionSymbols(containingClass
} }
context(Fir2IrComponents) context(Fir2IrComponents)
@OptIn(UnsafeDuringIrConstructionAPI::class)
private fun FirClass.getSuperTypesAsIrClasses(): Set<IrClass> { private fun FirClass.getSuperTypesAsIrClasses(): Set<IrClass> {
val irClass = declarationStorage.classifierStorage.getOrCreateIrClass(symbol) val irClass = declarationStorage.classifierStorage.getIrClassSymbol(symbol).owner
@OptIn(UnsafeDuringIrConstructionAPI::class)
return irClass.superTypes.mapNotNull { it.classifierOrNull?.owner as? IrClass }.toSet() return irClass.superTypes.mapNotNull { it.classifierOrNull?.owner as? IrClass }.toSet()
} }
@@ -108,7 +108,7 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
return irClass return irClass
} }
fun processClassHeader(klass: FirClass, irClass: IrClass = classifierStorage.getCachedIrClass(klass)!!): IrClass { fun processClassHeader(klass: FirClass, irClass: IrClass = classifierStorage.getIrClass(klass)): IrClass {
irClass.declareTypeParameters(klass) irClass.declareTypeParameters(klass)
irClass.setThisReceiver(klass.typeParameters) irClass.setThisReceiver(klass.typeParameters)
irClass.declareSupertypes(klass) irClass.declareSupertypes(klass)
@@ -221,8 +221,7 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
val irClass = if (classOrLocalParent === klass) { val irClass = if (classOrLocalParent === klass) {
result result
} else { } else {
classifierStorage.getCachedIrClass(klass) classifierStorage.getIrClass(klass)
?: error("Assuming that all nested classes of ${classOrLocalParent.classId.asString()} should already be cached")
} }
return LocalIrClassInfo(irClass, classOrLocalParent, result) return LocalIrClassInfo(irClass, classOrLocalParent, result)
} }
@@ -173,7 +173,7 @@ class Fir2IrLazyClass(
scope.processClassifiersByName(name) { scope.processClassifiersByName(name) {
val declaration = it.fir as? FirRegularClass ?: return@processClassifiersByName val declaration = it.fir as? FirRegularClass ?: return@processClassifiersByName
if (declaration.classId.outerClassId == fir.classId && shouldBuildStub(declaration)) { if (declaration.classId.outerClassId == fir.classId && shouldBuildStub(declaration)) {
result += classifierStorage.getOrCreateIrClass(declaration.symbol) result += classifierStorage.getIrClassSymbol(declaration.symbol).owner
} }
} }
} }