[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) { if (klass is FirRegularClass) {
preCacheTypeParameters(klass) preCacheTypeParameters(klass)
setTypeParameters(klass) setTypeParameters(klass)
} }
}
private fun IrClass.declareSupertypes(klass: FirClass<*>) {
superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() } superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() }
}
private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass {
declareTypeParameters(klass)
declareSupertypes(klass)
return this return this
} }
@@ -153,8 +161,9 @@ class Fir2IrClassifierStorage(
} }
fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass { fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass {
irClass.declareSupertypesAndTypeParameters(regularClass) irClass.declareTypeParameters(regularClass)
irClass.setThisReceiver(regularClass.typeParameters) irClass.setThisReceiver(regularClass.typeParameters)
irClass.declareSupertypes(regularClass)
return irClass return irClass
} }
@@ -179,8 +179,9 @@ class Fir2IrConverter(
BuiltinSymbolsBase(builtIns, moduleDescriptor.builtIns, symbolTable) BuiltinSymbolsBase(builtIns, moduleDescriptor.builtIns, symbolTable)
val sourceManager = PsiSourceManager() val sourceManager = PsiSourceManager()
val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, builtIns, mangler) val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, builtIns, mangler)
val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor) val conversionScope = Fir2IrConversionScope()
val classifierStorage = Fir2IrClassifierStorage(components) val classifierStorage = Fir2IrClassifierStorage(components)
val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor, classifierStorage, conversionScope, fakeOverrideMode)
val typeConverter = Fir2IrTypeConverter(components) val typeConverter = Fir2IrTypeConverter(components)
components.declarationStorage = declarationStorage components.declarationStorage = declarationStorage
components.classifierStorage = classifierStorage components.classifierStorage = classifierStorage
@@ -209,7 +210,7 @@ class Fir2IrConverter(
converter.processFileAndClassMembers(firFile) converter.processFileAndClassMembers(firFile)
} }
val fir2irVisitor = Fir2IrVisitor(converter, components, fakeOverrideMode) val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope, fakeOverrideMode)
for (firFile in firFiles) { for (firFile in firFiles) {
val irFile = firFile.accept(fir2irVisitor, null) as IrFile val irFile = firFile.accept(fir2irVisitor, null) as IrFile
val fileEntry = sourceManager.getOrCreateFileEntry(firFile.psi as KtFile) 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.builtins.KotlinBuiltIns.*
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations 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.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
@@ -48,8 +48,15 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
class Fir2IrDeclarationStorage( class Fir2IrDeclarationStorage(
private val components: Fir2IrComponents, private val components: Fir2IrComponents,
private val moduleDescriptor: FirModuleDescriptor private val moduleDescriptor: FirModuleDescriptor,
classifierStorage: Fir2IrClassifierStorage,
conversionScope: Fir2IrConversionScope,
fakeOverrideMode: FakeOverrideMode
) : Fir2IrComponents by components { ) : Fir2IrComponents by components {
private val fakeOverrideGenerator = FakeOverrideGenerator(
session, components.scopeSession, classifierStorage, this, conversionScope, fakeOverrideMode
)
private val firSymbolProvider = session.firSymbolProvider private val firSymbolProvider = session.firSymbolProvider
private val firProvider = session.firProvider private val firProvider = session.firProvider
@@ -203,6 +210,7 @@ class Fir2IrDeclarationStorage(
scope.processDeclaredConstructors { scope.processDeclaredConstructors {
irClass.declarations += createIrConstructor(it.fir, irClass) irClass.declarations += createIrConstructor(it.fir, irClass)
} }
classifierStorage.processClassHeader(regularClass, irClass)
for (declaration in regularClass.declarations) { for (declaration in regularClass.declarations) {
when (declaration) { when (declaration) {
is FirSimpleFunction -> { is FirSimpleFunction -> {
@@ -247,58 +255,8 @@ class Fir2IrDeclarationStorage(
else -> continue else -> continue
} }
} }
// TODO: better to refactor somehow so as to entirely reuse FakeOverrideGenerator's logic. with(fakeOverrideGenerator) {
val allNames = regularClass.collectCallableNamesFromSupertypes(session) irClass.addFakeOverrides(regularClass, processedNames)
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)
}
}
}
} }
for (irDeclaration in irClass.declarations) { for (irDeclaration in irClass.declarations) {
irDeclaration.parent = irClass irDeclaration.parent = irClass
@@ -421,7 +379,8 @@ class Fir2IrDeclarationStorage(
if (function !is FirAnonymousFunction && containingClass != null && !isStatic) { if (function !is FirAnonymousFunction && containingClass != null && !isStatic) {
dispatchReceiverParameter = declareThisReceiverParameter( dispatchReceiverParameter = declareThisReceiverParameter(
symbolTable, symbolTable,
thisType = containingClass.thisReceiver!!.type, thisType = containingClass.thisReceiver?.type
?: throw AssertionError(),
thisOrigin = thisOrigin thisOrigin = thisOrigin
) )
} }
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.psi.KtForExpression
class Fir2IrVisitor( class Fir2IrVisitor(
private val converter: Fir2IrConverter, private val converter: Fir2IrConverter,
private val components: Fir2IrComponents, private val components: Fir2IrComponents,
private val conversionScope: Fir2IrConversionScope,
fakeOverrideMode: FakeOverrideMode fakeOverrideMode: FakeOverrideMode
) : Fir2IrComponents by components, FirDefaultVisitor<IrElement, Any?>(), IrGeneratorContextInterface { ) : Fir2IrComponents by components, FirDefaultVisitor<IrElement, Any?>(), IrGeneratorContextInterface {
@@ -60,8 +61,6 @@ class Fir2IrVisitor(
session session
) )
private val conversionScope = Fir2IrConversionScope()
private val callGenerator = CallAndReferenceGenerator(components, this, conversionScope) private val callGenerator = CallAndReferenceGenerator(components, this, conversionScope)
private val memberGenerator = ClassMemberGenerator(components, this, conversionScope, callGenerator, fakeOverrideMode) private val memberGenerator = ClassMemberGenerator(components, this, conversionScope, callGenerator, fakeOverrideMode)
@@ -57,7 +57,7 @@ internal class ClassMemberGenerator(
convertFunctionContent(irPrimaryConstructor, primaryConstructor) convertFunctionContent(irPrimaryConstructor, primaryConstructor)
} }
} }
val processedCallableNames = klass.declarations.mapNotNullTo(mutableListOf()) { val processedCallableNames = klass.declarations.mapNotNullTo(mutableSetOf()) {
when (it) { when (it) {
is FirSimpleFunction -> it.name is FirSimpleFunction -> it.name
is FirProperty -> it.name is FirProperty -> it.name
@@ -34,11 +34,11 @@ internal class FakeOverrideGenerator(
) { ) {
private fun IrSimpleFunction.withFunction(f: IrSimpleFunction.() -> Unit): IrSimpleFunction { 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 { 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 { 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 if (fakeOverrideMode == FakeOverrideMode.NONE) return
val superTypesCallableNames = klass.collectCallableNamesFromSupertypes(session) val superTypesCallableNames = klass.collectCallableNamesFromSupertypes(session)
val useSiteMemberScope = klass.buildUseSiteMemberScope(session, scopeSession) ?: return 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, // parent of *original* function (base class) is used for dispatch receiver,
// but fake override itself uses parent from its containing (derived) class // but fake override itself uses parent from its containing (derived) class
val overriddenSymbol = declarationStorage.getIrFunctionSymbol(baseSymbol) as IrSimpleFunctionSymbol val overriddenSymbol = declarationStorage.getIrFunctionSymbol(baseSymbol) as IrSimpleFunctionSymbol
irFunction.parent = this
declarations += irFunction.withFunction { declarations += irFunction.withFunction {
overriddenSymbols = listOf(overriddenSymbol) overriddenSymbols = listOf(overriddenSymbol)
} }
@@ -101,6 +102,7 @@ internal class FakeOverrideGenerator(
return@processFunctionsByName return@processFunctionsByName
} }
val overriddenSymbol = declarationStorage.getIrFunctionSymbol(functionSymbol) as IrSimpleFunctionSymbol val overriddenSymbol = declarationStorage.getIrFunctionSymbol(functionSymbol) as IrSimpleFunctionSymbol
irFunction.parent = this
declarations += irFunction.withFunction { declarations += irFunction.withFunction {
overriddenSymbols = listOf(overriddenSymbol) overriddenSymbols = listOf(overriddenSymbol)
} }
@@ -119,6 +121,7 @@ internal class FakeOverrideGenerator(
thisReceiverOwner = declarationStorage.findIrParent(baseSymbol.fir) as? IrClass, thisReceiverOwner = declarationStorage.findIrParent(baseSymbol.fir) as? IrClass,
origin = origin origin = origin
) )
irProperty.parent = this
declarations += irProperty.withProperty { declarations += irProperty.withProperty {
setOverriddenSymbolsForAccessors(declarationStorage, originalProperty, firOverriddenSymbol = baseSymbol) setOverriddenSymbolsForAccessors(declarationStorage, originalProperty, firOverriddenSymbol = baseSymbol)
} }
@@ -148,6 +151,7 @@ internal class FakeOverrideGenerator(
) { ) {
return@processPropertiesByName return@processPropertiesByName
} }
irProperty.parent = this
declarations += irProperty.withProperty { declarations += irProperty.withProperty {
setOverriddenSymbolsForAccessors(declarationStorage, fakeOverrideProperty, firOverriddenSymbol = propertySymbol) 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
}