[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.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.declarations.* 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.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression 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.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol 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.fir.types.FirTypeRef
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.* 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.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol 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.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType 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.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,
@@ -162,12 +166,27 @@ class Fir2IrClassifierStorage(
parent: IrDeclarationParent, parent: IrDeclarationParent,
predefinedOrigin: IrDeclarationOrigin? = null predefinedOrigin: IrDeclarationOrigin? = null
): IrClass { ): IrClass {
return classifiersGenerator.createIrClass(regularClass, parent, predefinedOrigin).also { val symbol = createClassSymbol(regularClass)
return classifiersGenerator.createIrClass(regularClass, parent, symbol, predefinedOrigin).also {
@OptIn(LeakedDeclarationCaches::class) @OptIn(LeakedDeclarationCaches::class)
cacheIrClass(regularClass, it) 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 @LeakedDeclarationCaches
internal fun cacheIrClass(regularClass: FirRegularClass, irClass: IrClass) { internal fun cacheIrClass(regularClass: FirRegularClass, irClass: IrClass) {
if (regularClass.visibility == Visibilities.Local) { 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. // 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 } 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 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 as Fir2IrLazyClass).prepareTypeParameters() irClass.prepareTypeParameters()
return irClass return irClass
@@ -359,7 +379,9 @@ class Fir2IrClassifierStorage(
} }
fun createAndCacheCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile): IrClass { 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 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.FqName
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.runUnless
class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components { class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components {
// ------------------------------------ type parameters ------------------------------------ // ------------------------------------ type parameters ------------------------------------
@@ -62,16 +61,10 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
// ------------------------------------ classes ------------------------------------ // ------------------------------------ classes ------------------------------------
fun declareIrClass(signature: IdSignature?, factory: (IrClassSymbol) -> IrClass): IrClass {
return if (signature == null)
factory(IrClassSymbolImpl())
else
symbolTable.declareClass(signature, { IrClassPublicSymbolImpl(signature) }, factory)
}
fun createIrClass( fun createIrClass(
regularClass: FirRegularClass, regularClass: FirRegularClass,
parent: IrDeclarationParent, parent: IrDeclarationParent,
symbol: IrClassSymbol,
predefinedOrigin: IrDeclarationOrigin? = null predefinedOrigin: IrDeclarationOrigin? = null
): IrClass { ): IrClass {
val visibility = regularClass.visibility val visibility = regularClass.visibility
@@ -80,31 +73,26 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
ClassKind.ANNOTATION_CLASS -> Modality.OPEN ClassKind.ANNOTATION_CLASS -> Modality.OPEN
else -> regularClass.modality ?: Modality.FINAL else -> regularClass.modality ?: Modality.FINAL
} }
val signature = runUnless(regularClass.isLocal || !configuration.linkViaSignatures) {
signatureComposer.composeSignature(regularClass)
}
val irClass = regularClass.convertWithOffsets { startOffset, endOffset -> val irClass = regularClass.convertWithOffsets { startOffset, endOffset ->
declareIrClass(signature) { symbol -> irFactory.createClass(
irFactory.createClass( startOffset = startOffset,
startOffset = startOffset, endOffset = endOffset,
endOffset = endOffset, origin = regularClass.computeIrOrigin(predefinedOrigin),
origin = regularClass.computeIrOrigin(predefinedOrigin), name = regularClass.name,
name = regularClass.name, visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility),
visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), symbol = symbol,
symbol = symbol, kind = regularClass.classKind,
kind = regularClass.classKind, modality = modality,
modality = modality, isExternal = regularClass.isExternal,
isExternal = regularClass.isExternal, isCompanion = regularClass.isCompanion,
isCompanion = regularClass.isCompanion, isInner = regularClass.isInner,
isInner = regularClass.isInner, isData = regularClass.isData,
isData = regularClass.isData, isValue = regularClass.isInline,
isValue = regularClass.isInline, isExpect = regularClass.isExpect,
isExpect = regularClass.isExpect, isFun = regularClass.isFun,
isFun = regularClass.isFun, hasEnumEntries = regularClass.hasEnumEntries,
hasEnumEntries = regularClass.hasEnumEntries, ).apply {
).apply { metadata = FirMetadataSource.Class(regularClass)
metadata = FirMetadataSource.Class(regularClass)
}
} }
} }
/* /*
@@ -326,40 +314,37 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
// ------------------------------------ code fragments ------------------------------------ // ------------------------------------ code fragments ------------------------------------
fun createCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile): IrClass { fun createCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile, symbol: IrClassSymbol): IrClass {
val conversionData = codeFragment.conversionData val conversionData = codeFragment.conversionData
val signature = signatureComposer.composeSignature(codeFragment)
val irClass = codeFragment.convertWithOffsets { startOffset, endOffset -> val irClass = codeFragment.convertWithOffsets { startOffset, endOffset ->
declareIrClass(signature) { symbol -> irFactory.createClass(
irFactory.createClass( startOffset,
startOffset, endOffset,
endOffset, IrDeclarationOrigin.DEFINED,
IrDeclarationOrigin.DEFINED, conversionData.classId.shortClassName,
conversionData.classId.shortClassName, DescriptorVisibilities.PUBLIC,
DescriptorVisibilities.PUBLIC, symbol,
symbol, ClassKind.CLASS,
ClassKind.CLASS, Modality.FINAL,
Modality.FINAL, isExternal = false,
isExternal = false, isCompanion = false,
isCompanion = false, isInner = false,
isInner = false, isData = false,
isData = false, isValue = false,
isValue = false, isExpect = false,
isExpect = false, isFun = false,
isFun = false, hasEnumEntries = false,
hasEnumEntries = false, ).apply {
).apply { metadata = FirMetadataSource.CodeFragment(codeFragment)
metadata = FirMetadataSource.CodeFragment(codeFragment) setParent(containingFile)
setParent(containingFile) addDeclarationToParent(this, containingFile)
addDeclarationToParent(this, containingFile) typeParameters = emptyList()
typeParameters = emptyList() thisReceiver = declareThisReceiverParameter(
thisReceiver = declareThisReceiverParameter( thisType = IrSimpleTypeImpl(symbol, false, emptyList(), emptyList()),
thisType = IrSimpleTypeImpl(symbol, false, emptyList(), emptyList()), thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER )
) superTypes = listOf(irBuiltIns.anyType)
superTypes = listOf(irBuiltIns.anyType)
}
} }
} }
return irClass return irClass
@@ -13,12 +13,10 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.lazy.* import org.jetbrains.kotlin.fir.lazy.*
import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.ir.declarations.* 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.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol 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 { class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components {
internal fun createIrLazyFunction( internal fun createIrLazyFunction(
@@ -82,15 +80,11 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir
fun createIrLazyClass( fun createIrLazyClass(
firClass: FirRegularClass, firClass: FirRegularClass,
irParent: IrDeclarationParent, irParent: IrDeclarationParent,
): IrClass = firClass.convertWithOffsets { startOffset, endOffset -> symbol: IrClassSymbol
): Fir2IrLazyClass = firClass.convertWithOffsets { startOffset, endOffset ->
val firClassOrigin = firClass.irOrigin(session.firProvider) val firClassOrigin = firClass.irOrigin(session.firProvider)
val signature = runIf(configuration.linkViaSignatures) { Fir2IrLazyClass(components, startOffset, endOffset, firClassOrigin, firClass, symbol).apply {
signatureComposer.composeSignature(firClass) parent = irParent
}
classifiersGenerator.declareIrClass(signature) { symbol ->
Fir2IrLazyClass(components, startOffset, endOffset, firClassOrigin, firClass, symbol).apply {
parent = irParent
}
} }
} }