From 175145ce4e41c275faca721a336e8560e585a8a7 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 13 Mar 2020 09:49:12 +0300 Subject: [PATCH] [FIR2IR] Extract separate classifier storage from declaration storage --- .../kotlin/fir/backend/ConversionUtils.kt | 35 +- .../fir/backend/Fir2IrClassifierStorage.kt | 364 ++++++++++++++++ .../kotlin/fir/backend/Fir2IrConverter.kt | 21 +- .../fir/backend/Fir2IrDeclarationStorage.kt | 392 ++---------------- .../kotlin/fir/backend/Fir2IrTypeConverter.kt | 4 +- .../kotlin/fir/backend/Fir2IrVisitor.kt | 29 +- 6 files changed, 455 insertions(+), 390 deletions(-) create mode 100644 compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 1141049f578..0414d561c20 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.fir.references.FirThisReference import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AccessorSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* @@ -70,28 +69,32 @@ class ConversionTypeContext internal constructor( } } -fun FirClassifierSymbol<*>.toIrSymbol( +fun FirClassifierSymbol<*>.toSymbol( session: FirSession, - declarationStorage: Fir2IrDeclarationStorage, + classifierStorage: Fir2IrClassifierStorage, typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT ): IrClassifierSymbol { return when (this) { is FirTypeParameterSymbol -> { - declarationStorage.getIrTypeParameterSymbol(this, typeContext) + classifierStorage.getIrTypeParameterSymbol(this, typeContext) } is FirTypeAliasSymbol -> { val typeAlias = fir val coneClassLikeType = (typeAlias.expandedTypeRef as FirResolvedTypeRef).type as ConeClassLikeType - coneClassLikeType.lookupTag.toSymbol(session)!!.toIrSymbol(session, declarationStorage) + coneClassLikeType.lookupTag.toSymbol(session)!!.toSymbol(session, classifierStorage) } is FirClassSymbol -> { - declarationStorage.getIrClassSymbol(this) + classifierStorage.getIrClassSymbol(this) } else -> throw AssertionError("Should not be here: $this") } } -fun FirReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? { +fun FirReference.toSymbol( + session: FirSession, + classifierStorage: Fir2IrClassifierStorage, + declarationStorage: Fir2IrDeclarationStorage +): IrSymbol? { return when (this) { is FirResolvedNamedReference -> { when (val resolvedSymbol = resolvedSymbol) { @@ -100,15 +103,18 @@ fun FirReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbo resolvedSymbol.overriddenSymbol?.takeIf { it.callableId == resolvedSymbol.callableId } ?: resolvedSymbol originalCallableSymbol.toSymbol(declarationStorage) } + is FirClassifierSymbol<*> -> { + resolvedSymbol.toSymbol(session, classifierStorage) + } else -> { - resolvedSymbol.toSymbol(declarationStorage) + throw AssertionError("Unknown symbol: $resolvedSymbol") } } } is FirThisReference -> { - when (val boundSymbol = boundSymbol?.toSymbol(declarationStorage)) { - is IrClassSymbol -> boundSymbol.owner.thisReceiver?.symbol - is IrFunctionSymbol -> boundSymbol.owner.extensionReceiverParameter?.symbol + when (val boundSymbol = boundSymbol) { + is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol).owner.thisReceiver?.symbol + is FirFunctionSymbol -> declarationStorage.getIrFunctionSymbol(boundSymbol).owner.extensionReceiverParameter?.symbol else -> null } } @@ -116,10 +122,11 @@ fun FirReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbo } } -private fun AbstractFirBasedSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? = when (this) { - is FirClassSymbol -> declarationStorage.getIrClassSymbol(this) +private fun FirCallableSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? = when (this) { is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this) - is FirPropertySymbol -> if (fir.isLocal) declarationStorage.getIrValueSymbol(this) else declarationStorage.getIrPropertyOrFieldSymbol(this) + is FirPropertySymbol -> { + if (fir.isLocal) declarationStorage.getIrValueSymbol(this) else declarationStorage.getIrPropertyOrFieldSymbol(this) + } is FirFieldSymbol -> declarationStorage.getIrPropertyOrFieldSymbol(this) is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this) is FirDelegateFieldSymbol<*> -> declarationStorage.getIrBackingFieldSymbol(this) 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 new file mode 100644 index 00000000000..c97e2e141a9 --- /dev/null +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -0,0 +1,364 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.backend + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.resolve.firProvider +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrEnumEntryImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl +import org.jetbrains.kotlin.ir.descriptors.* +import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.constructors +import org.jetbrains.kotlin.name.Name + +class Fir2IrClassifierStorage( + session: FirSession, + private val irSymbolTable: SymbolTable +) { + private val firProvider = session.firProvider + + private val classCache = mutableMapOf() + + private val typeParameterCache = mutableMapOf() + + private val typeParameterCacheForSetter = mutableMapOf() + + private val enumEntryCache = mutableMapOf() + + private val localStorage = Fir2IrLocalStorage() + + lateinit var typeConverter: Fir2IrTypeConverter + + lateinit var declarationStorage: Fir2IrDeclarationStorage + + private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType = + with(typeConverter) { toIrType(typeContext) } + + internal fun IrDeclaration.declareThisReceiverParameter( + parent: IrDeclarationParent, + thisType: IrType, + thisOrigin: IrDeclarationOrigin, + startOffset: Int = this.startOffset, + endOffset: Int = this.endOffset + ): IrValueParameter { + val receiverDescriptor = WrappedReceiverParameterDescriptor() + return irSymbolTable.declareValueParameter( + startOffset, endOffset, thisOrigin, receiverDescriptor, thisType + ) { symbol -> + IrValueParameterImpl( + startOffset, endOffset, thisOrigin, symbol, + Name.special(""), -1, thisType, + varargElementType = null, isCrossinline = false, isNoinline = false + ).apply { + this.parent = parent + receiverDescriptor.bind(this) + } + } + } + + private fun IrClass.setThisReceiver() { + irSymbolTable.enterScope(descriptor) + val typeArguments = this.typeParameters.map { + IrSimpleTypeImpl(it.symbol, false, emptyList(), emptyList()) + } + thisReceiver = declareThisReceiverParameter( + parent = this, + thisType = IrSimpleTypeImpl(symbol, false, typeArguments, emptyList()), + thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER + ) + irSymbolTable.leaveScope(descriptor) + } + + internal fun preCacheTypeParameters(owner: FirTypeParametersOwner) { + owner.typeParameters.mapIndexed { index, typeParameter -> + getIrTypeParameter(typeParameter, index) + if (owner is FirProperty && owner.isVar) { + getIrTypeParameter(typeParameter, index, ConversionTypeContext.DEFAULT.inSetter()) + } + } + } + + internal fun IrTypeParametersContainer.setTypeParameters( + owner: FirTypeParametersOwner, + typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT + ) { + typeParameters = owner.typeParameters.mapIndexed { index, typeParameter -> + getIrTypeParameter(typeParameter, index, typeContext).apply { parent = this@setTypeParameters } + } + } + + private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass { + if (klass is FirRegularClass) { + setTypeParameters(klass) + } + superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() } + return this + } + + fun getCachedIrClass(klass: FirClass<*>): IrClass? { + return if (klass is FirAnonymousObject || klass is FirRegularClass && klass.visibility == Visibilities.LOCAL) { + localStorage.getLocalClass(klass) + } else { + classCache[klass] + } + } + + private fun FirRegularClass.enumClassModality(): Modality { + return when { + declarations.any { it is FirCallableMemberDeclaration<*> && it.modality == Modality.ABSTRACT } -> { + Modality.ABSTRACT + } + declarations.any { it is FirEnumEntry && it.initializer != null } -> { + Modality.OPEN + } + else -> { + Modality.FINAL + } + } + } + + internal fun createIrClass(klass: FirClass<*>, parent: IrDeclarationParent? = null): IrClass { + // NB: klass can be either FirRegularClass or FirAnonymousObject + if (klass is FirAnonymousObject) { + return createIrAnonymousObject(klass, irParent = parent) + } + val regularClass = klass as FirRegularClass + val origin = + if (firProvider.getFirClassifierContainerFileIfAny(klass.symbol) != null) IrDeclarationOrigin.DEFINED + else IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB + val irClass = registerIrClass(regularClass, parent, origin) + processClassHeader(regularClass, irClass) + return irClass + } + + fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass { + irClass.declareSupertypesAndTypeParameters(regularClass) + irClass.setThisReceiver() + return irClass + } + + fun registerIrClass( + regularClass: FirRegularClass, + parent: IrDeclarationParent? = null, + origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED + ): IrClass { + val descriptor = WrappedClassDescriptor() + val visibility = regularClass.visibility + val modality = if (regularClass.classKind == ClassKind.ENUM_CLASS) { + regularClass.enumClassModality() + } else { + regularClass.modality ?: Modality.FINAL + } + val irClass = regularClass.convertWithOffsets { startOffset, endOffset -> + irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol -> + IrClassImpl( + startOffset, + endOffset, + origin, + symbol, + regularClass.name, + regularClass.classKind, + visibility, + modality, + isCompanion = regularClass.isCompanion, + isInner = regularClass.isInner, + isData = regularClass.isData, + isExternal = regularClass.isExternal, + isInline = regularClass.isInline, + isExpect = regularClass.isExpect, + isFun = false // TODO FirRegularClass.isFun + ).apply { + descriptor.bind(this) + } + } + } + if (parent != null) { + irClass.parent = parent + } + if (regularClass.visibility == Visibilities.LOCAL) { + localStorage.putLocalClass(regularClass, irClass) + } else { + classCache[regularClass] = irClass + } + return irClass + } + + fun createIrAnonymousObject( + anonymousObject: FirAnonymousObject, + visibility: Visibility = Visibilities.LOCAL, + name: Name = Name.special(""), + irParent: IrDeclarationParent? = null + ): IrClass { + val descriptor = WrappedClassDescriptor() + val origin = IrDeclarationOrigin.DEFINED + val modality = Modality.FINAL + val result = anonymousObject.convertWithOffsets { startOffset, endOffset -> + irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol -> + IrClassImpl( + startOffset, endOffset, origin, symbol, name, + // NB: for unknown reason, IR uses 'CLASS' kind for simple anonymous objects + anonymousObject.classKind.takeIf { it == ClassKind.ENUM_ENTRY } ?: ClassKind.CLASS, + visibility, modality, + isCompanion = false, isInner = false, isData = false, + isExternal = false, isInline = false, isExpect = false, isFun = false + ).apply { + descriptor.bind(this) + setThisReceiver() + if (irParent != null) { + this.parent = irParent + } + } + } + }.declareSupertypesAndTypeParameters(anonymousObject) + localStorage.putLocalClass(anonymousObject, result) + return result + } + + private fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass { + localStorage.getLocalClass(anonymousObject)?.let { return it } + return createIrAnonymousObject(anonymousObject, Visibilities.PRIVATE, name, irParent) + } + + private fun getIrTypeParameter( + typeParameter: FirTypeParameter, + index: Int = -1, + typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT + ): IrTypeParameter { + // Here transformation is a bit difficult because one FIR property type parameter + // can be transformed to two different type parameters: one for getter and another one for setter + val simpleCachedParameter = typeParameterCache[typeParameter] + if (simpleCachedParameter != null) { + if (typeContext.origin != ConversionTypeOrigin.SETTER) { + return simpleCachedParameter + } + if (index < 0) { + val parent = simpleCachedParameter.parent + if (parent !is IrSimpleFunction || parent.returnType == typeConverter.unitType) { + return simpleCachedParameter + } + } + } + if (typeContext.origin == ConversionTypeOrigin.SETTER) { + typeParameterCacheForSetter[typeParameter]?.let { return it } + } + return typeParameter.run { + // Yet I don't want to enable this requirement because it breaks some tests + // However, if we get here it *should* mean that type parameter index is given explicitly + // At this moment (20.02.2020) this requirement breaks 11/355 Fir2IrText tests + // require(index != -1) + val descriptor = WrappedTypeParameterDescriptor() + val origin = IrDeclarationOrigin.DEFINED + val irTypeParameter = + convertWithOffsets { startOffset, endOffset -> + irSymbolTable.declareGlobalTypeParameter(startOffset, endOffset, origin, descriptor) { symbol -> + IrTypeParameterImpl( + startOffset, endOffset, origin, symbol, + name, if (index < 0) 0 else index, + isReified, + variance + ).apply { + descriptor.bind(this) + } + } + } + + // Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds. + if (typeContext.origin == ConversionTypeOrigin.SETTER) { + typeParameterCacheForSetter[typeParameter] = irTypeParameter + } else { + typeParameterCache[typeParameter] = irTypeParameter + } + bounds.mapTo(irTypeParameter.superTypes) { it.toIrType() } + irTypeParameter + } + } + + fun putEnumEntryClassInScope(enumEntry: FirEnumEntry, correspondingClass: IrClass) { + localStorage.putLocalClass(enumEntry.initializer as FirAnonymousObject, correspondingClass) + } + + fun getCachedIrEnumEntry(enumEntry: FirEnumEntry): IrEnumEntry? = enumEntryCache[enumEntry] + + fun createIrEnumEntry( + enumEntry: FirEnumEntry, + irParent: IrClass?, + origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED + ): IrEnumEntry { + return enumEntry.convertWithOffsets { startOffset, endOffset -> + val desc = WrappedEnumEntryDescriptor() + declarationStorage.enterScope(desc) + val result = irSymbolTable.declareEnumEntry(startOffset, endOffset, origin, desc) { symbol -> + IrEnumEntryImpl( + startOffset, endOffset, origin, symbol, enumEntry.name + ).apply { + desc.bind(this) + val irType = enumEntry.returnTypeRef.toIrType() + if (irParent != null) { + this.parent = irParent + } + val initializer = enumEntry.initializer + if (initializer != null) { + initializer as FirAnonymousObject + val klass = getIrAnonymousObjectForEnumEntry(initializer, enumEntry.name, irParent) + + this.correspondingClass = klass + } else if (irParent != null) { + this.initializerExpression = IrExpressionBodyImpl( + IrEnumConstructorCallImpl(startOffset, endOffset, irType, irParent.constructors.first().symbol) + ) + } + } + } + declarationStorage.leaveScope(desc) + enumEntryCache[enumEntry] = result + result + } + } + + fun getIrClassSymbol(firClassSymbol: FirClassSymbol<*>): IrClassSymbol { + val firClass = firClassSymbol.fir + getCachedIrClass(firClass)?.let { return irSymbolTable.referenceClass(it.descriptor) } + // TODO: remove all this code and change to unbound symbol creation + val irClass = createIrClass(firClass) + if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.LOCAL) { + return irSymbolTable.referenceClass(irClass.descriptor) + } + val classId = firClassSymbol.classId + val parentId = classId.outerClassId + val irParent = declarationStorage.findIrParent(classId.packageFqName, parentId, firClassSymbol) + if (irParent != null) { + irClass.parent = irParent + } + if (irParent is IrExternalPackageFragment) { + declarationStorage.addDeclarationsToExternalClass(firClass as FirRegularClass, irClass) + } + + return irSymbolTable.referenceClass(irClass.descriptor) + } + + fun getIrTypeParameterSymbol( + firTypeParameterSymbol: FirTypeParameterSymbol, + typeContext: ConversionTypeContext + ): IrTypeParameterSymbol { + // TODO: use cached type parameter here + val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir, typeContext = typeContext) + return irSymbolTable.referenceTypeParameter(irTypeParameter.descriptor) + } +} \ No newline at end of file diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 4b963b94209..a7229b645bd 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager class Fir2IrConverter( private val moduleDescriptor: FirModuleDescriptor, private val sourceManager: PsiSourceManager, + private val classifierStorage: Fir2IrClassifierStorage, private val declarationStorage: Fir2IrDeclarationStorage ) { @@ -71,7 +72,7 @@ class Fir2IrConverter( fun processAnonymousObjectMembers( anonymousObject: FirAnonymousObject, - irClass: IrClass = declarationStorage.getCachedIrClass(anonymousObject)!! + irClass: IrClass = classifierStorage.getCachedIrClass(anonymousObject)!! ): IrClass { anonymousObject.getPrimaryConstructorIfAny()?.let { irClass.declarations += declarationStorage.createIrConstructor(it, irClass) @@ -89,7 +90,7 @@ class Fir2IrConverter( private fun processClassMembers( regularClass: FirRegularClass, - irClass: IrClass = declarationStorage.getCachedIrClass(regularClass)!! + irClass: IrClass = classifierStorage.getCachedIrClass(regularClass)!! ): IrClass { regularClass.getPrimaryConstructorIfAny()?.let { irClass.declarations += declarationStorage.createIrConstructor(it, irClass) @@ -102,7 +103,7 @@ class Fir2IrConverter( } private fun registerClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass { - val irClass = declarationStorage.registerIrClass(regularClass, parent) + val irClass = classifierStorage.registerIrClass(regularClass, parent) regularClass.declarations.forEach { if (it is FirRegularClass) { registerClassAndNestedClasses(it, irClass) @@ -112,7 +113,7 @@ class Fir2IrConverter( } private fun processClassAndNestedClassHeaders(regularClass: FirRegularClass) { - declarationStorage.processClassHeader(regularClass) + classifierStorage.processClassHeader(regularClass) regularClass.declarations.forEach { if (it is FirRegularClass) { processClassAndNestedClassHeaders(it) @@ -137,7 +138,7 @@ class Fir2IrConverter( null } is FirEnumEntry -> { - declarationStorage.createIrEnumEntry(declaration, parent as IrClass) + classifierStorage.createIrEnumEntry(declaration, parent as IrClass) } is FirAnonymousInitializer -> { declarationStorage.createIrAnonymousInitializer(declaration, parent as IrClass) @@ -169,12 +170,16 @@ class Fir2IrConverter( val builtIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable) val sourceManager = PsiSourceManager() val declarationStorage = Fir2IrDeclarationStorage(session, symbolTable, moduleDescriptor) - val typeConverter = Fir2IrTypeConverter(session, declarationStorage, builtIns) + val classifierStorage = Fir2IrClassifierStorage(session, symbolTable) + val typeConverter = Fir2IrTypeConverter(session, classifierStorage, builtIns) declarationStorage.typeConverter = typeConverter + classifierStorage.typeConverter = typeConverter + declarationStorage.classifierStorage = classifierStorage + classifierStorage.declarationStorage = declarationStorage typeConverter.initBuiltinTypes() val irFiles = mutableListOf() - val converter = Fir2IrConverter(moduleDescriptor, sourceManager, declarationStorage) + val converter = Fir2IrConverter(moduleDescriptor, sourceManager, classifierStorage, declarationStorage) for (firFile in firFiles) { converter.registerFileAndClasses(firFile) } @@ -186,7 +191,7 @@ class Fir2IrConverter( } val fir2irVisitor = Fir2IrVisitor( - session, symbolTable, declarationStorage, converter, typeConverter, builtIns, fakeOverrideMode + session, symbolTable, classifierStorage, declarationStorage, converter, typeConverter, builtIns, fakeOverrideMode ) for (firFile in firFiles) { val irFile = firFile.accept(fir2irVisitor, null) as IrFile diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 3ebc3d0bc13..f69633cee0a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -5,7 +5,9 @@ package org.jetbrains.kotlin.fir.backend -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter @@ -28,14 +30,11 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -56,12 +55,6 @@ class Fir2IrDeclarationStorage( private val fileCache = mutableMapOf() - private val classCache = mutableMapOf() - - private val typeParameterCache = mutableMapOf() - - private val typeParameterCacheForSetter = mutableMapOf() - private val functionCache = mutableMapOf, IrSimpleFunction>() private val constructorCache = mutableMapOf() @@ -72,12 +65,12 @@ class Fir2IrDeclarationStorage( private val fieldCache = mutableMapOf() - private val enumEntryCache = mutableMapOf() - private val localStorage = Fir2IrLocalStorage() lateinit var typeConverter: Fir2IrTypeConverter + lateinit var classifierStorage: Fir2IrClassifierStorage + fun registerFile(firFile: FirFile, irFile: IrFile) { fileCache[firFile] = irFile } @@ -121,68 +114,7 @@ class Fir2IrDeclarationStorage( } } - private fun IrDeclaration.declareThisReceiverParameter( - parent: IrDeclarationParent, - thisType: IrType, - thisOrigin: IrDeclarationOrigin, - startOffset: Int = this.startOffset, - endOffset: Int = this.endOffset - ): IrValueParameter { - val receiverDescriptor = WrappedReceiverParameterDescriptor() - return irSymbolTable.declareValueParameter( - startOffset, endOffset, thisOrigin, receiverDescriptor, thisType - ) { symbol -> - IrValueParameterImpl( - startOffset, endOffset, thisOrigin, symbol, - Name.special(""), -1, thisType, - varargElementType = null, isCrossinline = false, isNoinline = false - ).apply { - this.parent = parent - receiverDescriptor.bind(this) - } - } - } - - private fun IrClass.setThisReceiver() { - enterScope(descriptor) - val typeArguments = this.typeParameters.map { - IrSimpleTypeImpl(it.symbol, false, emptyList(), emptyList()) - } - thisReceiver = declareThisReceiverParameter( - parent = this, - thisType = IrSimpleTypeImpl(symbol, false, typeArguments, emptyList()), - thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER - ) - leaveScope(descriptor) - } - - private fun preCacheTypeParameters(owner: FirTypeParametersOwner) { - owner.typeParameters.mapIndexed { index, typeParameter -> - getIrTypeParameter(typeParameter, index) - if (owner is FirProperty && owner.isVar) { - getIrTypeParameter(typeParameter, index, ConversionTypeContext.DEFAULT.inSetter()) - } - } - } - - private fun IrTypeParametersContainer.setTypeParameters( - owner: FirTypeParametersOwner, - typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT - ) { - typeParameters = owner.typeParameters.mapIndexed { index, typeParameter -> - getIrTypeParameter(typeParameter, index, typeContext).apply { parent = this@setTypeParameters } - } - } - - private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass { - if (klass is FirRegularClass) { - setTypeParameters(klass) - } - superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() } - return this - } - - private fun addDeclarationsToExternalClass(regularClass: FirRegularClass, irClass: IrClass) { + internal fun addDeclarationsToExternalClass(regularClass: FirRegularClass, irClass: IrClass) { if (regularClass.symbol.classId.packageFqName.startsWith(Name.identifier("kotlin"))) { // Note: yet this is necessary only for *Range / *Progression classes // due to BE optimizations (for lowering) that use their first / last / step members @@ -202,7 +134,7 @@ class Fir2IrDeclarationStorage( createIrConstructor(declaration, irClass) } is FirRegularClass -> { - createIrClass(declaration, irClass) + classifierStorage.createIrClass(declaration, irClass) } else -> continue } @@ -235,190 +167,12 @@ class Fir2IrDeclarationStorage( } } - fun getCachedIrClass(klass: FirClass<*>): IrClass? { - return if (klass is FirAnonymousObject || klass is FirRegularClass && klass.visibility == Visibilities.LOCAL) { - localStorage.getLocalClass(klass) - } else { - classCache[klass] - } - } - - private fun FirRegularClass.enumClassModality(): Modality { - return when { - declarations.any { it is FirCallableMemberDeclaration<*> && it.modality == Modality.ABSTRACT } -> { - Modality.ABSTRACT - } - declarations.any { it is FirEnumEntry && it.initializer != null } -> { - Modality.OPEN - } - else -> { - Modality.FINAL - } - } - } - - private fun createIrClass(klass: FirClass<*>, parent: IrDeclarationParent? = null): IrClass { - // NB: klass can be either FirRegularClass or FirAnonymousObject - if (klass is FirAnonymousObject) { - return createIrAnonymousObject(klass, irParent = parent) - } - val regularClass = klass as FirRegularClass - val origin = - if (firProvider.getFirClassifierContainerFileIfAny(klass.symbol) != null) IrDeclarationOrigin.DEFINED - else IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB - val irClass = registerIrClass(regularClass, parent, origin) - processClassHeader(regularClass, irClass) - return irClass - } - - fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass { - irClass.declareSupertypesAndTypeParameters(regularClass) - irClass.setThisReceiver() - return irClass - } - - fun registerIrClass( - regularClass: FirRegularClass, - parent: IrDeclarationParent? = null, - origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED - ): IrClass { - val descriptor = WrappedClassDescriptor() - val visibility = regularClass.visibility - val modality = if (regularClass.classKind == ClassKind.ENUM_CLASS) { - regularClass.enumClassModality() - } else { - regularClass.modality ?: Modality.FINAL - } - val irClass = regularClass.convertWithOffsets { startOffset, endOffset -> - irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol -> - IrClassImpl( - startOffset, - endOffset, - origin, - symbol, - regularClass.name, - regularClass.classKind, - visibility, - modality, - isCompanion = regularClass.isCompanion, - isInner = regularClass.isInner, - isData = regularClass.isData, - isExternal = regularClass.isExternal, - isInline = regularClass.isInline, - isExpect = regularClass.isExpect, - isFun = false // TODO FirRegularClass.isFun - ).apply { - descriptor.bind(this) - } - } - } - if (parent != null) { - irClass.parent = parent - } - if (regularClass.visibility == Visibilities.LOCAL) { - localStorage.putLocalClass(regularClass, irClass) - } else { - classCache[regularClass] = irClass - } - return irClass - } - - fun createIrAnonymousObject( - anonymousObject: FirAnonymousObject, - visibility: Visibility = Visibilities.LOCAL, - name: Name = Name.special(""), - irParent: IrDeclarationParent? = null - ): IrClass { - val descriptor = WrappedClassDescriptor() - val origin = IrDeclarationOrigin.DEFINED - val modality = Modality.FINAL - val result = anonymousObject.convertWithOffsets { startOffset, endOffset -> - irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol -> - IrClassImpl( - startOffset, endOffset, origin, symbol, name, - // NB: for unknown reason, IR uses 'CLASS' kind for simple anonymous objects - anonymousObject.classKind.takeIf { it == ClassKind.ENUM_ENTRY } ?: ClassKind.CLASS, - visibility, modality, - isCompanion = false, isInner = false, isData = false, - isExternal = false, isInline = false, isExpect = false, isFun = false - ).apply { - descriptor.bind(this) - setThisReceiver() - if (irParent != null) { - this.parent = irParent - } - } - } - }.declareSupertypesAndTypeParameters(anonymousObject) - localStorage.putLocalClass(anonymousObject, result) - return result - } - - private fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass { - localStorage.getLocalClass(anonymousObject)?.let { return it } - return createIrAnonymousObject(anonymousObject, Visibilities.PRIVATE, name, irParent) - } - - private fun getIrTypeParameter( - typeParameter: FirTypeParameter, - index: Int = -1, - typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT - ): IrTypeParameter { - // Here transformation is a bit difficult because one FIR property type parameter - // can be transformed to two different type parameters: one for getter and another one for setter - val simpleCachedParameter = typeParameterCache[typeParameter] - if (simpleCachedParameter != null) { - if (typeContext.origin != ConversionTypeOrigin.SETTER) { - return simpleCachedParameter - } - if (index < 0) { - val parent = simpleCachedParameter.parent - if (parent !is IrSimpleFunction || parent.returnType == typeConverter.unitType) { - return simpleCachedParameter - } - } - } - if (typeContext.origin == ConversionTypeOrigin.SETTER) { - typeParameterCacheForSetter[typeParameter]?.let { return it } - } - return typeParameter.run { - // Yet I don't want to enable this requirement because it breaks some tests - // However, if we get here it *should* mean that type parameter index is given explicitly - // At this moment (20.02.2020) this requirement breaks 11/355 Fir2IrText tests - // require(index != -1) - val descriptor = WrappedTypeParameterDescriptor() - val origin = IrDeclarationOrigin.DEFINED - val irTypeParameter = - convertWithOffsets { startOffset, endOffset -> - irSymbolTable.declareGlobalTypeParameter(startOffset, endOffset, origin, descriptor) { symbol -> - IrTypeParameterImpl( - startOffset, endOffset, origin, symbol, - name, if (index < 0) 0 else index, - isReified, - variance - ).apply { - descriptor.bind(this) - } - } - } - - // Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds. - if (typeContext.origin == ConversionTypeOrigin.SETTER) { - typeParameterCacheForSetter[typeParameter] = irTypeParameter - } else { - typeParameterCache[typeParameter] = irTypeParameter - } - bounds.mapTo(irTypeParameter.superTypes) { it.toIrType() } - irTypeParameter - } - } - - private fun findIrParent(packageFqName: FqName, parentClassId: ClassId?, firBasedSymbol: FirBasedSymbol<*>): IrDeclarationParent? { + internal fun findIrParent(packageFqName: FqName, parentClassId: ClassId?, firBasedSymbol: FirBasedSymbol<*>): IrDeclarationParent? { return if (parentClassId != null) { // TODO: this will never work for local classes val parentFirSymbol = firSymbolProvider.getClassLikeSymbolByFqName(parentClassId) if (parentFirSymbol is FirClassSymbol) { - val parentIrSymbol = getIrClassSymbol(parentFirSymbol) + val parentIrSymbol = classifierStorage.getIrClassSymbol(parentFirSymbol) parentIrSymbol.owner } else { null @@ -485,7 +239,9 @@ class Fir2IrDeclarationStorage( ) { val parent = this if (function is FirSimpleFunction) { - setTypeParameters(function) + with(classifierStorage) { + setTypeParameters(function) + } } val forSetter = function is FirPropertyAccessor && function.isSetter val typeContext = ConversionTypeContext( @@ -509,24 +265,26 @@ class Fir2IrDeclarationStorage( if (function !is FirConstructor) { val thisOrigin = IrDeclarationOrigin.DEFINED val receiverTypeRef = if (function !is FirPropertyAccessor) function?.receiverTypeRef else parentPropertyReceiverType - if (receiverTypeRef != null) { - extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset -> - declareThisReceiverParameter( + with(classifierStorage) { + if (receiverTypeRef != null) { + extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset -> + declareThisReceiverParameter( + parent, + thisType = receiverTypeRef.toIrType(typeContext), + thisOrigin = thisOrigin, + startOffset = startOffset, + endOffset = endOffset + ) + } + } + if (function !is FirAnonymousFunction && containingClass != null && !isStatic) { + dispatchReceiverParameter = declareThisReceiverParameter( parent, - thisType = receiverTypeRef.toIrType(typeContext), - thisOrigin = thisOrigin, - startOffset = startOffset, - endOffset = endOffset + thisType = containingClass.thisReceiver!!.type, + thisOrigin = thisOrigin ) } } - if (function !is FirAnonymousFunction && containingClass != null && !isStatic) { - dispatchReceiverParameter = declareThisReceiverParameter( - parent, - thisType = containingClass.thisReceiver!!.type, - thisOrigin = thisOrigin - ) - } } } @@ -552,10 +310,6 @@ class Fir2IrDeclarationStorage( return this } - fun putEnumEntryClassInScope(enumEntry: FirEnumEntry, correspondingClass: IrClass) { - localStorage.putLocalClass(enumEntry.initializer as FirAnonymousObject, correspondingClass) - } - fun getCachedIrFunction(function: FirFunction<*>): IrSimpleFunction? { return if (function !is FirSimpleFunction || function.visibility == Visibilities.LOCAL) { localStorage.getLocalFunction(function) @@ -578,7 +332,7 @@ class Fir2IrDeclarationStorage( function.symbol.callableId.isKFunctionInvoke() -> IrDeclarationOrigin.FAKE_OVERRIDE else -> origin } - preCacheTypeParameters(function) + classifierStorage.preCacheTypeParameters(function) val name = simpleFunction?.name ?: if (isLambda) Name.special("") else Name.special("") val visibility = simpleFunction?.visibility ?: Visibilities.LOCAL @@ -694,12 +448,14 @@ class Fir2IrDeclarationStorage( isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE, isOperator = false ).apply { - setTypeParameters( - property, ConversionTypeContext( - definitelyNotNull = false, - origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT + with(classifierStorage) { + setTypeParameters( + property, ConversionTypeContext( + definitelyNotNull = false, + origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT + ) ) - ) + } if (propertyAccessor == null && isSetter) { declareDefaultSetterParameter( property.returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter()) @@ -719,44 +475,6 @@ class Fir2IrDeclarationStorage( } } - fun getCachedIrEnumEntry(enumEntry: FirEnumEntry): IrEnumEntry? = enumEntryCache[enumEntry] - - fun createIrEnumEntry( - enumEntry: FirEnumEntry, - irParent: IrClass?, - origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED - ): IrEnumEntry { - return enumEntry.convertWithOffsets { startOffset, endOffset -> - val desc = WrappedEnumEntryDescriptor() - enterScope(desc) - val result = irSymbolTable.declareEnumEntry(startOffset, endOffset, origin, desc) { symbol -> - IrEnumEntryImpl( - startOffset, endOffset, origin, symbol, enumEntry.name - ).apply { - desc.bind(this) - val irType = enumEntry.returnTypeRef.toIrType() - if (irParent != null) { - this.parent = irParent - } - val initializer = enumEntry.initializer - if (initializer != null) { - initializer as FirAnonymousObject - val klass = getIrAnonymousObjectForEnumEntry(initializer, enumEntry.name, irParent) - - this.correspondingClass = klass - } else if (irParent != null) { - this.initializerExpression = IrExpressionBodyImpl( - IrEnumConstructorCallImpl(startOffset, endOffset, irType, irParent.constructors.first().symbol) - ) - } - } - } - leaveScope(desc) - enumEntryCache[enumEntry] = result - result - } - } - fun createIrProperty( property: FirProperty, irParent: IrDeclarationParent?, @@ -764,7 +482,7 @@ class Fir2IrDeclarationStorage( ): IrProperty { val containerSource = property.containerSource val descriptor = containerSource?.let { WrappedPropertyDescriptorWithContainerSource(it) } ?: WrappedPropertyDescriptor() - preCacheTypeParameters(property) + classifierStorage.preCacheTypeParameters(property) return property.convertWithOffsets { startOffset, endOffset -> enterScope(descriptor) val result = irSymbolTable.declareProperty( @@ -936,36 +654,6 @@ class Fir2IrDeclarationStorage( } } - fun getIrClassSymbol(firClassSymbol: FirClassSymbol<*>): IrClassSymbol { - val firClass = firClassSymbol.fir - getCachedIrClass(firClass)?.let { return irSymbolTable.referenceClass(it.descriptor) } - // TODO: remove all this code and change to unbound symbol creation - val irClass = createIrClass(firClass) - if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.LOCAL) { - return irSymbolTable.referenceClass(irClass.descriptor) - } - val classId = firClassSymbol.classId - val parentId = classId.outerClassId - val irParent = findIrParent(classId.packageFqName, parentId, firClassSymbol) - if (irParent != null) { - irClass.parent = irParent - } - if (irParent is IrExternalPackageFragment) { - addDeclarationsToExternalClass(firClass as FirRegularClass, irClass) - } - - return irSymbolTable.referenceClass(irClass.descriptor) - } - - fun getIrTypeParameterSymbol( - firTypeParameterSymbol: FirTypeParameterSymbol, - typeContext: ConversionTypeContext - ): IrTypeParameterSymbol { - // TODO: use cached type parameter here - val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir, typeContext = typeContext) - return irSymbolTable.referenceTypeParameter(irTypeParameter.descriptor) - } - fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol { val firConstructor = firConstructorSymbol.fir getCachedIrConstructor(firConstructor)?.let { return irSymbolTable.referenceConstructor(it.descriptor) } @@ -1043,11 +731,11 @@ class Fir2IrDeclarationStorage( fun getIrValueSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol { return when (val firDeclaration = firVariableSymbol.fir) { is FirEnumEntry -> { - getCachedIrEnumEntry(firDeclaration)?.let { return irSymbolTable.referenceEnumEntry(it.descriptor) } + classifierStorage.getCachedIrEnumEntry(firDeclaration)?.let { return irSymbolTable.referenceEnumEntry(it.descriptor) } val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol) val parentClassSymbol = firVariableSymbol.callableId.classId?.let { firSymbolProvider.getClassLikeSymbolByFqName(it) } - val irParentClass = (parentClassSymbol?.fir as? FirClass<*>)?.let { getCachedIrClass(it) } - val irEnumEntry = createIrEnumEntry( + val irParentClass = (parentClassSymbol?.fir as? FirClass<*>)?.let { classifierStorage.getCachedIrClass(it) } + val irEnumEntry = classifierStorage.createIrEnumEntry( firDeclaration, irParent = irParentClass, origin = if (containingFile == null) IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB else IrDeclarationOrigin.DEFINED diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt index f83fff962e5..f87f722ab61 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.types.Variance class Fir2IrTypeConverter( private val session: FirSession, - private val declarationStorage: Fir2IrDeclarationStorage, + private val classifierStorage: Fir2IrClassifierStorage, private val irBuiltIns: IrBuiltIns ) { lateinit var nothingType: IrType @@ -49,7 +49,7 @@ class Fir2IrTypeConverter( is ConeLookupTagBasedType -> { val irSymbol = getArrayType(this.classId) ?: run { val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType() - firSymbol.toIrSymbol(session, declarationStorage, typeContext) + firSymbol.toSymbol(session, classifierStorage, typeContext) } // TODO: annotations IrSimpleTypeImpl( diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 3370e49ea6c..eca34f81129 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -47,6 +47,7 @@ import java.util.* class Fir2IrVisitor( private val session: FirSession, private val symbolTable: SymbolTable, + private val classifierStorage: Fir2IrClassifierStorage, private val declarationStorage: Fir2IrDeclarationStorage, private val converter: Fir2IrConverter, private val typeConverter: Fir2IrTypeConverter, @@ -95,10 +96,10 @@ class Fir2IrVisitor( // ================================================================================== override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement { - val irEnumEntry = declarationStorage.getCachedIrEnumEntry(enumEntry)!! + val irEnumEntry = classifierStorage.getCachedIrEnumEntry(enumEntry)!! val correspondingClass = irEnumEntry.correspondingClass ?: return irEnumEntry declarationStorage.enterScope(irEnumEntry.descriptor) - declarationStorage.putEnumEntryClassInScope(enumEntry, correspondingClass) + classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass) converter.processAnonymousObjectMembers(enumEntry.initializer as FirAnonymousObject, correspondingClass) conversionScope.withParent(correspondingClass) { setClassContent(enumEntry.initializer as FirAnonymousObject) @@ -150,7 +151,7 @@ class Fir2IrVisitor( override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement { if (regularClass.visibility == Visibilities.LOCAL) { val irParent = conversionScope.parentFromStack() - val irClass = declarationStorage.getCachedIrClass(regularClass)?.apply { this.parent = irParent } + val irClass = classifierStorage.getCachedIrClass(regularClass)?.apply { this.parent = irParent } if (irClass != null) { converter.processRegisteredLocalClassAndNestedClasses(regularClass, irClass) return conversionScope.withParent(irClass) { @@ -159,7 +160,7 @@ class Fir2IrVisitor( } converter.processLocalClassAndNestedClasses(regularClass, irParent) } - val irClass = declarationStorage.getCachedIrClass(regularClass)!! + val irClass = classifierStorage.getCachedIrClass(regularClass)!! return conversionScope.withParent(irClass) { setClassContent(regularClass) } @@ -168,8 +169,8 @@ class Fir2IrVisitor( override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): IrElement { val irParent = conversionScope.parentFromStack() // NB: for implicit types it is possible that anonymous object is already cached - val irAnonymousObject = declarationStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent } - ?: declarationStorage.createIrAnonymousObject(anonymousObject, irParent = irParent) + val irAnonymousObject = classifierStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent } + ?: classifierStorage.createIrAnonymousObject(anonymousObject, irParent = irParent) converter.processAnonymousObjectMembers(anonymousObject, irAnonymousObject) conversionScope.withParent(irAnonymousObject) { setClassContent(anonymousObject) @@ -499,7 +500,7 @@ class Fir2IrVisitor( private fun FirQualifiedAccess.toIrExpression(typeRef: FirTypeRef): IrExpression { val type = typeRef.toIrType() - val symbol = calleeReference.toSymbol(declarationStorage) + val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage) return typeRef.convertWithOffsets { startOffset, endOffset -> if (calleeReference is FirSuperReference) { if (typeRef !is FirComposedSuperTypeRef) { @@ -647,7 +648,7 @@ class Fir2IrVisitor( it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT } firClass?.convertWithOffsets { startOffset, endOffset -> - val irClass = declarationStorage.getCachedIrClass(firClass)!! + val irClass = classifierStorage.getCachedIrClass(firClass)!! IrGetObjectValueImpl(startOffset, endOffset, irClass.defaultType, irClass.symbol) } } @@ -715,7 +716,7 @@ class Fir2IrVisitor( it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT } if (firObject != null) { - val irObject = declarationStorage.getCachedIrClass(firObject)!! + val irObject = classifierStorage.getCachedIrClass(firObject)!! if (irObject != conversionScope.lastClass()) { return thisReceiverExpression.convertWithOffsets { startOffset, endOffset -> IrGetObjectValueImpl(startOffset, endOffset, irObject.defaultType, irObject.symbol) @@ -750,7 +751,7 @@ class Fir2IrVisitor( } override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement { - val symbol = callableReferenceAccess.calleeReference.toSymbol(declarationStorage) + val symbol = callableReferenceAccess.calleeReference.toSymbol(session, classifierStorage, declarationStorage) val type = callableReferenceAccess.typeRef.toIrType() return callableReferenceAccess.convertWithOffsets { startOffset, endOffset -> when (symbol) { @@ -792,7 +793,7 @@ class Fir2IrVisitor( override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Any?): IrElement { val calleeReference = variableAssignment.calleeReference - val symbol = calleeReference.toSymbol(declarationStorage) + val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage) return variableAssignment.convertWithOffsets { startOffset, endOffset -> if (symbol != null && symbol.isBound) { when (symbol) { @@ -1235,7 +1236,7 @@ class Fir2IrVisitor( val irClassType = argument.typeRef.toIrType() val irClassReferenceSymbol = when (argument) { is FirResolvedReifiedParameterReference -> { - declarationStorage.getIrTypeParameterSymbol(argument.symbol, ConversionTypeContext.DEFAULT) + classifierStorage.getIrTypeParameterSymbol(argument.symbol, ConversionTypeContext.DEFAULT) } is FirResolvedQualifier -> { val symbol = argument.symbol as? FirClassSymbol @@ -1244,7 +1245,7 @@ class Fir2IrVisitor( startOffset, endOffset, irType, "Resolved qualifier ${argument.render()} does not have correct symbol" ) } - declarationStorage.getIrClassSymbol(symbol) + classifierStorage.getIrClassSymbol(symbol) } else -> null } @@ -1274,7 +1275,7 @@ class Fir2IrVisitor( if (classSymbol != null) { IrGetObjectValueImpl( startOffset, endOffset, irType, - classSymbol.toIrSymbol(session, declarationStorage) as IrClassSymbol + classSymbol.toSymbol(session, classifierStorage) as IrClassSymbol ) } else { IrErrorCallExpressionImpl(