From 8677d63003324a56685e008bbfa78c67214e0092 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 4 Jun 2020 13:35:46 +0300 Subject: [PATCH] [FIR2IR] Re-use FakeOverrideGenerator for external classes --- .../fir/backend/Fir2IrClassifierStorage.kt | 13 +++- .../kotlin/fir/backend/Fir2IrConverter.kt | 5 +- .../fir/backend/Fir2IrDeclarationStorage.kt | 69 ++++--------------- .../kotlin/fir/backend/Fir2IrVisitor.kt | 3 +- .../generators/ClassMemberGenerator.kt | 2 +- .../generators/FakeOverrideGenerator.kt | 45 ++++++------ 6 files changed, 55 insertions(+), 82 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 a0a9ca83e11..5d47ccc928d 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 @@ -109,12 +109,20 @@ class Fir2IrClassifierStorage( } } - private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass { + private fun IrClass.declareTypeParameters(klass: FirClass<*>) { if (klass is FirRegularClass) { preCacheTypeParameters(klass) setTypeParameters(klass) } + } + + private fun IrClass.declareSupertypes(klass: FirClass<*>) { superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() } + } + + private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass { + declareTypeParameters(klass) + declareSupertypes(klass) return this } @@ -153,8 +161,9 @@ class Fir2IrClassifierStorage( } fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass { - irClass.declareSupertypesAndTypeParameters(regularClass) + irClass.declareTypeParameters(regularClass) irClass.setThisReceiver(regularClass.typeParameters) + irClass.declareSupertypes(regularClass) return irClass } 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 dc1890964a1..8f5a4d8479c 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 @@ -179,8 +179,9 @@ class Fir2IrConverter( BuiltinSymbolsBase(builtIns, moduleDescriptor.builtIns, symbolTable) val sourceManager = PsiSourceManager() val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, builtIns, mangler) - val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor) + val conversionScope = Fir2IrConversionScope() val classifierStorage = Fir2IrClassifierStorage(components) + val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor, classifierStorage, conversionScope, fakeOverrideMode) val typeConverter = Fir2IrTypeConverter(components) components.declarationStorage = declarationStorage components.classifierStorage = classifierStorage @@ -209,7 +210,7 @@ class Fir2IrConverter( converter.processFileAndClassMembers(firFile) } - val fir2irVisitor = Fir2IrVisitor(converter, components, fakeOverrideMode) + val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope, fakeOverrideMode) for (firFile in firFiles) { val irFile = firFile.accept(fir2irVisitor, null) as IrFile val fileEntry = sourceManager.getOrCreateFileEntry(firFile.psi as KtFile) 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 cbffb72f0fd..aaf6871887d 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 @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.builtins.KotlinBuiltIns.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.fir.backend.generators.setOverriddenSymbolsForAccessors +import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter @@ -48,8 +48,15 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ class Fir2IrDeclarationStorage( private val components: Fir2IrComponents, - private val moduleDescriptor: FirModuleDescriptor + private val moduleDescriptor: FirModuleDescriptor, + classifierStorage: Fir2IrClassifierStorage, + conversionScope: Fir2IrConversionScope, + fakeOverrideMode: FakeOverrideMode ) : Fir2IrComponents by components { + private val fakeOverrideGenerator = FakeOverrideGenerator( + session, components.scopeSession, classifierStorage, this, conversionScope, fakeOverrideMode + ) + private val firSymbolProvider = session.firSymbolProvider private val firProvider = session.firProvider @@ -203,6 +210,7 @@ class Fir2IrDeclarationStorage( scope.processDeclaredConstructors { irClass.declarations += createIrConstructor(it.fir, irClass) } + classifierStorage.processClassHeader(regularClass, irClass) for (declaration in regularClass.declarations) { when (declaration) { is FirSimpleFunction -> { @@ -247,58 +255,8 @@ class Fir2IrDeclarationStorage( else -> continue } } - // TODO: better to refactor somehow so as to entirely reuse FakeOverrideGenerator's logic. - val allNames = regularClass.collectCallableNamesFromSupertypes(session) - for (name in allNames) { - if (name in processedNames) continue - processedNames += name - scope.processFunctionsByName(name) { functionSymbol -> - if (functionSymbol is FirNamedFunctionSymbol) { - val originalFunction = functionSymbol.fir - if (functionSymbol.isFakeOverride) { - // Substitution case - val baseSymbol = functionSymbol.deepestOverriddenSymbol() as FirNamedFunctionSymbol - val irFunction = createIrFunction( - originalFunction, irParent = irClass, - thisReceiverOwner = findIrParent(baseSymbol.fir) as? IrClass, - origin = IrDeclarationOrigin.FAKE_OVERRIDE - ) - val overriddenSymbol = getIrFunctionSymbol(baseSymbol) as IrSimpleFunctionSymbol - irClass.declarations += irFunction.apply { - overriddenSymbols = listOf(overriddenSymbol) - } - } else { - val fakeOverrideSymbol = FirClassSubstitutionScope.createFakeOverrideFunction( - session, originalFunction, functionSymbol, derivedClassId = regularClass.symbol.classId - ) - classifierStorage.preCacheTypeParameters(functionSymbol.fir) - irClass.declarations += createIrFunction(fakeOverrideSymbol.fir, irClass) - } - } - } - scope.processPropertiesByName(name) { propertySymbol -> - if (propertySymbol is FirPropertySymbol) { - val originalProperty = propertySymbol.fir - if (propertySymbol.isFakeOverride) { - // Substitution case - val baseSymbol = propertySymbol.deepestOverriddenSymbol() as FirPropertySymbol - val irProperty = createIrProperty( - originalProperty, irParent = irClass, - thisReceiverOwner = findIrParent(baseSymbol.fir) as? IrClass, - origin = IrDeclarationOrigin.FAKE_OVERRIDE - ) - irClass.declarations += irProperty.apply { - setOverriddenSymbolsForAccessors(declarationStorage, originalProperty, baseSymbol) - } - } else { - val fakeOverrideSymbol = FirClassSubstitutionScope.createFakeOverrideProperty( - session, originalProperty, propertySymbol, derivedClassId = regularClass.symbol.classId - ) - classifierStorage.preCacheTypeParameters(propertySymbol.fir) - irClass.declarations += createIrProperty(fakeOverrideSymbol.fir, irClass) - } - } - } + with(fakeOverrideGenerator) { + irClass.addFakeOverrides(regularClass, processedNames) } for (irDeclaration in irClass.declarations) { irDeclaration.parent = irClass @@ -421,7 +379,8 @@ class Fir2IrDeclarationStorage( if (function !is FirAnonymousFunction && containingClass != null && !isStatic) { dispatchReceiverParameter = declareThisReceiverParameter( symbolTable, - thisType = containingClass.thisReceiver!!.type, + thisType = containingClass.thisReceiver?.type + ?: throw AssertionError(), thisOrigin = thisOrigin ) } 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 8db5a79ad7d..7232c18097a 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 @@ -51,6 +51,7 @@ import org.jetbrains.kotlin.psi.KtForExpression class Fir2IrVisitor( private val converter: Fir2IrConverter, private val components: Fir2IrComponents, + private val conversionScope: Fir2IrConversionScope, fakeOverrideMode: FakeOverrideMode ) : Fir2IrComponents by components, FirDefaultVisitor(), IrGeneratorContextInterface { @@ -60,8 +61,6 @@ class Fir2IrVisitor( session ) - private val conversionScope = Fir2IrConversionScope() - private val callGenerator = CallAndReferenceGenerator(components, this, conversionScope) private val memberGenerator = ClassMemberGenerator(components, this, conversionScope, callGenerator, fakeOverrideMode) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt index a35874f6dda..aec81407578 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt @@ -57,7 +57,7 @@ internal class ClassMemberGenerator( convertFunctionContent(irPrimaryConstructor, primaryConstructor) } } - val processedCallableNames = klass.declarations.mapNotNullTo(mutableListOf()) { + val processedCallableNames = klass.declarations.mapNotNullTo(mutableSetOf()) { when (it) { is FirSimpleFunction -> it.name is FirProperty -> it.name diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index 39db26ee248..73f8a68cc0d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -34,11 +34,11 @@ internal class FakeOverrideGenerator( ) { private fun IrSimpleFunction.withFunction(f: IrSimpleFunction.() -> Unit): IrSimpleFunction { - return conversionScope.withFunction(conversionScope.applyParentFromStackTo(this), f) + return conversionScope.withFunction(this, f) } private fun IrProperty.withProperty(f: IrProperty.() -> Unit): IrProperty { - return conversionScope.withProperty(conversionScope.applyParentFromStackTo(this), f) + return conversionScope.withProperty(this, f) } private fun FirCallableMemberDeclaration<*>.allowsToHaveFakeOverrideIn(klass: FirClass<*>): Boolean { @@ -55,7 +55,7 @@ internal class FakeOverrideGenerator( } } - fun IrClass.addFakeOverrides(klass: FirClass<*>, processedCallableNames: MutableList) { + fun IrClass.addFakeOverrides(klass: FirClass<*>, processedCallableNames: MutableSet) { if (fakeOverrideMode == FakeOverrideMode.NONE) return val superTypesCallableNames = klass.collectCallableNamesFromSupertypes(session) val useSiteMemberScope = klass.buildUseSiteMemberScope(session, scopeSession) ?: return @@ -81,6 +81,7 @@ internal class FakeOverrideGenerator( // parent of *original* function (base class) is used for dispatch receiver, // but fake override itself uses parent from its containing (derived) class val overriddenSymbol = declarationStorage.getIrFunctionSymbol(baseSymbol) as IrSimpleFunctionSymbol + irFunction.parent = this declarations += irFunction.withFunction { overriddenSymbols = listOf(overriddenSymbol) } @@ -101,6 +102,7 @@ internal class FakeOverrideGenerator( return@processFunctionsByName } val overriddenSymbol = declarationStorage.getIrFunctionSymbol(functionSymbol) as IrSimpleFunctionSymbol + irFunction.parent = this declarations += irFunction.withFunction { overriddenSymbols = listOf(overriddenSymbol) } @@ -119,6 +121,7 @@ internal class FakeOverrideGenerator( thisReceiverOwner = declarationStorage.findIrParent(baseSymbol.fir) as? IrClass, origin = origin ) + irProperty.parent = this declarations += irProperty.withProperty { setOverriddenSymbolsForAccessors(declarationStorage, originalProperty, firOverriddenSymbol = baseSymbol) } @@ -148,6 +151,7 @@ internal class FakeOverrideGenerator( ) { return@processPropertiesByName } + irProperty.parent = this declarations += irProperty.withProperty { setOverriddenSymbolsForAccessors(declarationStorage, fakeOverrideProperty, firOverriddenSymbol = propertySymbol) } @@ -156,22 +160,23 @@ internal class FakeOverrideGenerator( } } } + + private fun IrProperty.setOverriddenSymbolsForAccessors( + declarationStorage: Fir2IrDeclarationStorage, + property: FirProperty, + firOverriddenSymbol: FirPropertySymbol + ): IrProperty { + val irSymbol = declarationStorage.getIrPropertyOrFieldSymbol(firOverriddenSymbol) as? IrPropertySymbol ?: return this + val overriddenProperty = irSymbol.owner + getter?.apply { + overriddenProperty.getter?.symbol?.let { overriddenSymbols = listOf(it) } + } + if (property.isVar) { + setter?.apply { + overriddenProperty.setter?.symbol?.let { overriddenSymbols = listOf(it) } + } + } + return this + } } -internal fun IrProperty.setOverriddenSymbolsForAccessors( - declarationStorage: Fir2IrDeclarationStorage, - property: FirProperty, - firOverriddenSymbol: FirPropertySymbol -): IrProperty { - val irSymbol = declarationStorage.getIrPropertyOrFieldSymbol(firOverriddenSymbol) as? IrPropertySymbol ?: return this - val overriddenProperty = irSymbol.owner - getter?.apply { - overriddenProperty.getter?.symbol?.let { overriddenSymbols = listOf(it) } - } - if (property.isVar) { - setter?.apply { - overriddenProperty.setter?.symbol?.let { overriddenSymbols = listOf(it) } - } - } - return this -}