[FIR2IR] Extract logic of IR declarations generation into separate component. Part 13
Move almost all caching of created classifiers from Fir2IrClassifiersGenerator back to Fir2IrClassifierStorage
This commit is contained in:
committed by
Space Team
parent
26211a0277
commit
41fa276022
+62
-10
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
|
||||||
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.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
@@ -80,15 +79,31 @@ class Fir2IrClassifierStorage(
|
|||||||
for ((index, typeParameter) in owner.typeParameters.withIndex()) {
|
for ((index, typeParameter) in owner.typeParameters.withIndex()) {
|
||||||
val original = typeParameter.symbol.fir
|
val original = typeParameter.symbol.fir
|
||||||
getCachedIrTypeParameter(original)
|
getCachedIrTypeParameter(original)
|
||||||
?: classifiersGenerator.createIrTypeParameterWithoutBounds(original, index, irOwnerSymbol)
|
?: createAndCacheIrTypeParameter(original, index, irOwnerSymbol)
|
||||||
if (owner is FirProperty && owner.isVar) {
|
if (owner is FirProperty && owner.isVar) {
|
||||||
val context = ConversionTypeOrigin.SETTER
|
val context = ConversionTypeOrigin.SETTER
|
||||||
getCachedIrTypeParameter(original, context)
|
getCachedIrTypeParameter(original, context)
|
||||||
?: classifiersGenerator.createIrTypeParameterWithoutBounds(original, index, irOwnerSymbol, context)
|
?: createAndCacheIrTypeParameter(original, index, irOwnerSymbol, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createAndCacheIrTypeParameter(
|
||||||
|
typeParameter: FirTypeParameter,
|
||||||
|
index: Int,
|
||||||
|
ownerSymbol: IrSymbol,
|
||||||
|
typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT,
|
||||||
|
): IrTypeParameter {
|
||||||
|
val irTypeParameter = classifiersGenerator.createIrTypeParameterWithoutBounds(typeParameter, index, ownerSymbol)
|
||||||
|
// Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds.
|
||||||
|
if (typeOrigin.forSetter) {
|
||||||
|
typeParameterCacheForSetter[typeParameter] = irTypeParameter
|
||||||
|
} else {
|
||||||
|
typeParameterCache[typeParameter] = irTypeParameter
|
||||||
|
}
|
||||||
|
return irTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
internal fun setTypeParameters(
|
internal fun setTypeParameters(
|
||||||
irOwner: IrTypeParametersContainer,
|
irOwner: IrTypeParametersContainer,
|
||||||
owner: FirTypeParameterRefsOwner,
|
owner: FirTypeParameterRefsOwner,
|
||||||
@@ -140,7 +155,9 @@ class Fir2IrClassifierStorage(
|
|||||||
typeAlias: FirTypeAlias,
|
typeAlias: FirTypeAlias,
|
||||||
parent: IrDeclarationParent
|
parent: IrDeclarationParent
|
||||||
): IrTypeAlias {
|
): IrTypeAlias {
|
||||||
return classifiersGenerator.createIrTypeAlias(typeAlias, parent)
|
return classifiersGenerator.createIrTypeAlias(typeAlias, parent).also {
|
||||||
|
typeAliasCache[typeAlias] = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getCachedTypeAlias(firTypeAlias: FirTypeAlias): IrTypeAlias? = typeAliasCache[firTypeAlias]
|
internal fun getCachedTypeAlias(firTypeAlias: FirTypeAlias): IrTypeAlias? = typeAliasCache[firTypeAlias]
|
||||||
@@ -150,7 +167,13 @@ class Fir2IrClassifierStorage(
|
|||||||
parent: IrDeclarationParent,
|
parent: IrDeclarationParent,
|
||||||
predefinedOrigin: IrDeclarationOrigin? = null
|
predefinedOrigin: IrDeclarationOrigin? = null
|
||||||
): IrClass {
|
): IrClass {
|
||||||
return classifiersGenerator.createIrClass(regularClass, parent, predefinedOrigin)
|
return classifiersGenerator.createIrClass(regularClass, parent, predefinedOrigin).also {
|
||||||
|
if (regularClass.visibility == Visibilities.Local) {
|
||||||
|
localStorage[regularClass] = it
|
||||||
|
} else {
|
||||||
|
classCache[regularClass] = it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createAndCacheAnonymousObject(
|
fun createAndCacheAnonymousObject(
|
||||||
@@ -159,11 +182,22 @@ class Fir2IrClassifierStorage(
|
|||||||
name: Name = SpecialNames.NO_NAME_PROVIDED,
|
name: Name = SpecialNames.NO_NAME_PROVIDED,
|
||||||
irParent: IrDeclarationParent? = null
|
irParent: IrDeclarationParent? = null
|
||||||
): IrClass {
|
): IrClass {
|
||||||
return classifiersGenerator.createAnonymousObject(anonymousObject, visibility, name, irParent)
|
return classifiersGenerator.createAnonymousObject(anonymousObject, visibility, name, irParent).also {
|
||||||
|
localStorage[anonymousObject] = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createAndCacheCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile): IrClass {
|
fun createAndCacheCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile): IrClass {
|
||||||
return classifiersGenerator.createCodeFragmentClass(codeFragment, containingFile)
|
return classifiersGenerator.createCodeFragmentClass(codeFragment, containingFile).also {
|
||||||
|
codeFragmentCache[codeFragment] = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass {
|
||||||
|
localStorage[anonymousObject]?.let { return it }
|
||||||
|
val irAnonymousObject = classifierStorage.createAndCacheAnonymousObject(anonymousObject, Visibilities.Private, name, irParent)
|
||||||
|
classifiersGenerator.processClassHeader(anonymousObject, irAnonymousObject)
|
||||||
|
return irAnonymousObject
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getCachedIrTypeParameter(
|
internal fun getCachedIrTypeParameter(
|
||||||
@@ -183,7 +217,9 @@ class Fir2IrClassifierStorage(
|
|||||||
typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT
|
typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT
|
||||||
): IrTypeParameter {
|
): IrTypeParameter {
|
||||||
getCachedIrTypeParameter(typeParameter, typeOrigin)?.let { return it }
|
getCachedIrTypeParameter(typeParameter, typeOrigin)?.let { return it }
|
||||||
return classifiersGenerator.createIrTypeParameterWithBounds(typeParameter, index, ownerSymbol, typeOrigin)
|
val irTypeParameter = createAndCacheIrTypeParameter(typeParameter, index, ownerSymbol, typeOrigin)
|
||||||
|
classifiersGenerator.initializeTypeParameterBounds(typeParameter, irTypeParameter)
|
||||||
|
return irTypeParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putEnumEntryClassInScope(enumEntry: FirEnumEntry, correspondingClass: IrClass) {
|
fun putEnumEntryClassInScope(enumEntry: FirEnumEntry, correspondingClass: IrClass) {
|
||||||
@@ -212,7 +248,9 @@ class Fir2IrClassifierStorage(
|
|||||||
enumEntry,
|
enumEntry,
|
||||||
irParent = irParent,
|
irParent = irParent,
|
||||||
predefinedOrigin = predefinedOrigin
|
predefinedOrigin = predefinedOrigin
|
||||||
)
|
).also {
|
||||||
|
enumEntryCache[enumEntry] = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
@OptIn(IrSymbolInternals::class)
|
||||||
@@ -247,9 +285,23 @@ class Fir2IrClassifierStorage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (components.configuration.allowNonCachedDeclarations) {
|
if (components.configuration.allowNonCachedDeclarations) {
|
||||||
return classifiersGenerator.createIrTypeParameterForNonCachedDeclaration(firTypeParameter)
|
return createIrTypeParameterForNonCachedDeclaration(firTypeParameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
error("Cannot find cached type parameter by FIR symbol: ${firTypeParameterSymbol.name} of the owner: ${firTypeParameter.containingDeclarationSymbol}")
|
error("Cannot find cached type parameter by FIR symbol: ${firTypeParameterSymbol.name} of the owner: ${firTypeParameter.containingDeclarationSymbol}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createIrTypeParameterForNonCachedDeclaration(firTypeParameter: FirTypeParameter): IrTypeParameterSymbol {
|
||||||
|
val firTypeParameterOwnerSymbol = firTypeParameter.containingDeclarationSymbol
|
||||||
|
val firTypeParameterOwner = firTypeParameterOwnerSymbol.fir as FirTypeParameterRefsOwner
|
||||||
|
val index = firTypeParameterOwner.typeParameters.indexOf(firTypeParameter).also { check(it >= 0) }
|
||||||
|
|
||||||
|
val isSetter = firTypeParameterOwner is FirPropertyAccessor && firTypeParameterOwner.isSetter
|
||||||
|
val conversionTypeOrigin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
||||||
|
|
||||||
|
return createAndCacheIrTypeParameter(firTypeParameter, index, IrTypeParameterSymbolImpl(), conversionTypeOrigin).also {
|
||||||
|
classifiersGenerator.initializeTypeParameterBounds(firTypeParameter, it)
|
||||||
|
}.symbol
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-73
@@ -215,7 +215,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
parent.declarations += this
|
parent.declarations += this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typeAliasCache[typeAlias] = irTypeAlias
|
|
||||||
irTypeAlias
|
irTypeAlias
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,11 +264,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
irClass.parent = parent
|
irClass.parent = parent
|
||||||
if (regularClass.visibility == Visibilities.Local) {
|
|
||||||
localStorage[regularClass] = irClass
|
|
||||||
} else {
|
|
||||||
classCache[regularClass] = irClass
|
|
||||||
}
|
|
||||||
return irClass
|
return irClass
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +292,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
if (irParent != null) {
|
if (irParent != null) {
|
||||||
irAnonymousObject.parent = irParent
|
irAnonymousObject.parent = irParent
|
||||||
}
|
}
|
||||||
localStorage[anonymousObject] = irAnonymousObject
|
|
||||||
return irAnonymousObject
|
return irAnonymousObject
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,33 +329,17 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codeFragmentCache[codeFragment] = irClass
|
|
||||||
return irClass
|
return irClass
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass {
|
fun initializeTypeParameterBounds(typeParameter: FirTypeParameter, irTypeParameter: IrTypeParameter) {
|
||||||
localStorage[anonymousObject]?.let { return it }
|
|
||||||
val irAnonymousObject = classifierStorage.createAndCacheAnonymousObject(anonymousObject, Visibilities.Private, name, irParent)
|
|
||||||
processClassHeader(anonymousObject, irAnonymousObject)
|
|
||||||
return irAnonymousObject
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createIrTypeParameterWithBounds(
|
|
||||||
typeParameter: FirTypeParameter,
|
|
||||||
index: Int,
|
|
||||||
ownerSymbol: IrSymbol,
|
|
||||||
typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT,
|
|
||||||
): IrTypeParameter {
|
|
||||||
val irTypeParameter = createIrTypeParameterWithoutBounds(typeParameter, index, ownerSymbol, typeOrigin)
|
|
||||||
irTypeParameter.superTypes = typeParameter.bounds.map { it.toIrType() }
|
irTypeParameter.superTypes = typeParameter.bounds.map { it.toIrType() }
|
||||||
return irTypeParameter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createIrTypeParameterWithoutBounds(
|
fun createIrTypeParameterWithoutBounds(
|
||||||
typeParameter: FirTypeParameter,
|
typeParameter: FirTypeParameter,
|
||||||
index: Int,
|
index: Int,
|
||||||
ownerSymbol: IrSymbol,
|
ownerSymbol: IrSymbol,
|
||||||
typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT,
|
|
||||||
): IrTypeParameter {
|
): IrTypeParameter {
|
||||||
require(index >= 0)
|
require(index >= 0)
|
||||||
val origin = typeParameter.computeIrOrigin()
|
val origin = typeParameter.computeIrOrigin()
|
||||||
@@ -417,13 +394,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds.
|
|
||||||
if (typeOrigin.forSetter) {
|
|
||||||
typeParameterCacheForSetter[typeParameter] = irTypeParameter
|
|
||||||
} else {
|
|
||||||
typeParameterCache[typeParameter] = irTypeParameter
|
|
||||||
}
|
|
||||||
annotationGenerator.generate(irTypeParameter, typeParameter)
|
annotationGenerator.generate(irTypeParameter, typeParameter)
|
||||||
return irTypeParameter
|
return irTypeParameter
|
||||||
}
|
}
|
||||||
@@ -442,7 +412,7 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
): IrEnumEntry {
|
): IrEnumEntry {
|
||||||
return enumEntry.convertWithOffsets { startOffset, endOffset ->
|
return enumEntry.convertWithOffsets { startOffset, endOffset ->
|
||||||
val signature = signatureComposer.composeSignature(enumEntry)
|
val signature = signatureComposer.composeSignature(enumEntry)
|
||||||
val result = declareIrEnumEntry(signature) { symbol ->
|
declareIrEnumEntry(signature) { symbol ->
|
||||||
val origin = enumEntry.computeIrOrigin(predefinedOrigin)
|
val origin = enumEntry.computeIrOrigin(predefinedOrigin)
|
||||||
irFactory.createEnumEntry(
|
irFactory.createEnumEntry(
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
@@ -459,7 +429,7 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
// An enum entry with its own members requires an anonymous object generated.
|
// An enum entry with its own members requires an anonymous object generated.
|
||||||
// Otherwise, this is a default-ish enum entry whose initializer would be a delegating constructor call,
|
// Otherwise, this is a default-ish enum entry whose initializer would be a delegating constructor call,
|
||||||
// which will be translated via visitor later.
|
// which will be translated via visitor later.
|
||||||
val klass = getIrAnonymousObjectForEnumEntry(
|
val klass = classifierStorage.getIrAnonymousObjectForEnumEntry(
|
||||||
(enumEntry.initializer as FirAnonymousObjectExpression).anonymousObject, enumEntry.name, irParent
|
(enumEntry.initializer as FirAnonymousObjectExpression).anonymousObject, enumEntry.name, irParent
|
||||||
)
|
)
|
||||||
this.correspondingClass = klass
|
this.correspondingClass = klass
|
||||||
@@ -467,8 +437,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
declarationStorage.leaveScope(this.symbol)
|
declarationStorage.leaveScope(this.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumEntryCache[enumEntry] = result
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,44 +476,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: should be decomposed
|
|
||||||
fun createIrClassSymbolByFirSymbol(firClassSymbol: FirClassSymbol<*>): IrClassSymbol {
|
|
||||||
val firClass = firClassSymbol.fir
|
|
||||||
classifierStorage.getCachedIrClass(firClass)?.let { return it.symbol }
|
|
||||||
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.Local) {
|
|
||||||
return createLocalIrClassOnTheFly(firClass).symbol
|
|
||||||
}
|
|
||||||
firClass as FirRegularClass
|
|
||||||
val classId = firClassSymbol.classId
|
|
||||||
val parentId = classId.outerClassId
|
|
||||||
val parentClass = parentId?.let { session.symbolProvider.getClassLikeSymbolByClassId(it) }
|
|
||||||
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentClass?.toLookupTag(), firClassSymbol, firClass.origin)!!
|
|
||||||
|
|
||||||
// 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.symbol }
|
|
||||||
|
|
||||||
val irClass = lazyDeclarationsGenerator.createIrLazyClass(firClass, irParent)
|
|
||||||
classCache[firClass] = irClass
|
|
||||||
// NB: this is needed to prevent recursions in case of self bounds
|
|
||||||
(irClass as Fir2IrLazyClass).prepareTypeParameters()
|
|
||||||
|
|
||||||
return irClass.symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun createIrTypeParameterForNonCachedDeclaration(firTypeParameter: FirTypeParameter): IrTypeParameterSymbol {
|
|
||||||
val firTypeParameterOwnerSymbol = firTypeParameter.containingDeclarationSymbol
|
|
||||||
val firTypeParameterOwner = firTypeParameterOwnerSymbol.fir as FirTypeParameterRefsOwner
|
|
||||||
val index = firTypeParameterOwner.typeParameters.indexOf(firTypeParameter).also { check(it >= 0) }
|
|
||||||
|
|
||||||
val isSetter = firTypeParameterOwner is FirPropertyAccessor && firTypeParameterOwner.isSetter
|
|
||||||
val conversionTypeOrigin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
|
||||||
|
|
||||||
return createIrTypeParameterWithoutBounds(firTypeParameter, index, IrTypeParameterSymbolImpl(), conversionTypeOrigin).apply {
|
|
||||||
superTypes = firTypeParameter.bounds.map { it.toIrType(typeConverter) }
|
|
||||||
}.symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
private val temporaryParent by lazy {
|
private val temporaryParent by lazy {
|
||||||
irFactory.createSimpleFunction(
|
irFactory.createSimpleFunction(
|
||||||
startOffset = UNDEFINED_OFFSET,
|
startOffset = UNDEFINED_OFFSET,
|
||||||
|
|||||||
Reference in New Issue
Block a user