From 41fa27602258deabbd8b41742873b12ef3a2d92f Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 29 Aug 2023 14:52:22 +0300 Subject: [PATCH] [FIR2IR] Extract logic of IR declarations generation into separate component. Part 13 Move almost all caching of created classifiers from Fir2IrClassifiersGenerator back to Fir2IrClassifierStorage --- .../fir/backend/Fir2IrClassifierStorage.kt | 72 +++++++++++++++--- .../generators/Fir2IrClassifiersGenerator.kt | 76 +------------------ 2 files changed, 65 insertions(+), 83 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index adb902a56bd..2d20b823071 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -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 + } + } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrClassifiersGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrClassifiersGenerator.kt index 419338f442d..285f3bb8cdf 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrClassifiersGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrClassifiersGenerator.kt @@ -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,