Fir2Ir: deal with fake overrides in FirIrLinker
This commit is contained in:
committed by
Alexander Udalov
parent
0ef474a8d3
commit
1c00f731fd
+1
-1
@@ -1260,7 +1260,7 @@ class Fir2IrDeclarationStorage(
|
||||
lazyParent: IrDeclarationParent,
|
||||
declarationOrigin: IrDeclarationOrigin
|
||||
): IrSimpleFunction {
|
||||
val symbol = Fir2IrSimpleFunctionSymbol(signature, fir.containerSource)
|
||||
val symbol = symbolTable.referenceSimpleFunction(signature)
|
||||
val firFunctionSymbol = fir.symbol
|
||||
val irFunction = fir.convertWithOffsets { startOffset, endOffset ->
|
||||
symbolTable.declareSimpleFunction(signature, { symbol }) {
|
||||
|
||||
@@ -7,10 +7,14 @@ package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData.SymbolKind
|
||||
import org.jetbrains.kotlin.backend.common.serialization.kind
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
@@ -27,6 +31,7 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
|
||||
private val symbolProvider = fir2IrComponents.session.symbolProvider
|
||||
private val declarationStorage = fir2IrComponents.declarationStorage
|
||||
private val classifierStorage = fir2IrComponents.classifierStorage
|
||||
private val fakeOverrideGenerator = FakeOverrideGenerator(fir2IrComponents, Fir2IrConversionScope())
|
||||
|
||||
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
||||
val signature = symbol.signature ?: return null
|
||||
@@ -78,6 +83,7 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
|
||||
firClass = firClass.declarations.singleOrNull { (it as? FirRegularClass)?.name?.asString() == midName } as? FirRegularClass
|
||||
?: return null
|
||||
}
|
||||
val classId = firClass.classId
|
||||
val scope =
|
||||
firClass.unsubstitutedScope(fir2IrComponents.session, fir2IrComponents.scopeSession, withForcedTypeCalculator = true)
|
||||
when (kind) {
|
||||
@@ -92,18 +98,31 @@ class FirIrProvider(val fir2IrComponents: Fir2IrComponents) : IrProvider {
|
||||
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
|
||||
}
|
||||
SymbolKind.FUNCTION_SYMBOL -> {
|
||||
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
|
||||
val lastName = Name.guessByFirstCharacter(nameSegments.last())
|
||||
val functions = mutableListOf<FirSimpleFunction>()
|
||||
scope.processFunctionsByName(lastName) { functions.add(it.fir) }
|
||||
scope.processFunctionsByName(lastName) { functionSymbol ->
|
||||
val dispatchReceiverClassId = (functionSymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.classId
|
||||
val function = if (dispatchReceiverClassId != null && dispatchReceiverClassId != classId) {
|
||||
fakeOverrideGenerator.createFirFunctionFakeOverride(firClass, parent, functionSymbol, scope)!!.first
|
||||
} else functionSymbol.fir
|
||||
functions.add(function)
|
||||
}
|
||||
firCandidates = functions
|
||||
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
|
||||
}
|
||||
SymbolKind.PROPERTY_SYMBOL -> {
|
||||
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
|
||||
val lastName = Name.guessByFirstCharacter(nameSegments.last())
|
||||
val properties = mutableListOf<FirVariable>()
|
||||
scope.processPropertiesByName(lastName) { properties.add(it.fir) }
|
||||
scope.processPropertiesByName(lastName) { propertySymbol ->
|
||||
propertySymbol as FirPropertySymbol
|
||||
val dispatchReceiverClassId = (propertySymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.classId
|
||||
val property = if (dispatchReceiverClassId != null && dispatchReceiverClassId != classId) {
|
||||
fakeOverrideGenerator.createFirPropertyFakeOverride(firClass, parent, propertySymbol, scope)!!.first
|
||||
} else propertySymbol.fir
|
||||
properties.add(property)
|
||||
}
|
||||
firCandidates = properties
|
||||
parent = classifierStorage.getIrClassSymbol(firClass.symbol).owner
|
||||
}
|
||||
else -> {
|
||||
val lastName = nameSegments.last()
|
||||
|
||||
+71
-2
@@ -16,8 +16,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.allowsToHaveFakeOverride
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
@@ -250,6 +248,77 @@ class FakeOverrideGenerator(
|
||||
result += irDeclaration
|
||||
}
|
||||
|
||||
private inline fun <D : FirCallableDeclaration, reified S : FirCallableSymbol<D>> createFirFakeOverride(
|
||||
klass: FirClass,
|
||||
irClass: IrClass,
|
||||
originalSymbol: S,
|
||||
createFakeOverrideSymbol: (firDeclaration: D, baseSymbol: S) -> S,
|
||||
computeDirectOverridden: FirTypeScope.(S) -> List<S>,
|
||||
scope: FirTypeScope,
|
||||
): Pair<D, List<S>>? {
|
||||
val classLookupTag = klass.symbol.toLookupTag()
|
||||
val originalDeclaration = originalSymbol.fir
|
||||
val baseSymbol = originalSymbol.unwrapSubstitutionAndIntersectionOverrides() as S
|
||||
return when {
|
||||
originalSymbol.shouldHaveComputedBaseSymbolsForClass(classLookupTag) -> {
|
||||
// Substitution or intersection case
|
||||
// We have already a FIR declaration for such fake override
|
||||
originalDeclaration to computeBaseSymbols(
|
||||
originalSymbol,
|
||||
computeDirectOverridden,
|
||||
scope, classLookupTag
|
||||
)
|
||||
}
|
||||
originalDeclaration.allowsToHaveFakeOverrideIn(klass) -> {
|
||||
// Trivial fake override case
|
||||
// We've got no relevant declaration in FIR world for such a fake override in current class, thus we're creating it here
|
||||
val fakeOverrideSymbol = createFakeOverrideSymbol(originalDeclaration, baseSymbol)
|
||||
declarationStorage.saveFakeOverrideInClass(irClass, originalDeclaration, fakeOverrideSymbol.fir)
|
||||
classifierStorage.preCacheTypeParameters(originalDeclaration)
|
||||
fakeOverrideSymbol.fir to listOf(originalSymbol)
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createFirFunctionFakeOverride(
|
||||
klass: FirClass,
|
||||
irClass: IrClass,
|
||||
originalSymbol: FirNamedFunctionSymbol,
|
||||
scope: FirTypeScope
|
||||
) = createFirFakeOverride(
|
||||
klass, irClass, originalSymbol,
|
||||
createFakeOverrideSymbol = { firFunction, callableSymbol ->
|
||||
FirFakeOverrideGenerator.createSubstitutionOverrideFunction(
|
||||
session, callableSymbol, firFunction,
|
||||
newDispatchReceiverType = klass.defaultType(),
|
||||
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
},
|
||||
computeDirectOverridden = FirTypeScope::getDirectOverriddenFunctions,
|
||||
scope
|
||||
)
|
||||
|
||||
fun createFirPropertyFakeOverride(
|
||||
klass: FirClass,
|
||||
irClass: IrClass,
|
||||
originalSymbol: FirPropertySymbol,
|
||||
scope: FirTypeScope
|
||||
) = createFirFakeOverride(
|
||||
klass, irClass, originalSymbol,
|
||||
createFakeOverrideSymbol = { firProperty, callableSymbol ->
|
||||
FirFakeOverrideGenerator.createSubstitutionOverrideProperty(
|
||||
session, callableSymbol, firProperty,
|
||||
newDispatchReceiverType = klass.defaultType(),
|
||||
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
||||
)
|
||||
},
|
||||
computeDirectOverridden = FirTypeScope::getDirectOverriddenProperties,
|
||||
scope
|
||||
)
|
||||
|
||||
private inline fun <reified S : FirCallableSymbol<*>> computeBaseSymbols(
|
||||
symbol: S,
|
||||
directOverridden: FirTypeScope.(S) -> List<S>,
|
||||
|
||||
@@ -13,14 +13,11 @@ import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.initialSignatureAttr
|
||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.DeserializableClass
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
@@ -31,7 +28,7 @@ class Fir2IrLazySimpleFunction(
|
||||
origin: IrDeclarationOrigin,
|
||||
override val fir: FirSimpleFunction,
|
||||
firParent: FirRegularClass?,
|
||||
symbol: Fir2IrSimpleFunctionSymbol,
|
||||
symbol: IrSimpleFunctionSymbol,
|
||||
isFakeOverride: Boolean
|
||||
) : AbstractFir2IrLazyFunction<FirSimpleFunction>(components, startOffset, endOffset, origin, symbol, isFakeOverride) {
|
||||
init {
|
||||
|
||||
Reference in New Issue
Block a user