[FIR2IR] Re-use FakeOverrideGenerator for external classes

This commit is contained in:
Mikhail Glukhikh
2020-06-04 13:35:46 +03:00
parent ba1172b3ad
commit 8677d63003
6 changed files with 55 additions and 82 deletions
@@ -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
}
@@ -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)
@@ -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
)
}
@@ -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<IrElement, Any?>(), 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)
@@ -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
@@ -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<Name>) {
fun IrClass.addFakeOverrides(klass: FirClass<*>, processedCallableNames: MutableSet<Name>) {
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
}