[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.impl.*
|
||||
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.SpecialNames
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
@@ -80,15 +79,31 @@ class Fir2IrClassifierStorage(
|
||||
for ((index, typeParameter) in owner.typeParameters.withIndex()) {
|
||||
val original = typeParameter.symbol.fir
|
||||
getCachedIrTypeParameter(original)
|
||||
?: classifiersGenerator.createIrTypeParameterWithoutBounds(original, index, irOwnerSymbol)
|
||||
?: createAndCacheIrTypeParameter(original, index, irOwnerSymbol)
|
||||
if (owner is FirProperty && owner.isVar) {
|
||||
val context = ConversionTypeOrigin.SETTER
|
||||
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(
|
||||
irOwner: IrTypeParametersContainer,
|
||||
owner: FirTypeParameterRefsOwner,
|
||||
@@ -140,7 +155,9 @@ class Fir2IrClassifierStorage(
|
||||
typeAlias: FirTypeAlias,
|
||||
parent: IrDeclarationParent
|
||||
): IrTypeAlias {
|
||||
return classifiersGenerator.createIrTypeAlias(typeAlias, parent)
|
||||
return classifiersGenerator.createIrTypeAlias(typeAlias, parent).also {
|
||||
typeAliasCache[typeAlias] = it
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getCachedTypeAlias(firTypeAlias: FirTypeAlias): IrTypeAlias? = typeAliasCache[firTypeAlias]
|
||||
@@ -150,7 +167,13 @@ class Fir2IrClassifierStorage(
|
||||
parent: IrDeclarationParent,
|
||||
predefinedOrigin: IrDeclarationOrigin? = null
|
||||
): 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(
|
||||
@@ -159,11 +182,22 @@ class Fir2IrClassifierStorage(
|
||||
name: Name = SpecialNames.NO_NAME_PROVIDED,
|
||||
irParent: IrDeclarationParent? = null
|
||||
): 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 {
|
||||
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(
|
||||
@@ -183,7 +217,9 @@ class Fir2IrClassifierStorage(
|
||||
typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT
|
||||
): IrTypeParameter {
|
||||
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) {
|
||||
@@ -212,7 +248,9 @@ class Fir2IrClassifierStorage(
|
||||
enumEntry,
|
||||
irParent = irParent,
|
||||
predefinedOrigin = predefinedOrigin
|
||||
)
|
||||
).also {
|
||||
enumEntryCache[enumEntry] = it
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(IrSymbolInternals::class)
|
||||
@@ -247,9 +285,23 @@ class Fir2IrClassifierStorage(
|
||||
}
|
||||
|
||||
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}")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
typeAliasCache[typeAlias] = irTypeAlias
|
||||
irTypeAlias
|
||||
}
|
||||
}
|
||||
@@ -265,11 +264,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
||||
}
|
||||
}
|
||||
irClass.parent = parent
|
||||
if (regularClass.visibility == Visibilities.Local) {
|
||||
localStorage[regularClass] = irClass
|
||||
} else {
|
||||
classCache[regularClass] = irClass
|
||||
}
|
||||
return irClass
|
||||
}
|
||||
|
||||
@@ -298,7 +292,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
||||
if (irParent != null) {
|
||||
irAnonymousObject.parent = irParent
|
||||
}
|
||||
localStorage[anonymousObject] = irAnonymousObject
|
||||
return irAnonymousObject
|
||||
}
|
||||
|
||||
@@ -336,33 +329,17 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
||||
}
|
||||
}
|
||||
}
|
||||
codeFragmentCache[codeFragment] = irClass
|
||||
return irClass
|
||||
}
|
||||
|
||||
private fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass {
|
||||
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)
|
||||
fun initializeTypeParameterBounds(typeParameter: FirTypeParameter, irTypeParameter: IrTypeParameter) {
|
||||
irTypeParameter.superTypes = typeParameter.bounds.map { it.toIrType() }
|
||||
return irTypeParameter
|
||||
}
|
||||
|
||||
fun createIrTypeParameterWithoutBounds(
|
||||
typeParameter: FirTypeParameter,
|
||||
index: Int,
|
||||
ownerSymbol: IrSymbol,
|
||||
typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT,
|
||||
): IrTypeParameter {
|
||||
require(index >= 0)
|
||||
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)
|
||||
return irTypeParameter
|
||||
}
|
||||
@@ -442,7 +412,7 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
||||
): IrEnumEntry {
|
||||
return enumEntry.convertWithOffsets { startOffset, endOffset ->
|
||||
val signature = signatureComposer.composeSignature(enumEntry)
|
||||
val result = declareIrEnumEntry(signature) { symbol ->
|
||||
declareIrEnumEntry(signature) { symbol ->
|
||||
val origin = enumEntry.computeIrOrigin(predefinedOrigin)
|
||||
irFactory.createEnumEntry(
|
||||
startOffset = startOffset,
|
||||
@@ -459,7 +429,7 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
||||
// 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,
|
||||
// which will be translated via visitor later.
|
||||
val klass = getIrAnonymousObjectForEnumEntry(
|
||||
val klass = classifierStorage.getIrAnonymousObjectForEnumEntry(
|
||||
(enumEntry.initializer as FirAnonymousObjectExpression).anonymousObject, enumEntry.name, irParent
|
||||
)
|
||||
this.correspondingClass = klass
|
||||
@@ -467,8 +437,6 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
|
||||
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 {
|
||||
irFactory.createSimpleFunction(
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
|
||||
Reference in New Issue
Block a user