[FIR2IR] Make most functions of Fir2IrDeclarationStorage return symbols instead of IR elements

This is a preparation to introducing unbound symbols in fir2ir conversion
This commit is contained in:
Dmitriy Novozhilov
2023-10-24 11:44:14 +03:00
committed by Space Team
parent d08567c2c7
commit a38d60b275
8 changed files with 110 additions and 92 deletions
@@ -37,11 +37,11 @@ class Fir2IrCommonMemberStorage(
val localClassCache: MutableMap<FirClass, IrClass> = mutableMapOf() val localClassCache: MutableMap<FirClass, IrClass> = mutableMapOf()
val functionCache: ConcurrentHashMap<FirFunction, IrSimpleFunction> = ConcurrentHashMap() val functionCache: ConcurrentHashMap<FirFunction, IrSimpleFunctionSymbol> = ConcurrentHashMap()
val constructorCache: ConcurrentHashMap<FirConstructor, IrConstructor> = ConcurrentHashMap() val constructorCache: ConcurrentHashMap<FirConstructor, IrConstructorSymbol> = ConcurrentHashMap()
val propertyCache: ConcurrentHashMap<FirProperty, IrProperty> = ConcurrentHashMap() val propertyCache: ConcurrentHashMap<FirProperty, IrPropertySymbol> = ConcurrentHashMap()
val getterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> = ConcurrentHashMap() val getterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> = ConcurrentHashMap()
val setterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> = ConcurrentHashMap() val setterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> = ConcurrentHashMap()
val backingFieldForPropertyCache: ConcurrentHashMap<IrPropertySymbol, IrFieldSymbol> = ConcurrentHashMap() val backingFieldForPropertyCache: ConcurrentHashMap<IrPropertySymbol, IrFieldSymbol> = ConcurrentHashMap()
@@ -50,5 +50,5 @@ class Fir2IrCommonMemberStorage(
val fakeOverridesInClass: MutableMap<IrClass, MutableMap<Fir2IrDeclarationStorage.FirOverrideKey, FirCallableDeclaration>> = mutableMapOf() val fakeOverridesInClass: MutableMap<IrClass, MutableMap<Fir2IrDeclarationStorage.FirOverrideKey, FirCallableDeclaration>> = mutableMapOf()
val irForFirSessionDependantDeclarationMap: MutableMap<Fir2IrDeclarationStorage.FakeOverrideIdentifier, IrDeclaration> = mutableMapOf() val irForFirSessionDependantDeclarationMap: MutableMap<Fir2IrDeclarationStorage.FakeOverrideIdentifier, IrSymbol> = mutableMapOf()
} }
@@ -195,7 +195,7 @@ class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
fun returnTarget(expression: FirReturnExpression, declarationStorage: Fir2IrDeclarationStorage): IrFunction { fun returnTarget(expression: FirReturnExpression, declarationStorage: Fir2IrDeclarationStorage): IrFunction {
val irTarget = when (val firTarget = expression.target.labeledElement) { val irTarget = when (val firTarget = expression.target.labeledElement) {
is FirConstructor -> declarationStorage.getCachedIrConstructor(firTarget) is FirConstructor -> declarationStorage.getCachedIrConstructorSymbol(firTarget)?.ownerIfBound()
is FirPropertyAccessor -> { is FirPropertyAccessor -> {
var answer: IrFunction? = null var answer: IrFunction? = null
for ((property, firProperty) in propertyStack.asReversed()) { for ((property, firProperty) in propertyStack.asReversed()) {
@@ -207,7 +207,7 @@ class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
} }
answer answer
} }
else -> declarationStorage.getCachedIrFunction(firTarget) else -> declarationStorage.getCachedIrFunctionSymbol(firTarget)?.ownerIfBound()
} }
for (potentialTarget in functionStack.asReversed()) { for (potentialTarget in functionStack.asReversed()) {
if (potentialTarget == irTarget) { if (potentialTarget == irTarget) {
@@ -590,7 +590,10 @@ class Fir2IrConverter(
} }
private fun FirProperty.evaluate(components: Fir2IrComponents, interpreter: IrInterpreter, mode: EvaluationMode): String? { private fun FirProperty.evaluate(components: Fir2IrComponents, interpreter: IrInterpreter, mode: EvaluationMode): String? {
val irProperty = components.declarationStorage.getCachedIrProperty(this, fakeOverrideOwnerLookupTag = null) ?: return null @OptIn(UnsafeDuringIrConstructionAPI::class)
val irProperty = components.declarationStorage.getCachedIrPropertySymbol(
property = this, fakeOverrideOwnerLookupTag = null
)?.owner ?: return null
fun IrProperty.tryToGetConst(): IrConst<*>? = (backingField?.initializer?.expression as? IrConst<*>) fun IrProperty.tryToGetConst(): IrConst<*>? = (backingField?.initializer?.expression as? IrConst<*>)
fun IrConst<*>.asString(): String { fun IrConst<*>.asString(): String {
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerAbiStability import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerAbiStability
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import org.jetbrains.kotlin.utils.threadLocal import org.jetbrains.kotlin.utils.threadLocal
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -71,13 +72,13 @@ class Fir2IrDeclarationStorage(
private val scriptCache: ConcurrentHashMap<FirScript, IrScript> = ConcurrentHashMap() private val scriptCache: ConcurrentHashMap<FirScript, IrScript> = ConcurrentHashMap()
private val functionCache: ConcurrentHashMap<FirFunction, IrSimpleFunction> = commonMemberStorage.functionCache private val functionCache: ConcurrentHashMap<FirFunction, IrSimpleFunctionSymbol> = commonMemberStorage.functionCache
private val constructorCache: ConcurrentHashMap<FirConstructor, IrConstructor> = commonMemberStorage.constructorCache private val constructorCache: ConcurrentHashMap<FirConstructor, IrConstructorSymbol> = commonMemberStorage.constructorCache
private val initializerCache: ConcurrentHashMap<FirAnonymousInitializer, IrAnonymousInitializer> = ConcurrentHashMap() private val initializerCache: ConcurrentHashMap<FirAnonymousInitializer, IrAnonymousInitializer> = ConcurrentHashMap()
private val propertyCache: ConcurrentHashMap<FirProperty, IrProperty> = commonMemberStorage.propertyCache private val propertyCache: ConcurrentHashMap<FirProperty, IrPropertySymbol> = commonMemberStorage.propertyCache
private val getterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> = private val getterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> =
commonMemberStorage.getterForPropertyCache commonMemberStorage.getterForPropertyCache
private val setterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> = private val setterForPropertyCache: ConcurrentHashMap<IrSymbol, IrSimpleFunctionSymbol> =
@@ -120,7 +121,7 @@ class Fir2IrDeclarationStorage(
* The key here is a pair of the original function (first not f/o) and lookup tag of class for which this fake override was created * The key here is a pair of the original function (first not f/o) and lookup tag of class for which this fake override was created
* THe value is IR function, build for this fake override during fir2ir translation of the module that contains parent class of this function * THe value is IR function, build for this fake override during fir2ir translation of the module that contains parent class of this function
*/ */
private val irForFirSessionDependantDeclarationMap: MutableMap<FakeOverrideIdentifier, IrDeclaration> = private val irForFirSessionDependantDeclarationMap: MutableMap<FakeOverrideIdentifier, IrSymbol> =
commonMemberStorage.irForFirSessionDependantDeclarationMap commonMemberStorage.irForFirSessionDependantDeclarationMap
data class FakeOverrideIdentifier(val originalSymbol: FirCallableSymbol<*>, val dispatchReceiverLookupTag: ConeClassLikeLookupTag) data class FakeOverrideIdentifier(val originalSymbol: FirCallableSymbol<*>, val dispatchReceiverLookupTag: ConeClassLikeLookupTag)
@@ -144,7 +145,7 @@ class Fir2IrDeclarationStorage(
// For pure fields (from Java) only // For pure fields (from Java) only
private val fieldToPropertyCache: ConcurrentHashMap<Pair<FirField, IrDeclarationParent>, IrProperty> = ConcurrentHashMap() private val fieldToPropertyCache: ConcurrentHashMap<Pair<FirField, IrDeclarationParent>, IrProperty> = ConcurrentHashMap()
private val delegatedReverseCache: ConcurrentHashMap<IrDeclaration, FirDeclaration> = ConcurrentHashMap() private val delegatedReverseCache: ConcurrentHashMap<IrSymbol, FirDeclaration> = ConcurrentHashMap()
private val fieldCache: ConcurrentHashMap<FirField, IrField> = ConcurrentHashMap() private val fieldCache: ConcurrentHashMap<FirField, IrField> = ConcurrentHashMap()
@@ -232,33 +233,32 @@ class Fir2IrDeclarationStorage(
// ------------------------------------ functions ------------------------------------ // ------------------------------------ functions ------------------------------------
fun getCachedIrFunction(function: FirFunction, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null): IrSimpleFunction? { fun getCachedIrFunctionSymbol(function: FirFunction, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null): IrSimpleFunctionSymbol? {
return if (function is FirSimpleFunction) getCachedIrFunction(function, fakeOverrideOwnerLookupTag) return if (function is FirSimpleFunction) getCachedIrFunctionSymbol(function, fakeOverrideOwnerLookupTag)
else localStorage.getLocalFunction(function) else localStorage.getLocalFunctionSymbol(function)
} }
fun getCachedIrFunction(function: FirSimpleFunction, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null): IrSimpleFunction? { fun getCachedIrFunctionSymbol(function: FirSimpleFunction, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null): IrSimpleFunctionSymbol? {
return getCachedIrFunction(function, fakeOverrideOwnerLookupTag) { return getCachedIrFunctionSymbol(function, fakeOverrideOwnerLookupTag) {
signatureComposer.composeSignature(function, fakeOverrideOwnerLookupTag) signatureComposer.composeSignature(function, fakeOverrideOwnerLookupTag)
} }
} }
fun getCachedIrFunction( fun getCachedIrFunctionSymbol(
function: FirSimpleFunction, function: FirSimpleFunction,
fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
signatureCalculator: () -> IdSignature? signatureCalculator: () -> IdSignature?
): IrSimpleFunction? { ): IrSimpleFunctionSymbol? {
if (function.visibility == Visibilities.Local) { if (function.visibility == Visibilities.Local) {
return localStorage.getLocalFunction(function) return localStorage.getLocalFunctionSymbol(function)
} }
val cachedIrCallable = getCachedIrCallable( val cachedIrCallable = getCachedIrCallableSymbol(
function, function,
fakeOverrideOwnerLookupTag, fakeOverrideOwnerLookupTag,
functionCache, functionCache,
signatureCalculator signatureCalculator
) { signature -> ) { signature ->
@OptIn(UnsafeDuringIrConstructionAPI::class) symbolTable.referenceSimpleFunctionIfAny(signature)
symbolTable.referenceSimpleFunctionIfAny(signature)?.owner
} }
return cachedIrCallable return cachedIrCallable
} }
@@ -280,7 +280,7 @@ class Fir2IrDeclarationStorage(
isLocal: Boolean = false, isLocal: Boolean = false,
fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null
): IrSimpleFunction { ): IrSimpleFunction {
getCachedIrFunction(function, fakeOverrideOwnerLookupTag)?.let { return it } getCachedIrFunctionSymbol(function, fakeOverrideOwnerLookupTag)?.ownerIfBound()?.let { return it }
/* /*
* Declaration storage doesn't know how to create lazy fake-overrides, it is responsibility of * Declaration storage doesn't know how to create lazy fake-overrides, it is responsibility of
* FakeOverrideGenerator. So if function to be created is potentially lazy fake-override, we * FakeOverrideGenerator. So if function to be created is potentially lazy fake-override, we
@@ -290,7 +290,7 @@ class Fir2IrDeclarationStorage(
*/ */
if (fakeOverrideOwnerLookupTag != function.containingClassLookupTag()) { if (fakeOverrideOwnerLookupTag != function.containingClassLookupTag()) {
generateLazyFakeOverrides(function.nameOrSpecialName, fakeOverrideOwnerLookupTag) generateLazyFakeOverrides(function.nameOrSpecialName, fakeOverrideOwnerLookupTag)
getCachedIrFunction(function, fakeOverrideOwnerLookupTag)?.let { return it } getCachedIrFunctionSymbol(function, fakeOverrideOwnerLookupTag)?.ownerIfBound()?.let { return it }
} }
return createAndCacheIrFunction(function, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag) return createAndCacheIrFunction(function, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
} }
@@ -327,11 +327,11 @@ class Fir2IrDeclarationStorage(
originalFunction.symbol, originalFunction.symbol,
fakeOverrideOwnerLookupTag ?: function.containingClassLookupTag()!! fakeOverrideOwnerLookupTag ?: function.containingClassLookupTag()!!
) )
irForFirSessionDependantDeclarationMap[key] = irFunction irForFirSessionDependantDeclarationMap[key] = irFunction.symbol
} }
else -> { else -> {
functionCache[function] = irFunction functionCache[function] = irFunction.symbol
} }
} }
} }
@@ -346,26 +346,24 @@ class Fir2IrDeclarationStorage(
} }
internal fun cacheDelegationFunction(function: FirSimpleFunction, irFunction: IrSimpleFunction) { internal fun cacheDelegationFunction(function: FirSimpleFunction, irFunction: IrSimpleFunction) {
functionCache[function] = irFunction val symbol = irFunction.symbol
delegatedReverseCache[irFunction] = function functionCache[function] = symbol
delegatedReverseCache[symbol] = function
} }
internal fun cacheGeneratedFunction(firFunction: FirSimpleFunction, irFunction: IrSimpleFunction) { internal fun cacheGeneratedFunction(firFunction: FirSimpleFunction, irFunction: IrSimpleFunction) {
functionCache[firFunction] = irFunction functionCache[firFunction] = irFunction.symbol
} }
// ------------------------------------ constructors ------------------------------------ // ------------------------------------ constructors ------------------------------------
fun getCachedIrConstructor( fun getCachedIrConstructorSymbol(
constructor: FirConstructor, constructor: FirConstructor,
signatureCalculator: () -> IdSignature? = { null } signatureCalculator: () -> IdSignature? = { null }
): IrConstructor? { ): IrConstructorSymbol? {
return constructorCache[constructor] ?: signatureCalculator()?.let { signature -> return constructorCache[constructor] ?: signatureCalculator()?.let { signature ->
symbolTable.referenceConstructorIfAny(signature)?.let { irConstructorSymbol -> symbolTable.referenceConstructorIfAny(signature)?.also { irConstructorSymbol ->
@OptIn(UnsafeDuringIrConstructionAPI::class) constructorCache[constructor] = irConstructorSymbol
val irConstructor = irConstructorSymbol.owner
constructorCache[constructor] = irConstructor
irConstructor
} }
} }
} }
@@ -385,14 +383,14 @@ class Fir2IrDeclarationStorage(
predefinedOrigin: IrDeclarationOrigin? = null, predefinedOrigin: IrDeclarationOrigin? = null,
isLocal: Boolean = false, isLocal: Boolean = false,
): IrConstructor { ): IrConstructor {
getCachedIrConstructor(constructor)?.let { return it } getCachedIrConstructorSymbol(constructor)?.ownerIfBound()?.let { return it }
// caching of created constructor is not called here, because `callablesGenerator` calls `cacheIrConstructor` by itself // caching of created constructor is not called here, because `callablesGenerator` calls `cacheIrConstructor` by itself
return callablesGenerator.createIrConstructor(constructor, irParent(), predefinedOrigin, isLocal) return callablesGenerator.createIrConstructor(constructor, irParent(), predefinedOrigin, isLocal)
} }
@LeakedDeclarationCaches @LeakedDeclarationCaches
internal fun cacheIrConstructor(constructor: FirConstructor, irConstructor: IrConstructor) { internal fun cacheIrConstructor(constructor: FirConstructor, irConstructor: IrConstructor) {
constructorCache[constructor] = irConstructor constructorCache[constructor] = irConstructor.symbol
} }
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol { fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol {
@@ -462,11 +460,11 @@ class Fir2IrDeclarationStorage(
): IrProperty { ): IrProperty {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val property = prepareProperty(property) val property = prepareProperty(property)
getCachedIrProperty(property, fakeOverrideOwnerLookupTag)?.let { return it } getCachedIrPropertySymbol(property, fakeOverrideOwnerLookupTag)?.ownerIfBound()?.let { return it }
// See comment in [getOrCreateIrFunction] // See comment in [getOrCreateIrFunction]
if (fakeOverrideOwnerLookupTag != property.containingClassLookupTag()) { if (fakeOverrideOwnerLookupTag != property.containingClassLookupTag()) {
generateLazyFakeOverrides(property.name, fakeOverrideOwnerLookupTag) generateLazyFakeOverrides(property.name, fakeOverrideOwnerLookupTag)
getCachedIrProperty(property, fakeOverrideOwnerLookupTag)?.let { return it } getCachedIrPropertySymbol(property, fakeOverrideOwnerLookupTag)?.ownerIfBound()?.let { return it }
} }
return createAndCacheIrProperty(property, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag) return createAndCacheIrProperty(property, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag)
} }
@@ -522,9 +520,9 @@ class Fir2IrDeclarationStorage(
originalProperty.symbol, originalProperty.symbol,
fakeOverrideOwnerLookupTag ?: property.containingClassLookupTag()!! fakeOverrideOwnerLookupTag ?: property.containingClassLookupTag()!!
) )
irForFirSessionDependantDeclarationMap[key] = irProperty irForFirSessionDependantDeclarationMap[key] = irProperty.symbol
} else { } else {
propertyCache[property] = irProperty propertyCache[property] = irProperty.symbol
} }
} }
@@ -563,21 +561,20 @@ class Fir2IrDeclarationStorage(
return result.symbol return result.symbol
} }
fun getCachedIrProperty( fun getCachedIrPropertySymbol(
property: FirProperty, property: FirProperty,
fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
signatureCalculator: () -> IdSignature? = { signatureComposer.composeSignature(property, fakeOverrideOwnerLookupTag) } signatureCalculator: () -> IdSignature? = { signatureComposer.composeSignature(property, fakeOverrideOwnerLookupTag) }
): IrProperty? { ): IrPropertySymbol? {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val property = prepareProperty(property) val property = prepareProperty(property)
return getCachedIrCallable( return getCachedIrCallableSymbol(
property, property,
fakeOverrideOwnerLookupTag, fakeOverrideOwnerLookupTag,
propertyCache, propertyCache,
signatureCalculator signatureCalculator
) { signature -> ) { signature ->
@OptIn(UnsafeDuringIrConstructionAPI::class) symbolTable.referencePropertyIfAny(signature)
symbolTable.referencePropertyIfAny(signature)?.owner
} }
} }
@@ -598,8 +595,9 @@ class Fir2IrDeclarationStorage(
} }
internal fun cacheDelegatedProperty(property: FirProperty, irProperty: IrProperty) { internal fun cacheDelegatedProperty(property: FirProperty, irProperty: IrProperty) {
propertyCache[property] = irProperty val symbol = irProperty.symbol
delegatedReverseCache[irProperty] = property propertyCache[property] = symbol
delegatedReverseCache[symbol] = property
} }
// ------------------------------------ fields ------------------------------------ // ------------------------------------ fields ------------------------------------
@@ -658,7 +656,7 @@ class Fir2IrDeclarationStorage(
if (fir.isLocal) { if (fir.isLocal) {
return localStorage.getDelegatedProperty(fir)?.delegate?.symbol ?: getIrVariableSymbol(fir) return localStorage.getDelegatedProperty(fir)?.delegate?.symbol ?: getIrVariableSymbol(fir)
} }
propertyCache[fir]?.let { return it.backingField!!.symbol } propertyCache[fir]?.ownerIfBound()?.let { return it.backingField!!.symbol }
val irParent = findIrParent(fir, fakeOverrideOwnerLookupTag = null) val irParent = findIrParent(fir, fakeOverrideOwnerLookupTag = null)
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
createAndCacheIrProperty(fir, irParent, predefinedOrigin = parentOrigin).backingField!!.symbol createAndCacheIrProperty(fir, irParent, predefinedOrigin = parentOrigin).backingField!!.symbol
@@ -840,7 +838,7 @@ class Fir2IrDeclarationStorage(
// ------------------------------------ callables ------------------------------------ // ------------------------------------ callables ------------------------------------
fun originalDeclarationForDelegated(irDeclaration: IrDeclaration): FirDeclaration? { fun originalDeclarationForDelegated(irDeclaration: IrDeclaration): FirDeclaration? {
return delegatedReverseCache[irDeclaration] return delegatedReverseCache[irDeclaration.symbol]
} }
internal fun saveFakeOverrideInClass( internal fun saveFakeOverrideInClass(
@@ -880,13 +878,13 @@ class Fir2IrDeclarationStorage(
} }
} }
private inline fun <reified FC : FirCallableDeclaration, reified IC : IrDeclaration> getCachedIrCallable( private inline fun <reified FC : FirCallableDeclaration, reified IS : IrSymbol> getCachedIrCallableSymbol(
declaration: FC, declaration: FC,
fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?,
cache: MutableMap<FC, IC>, cache: MutableMap<FC, IS>,
signatureCalculator: () -> IdSignature?, signatureCalculator: () -> IdSignature?,
referenceIfAny: (IdSignature) -> IC? referenceIfAny: (IdSignature) -> IS?
): IC? { ): IS? {
/* /*
* There should be two types of declarations: * There should be two types of declarations:
* 1. Real declarations. They are stored in simple FirDeclaration -> IrDeclaration [cache] * 1. Real declarations. They are stored in simple FirDeclaration -> IrDeclaration [cache]
@@ -909,7 +907,7 @@ class Fir2IrDeclarationStorage(
declaration.unwrapFakeOverridesOrDelegated().symbol, declaration.unwrapFakeOverridesOrDelegated().symbol,
fakeOverrideOwnerLookupTag ?: declaration.containingClassLookupTag()!! fakeOverrideOwnerLookupTag ?: declaration.containingClassLookupTag()!!
) )
irForFirSessionDependantDeclarationMap[key]?.let { return it as IC } irForFirSessionDependantDeclarationMap[key]?.let { return it as IS }
} else { } else {
cache[declaration]?.let { return it } cache[declaration]?.let { return it }
} }
@@ -1173,3 +1171,8 @@ internal var FirProperty.isStubPropertyForPureField: Boolean? by FirDeclarationD
*/ */
@RequiresOptIn @RequiresOptIn
annotation class LeakedDeclarationCaches annotation class LeakedDeclarationCaches
@OptIn(UnsafeDuringIrConstructionAPI::class)
internal fun <D : IrDeclaration> IrBindableSymbol<*, D>.ownerIfBound(): D? {
return runIf(isBound) { owner }
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
class Fir2IrLocalCallableStorage { class Fir2IrLocalCallableStorage {
@@ -32,8 +33,8 @@ class Fir2IrLocalCallableStorage {
fun getVariable(variable: FirVariable): IrVariable? = fun getVariable(variable: FirVariable): IrVariable? =
last { getVariable(variable) } last { getVariable(variable) }
fun getLocalFunction(localFunction: FirFunction): IrSimpleFunction? = fun getLocalFunctionSymbol(localFunction: FirFunction): IrSimpleFunctionSymbol? =
last { getLocalFunction(localFunction) } last { getLocalFunction(localFunction)?.symbol }
fun getDelegatedProperty(property: FirProperty): IrLocalDelegatedProperty? = fun getDelegatedProperty(property: FirProperty): IrLocalDelegatedProperty? =
last { getDelegatedProperty(property) } last { getDelegatedProperty(property) }
@@ -383,7 +383,8 @@ class Fir2IrVisitor(
// ================================================================================== // ==================================================================================
override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement = whileAnalysing(session, constructor) { override fun visitConstructor(constructor: FirConstructor, data: Any?): IrElement = whileAnalysing(session, constructor) {
val irConstructor = declarationStorage.getCachedIrConstructor(constructor)!! @OptIn(UnsafeDuringIrConstructionAPI::class)
val irConstructor = declarationStorage.getCachedIrConstructorSymbol(constructor)!!.owner
return conversionScope.withFunction(irConstructor) { return conversionScope.withFunction(irConstructor) {
memberGenerator.convertFunctionContent(irConstructor, constructor, containingClass = conversionScope.containerFirClass()) memberGenerator.convertFunctionContent(irConstructor, constructor, containingClass = conversionScope.containerFirClass())
} }
@@ -406,7 +407,8 @@ class Fir2IrVisitor(
simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true
) )
} else { } else {
declarationStorage.getCachedIrFunction(simpleFunction)!! @OptIn(UnsafeDuringIrConstructionAPI::class)
declarationStorage.getCachedIrFunctionSymbol(simpleFunction)!!.owner
} }
return conversionScope.withFunction(irFunction) { return conversionScope.withFunction(irFunction) {
memberGenerator.convertFunctionContent( memberGenerator.convertFunctionContent(
@@ -496,7 +498,8 @@ class Fir2IrVisitor(
override fun visitProperty(property: FirProperty, data: Any?): IrElement = whileAnalysing(session, property) { override fun visitProperty(property: FirProperty, data: Any?): IrElement = whileAnalysing(session, property) {
if (property.isLocal) return visitLocalVariable(property) if (property.isLocal) return visitLocalVariable(property)
val irProperty = declarationStorage.getCachedIrProperty(property, fakeOverrideOwnerLookupTag = null) @OptIn(UnsafeDuringIrConstructionAPI::class)
val irProperty = declarationStorage.getCachedIrPropertySymbol(property, fakeOverrideOwnerLookupTag = null)?.owner
?: return IrErrorExpressionImpl( ?: return IrErrorExpressionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET,
IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT), IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT),
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.constructedClassType import org.jetbrains.kotlin.ir.util.constructedClassType
import org.jetbrains.kotlin.ir.util.isSetter import org.jetbrains.kotlin.ir.util.isSetter
@@ -63,7 +64,9 @@ internal class ClassMemberGenerator(
} }
val primaryConstructor = allDeclarations.firstOrNull { it is FirConstructor && it.isPrimary } as FirConstructor? val primaryConstructor = allDeclarations.firstOrNull { it is FirConstructor && it.isPrimary } as FirConstructor?
val irPrimaryConstructor = primaryConstructor?.let { declarationStorage.getCachedIrConstructor(it)!! }
@OptIn(UnsafeDuringIrConstructionAPI::class)
val irPrimaryConstructor = primaryConstructor?.let { declarationStorage.getCachedIrConstructorSymbol(it)!!.owner }
if (irPrimaryConstructor != null) { if (irPrimaryConstructor != null) {
with(declarationStorage) { with(declarationStorage) {
enterScope(irPrimaryConstructor.symbol) enterScope(irPrimaryConstructor.symbol)
@@ -18,10 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.parentAsClass
@@ -31,9 +28,9 @@ class FakeOverrideGenerator(
private val components: Fir2IrComponents, private val components: Fir2IrComponents,
private val conversionScope: Fir2IrConversionScope private val conversionScope: Fir2IrConversionScope
) : Fir2IrComponents by components { ) : Fir2IrComponents by components {
private val baseFunctionSymbols: MutableMap<IrFunction, List<FirNamedFunctionSymbol>> = mutableMapOf() private val baseFunctionSymbols: MutableMap<IrSimpleFunctionSymbol, List<FirNamedFunctionSymbol>> = mutableMapOf()
private val basePropertySymbols: MutableMap<IrProperty, List<FirPropertySymbol>> = mutableMapOf() private val basePropertySymbols: MutableMap<IrPropertySymbol, List<FirPropertySymbol>> = mutableMapOf()
private val baseStaticFieldSymbols: MutableMap<IrField, List<FirFieldSymbol>> = mutableMapOf() private val baseStaticFieldSymbols: MutableMap<IrFieldSymbol, List<FirFieldSymbol>> = mutableMapOf()
private inline fun IrSimpleFunction.withFunction(f: IrSimpleFunction.() -> Unit) { private inline fun IrSimpleFunction.withFunction(f: IrSimpleFunction.() -> Unit) {
conversionScope.withFunction(this, f) conversionScope.withFunction(this, f)
@@ -85,7 +82,7 @@ class FakeOverrideGenerator(
} }
} }
internal fun generateFakeOverridesForName( private fun generateFakeOverridesForName(
irClass: IrClass, irClass: IrClass,
useSiteOrStaticScope: FirScope, useSiteOrStaticScope: FirScope,
name: Name, name: Name,
@@ -95,10 +92,9 @@ class FakeOverrideGenerator(
) { ) {
val isLocal = firClass !is FirRegularClass || firClass.isLocal val isLocal = firClass !is FirRegularClass || firClass.isLocal
useSiteOrStaticScope.processFunctionsByName(name) { functionSymbol -> useSiteOrStaticScope.processFunctionsByName(name) { functionSymbol ->
@OptIn(LeakedDeclarationCaches::class)
createFakeOverriddenIfNeeded( createFakeOverriddenIfNeeded(
firClass, irClass, isLocal, functionSymbol, firClass, irClass, isLocal, functionSymbol,
declarationStorage::getCachedIrFunction, declarationStorage::getCachedIrFunctionSymbol,
declarationStorage::createAndCacheIrFunction, declarationStorage::createAndCacheIrFunction,
createFakeOverrideSymbol = { firFunction, callableSymbol -> createFakeOverrideSymbol = { firFunction, callableSymbol ->
val symbol = FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId) val symbol = FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId)
@@ -127,7 +123,7 @@ class FakeOverrideGenerator(
@OptIn(LeakedDeclarationCaches::class) @OptIn(LeakedDeclarationCaches::class)
createFakeOverriddenIfNeeded( createFakeOverriddenIfNeeded(
firClass, irClass, isLocal, propertyOrFieldSymbol, firClass, irClass, isLocal, propertyOrFieldSymbol,
declarationStorage::getCachedIrProperty, declarationStorage::getCachedIrPropertySymbol,
declarationStorage::createAndCacheIrProperty, declarationStorage::createAndCacheIrProperty,
createFakeOverrideSymbol = { firProperty, callableSymbol -> createFakeOverrideSymbol = { firProperty, callableSymbol ->
val symbolForOverride = val symbolForOverride =
@@ -156,7 +152,7 @@ class FakeOverrideGenerator(
if (!propertyOrFieldSymbol.isStatic) return@processPropertiesByName if (!propertyOrFieldSymbol.isStatic) return@processPropertiesByName
createFakeOverriddenIfNeeded( createFakeOverriddenIfNeeded(
firClass, irClass, isLocal, propertyOrFieldSymbol, firClass, irClass, isLocal, propertyOrFieldSymbol,
{ field, _, _ -> declarationStorage.getCachedIrFieldStaticFakeOverrideByDeclaration(field) }, { field, _, _ -> declarationStorage.getCachedIrFieldStaticFakeOverrideByDeclaration(field)?.symbol },
{ field, irParent, _, _ -> { field, irParent, _, _ ->
declarationStorage.getOrCreateIrField(field, irParent) declarationStorage.getOrCreateIrField(field, irParent)
}, },
@@ -196,7 +192,7 @@ class FakeOverrideGenerator(
} else { } else {
listOf(originalSymbol) listOf(originalSymbol)
} }
baseFunctionSymbols[fakeOverride] = baseFirSymbolsForFakeOverride baseFunctionSymbols[fakeOverride.symbol] = baseFirSymbolsForFakeOverride
} }
internal fun calcBaseSymbolsForFakeOverrideProperty( internal fun calcBaseSymbolsForFakeOverrideProperty(
@@ -212,23 +208,29 @@ class FakeOverrideGenerator(
} else { } else {
listOf(originalSymbol) listOf(originalSymbol)
} }
basePropertySymbols[fakeOverride] = baseFirSymbolsForFakeOverride basePropertySymbols[fakeOverride.symbol] = baseFirSymbolsForFakeOverride
} }
private fun FirCallableSymbol<*>.shouldHaveComputedBaseSymbolsForClass(classLookupTag: ConeClassLikeLookupTag): Boolean = private fun FirCallableSymbol<*>.shouldHaveComputedBaseSymbolsForClass(classLookupTag: ConeClassLikeLookupTag): Boolean =
fir.origin.fromSupertypes && dispatchReceiverClassLookupTagOrNull() == classLookupTag fir.origin.fromSupertypes && dispatchReceiverClassLookupTagOrNull() == classLookupTag
private inline fun <reified D : FirCallableDeclaration, reified S : FirCallableSymbol<D>, reified I : IrDeclaration> createFakeOverriddenIfNeeded( @Suppress("IncorrectFormatting")
private inline fun <
reified D : FirCallableDeclaration,
reified S : FirCallableSymbol<D>,
reified ID : IrDeclaration,
reified IS : IrBindableSymbol<*, ID>
> createFakeOverriddenIfNeeded(
klass: FirClass, klass: FirClass,
irClass: IrClass, irClass: IrClass,
isLocal: Boolean, isLocal: Boolean,
originalSymbol: FirCallableSymbol<*>, originalSymbol: FirCallableSymbol<*>,
cachedIrDeclaration: (firDeclaration: D, dispatchReceiverLookupTag: ConeClassLikeLookupTag?, () -> IdSignature?) -> I?, cachedIrDeclarationSymbol: (firDeclaration: D, dispatchReceiverLookupTag: ConeClassLikeLookupTag?, () -> IdSignature?) -> IS?,
createIrDeclaration: (firDeclaration: D, irParent: IrClass, origin: IrDeclarationOrigin, isLocal: Boolean) -> I, createIrDeclaration: (firDeclaration: D, irParent: IrClass, origin: IrDeclarationOrigin, isLocal: Boolean) -> ID,
createFakeOverrideSymbol: (firDeclaration: D, baseSymbol: S) -> S, createFakeOverrideSymbol: (firDeclaration: D, baseSymbol: S) -> S,
baseSymbols: MutableMap<I, List<S>>, baseSymbols: MutableMap<IS, List<S>>,
result: MutableList<in I>?, result: MutableList<in ID>?,
containsErrorTypes: (I) -> Boolean, containsErrorTypes: (ID) -> Boolean,
realDeclarationSymbols: Set<FirBasedSymbol<*>>, realDeclarationSymbols: Set<FirBasedSymbol<*>>,
computeDirectOverridden: FirTypeScope.(S) -> List<S>, computeDirectOverridden: FirTypeScope.(S) -> List<S>,
scope: FirScope, scope: FirScope,
@@ -264,25 +266,28 @@ class FakeOverrideGenerator(
return return
} }
} }
val irDeclaration = cachedIrDeclaration(fakeOverrideFirDeclaration, null) { val irSymbol = cachedIrDeclarationSymbol(fakeOverrideFirDeclaration, null) {
// Sometimes we can have clashing here when FIR substitution/intersection override // Sometimes we can have clashing here when FIR substitution/intersection override
// have the same signature. // have the same signature.
// Now we avoid this problem by signature caching, // Now we avoid this problem by signature caching,
// so both FIR overrides correspond to one IR fake override // so both FIR overrides correspond to one IR fake override
signatureComposer.composeSignature(fakeOverrideFirDeclaration) signatureComposer.composeSignature(fakeOverrideFirDeclaration)
}?.takeIf { it.parent == irClass } }?.takeIf { it.ownerIfBound()?.parent == irClass }
?: createIrDeclaration( ?: createIrDeclaration(
fakeOverrideFirDeclaration, fakeOverrideFirDeclaration,
irClass, irClass,
IrDeclarationOrigin.FAKE_OVERRIDE, IrDeclarationOrigin.FAKE_OVERRIDE,
isLocal isLocal
) ).symbol as IS
if (containsErrorTypes(irDeclaration)) {
@OptIn(UnsafeDuringIrConstructionAPI::class)
val owner = irSymbol.owner
if (containsErrorTypes(owner)) {
return return
} }
baseSymbols[irDeclaration] = baseFirSymbolsForFakeOverride baseSymbols[irSymbol] = baseFirSymbolsForFakeOverride
result?.add(irDeclaration) result?.add(owner)
} }
private inline fun <D : FirCallableDeclaration, reified S : FirCallableSymbol<D>> createFirFakeOverride( private inline fun <D : FirCallableDeclaration, reified S : FirCallableSymbol<D>> createFirFakeOverride(
@@ -384,7 +389,7 @@ class FakeOverrideGenerator(
} }
internal fun getOverriddenSymbolsForFakeOverride(function: IrSimpleFunction): List<IrSimpleFunctionSymbol>? { internal fun getOverriddenSymbolsForFakeOverride(function: IrSimpleFunction): List<IrSimpleFunctionSymbol>? {
val baseSymbols = baseFunctionSymbols[function] ?: return null val baseSymbols = baseFunctionSymbols[function.symbol] ?: return null
return getOverriddenSymbolsInSupertypes( return getOverriddenSymbolsInSupertypes(
function, function,
baseSymbols baseSymbols
@@ -411,7 +416,7 @@ class FakeOverrideGenerator(
} }
internal fun getOverriddenSymbolsForFakeOverride(property: IrProperty): List<IrPropertySymbol>? { internal fun getOverriddenSymbolsForFakeOverride(property: IrProperty): List<IrPropertySymbol>? {
val baseSymbols = basePropertySymbols[property] ?: return null val baseSymbols = basePropertySymbols[property.symbol] ?: return null
return getOverriddenSymbolsInSupertypes( return getOverriddenSymbolsInSupertypes(
property, property,
baseSymbols baseSymbols
@@ -472,7 +477,7 @@ class FakeOverrideGenerator(
} }
} }
is IrProperty -> { is IrProperty -> {
val baseSymbols = basePropertySymbols[declaration]!! val baseSymbols = basePropertySymbols[declaration.symbol]!!
declaration.withProperty { declaration.withProperty {
discardAccessorsAccordingToBaseVisibility(baseSymbols) discardAccessorsAccordingToBaseVisibility(baseSymbols)
setOverriddenSymbolsForProperty(declarationStorage, declaration.isVar, baseSymbols) setOverriddenSymbolsForProperty(declarationStorage, declaration.isVar, baseSymbols)