diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 6be1c667ce5..a0a1027cefb 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -280,7 +280,10 @@ class Fir2IrConverter( } declarationStorage.leaveScope(irConstructor.symbol) } - fakeOverrideGenerator.computeFakeOverrides(klass, irClass, allDeclarations) + + if (!configuration.useIrFakeOverrideBuilder) { + fakeOverrideGenerator.computeFakeOverrides(klass, irClass, allDeclarations) + } return irClass } 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 d428fba2201..200f53fb32e 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 @@ -51,6 +51,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerAbiStability import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.utils.addToStdlib.runIf +import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import org.jetbrains.kotlin.utils.threadLocal import java.util.concurrent.ConcurrentHashMap @@ -318,6 +319,33 @@ class Fir2IrDeclarationStorage( } } + private fun createMemberFunctionSymbol( + function: FirFunction, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, + signature: IdSignature?, + parentIsExternal: Boolean + ): IrSimpleFunctionSymbol { + if ( + !configuration.useIrFakeOverrideBuilder || + parentIsExternal || + function !is FirSimpleFunction || + !function.isFakeOverride(fakeOverrideOwnerLookupTag) + ) { + return createFunctionSymbol(signature) + } + val containingClassLookupTag = when { + fakeOverrideOwnerLookupTag != null -> fakeOverrideOwnerLookupTag + function.isSubstitutionOrIntersectionOverride -> function.containingClassLookupTag() + else -> shouldNotBeCalled() + } + requireNotNull(containingClassLookupTag) { "Containing class not found for ${function.render()}"} + val containingClassSymbol = classifierStorage.findIrClass(containingClassLookupTag)?.symbol + ?: error("IR class for $containingClassLookupTag not found") + val originalFirFunction = function.unwrapFakeOverrides() + val originalSymbol = getIrFunctionSymbol(originalFirFunction.symbol) as IrSimpleFunctionSymbol + return IrFunctionFakeOverrideSymbol(originalSymbol, containingClassSymbol, signature) + } + private fun cacheIrFunctionSymbol( function: FirFunction, irFunctionSymbol: IrSimpleFunctionSymbol, @@ -988,10 +1016,10 @@ class Fir2IrDeclarationStorage( val signature = runIf(!isLocal && configuration.linkViaSignatures) { signatureComposer.composeSignature(firFunctionSymbol.fir, fakeOverrideOwnerLookupTag) } - val symbol = createFunctionSymbol(signature) if (function is FirSimpleFunction && !isLocal) { val irParent = findIrParent(function, fakeOverrideOwnerLookupTag) if (irParent?.isExternalParent() == true) { + val symbol = createMemberFunctionSymbol(function, fakeOverrideOwnerLookupTag, signature, parentIsExternal = true) val firForLazyFunction = calculateFirForLazyDeclaration( function, fakeOverrideOwnerLookupTag, irParent, fakeOverrideGenerator::createFirFunctionFakeOverrideIfNeeded @@ -1009,9 +1037,12 @@ class Fir2IrDeclarationStorage( ).also { check(it is Fir2IrLazySimpleFunction) } + cacheIrFunctionSymbol(function, symbol, fakeOverrideOwnerLookupTag) + return symbol } } + val symbol = createMemberFunctionSymbol(function, fakeOverrideOwnerLookupTag, signature, parentIsExternal = false) cacheIrFunctionSymbol(function, symbol, fakeOverrideOwnerLookupTag) return symbol } @@ -1437,6 +1468,15 @@ class Fir2IrDeclarationStorage( private fun FirCallableDeclaration.isFakeOverrideOrDelegated(fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?): Boolean { if (isCopyCreatedInScope) return true + return isFakeOverrideImpl(fakeOverrideOwnerLookupTag) +} + +private fun FirCallableDeclaration.isFakeOverride(fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?): Boolean { + if (isSubstitutionOrIntersectionOverride) return true + return isFakeOverrideImpl(fakeOverrideOwnerLookupTag) +} + +private fun FirCallableDeclaration.isFakeOverrideImpl(fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?): Boolean { if (fakeOverrideOwnerLookupTag == null) return false // this condition is true for all places when we are trying to create "fake" fake overrides in IR // "fake" fake overrides are f/o which are presented in IR but have no corresponding FIR f/o diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrFakeOverrideSymbol.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrFakeOverrideSymbol.kt new file mode 100644 index 00000000000..c4ff796b045 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrFakeOverrideSymbol.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.symbols.impl + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.util.IdSignature +import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled + +abstract class IrFakeOverrideSymbolBase, I : IrDeclaration, D : CallableDescriptor>( + val originalSymbol: S, + val containingClassSymbol: IrClassSymbol, + override val signature: IdSignature? +) : IrBindableSymbol { + @ObsoleteDescriptorBasedAPI + override val hasDescriptor: Boolean + get() = false + + override val isBound: Boolean + get() = false + + override var privateSignature: IdSignature? + get() = shouldNotBeCalled() + set(_) { + shouldNotBeCalled() + } + + @UnsafeDuringIrConstructionAPI + @Deprecated("Fake-override symbols never has its owner", level = DeprecationLevel.HIDDEN) + override val owner: I + get() = shouldNotBeCalled() + + @ObsoleteDescriptorBasedAPI + @Deprecated("Fake-override symbols never has its owner", level = DeprecationLevel.HIDDEN) + override val descriptor: D + get() = shouldNotBeCalled() + + @Deprecated("Fake-override symbols never has its owner", level = DeprecationLevel.HIDDEN) + override fun bind(owner: I) { + shouldNotBeCalled() + } +} + +class IrFunctionFakeOverrideSymbol( + originalSymbol: IrSimpleFunctionSymbol, + containingClassSymbol: IrClassSymbol, + idSignature: IdSignature? +) : IrFakeOverrideSymbolBase( + originalSymbol, containingClassSymbol, idSignature +), IrSimpleFunctionSymbol