From bb093037c06edfbd2eabd64e185018e923262158 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 13 Sep 2023 16:07:13 +0300 Subject: [PATCH] [FIR2IR] Simplify Fir2IrDeclarationStorage.getIrFunctionSymbol Previously `getIrFunctionSymbol` effectively did the same thing as `getOrCreateIrFunction`, but in a slightly different way. To avoid logic duplication and source of potential inconsistencies, implementation was changed to just delegate to `getOrCreateIrFunction` Changes in `computeIrOrigin` were required because origin for callables in `getOrCreateIrFunction` and `getIrFunctionSymbol` was computed differently, so `computeIrOrigin` was changed to preserve existing behavior ^KT-60924 --- .../kotlin/fir/backend/ConversionUtils.kt | 39 +++++-- .../fir/backend/Fir2IrDeclarationStorage.kt | 104 ++++++++---------- .../Fir2IrCallableDeclarationsGenerator.kt | 2 +- 3 files changed, 74 insertions(+), 71 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 0504552e65c..da089b32f39 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -681,17 +681,36 @@ fun FirSession.createFilesWithGeneratedDeclarations(): List { } } -fun FirDeclaration?.computeIrOrigin(predefinedOrigin: IrDeclarationOrigin? = null): IrDeclarationOrigin { - return predefinedOrigin - ?: (this?.origin as? FirDeclarationOrigin.Plugin)?.let { GeneratedByPlugin(it.key) } - ?: (this as? FirValueParameter)?.name?.let { - when (it) { - SpecialNames.UNDERSCORE_FOR_UNUSED_VAR -> IrDeclarationOrigin.UNDERSCORE_PARAMETER - SpecialNames.DESTRUCT -> IrDeclarationOrigin.DESTRUCTURED_OBJECT_PARAMETER - else -> null - } +fun FirDeclaration?.computeIrOrigin( + predefinedOrigin: IrDeclarationOrigin? = null, + parentOrigin: IrDeclarationOrigin? = null +): IrDeclarationOrigin { + if (this == null) { + return predefinedOrigin ?: parentOrigin ?: IrDeclarationOrigin.DEFINED + } + + val firOrigin = origin + val computed = when { + firOrigin is FirDeclarationOrigin.Plugin -> GeneratedByPlugin(firOrigin.key) + + this is FirValueParameter -> when (name) { + SpecialNames.UNDERSCORE_FOR_UNUSED_VAR -> IrDeclarationOrigin.UNDERSCORE_PARAMETER + SpecialNames.DESTRUCT -> IrDeclarationOrigin.DESTRUCTURED_OBJECT_PARAMETER + else -> null } - ?: IrDeclarationOrigin.DEFINED + + this is FirCallableDeclaration -> when { + symbol.fir.isIntersectionOverride || symbol.fir.isSubstitutionOverride -> IrDeclarationOrigin.FAKE_OVERRIDE + parentOrigin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB && symbol.isJavaOrEnhancement -> { + IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB + } + symbol.origin is FirDeclarationOrigin.Plugin -> GeneratedByPlugin((symbol.origin as FirDeclarationOrigin.Plugin).key) + else -> null + } + else -> null + } + + return computed ?: predefinedOrigin ?: parentOrigin ?: IrDeclarationOrigin.DEFINED } private typealias NameWithElementType = Pair 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 d83abb85ad6..8afafd9f868 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 @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.utils.isExpect import org.jetbrains.kotlin.fir.declarations.utils.isStatic +import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.descriptors.FirBuiltInsPackageFragment import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor @@ -28,11 +29,13 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.resolvedType +import org.jetbrains.kotlin.fir.types.toLookupTag import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin.GeneratedByPlugin import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind @@ -40,7 +43,8 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.kotlin.FacadeClassSource -import org.jetbrains.kotlin.name.* +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerAbiStability @@ -228,13 +232,15 @@ class Fir2IrDeclarationStorage( // ------------------------------------ functions ------------------------------------ - fun getCachedIrFunction(function: FirFunction): IrSimpleFunction? { - return if (function is FirSimpleFunction) getCachedIrFunction(function) + fun getCachedIrFunction(function: FirFunction, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null): IrSimpleFunction? { + return if (function is FirSimpleFunction) getCachedIrFunction(function, fakeOverrideOwnerLookupTag) else localStorage.getLocalFunction(function) } - fun getCachedIrFunction(function: FirSimpleFunction): IrSimpleFunction? { - return getCachedIrFunction(function, fakeOverrideOwnerLookupTag = null) { signatureComposer.composeSignature(function) } + fun getCachedIrFunction(function: FirSimpleFunction, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null): IrSimpleFunction? { + return getCachedIrFunction(function, fakeOverrideOwnerLookupTag) { + signatureComposer.composeSignature(function, fakeOverrideOwnerLookupTag) + } } fun getCachedIrFunction( @@ -264,8 +270,29 @@ class Fir2IrDeclarationStorage( isLocal: Boolean = false, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null ): IrSimpleFunction { - getCachedIrFunction(function)?.let { return it } - return createAndCacheIrFunction(function, irParent, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag) + return getOrCreateIrFunction(function, { irParent }, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag) + } + + private fun getOrCreateIrFunction( + function: FirFunction, + irParent: () -> IrDeclarationParent?, + predefinedOrigin: IrDeclarationOrigin? = null, + isLocal: Boolean = false, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null + ): IrSimpleFunction { + getCachedIrFunction(function, fakeOverrideOwnerLookupTag)?.let { return it } + /* + * 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 + * need to call FakeOverrideGenerator before checking any caches. Otherwise it will lead to + * the situation when lazy fake override is created based on original FIR function, not + * its f/o copy (which causes troubles with type parameters mapping) + */ + if (fakeOverrideOwnerLookupTag != function.containingClassLookupTag()) { + generateLazyFakeOverrides(function.nameOrSpecialName, fakeOverrideOwnerLookupTag) + getCachedIrFunction(function, fakeOverrideOwnerLookupTag)?.let { return it } + } + return createAndCacheIrFunction(function, irParent(), predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag) } @LeakedDeclarationCaches @@ -875,47 +902,16 @@ class Fir2IrDeclarationStorage( fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, ): IrFunctionSymbol { return when (val fir = firFunctionSymbol.fir) { - is FirAnonymousFunction -> { - getCachedIrFunction(fir)?.let { return it.symbol } - val irParent = findIrParent(fir, fakeOverrideOwnerLookupTag) - val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED - val declarationOrigin = computeDeclarationOrigin(firFunctionSymbol, parentOrigin) - createAndCacheIrFunction(fir, irParent, predefinedOrigin = declarationOrigin).symbol - } - is FirSimpleFunction -> { - val unmatchedOwner = fakeOverrideOwnerLookupTag != firFunctionSymbol.containingClassLookupTag() - if (unmatchedOwner) { - generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag) - } - val originalSymbol = getIrCallableSymbol( - firFunctionSymbol, - fakeOverrideOwnerLookupTag, - getCachedIrDeclaration = ::getCachedIrFunction, - createIrDeclaration = { parent, origin -> - createAndCacheIrFunction( - fir, parent, - predefinedOrigin = origin, - fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag, - ) - }, - createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> - lazyDeclarationsGenerator.createIrLazyFunction(fir, signature, lazyParent, declarationOrigin).also { - cacheIrFunction(fir, it, fakeOverrideOwnerLookupTag) - } - }, - ) as IrFunctionSymbol - if (unmatchedOwner && fakeOverrideOwnerLookupTag is ConeClassLookupTagWithFixedSymbol) { - @OptIn(IrSymbolInternals::class) - val originalFunction = originalSymbol.owner as IrSimpleFunction - fakeOverrideOwnerLookupTag.findIrFakeOverride(fir.name, originalFunction) as IrFunctionSymbol? ?: originalSymbol - } else { - originalSymbol - } - } is FirConstructor -> { getIrConstructorSymbol(fir.symbol) } - else -> error("Unknown kind of function: ${fir::class.java}: ${fir.render()}") + else -> { + getOrCreateIrFunction( + fir, + { findIrParent(fir, fakeOverrideOwnerLookupTag) }, + fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag + ).symbol + } } } @@ -1077,7 +1073,7 @@ class Fir2IrDeclarationStorage( }?.let { return it.symbol } val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED - val declarationOrigin = computeDeclarationOrigin(firSymbol, parentOrigin) + val declarationOrigin = firSymbol.fir.computeIrOrigin(parentOrigin = parentOrigin) when (val parent = irParent) { is Fir2IrLazyClass -> { assert(parentOrigin != IrDeclarationOrigin.DEFINED || configuration.allowNonCachedDeclarations) { @@ -1257,18 +1253,6 @@ class Fir2IrDeclarationStorage( }?.symbol } - private fun computeDeclarationOrigin( - symbol: FirCallableSymbol<*>, - parentOrigin: IrDeclarationOrigin - ): IrDeclarationOrigin = when { - symbol.fir.isIntersectionOverride || symbol.fir.isSubstitutionOverride -> IrDeclarationOrigin.FAKE_OVERRIDE - parentOrigin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB && symbol.isJavaOrEnhancement -> { - IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB - } - symbol.origin is FirDeclarationOrigin.Plugin -> GeneratedByPlugin((symbol.origin as FirDeclarationOrigin.Plugin).key) - else -> parentOrigin - } - companion object { internal val ENUM_SYNTHETIC_NAMES = mapOf( Name.identifier("values") to IrSyntheticBodyKind.ENUM_VALUES, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt index 493d58395b1..f39c9bdcb92 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt @@ -103,7 +103,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi // See org.jetbrains.kotlin.backend.jvm.lower.InheritedDefaultMethodsOnClassesLoweringKt.isDefinitelyNotDefaultImplsMethod (irParent as? IrClass)?.origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB && function.isJavaOrEnhancement -> IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB - else -> function.computeIrOrigin(predefinedOrigin) + else -> function.computeIrOrigin(predefinedOrigin, parentOrigin = (irParent as? IrDeclaration)?.origin) } // We don't generate signatures for local classes // We attempt to avoid signature generation for non-local classes, with the following exceptions: