[FIR2IR] Manage class symbols in declaration storage instead of declaration generator

This is needed to be able to implement creation of unbound symbols
 for references of corresponding declarations (KT-62856)
This commit is contained in:
Dmitriy Novozhilov
2023-11-03 15:50:32 +02:00
committed by Space Team
parent 7652752e3f
commit d4b0627640
3 changed files with 80 additions and 79 deletions
@@ -9,9 +9,9 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -21,14 +21,18 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.utils.addToStdlib.runIf
class Fir2IrClassifierStorage(
private val components: Fir2IrComponents,
@@ -162,12 +166,27 @@ class Fir2IrClassifierStorage(
parent: IrDeclarationParent,
predefinedOrigin: IrDeclarationOrigin? = null
): IrClass {
return classifiersGenerator.createIrClass(regularClass, parent, predefinedOrigin).also {
val symbol = createClassSymbol(regularClass)
return classifiersGenerator.createIrClass(regularClass, parent, symbol, predefinedOrigin).also {
@OptIn(LeakedDeclarationCaches::class)
cacheIrClass(regularClass, it)
}
}
private fun createClassSymbol(regularClass: FirRegularClass): IrClassSymbol {
val signature = runIf(!regularClass.isLocal && configuration.linkViaSignatures) {
signatureComposer.composeSignature(regularClass)
}
return createClassSymbol(signature)
}
private fun createClassSymbol(signature: IdSignature?): IrClassSymbol {
return when {
signature != null -> symbolTable.referenceClass(signature)
else -> IrClassSymbolImpl()
}
}
@LeakedDeclarationCaches
internal fun cacheIrClass(regularClass: FirRegularClass, irClass: IrClass) {
if (regularClass.visibility == Visibilities.Local) {
@@ -217,10 +236,11 @@ class Fir2IrClassifierStorage(
// firClass may be referenced by some parent's type parameters as a bound. In that case, getIrClassSymbol will be called recursively.
classifierStorage.getCachedIrClass(firClass)?.let { return it }
val irClass = lazyDeclarationsGenerator.createIrLazyClass(firClass, irParent)
val symbol = createClassSymbol(firClass)
val irClass = lazyDeclarationsGenerator.createIrLazyClass(firClass, irParent, symbol)
classCache[firClass] = irClass
// NB: this is needed to prevent recursions in case of self bounds
(irClass as Fir2IrLazyClass).prepareTypeParameters()
irClass.prepareTypeParameters()
return irClass
@@ -359,7 +379,9 @@ class Fir2IrClassifierStorage(
}
fun createAndCacheCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile): IrClass {
return classifiersGenerator.createCodeFragmentClass(codeFragment, containingFile).also {
val signature = signatureComposer.composeSignature(codeFragment)
val symbol = createClassSymbol(signature)
return classifiersGenerator.createCodeFragmentClass(codeFragment, containingFile, symbol).also {
codeFragmentCache[codeFragment] = it
}
}
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components {
// ------------------------------------ type parameters ------------------------------------
@@ -62,16 +61,10 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
// ------------------------------------ classes ------------------------------------
fun declareIrClass(signature: IdSignature?, factory: (IrClassSymbol) -> IrClass): IrClass {
return if (signature == null)
factory(IrClassSymbolImpl())
else
symbolTable.declareClass(signature, { IrClassPublicSymbolImpl(signature) }, factory)
}
fun createIrClass(
regularClass: FirRegularClass,
parent: IrDeclarationParent,
symbol: IrClassSymbol,
predefinedOrigin: IrDeclarationOrigin? = null
): IrClass {
val visibility = regularClass.visibility
@@ -80,31 +73,26 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
ClassKind.ANNOTATION_CLASS -> Modality.OPEN
else -> regularClass.modality ?: Modality.FINAL
}
val signature = runUnless(regularClass.isLocal || !configuration.linkViaSignatures) {
signatureComposer.composeSignature(regularClass)
}
val irClass = regularClass.convertWithOffsets { startOffset, endOffset ->
declareIrClass(signature) { symbol ->
irFactory.createClass(
startOffset = startOffset,
endOffset = endOffset,
origin = regularClass.computeIrOrigin(predefinedOrigin),
name = regularClass.name,
visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility),
symbol = symbol,
kind = regularClass.classKind,
modality = modality,
isExternal = regularClass.isExternal,
isCompanion = regularClass.isCompanion,
isInner = regularClass.isInner,
isData = regularClass.isData,
isValue = regularClass.isInline,
isExpect = regularClass.isExpect,
isFun = regularClass.isFun,
hasEnumEntries = regularClass.hasEnumEntries,
).apply {
metadata = FirMetadataSource.Class(regularClass)
}
irFactory.createClass(
startOffset = startOffset,
endOffset = endOffset,
origin = regularClass.computeIrOrigin(predefinedOrigin),
name = regularClass.name,
visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility),
symbol = symbol,
kind = regularClass.classKind,
modality = modality,
isExternal = regularClass.isExternal,
isCompanion = regularClass.isCompanion,
isInner = regularClass.isInner,
isData = regularClass.isData,
isValue = regularClass.isInline,
isExpect = regularClass.isExpect,
isFun = regularClass.isFun,
hasEnumEntries = regularClass.hasEnumEntries,
).apply {
metadata = FirMetadataSource.Class(regularClass)
}
}
/*
@@ -326,40 +314,37 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
// ------------------------------------ code fragments ------------------------------------
fun createCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile): IrClass {
fun createCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile, symbol: IrClassSymbol): IrClass {
val conversionData = codeFragment.conversionData
val signature = signatureComposer.composeSignature(codeFragment)
val irClass = codeFragment.convertWithOffsets { startOffset, endOffset ->
declareIrClass(signature) { symbol ->
irFactory.createClass(
startOffset,
endOffset,
IrDeclarationOrigin.DEFINED,
conversionData.classId.shortClassName,
DescriptorVisibilities.PUBLIC,
symbol,
ClassKind.CLASS,
Modality.FINAL,
isExternal = false,
isCompanion = false,
isInner = false,
isData = false,
isValue = false,
isExpect = false,
isFun = false,
hasEnumEntries = false,
).apply {
metadata = FirMetadataSource.CodeFragment(codeFragment)
setParent(containingFile)
addDeclarationToParent(this, containingFile)
typeParameters = emptyList()
thisReceiver = declareThisReceiverParameter(
thisType = IrSimpleTypeImpl(symbol, false, emptyList(), emptyList()),
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
)
superTypes = listOf(irBuiltIns.anyType)
}
irFactory.createClass(
startOffset,
endOffset,
IrDeclarationOrigin.DEFINED,
conversionData.classId.shortClassName,
DescriptorVisibilities.PUBLIC,
symbol,
ClassKind.CLASS,
Modality.FINAL,
isExternal = false,
isCompanion = false,
isInner = false,
isData = false,
isValue = false,
isExpect = false,
isFun = false,
hasEnumEntries = false,
).apply {
metadata = FirMetadataSource.CodeFragment(codeFragment)
setParent(containingFile)
addDeclarationToParent(this, containingFile)
typeParameters = emptyList()
thisReceiver = declareThisReceiverParameter(
thisType = IrSimpleTypeImpl(symbol, false, emptyList(), emptyList()),
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
)
superTypes = listOf(irBuiltIns.anyType)
}
}
return irClass
@@ -13,12 +13,10 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.lazy.*
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldPublicSymbolImpl
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.utils.addToStdlib.runIf
class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components {
internal fun createIrLazyFunction(
@@ -82,15 +80,11 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir
fun createIrLazyClass(
firClass: FirRegularClass,
irParent: IrDeclarationParent,
): IrClass = firClass.convertWithOffsets { startOffset, endOffset ->
symbol: IrClassSymbol
): Fir2IrLazyClass = firClass.convertWithOffsets { startOffset, endOffset ->
val firClassOrigin = firClass.irOrigin(session.firProvider)
val signature = runIf(configuration.linkViaSignatures) {
signatureComposer.composeSignature(firClass)
}
classifiersGenerator.declareIrClass(signature) { symbol ->
Fir2IrLazyClass(components, startOffset, endOffset, firClassOrigin, firClass, symbol).apply {
parent = irParent
}
Fir2IrLazyClass(components, startOffset, endOffset, firClassOrigin, firClass, symbol).apply {
parent = irParent
}
}