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 0cdb51befb5..b10bbd56376 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 @@ -583,7 +583,7 @@ fun Fir2IrComponents.createTemporaryVariable( conversionScope: Fir2IrConversionScope, nameHint: String? = null ): Pair { - val receiverVariable = declarationStorage.declareTemporaryVariable(receiverExpression, nameHint).apply { + val receiverVariable = callablesGenerator.declareTemporaryVariable(receiverExpression, nameHint).apply { parent = conversionScope.parentFromStack() } val variableSymbol = receiverVariable.symbol diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponents.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponents.kt index 902edb06314..18ca4e31152 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponents.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponents.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.fir.backend import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator -import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator -import org.jetbrains.kotlin.fir.backend.generators.DelegatedMemberGenerator -import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator +import org.jetbrains.kotlin.fir.backend.generators.* import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer import org.jetbrains.kotlin.ir.IrLock @@ -37,6 +34,9 @@ interface Fir2IrComponents { val signatureComposer: FirBasedSignatureComposer val visibilityConverter: Fir2IrVisibilityConverter + val callablesGenerator: Fir2IrCallableDeclarationsGenerator + val lazyDeclarationsGenerator: Fir2IrLazyDeclarationsGenerator + val annotationGenerator: AnnotationGenerator val callGenerator: CallAndReferenceGenerator val fakeOverrideGenerator: FakeOverrideGenerator diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponentsStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponentsStorage.kt index 214dbd8de69..dc2c5601a7e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponentsStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrComponentsStorage.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.fir.backend import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator -import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator -import org.jetbrains.kotlin.fir.backend.generators.DelegatedMemberGenerator -import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator +import org.jetbrains.kotlin.fir.backend.generators.* import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer @@ -40,16 +37,20 @@ class Fir2IrComponentsStorage( override val classifierStorage: Fir2IrClassifierStorage = Fir2IrClassifierStorage(this, commonMemberStorage) override val declarationStorage: Fir2IrDeclarationStorage = Fir2IrDeclarationStorage(this, moduleDescriptor, commonMemberStorage) + override val callablesGenerator: Fir2IrCallableDeclarationsGenerator = Fir2IrCallableDeclarationsGenerator(this) + override val lazyDeclarationsGenerator: Fir2IrLazyDeclarationsGenerator = Fir2IrLazyDeclarationsGenerator(this) + + // builtins should go after storages and generators, because they use them during initialization override val irBuiltIns: IrBuiltInsOverFir = initializedIrBuiltIns ?: IrBuiltInsOverFir( this, configuration.languageVersionSettings, moduleDescriptor, irMangler ) - override val builtIns: Fir2IrBuiltIns = Fir2IrBuiltIns(this, specialSymbolProvider) + override val irProviders: List = listOf(FirIrProvider(this)) override val typeConverter: Fir2IrTypeConverter = Fir2IrTypeConverter(this) - private val conversionScope = Fir2IrConversionScope(configuration) + val fir2IrVisitor: Fir2IrVisitor = Fir2IrVisitor(this, conversionScope) override val annotationGenerator: AnnotationGenerator = AnnotationGenerator(this) 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 b4ed221addd..d865d087c7c 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 @@ -470,7 +470,7 @@ class Fir2IrConverter( } is FirField -> { if (declaration.isSynthetic) { - declarationStorage.createIrFieldAndDelegatedMembers(declaration, containingClass!!, parent as IrClass) + callablesGenerator.createIrFieldAndDelegatedMembers(declaration, containingClass!!, parent as IrClass) } else { throw AssertionError("Unexpected non-synthetic field: ${declaration::class}") } @@ -486,7 +486,7 @@ class Fir2IrConverter( classifierStorage.getIrEnumEntry(declaration, parent as IrClass) } is FirAnonymousInitializer -> { - declarationStorage.createIrAnonymousInitializer(declaration, parent as IrClass) + callablesGenerator.createIrAnonymousInitializer(declaration, parent as IrClass) } is FirTypeAlias -> { // DO NOTHING 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 b81808f6a4d..6b1691ae25e 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 @@ -5,70 +5,54 @@ package org.jetbrains.kotlin.fir.backend -import com.intellij.openapi.progress.ProcessCanceledException import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_FQ_NAMES import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.backend.generators.generateOverriddenAccessorSymbols import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildProperty -import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter -import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter -import org.jetbrains.kotlin.fir.declarations.utils.* +import org.jetbrains.kotlin.fir.declarations.utils.isExpect +import org.jetbrains.kotlin.fir.declarations.utils.isStatic +import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.descriptors.FirBuiltInsPackageFragment import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor -import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor -import org.jetbrains.kotlin.fir.expressions.FirConstExpression -import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression -import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor -import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty -import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction -import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.references.toResolvedValueParameterSymbol -import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject -import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.symbols.* +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.symbols.Fir2IrConstructorSymbol +import org.jetbrains.kotlin.fir.symbols.Fir2IrScriptSymbol +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.utils.exceptions.withFirEntry -import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI 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.* +import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrScriptImpl +import org.jetbrains.kotlin.ir.declarations.impl.SCRIPT_K2_ORIGIN import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass -import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind -import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.symbols.impl.* +import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.kotlin.FacadeClassSource import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.NameUtils -import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.KtFile 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.types.AbstractTypeChecker -import org.jetbrains.kotlin.utils.addToStdlib.runUnless -import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import org.jetbrains.kotlin.utils.threadLocal import java.util.concurrent.ConcurrentHashMap -@OptIn(ObsoleteDescriptorBasedAPI::class) class Fir2IrDeclarationStorage( private val components: Fir2IrComponents, private val moduleDescriptor: FirModuleDescriptor, @@ -270,12 +254,6 @@ class Fir2IrDeclarationStorage( symbolTable.leaveScope(symbol) } - private fun FirTypeRef.toIrType(typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT): IrType = - with(typeConverter) { toIrType(typeOrigin) } - - private fun ConeKotlinType.toIrType(typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT): IrType = - with(typeConverter) { toIrType(typeOrigin) } - private fun getIrExternalOrBuiltInsPackageFragment(fqName: FqName, firOrigin: FirDeclarationOrigin): IrExternalPackageFragment { val isBuiltIn = fqName in BUILT_INS_PACKAGE_FQ_NAMES return if (isBuiltIn) getIrBuiltInsPackageFragment(fqName) else getIrExternalPackageFragment(fqName, firOrigin) @@ -283,7 +261,7 @@ class Fir2IrDeclarationStorage( private fun getIrBuiltInsPackageFragment(fqName: FqName): IrExternalPackageFragment { return builtInsFragmentCache.getOrPut(fqName) { - createExternalPackageFragment(FirBuiltInsPackageFragment(fqName, moduleDescriptor)) + callablesGenerator.createExternalPackageFragment(FirBuiltInsPackageFragment(fqName, moduleDescriptor)) } } @@ -293,8 +271,8 @@ class Fir2IrDeclarationStorage( ): IrExternalPackageFragment { val fragments = fragmentCache.getOrPut(fqName) { ExternalPackageFragments( - fragmentForDependencies = createExternalPackageFragment(fqName, FirModuleDescriptor(session, moduleDescriptor.builtIns)), - fragmentForPrecompiledBinaries = createExternalPackageFragment(fqName, moduleDescriptor) + fragmentForDependencies = callablesGenerator.createExternalPackageFragment(fqName, FirModuleDescriptor(session, moduleDescriptor.builtIns)), + fragmentForPrecompiledBinaries = callablesGenerator.createExternalPackageFragment(fqName, moduleDescriptor) ) } // Make sure that external package fragments have a different module descriptor. The module descriptors are compared @@ -306,15 +284,6 @@ class Fir2IrDeclarationStorage( } } - private fun createExternalPackageFragment(fqName: FqName, moduleDescriptor: FirModuleDescriptor): IrExternalPackageFragment { - return createExternalPackageFragment(FirPackageFragmentDescriptor(fqName, moduleDescriptor)) - } - - private fun createExternalPackageFragment(packageFragmentDescriptor: PackageFragmentDescriptor): IrExternalPackageFragment { - val symbol = IrExternalPackageFragmentSymbolImpl(packageFragmentDescriptor) - return IrExternalPackageFragmentImpl(symbol, packageFragmentDescriptor.fqName) - } - internal fun findIrParent( packageFqName: FqName, parentLookupTag: ConeClassLikeLookupTag?, @@ -381,7 +350,7 @@ class Fir2IrDeclarationStorage( return parentPackage } - private class NonCachedSourceFileFacadeClass( + internal class NonCachedSourceFileFacadeClass( origin: IrDeclarationOrigin, name: Name, source: SourceElement, @@ -403,51 +372,6 @@ class Fir2IrDeclarationStorage( override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE } - /** - * [firCallable] is function or property (if [irFunction] is a property accessor) for - * which [irFunction] was build - * - * It is needed to determine proper dispatch receiver type if this declaration is fake-override - */ - private fun computeDispatchReceiverType( - irFunction: IrSimpleFunction, - firCallable: FirCallableDeclaration?, - parent: IrDeclarationParent?, - ): IrType? { - /* - * If some function is not fake-override, then its type should be just - * default type of containing class - * For fake overrides the default type calculated in the following way: - * 1. Find first overridden function, which is not fake override - * 2. Take its containing class - * 3. Find supertype of current containing class with type constructor of - * class from step 2 - */ - if (firCallable is FirProperty && firCallable.isLocal) return null - val containingClass = computeContainingClass(parent) ?: return null - val defaultType = containingClass.defaultType - if (firCallable == null) return defaultType - if (irFunction.origin != IrDeclarationOrigin.FAKE_OVERRIDE) return defaultType - - val originalCallable = firCallable.unwrapFakeOverrides() - val containerOfOriginalCallable = originalCallable.containingClassLookupTag() ?: return defaultType - val containerOfFakeOverride = firCallable.dispatchReceiverType ?: return defaultType - val correspondingSupertype = AbstractTypeChecker.findCorrespondingSupertypes( - session.typeContext.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), - containerOfFakeOverride, - containerOfOriginalCallable - ).firstOrNull() as ConeKotlinType? ?: return defaultType - return correspondingSupertype.toIrType() - } - - private fun computeContainingClass(parent: IrDeclarationParent?): IrClass? { - return if (parent is IrClass && parent !is NonCachedSourceFileFacadeClass) { - parent - } else { - null - } - } - private fun findIrParent(callableDeclaration: FirCallableDeclaration): IrDeclarationParent? { val firBasedSymbol = callableDeclaration.symbol val callableId = firBasedSymbol.callableId @@ -455,151 +379,6 @@ class Fir2IrDeclarationStorage( return findIrParent(callableId.packageName, callableDeclaration.containingClassLookupTag(), firBasedSymbol, callableOrigin) } - private fun IrDeclaration.setAndModifyParent(irParent: IrDeclarationParent?) { - if (irParent != null) { - parent = irParent - if (irParent is IrExternalPackageFragment) { - irParent.declarations += this - } - } - } - - private fun T.declareDefaultSetterParameter(type: IrType, firValueParameter: FirValueParameter?): T { - valueParameters = listOf( - createDefaultSetterParameter(startOffset, endOffset, type, parent = this, firValueParameter) - ) - return this - } - - internal fun createDefaultSetterParameter( - startOffset: Int, - endOffset: Int, - type: IrType, - parent: IrFunction, - firValueParameter: FirValueParameter?, - name: Name? = null, - isCrossinline: Boolean = false, - isNoinline: Boolean = false, - ): IrValueParameter { - return irFactory.createValueParameter( - startOffset = startOffset, - endOffset = endOffset, - origin = IrDeclarationOrigin.DEFINED, - name = name ?: SpecialNames.IMPLICIT_SET_PARAMETER, - type = type, - isAssignable = false, - symbol = IrValueParameterSymbolImpl(), - index = parent.contextReceiverParametersCount, - varargElementType = null, - isCrossinline = isCrossinline, - isNoinline = isNoinline, - isHidden = false, - ).apply { - this.parent = parent - if (firValueParameter != null) { - annotationGenerator.generate(this, firValueParameter) - } - } - } - - fun addContextReceiverParametersTo( - contextReceivers: List, - parent: IrFunction, - result: MutableList, - ) { - contextReceivers.mapIndexedTo(result) { index, contextReceiver -> - createIrParameterFromContextReceiver(contextReceiver, index).apply { - this.parent = parent - } - } - } - - /* - * In perfect world dispatchReceiverType should always be the default type of containing class - * But fake-overrides for members from Any have special rules for type of dispatch receiver - */ - private fun IrFunction.declareParameters( - function: FirFunction?, - irParent: IrDeclarationParent?, - dispatchReceiverType: IrType?, // has no sense for constructors - isStatic: Boolean, - forSetter: Boolean, - // Can be not-null only for property accessors - parentPropertyReceiver: FirReceiverParameter? = null - ) { - val containingClass = computeContainingClass(irParent) - val parent = this - if (function is FirSimpleFunction || function is FirConstructor) { - with(classifierStorage) { - setTypeParameters(function) - } - } - val typeOrigin = if (forSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT - if (function is FirDefaultPropertySetter) { - val valueParameter = function.valueParameters.first() - val type = valueParameter.returnTypeRef.toIrType(ConversionTypeOrigin.SETTER) - declareDefaultSetterParameter(type, valueParameter) - } else if (function != null) { - val contextReceivers = function.contextReceiversForFunctionOrContainingProperty() - - contextReceiverParametersCount = contextReceivers.size - valueParameters = buildList { - addContextReceiverParametersTo(contextReceivers, parent, this) - - function.valueParameters.mapIndexedTo(this) { index, valueParameter -> - createIrParameter( - valueParameter, index + contextReceiverParametersCount, - useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum"), - typeOrigin, - skipDefaultParameter = isFakeOverride || origin == IrDeclarationOrigin.DELEGATED_MEMBER - ).apply { - this.parent = parent - } - } - } - } - - val thisOrigin = IrDeclarationOrigin.DEFINED - if (function !is FirConstructor) { - val receiver: FirReceiverParameter? = - if (function !is FirPropertyAccessor && function != null) function.receiverParameter - else parentPropertyReceiver - if (receiver != null) { - extensionReceiverParameter = receiver.convertWithOffsets { startOffset, endOffset -> - val name = (function as? FirAnonymousFunction)?.label?.name?.let { - val suffix = it.takeIf(Name::isValidIdentifier) ?: "\$receiver" - Name.identifier("\$this\$$suffix") - } ?: SpecialNames.THIS - declareThisReceiverParameter( - thisType = receiver.typeRef.toIrType(typeOrigin), - thisOrigin = thisOrigin, - startOffset = startOffset, - endOffset = endOffset, - name = name, - explicitReceiver = receiver, - ) - } - } - // See [LocalDeclarationsLowering]: "local function must not have dispatch receiver." - val isLocal = function is FirSimpleFunction && function.isLocal - if (function !is FirAnonymousFunction && dispatchReceiverType != null && !isStatic && !isLocal) { - dispatchReceiverParameter = declareThisReceiverParameter( - thisType = dispatchReceiverType, - thisOrigin = thisOrigin - ) - } - } else { - // Set dispatch receiver parameter for inner class's constructor. - val outerClass = containingClass?.parentClassOrNull - if (containingClass?.isInner == true && outerClass != null) { - dispatchReceiverParameter = declareThisReceiverParameter( - thisType = outerClass.thisReceiver!!.type, - thisOrigin = thisOrigin - ) - } - } - } - fun T.putParametersInScope(function: FirFunction): T { val contextReceivers = function.contextReceiversForFunctionOrContainingProperty() @@ -645,23 +424,13 @@ class Fir2IrDeclarationStorage( fun originalDeclarationForDelegated(irDeclaration: IrDeclaration): FirDeclaration? = delegatedReverseCache[irDeclaration] - internal fun declareIrSimpleFunction( - signature: IdSignature?, - factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction - ): IrSimpleFunction = - if (signature == null) { - factory(IrSimpleFunctionSymbolImpl()) - } else { - symbolTable.declareSimpleFunction(signature, { Fir2IrSimpleFunctionSymbol(signature) }, factory) - } - fun getOrCreateIrFunction( function: FirSimpleFunction, irParent: IrDeclarationParent?, isLocal: Boolean = false, ): IrSimpleFunction { getCachedIrFunction(function)?.let { return it } - return createIrFunction( + return callablesGenerator.createIrFunction( function, irParent, isLocal = isLocal, @@ -669,132 +438,9 @@ class Fir2IrDeclarationStorage( ) } - fun createIrFunction( - function: FirFunction, - irParent: IrDeclarationParent?, - predefinedOrigin: IrDeclarationOrigin? = null, - isLocal: Boolean = false, - fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, - ): IrSimpleFunction = convertCatching(function) { - val simpleFunction = function as? FirSimpleFunction - val isLambda = function is FirAnonymousFunction && function.isLambda - val updatedOrigin = when { - isLambda -> IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA - function.symbol.callableId.isKFunctionInvoke() -> IrDeclarationOrigin.FAKE_OVERRIDE - simpleFunction?.isStatic == true && simpleFunction.name in ENUM_SYNTHETIC_NAMES -> IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER - - // Kotlin built-in class and Java originated method (Collection.forEach, etc.) - // It's necessary to understand that such methods do not belong to DefaultImpls but actually generated as default - // 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) - } - // We don't generate signatures for local classes - // We attempt to avoid signature generation for non-local classes, with the following exceptions: - // - special mode (generateSignatures) oriented on special backend modes - // - lazy classes (they still use signatures) - // - primitive types (they can be from built-ins and don't have FIR counterpart) - // - overrides and fake overrides (sometimes we perform "receiver replacement" in FIR2IR breaking FIR->IR relation, - // or FIR counterpart can be just created on the fly) - val signature = - runUnless( - isLocal || - !configuration.linkViaSignatures && irParent !is Fir2IrLazyClass && - function.dispatchReceiverType?.isPrimitive != true && function.containerSource == null && - updatedOrigin != IrDeclarationOrigin.FAKE_OVERRIDE && !function.isOverride - ) { - signatureComposer.composeSignature(function, fakeOverrideOwnerLookupTag) - } - if (irParent is Fir2IrLazyClass && signature != null) { - // For private functions signature is null, fallback to non-lazy function - return createIrLazyFunction(function as FirSimpleFunction, signature, irParent, updatedOrigin) - } - val name = simpleFunction?.name - ?: if (isLambda) SpecialNames.ANONYMOUS else SpecialNames.NO_NAME_PROVIDED - val visibility = simpleFunction?.visibility ?: Visibilities.Local - val isSuspend = - if (isLambda) ((function as FirAnonymousFunction).typeRef as? FirResolvedTypeRef)?.type?.isSuspendOrKSuspendFunctionType(session) == true - else function.isSuspend - val created = function.convertWithOffsets { startOffset, endOffset -> - val result = declareIrSimpleFunction(signature) { symbol -> - classifierStorage.preCacheTypeParameters(function, symbol) - irFactory.createSimpleFunction( - startOffset = if (updatedOrigin == IrDeclarationOrigin.DELEGATED_MEMBER) SYNTHETIC_OFFSET else startOffset, - endOffset = if (updatedOrigin == IrDeclarationOrigin.DELEGATED_MEMBER) SYNTHETIC_OFFSET else endOffset, - origin = updatedOrigin, - name = name, - visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), - isInline = simpleFunction?.isInline == true, - isExpect = simpleFunction?.isExpect == true, - returnType = function.returnTypeRef.toIrType(), - modality = simpleFunction?.modality ?: Modality.FINAL, - symbol = symbol, - isTailrec = simpleFunction?.isTailRec == true, - isSuspend = isSuspend, - isOperator = simpleFunction?.isOperator == true, - isInfix = simpleFunction?.isInfix == true, - isExternal = simpleFunction?.isExternal == true, - containerSource = simpleFunction?.containerSource, - ).apply { - metadata = FirMetadataSource.Function(function) - enterScope(this.symbol) - setAndModifyParent(irParent) - declareParameters( - function, irParent, - dispatchReceiverType = computeDispatchReceiverType(this, simpleFunction, irParent), - isStatic = simpleFunction?.isStatic == true, - forSetter = false, - ) - convertAnnotationsForNonDeclaredMembers(function, origin) - leaveScope(this.symbol) - } - } - result - } - - if (visibility == Visibilities.Local) { - localStorage.putLocalFunction(function, created) - return created - } - if (function.symbol.callableId.isKFunctionInvoke()) { - (function.symbol.originalForSubstitutionOverride as? FirNamedFunctionSymbol)?.let { - created.overriddenSymbols += getIrFunctionSymbol(it) as IrSimpleFunctionSymbol - } - } - if (function.isFakeOverride(fakeOverrideOwnerLookupTag)) { - val originalFunction = function.unwrapFakeOverrides() - val key = FakeOverrideIdentifier( - originalFunction.symbol, - fakeOverrideOwnerLookupTag ?: function.containingClassLookupTag()!! - ) - irFakeOverridesForFirFakeOverrideMap[key] = created - } else { - functionCache[function] = created - } - return created - } - fun getCachedIrAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer): IrAnonymousInitializer? = initializerCache[anonymousInitializer] - fun createIrAnonymousInitializer( - anonymousInitializer: FirAnonymousInitializer, - irParent: IrClass - ): IrAnonymousInitializer = convertCatching(anonymousInitializer) { - return anonymousInitializer.convertWithOffsets { startOffset, endOffset -> - symbolTable.descriptorExtension.declareAnonymousInitializer( - startOffset, - endOffset, - IrDeclarationOrigin.DEFINED, - irParent.descriptor - ).apply { - this.parent = irParent - initializerCache[anonymousInitializer] = this - } - } - } - @OptIn(IrSymbolInternals::class) fun getCachedIrConstructor( constructor: FirConstructor, @@ -809,55 +455,6 @@ class Fir2IrDeclarationStorage( } } - private fun declareIrConstructor(signature: IdSignature?, factory: (IrConstructorSymbol) -> IrConstructor): IrConstructor = - if (signature == null) - factory(IrConstructorSymbolImpl()) - else - symbolTable.declareConstructor(signature, { Fir2IrConstructorSymbol(signature) }, factory) - - - fun createIrConstructor( - constructor: FirConstructor, - irParent: IrClass, - predefinedOrigin: IrDeclarationOrigin? = null, - isLocal: Boolean = false, - ): IrConstructor = convertCatching(constructor) { - val origin = constructor.computeIrOrigin(predefinedOrigin) - val isPrimary = constructor.isPrimary - val signature = - runUnless(isLocal || !configuration.linkViaSignatures) { - signatureComposer.composeSignature(constructor) - } - val visibility = if (irParent.isAnonymousObject) Visibilities.Public else constructor.visibility - return constructor.convertWithOffsets { startOffset, endOffset -> - declareIrConstructor(signature) { symbol -> - classifierStorage.preCacheTypeParameters(constructor, symbol) - irFactory.createConstructor( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = SpecialNames.INIT, - visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), - isInline = false, - isExpect = constructor.isExpect, - returnType = constructor.returnTypeRef.toIrType(), - symbol = symbol, - isPrimary = isPrimary, - isExternal = false, - ).apply { - metadata = FirMetadataSource.Function(constructor) - // Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated - // with the annotation itself. - constructorCache[constructor] = this - enterScope(this.symbol) - setAndModifyParent(irParent) - declareParameters(constructor, irParent, dispatchReceiverType = null, isStatic = false, forSetter = false) - leaveScope(this.symbol) - } - } - } - } - fun getOrCreateIrConstructor( constructor: FirConstructor, irParent: IrClass, @@ -865,164 +462,16 @@ class Fir2IrDeclarationStorage( isLocal: Boolean = false, ): IrConstructor { getCachedIrConstructor(constructor)?.let { return it } - return createIrConstructor(constructor, irParent, predefinedOrigin, isLocal) + return callablesGenerator.createIrConstructor(constructor, irParent, predefinedOrigin, isLocal) } - private fun declareIrAccessor( - signature: IdSignature?, - factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction - ): IrSimpleFunction = - if (signature == null) - factory(IrSimpleFunctionSymbolImpl()) - else - symbolTable.declareSimpleFunction(signature, { Fir2IrSimpleFunctionSymbol(signature) }, factory) - - private fun createIrPropertyAccessor( - propertyAccessor: FirPropertyAccessor?, - property: FirProperty, - correspondingProperty: IrDeclarationWithName, - propertyType: IrType, - irParent: IrDeclarationParent?, - isSetter: Boolean, - origin: IrDeclarationOrigin, - startOffset: Int, - endOffset: Int, - dontUseSignature: Boolean = false, - fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, - propertyAccessorForAnnotations: FirPropertyAccessor? = propertyAccessor, - ): IrSimpleFunction = convertCatching(propertyAccessor ?: property) { - val prefix = if (isSetter) "set" else "get" - val signature = - runUnless(dontUseSignature) { - signatureComposer.composeAccessorSignature(property, isSetter, fakeOverrideOwnerLookupTag) - } - val containerSource = (correspondingProperty as? IrProperty)?.containerSource - return declareIrAccessor( - signature - ) { symbol -> - val accessorReturnType = if (isSetter) irBuiltIns.unitType else propertyType - val visibility = propertyAccessor?.visibility?.let { - components.visibilityConverter.convertToDescriptorVisibility(it) - } - irFactory.createSimpleFunction( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = Name.special("<$prefix-${correspondingProperty.name}>"), - visibility = visibility ?: (correspondingProperty as IrDeclarationWithVisibility).visibility, - isInline = propertyAccessor?.isInline == true, - isExpect = false, - returnType = accessorReturnType, - modality = (correspondingProperty as? IrOverridableMember)?.modality ?: Modality.FINAL, - symbol = symbol, - isTailrec = false, - isSuspend = false, - isOperator = false, - isInfix = false, - isExternal = propertyAccessor?.isExternal == true, - containerSource = containerSource, - ).apply { - correspondingPropertySymbol = (correspondingProperty as? IrProperty)?.symbol - if (propertyAccessor != null) { - metadata = FirMetadataSource.Function(propertyAccessor) - // Note that deserialized annotations are stored in the accessor, not the property. - convertAnnotationsForNonDeclaredMembers(propertyAccessor, origin) - } - - if (propertyAccessorForAnnotations != null) { - convertAnnotationsForNonDeclaredMembers(propertyAccessorForAnnotations, origin) - } - with(classifierStorage) { - setTypeParameters( - property, if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT - ) - } - // NB: we should enter accessor' scope before declaring its parameters - // (both setter default and receiver ones, if any) - enterScope(this.symbol) - if (propertyAccessor == null && isSetter) { - declareDefaultSetterParameter( - property.returnTypeRef.toIrType(ConversionTypeOrigin.SETTER), - firValueParameter = null - ) - } - setAndModifyParent(irParent) - val dispatchReceiverType = computeDispatchReceiverType(this, property, irParent) - declareParameters( - propertyAccessor, irParent, dispatchReceiverType, - isStatic = irParent !is IrClass || propertyAccessor?.isStatic == true, forSetter = isSetter, - parentPropertyReceiver = property.receiverParameter, - ) - leaveScope(this.symbol) - if (correspondingProperty is Fir2IrLazyProperty && correspondingProperty.containingClass != null && !isFakeOverride && dispatchReceiverType != null) { - this.overriddenSymbols = correspondingProperty.fir.generateOverriddenAccessorSymbols( - correspondingProperty.containingClass, !isSetter - ) - } - } - } - } - - internal fun IrProperty.createBackingField( - property: FirProperty, - origin: IrDeclarationOrigin, - visibility: DescriptorVisibility, - name: Name, - isFinal: Boolean, - firInitializerExpression: FirExpression?, - type: IrType? = null - ): IrField = convertCatching(property) { - val inferredType = type ?: firInitializerExpression!!.resolvedType.toIrType() - return declareIrField { symbol -> - irFactory.createField( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = name, - visibility = visibility, - symbol = symbol, - type = inferredType, - isFinal = isFinal, - isStatic = property.isStatic || !(parent is IrClass || parent is IrScript), - isExternal = property.isExternal, - ).also { - it.correspondingPropertySymbol = this@createBackingField.symbol - }.apply { - metadata = FirMetadataSource.Property(property) - convertAnnotationsForNonDeclaredMembers(property, origin) - } - } - } - - private val FirProperty.fieldVisibility: Visibility - get() = when { - hasExplicitBackingField -> backingField?.visibility ?: status.visibility - isLateInit -> setter?.visibility ?: status.visibility - isConst -> status.visibility - hasJvmFieldAnnotation(session) -> status.visibility - origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty -> status.visibility - else -> Visibilities.Private - } - - private fun declareIrProperty( - signature: IdSignature?, - factory: (IrPropertySymbol) -> IrProperty - ): IrProperty = - if (signature == null) - factory(IrPropertySymbolImpl()) - else - symbolTable.declareProperty(signature, { Fir2IrPropertySymbol(signature) }, factory) - - private fun declareIrField(factory: (IrFieldSymbol) -> IrField): IrField = - factory(IrFieldSymbolImpl()) - fun getOrCreateIrProperty( property: FirProperty, irParent: IrDeclarationParent?, isLocal: Boolean = false, ): IrProperty { getCachedIrProperty(property)?.let { return it } - return createIrProperty(property, irParent, isLocal = isLocal) + return callablesGenerator.createIrProperty(property, irParent, isLocal = isLocal) } fun getOrCreateIrPropertyByPureField( @@ -1031,7 +480,7 @@ class Fir2IrDeclarationStorage( ): IrProperty { return fieldToPropertyCache.getOrPut(field to irParent) { val containingClassId = (irParent as? IrClass)?.classId - createIrProperty( + callablesGenerator.createIrProperty( field.toStubProperty(), irParent, fakeOverrideOwnerLookupTag = containingClassId?.toLookupTag() @@ -1058,10 +507,6 @@ class Fir2IrDeclarationStorage( } } - private object IsStubPropertyForPureFieldKey : FirDeclarationDataKey() - - private var FirProperty.isStubPropertyForPureField: Boolean? by FirDeclarationDataRegistry.data(IsStubPropertyForPureFieldKey) - fun findGetterOfProperty(propertySymbol: IrPropertySymbol): IrSimpleFunctionSymbol? { return getterForPropertyCache[propertySymbol] } @@ -1090,164 +535,6 @@ class Fir2IrDeclarationStorage( return delegateVariableForPropertyCache.getValue(propertySymbol) } - fun createIrProperty( - property: FirProperty, - irParent: IrDeclarationParent?, - predefinedOrigin: IrDeclarationOrigin? = null, - isLocal: Boolean = false, - fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, - ): IrProperty = convertCatching(property) { - val origin = - if (property.isStatic && property.name in ENUM_SYNTHETIC_NAMES) IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER - else property.computeIrOrigin(predefinedOrigin) - // See similar comments in createIrFunction above - val signature = - runUnless( - isLocal || - !configuration.linkViaSignatures && irParent !is Fir2IrLazyClass && - property.dispatchReceiverType?.isPrimitive != true && property.containerSource == null && - origin != IrDeclarationOrigin.FAKE_OVERRIDE && !property.isOverride - ) { - signatureComposer.composeSignature(property, fakeOverrideOwnerLookupTag) - } - if (irParent is Fir2IrLazyClass && signature != null) { - // For private functions signature is null, fallback to non-lazy property - return createIrLazyProperty(property, signature, irParent, origin) - } - return property.convertWithOffsets { startOffset, endOffset -> - val result = declareIrProperty(signature) { symbol -> - classifierStorage.preCacheTypeParameters(property, symbol) - irFactory.createProperty( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = property.name, - visibility = components.visibilityConverter.convertToDescriptorVisibility(property.visibility), - modality = property.modality!!, - symbol = symbol, - isVar = property.isVar, - isConst = property.isConst, - isLateinit = property.isLateInit, - isDelegated = property.delegate != null, - isExternal = property.isExternal, - containerSource = property.containerSource, - isExpect = property.isExpect, - ).apply { - metadata = FirMetadataSource.Property(property) - convertAnnotationsForNonDeclaredMembers(property, origin) - enterScope(this.symbol) - if (irParent != null) { - parent = irParent - } - val type = property.returnTypeRef.toIrType() - val delegate = property.delegate - val getter = property.getter - val setter = property.setter - if (delegate != null || property.hasBackingField) { - val backingField = if (delegate != null) { - ((delegate as? FirQualifiedAccessExpression)?.calleeReference?.toResolvedBaseSymbol()?.fir as? FirTypeParameterRefsOwner)?.let { - classifierStorage.preCacheTypeParameters(it, symbol) - } - createBackingField( - property, IrDeclarationOrigin.PROPERTY_DELEGATE, - components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), - NameUtils.propertyDelegateName(property.name), true, delegate - ) - } else { - val initializer = getEffectivePropertyInitializer(property, resolveIfNeeded = true) - // There are cases when we get here for properties - // that have no backing field. For example, in the - // funExpression.kt test there's an attempt - // to access the `javaClass` property of the `foo0`'s - // `block` argument - val typeToUse = property.backingField?.returnTypeRef?.toIrType() ?: type - createBackingField( - property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, - components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), - property.name, property.isVal, initializer, typeToUse - ).also { field -> - if (initializer is FirConstExpression<*>) { - val constType = initializer.resolvedType.toIrType() - field.initializer = factory.createExpressionBody(initializer.toIrConst(constType)) - } - } - } - backingField.symbol.let { - backingFieldForPropertyCache[symbol] = it - propertyForBackingFieldCache[it] = symbol - } - this.backingField = backingField - } - if (irParent != null) { - backingField?.parent = irParent - } - this.getter = createIrPropertyAccessor( - getter, property, this, type, irParent, false, - when { - origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin - origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> origin - delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR - origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin - origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin - getter == null || getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR - else -> origin - }, - startOffset, endOffset, - dontUseSignature = signature == null, fakeOverrideOwnerLookupTag, - property.unwrapFakeOverrides().getter, - ).also { - getterForPropertyCache[symbol] = it.symbol - } - if (property.isVar) { - this.setter = createIrPropertyAccessor( - setter, property, this, type, irParent, true, - when { - delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR - origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin - origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin - setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR - else -> origin - }, - startOffset, endOffset, - dontUseSignature = signature == null, fakeOverrideOwnerLookupTag, - property.unwrapFakeOverrides().setter, - ).also { - setterForPropertyCache[symbol] = it.symbol - } - } - leaveScope(this.symbol) - } - } - if (property.isFakeOverride(fakeOverrideOwnerLookupTag)) { - val originalProperty = property.unwrapFakeOverrides() - val key = FakeOverrideIdentifier( - originalProperty.symbol, - fakeOverrideOwnerLookupTag ?: property.containingClassLookupTag()!! - ) - irFakeOverridesForFirFakeOverrideMap[key] = result - } else { - propertyCache[property] = result - } - result - } - } - - /** - * In partial module compilation (see [org.jetbrains.kotlin.analysis.api.fir.components.KtFirCompilerFacility]), - * referenced properties might be resolved only up to [FirResolvePhase.CONTRACTS], - * however the backend requires the exact initializer type. - */ - private fun getEffectivePropertyInitializer(property: FirProperty, resolveIfNeeded: Boolean): FirExpression? { - val initializer = property.backingField?.initializer ?: property.initializer - - if (resolveIfNeeded && initializer is FirConstExpression<*>) { - property.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) - return getEffectivePropertyInitializer(property, resolveIfNeeded = false) - } - - return initializer - } - fun getCachedIrProperty(property: FirProperty): IrProperty? { return getCachedIrProperty(property, fakeOverrideOwnerLookupTag = null) { signatureComposer.composeSignature(property) @@ -1350,19 +637,7 @@ class Fir2IrDeclarationStorage( return fieldStaticOverrideCache[FieldStaticOverrideKey(ownerLookupTag, field.name)] } - fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? { - // Either take a corresponding constructor property backing field, - // or create a separate delegate field - val irField = getOrCreateDelegateIrField(field, owner, irClass) - delegatedMemberGenerator.generate(irField, field, owner, irClass) - if (owner.isLocalClassOrAnonymousObject()) { - delegatedMemberGenerator.generateBodies() - } - // If it's a property backing field, it should not be added to the class in Fir2IrConverter, so it's not returned - return irField.takeIf { it.correspondingPropertySymbol == null } - } - - private fun getOrCreateDelegateIrField(field: FirField, owner: FirClass, irClass: IrClass): IrField { + internal fun getOrCreateDelegateIrField(field: FirField, owner: FirClass, irClass: IrClass): IrField { val initializer = field.initializer if (initializer is FirQualifiedAccessExpression && initializer.explicitReceiver == null) { val resolvedSymbol = initializer.calleeReference.toResolvedValueParameterSymbol() @@ -1379,7 +654,7 @@ class Fir2IrDeclarationStorage( } } } - return createIrField( + return callablesGenerator.createIrField( field, irParent = irClass, type = initializer?.resolvedType ?: field.returnTypeRef.coneType, @@ -1389,64 +664,6 @@ class Fir2IrDeclarationStorage( } } - internal fun createIrField( - field: FirField, - irParent: IrDeclarationParent?, - type: ConeKotlinType = field.returnTypeRef.coneType, - origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB - ): IrField = convertCatching(field) { - val irType = type.toIrType() - val classId = (irParent as? IrClass)?.classId - val containingClassLookupTag = classId?.toLookupTag() - val signature = signatureComposer.composeSignature(field, containingClassLookupTag) - return field.convertWithOffsets { startOffset, endOffset -> - if (signature != null) { - symbolTable.declareField( - signature, symbolFactory = { IrFieldPublicSymbolImpl(signature) } - ) { symbol -> - irFactory.createField( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = field.name, - visibility = components.visibilityConverter.convertToDescriptorVisibility(field.visibility), - symbol = symbol, - type = irType, - isFinal = field.modality == Modality.FINAL, - isStatic = field.isStatic, - isExternal = false - ) - } - } else { - irFactory.createField( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = field.name, - visibility = components.visibilityConverter.convertToDescriptorVisibility(field.visibility), - symbol = IrFieldSymbolImpl(), - type = irType, - isFinal = field.modality == Modality.FINAL, - isStatic = field.isStatic, - isExternal = false - ) - }.apply { - metadata = FirMetadataSource.Field(field) - val staticFakeOverrideKey = getFieldStaticFakeOverrideKey(field, containingClassLookupTag) - if (staticFakeOverrideKey == null) { - fieldCache[field] = this - } else { - fieldStaticOverrideCache[staticFakeOverrideKey] = this - } - val initializer = field.unwrapFakeOverrides().initializer - if (initializer is FirConstExpression<*>) { - this.initializer = factory.createExpressionBody(initializer.toIrConst(irType)) - } - setAndModifyParent(irParent) - } - } - } - // This function returns null if this field/ownerClassId combination does not describe static fake override private fun getFieldStaticFakeOverrideKey(field: FirField, ownerLookupTag: ConeClassLikeLookupTag?): FieldStaticOverrideKey? { if (ownerLookupTag == null || !field.isStatic || @@ -1455,184 +672,6 @@ class Fir2IrDeclarationStorage( return FieldStaticOverrideKey(ownerLookupTag, field.name) } - internal fun createIrParameter( - valueParameter: FirValueParameter, - index: Int = UNDEFINED_PARAMETER_INDEX, - useStubForDefaultValueStub: Boolean = true, - typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT, - skipDefaultParameter: Boolean = false, - // Use this parameter if you want to insert the actual default value instead of the stub (overrides useStubForDefaultValueStub parameter). - // This parameter is intended to be used for default values of annotation parameters where they are needed and - // may produce incorrect results for values that may be encountered outside annotations. - // Does not do anything if valueParameter.defaultValue is already FirExpressionStub. - forcedDefaultValueConversion: Boolean = false, - ): IrValueParameter = convertCatching(valueParameter) { - val origin = valueParameter.computeIrOrigin() - val type = valueParameter.returnTypeRef.toIrType(typeOrigin) - val irParameter = valueParameter.convertWithOffsets { startOffset, endOffset -> - irFactory.createValueParameter( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = valueParameter.name, - type = type, - isAssignable = false, - symbol = IrValueParameterSymbolImpl(), - index = index, - varargElementType = valueParameter.varargElementType?.toIrType(typeOrigin), - isCrossinline = valueParameter.isCrossinline, - isNoinline = valueParameter.isNoinline, - isHidden = false, - ).apply { - val defaultValue = valueParameter.defaultValue - if (!skipDefaultParameter && defaultValue != null) { - this.defaultValue = when { - forcedDefaultValueConversion && defaultValue !is FirExpressionStub -> - defaultValue.asCompileTimeIrInitializer(components) - useStubForDefaultValueStub || defaultValue !is FirExpressionStub -> - factory.createExpressionBody( - IrErrorExpressionImpl( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, - "Stub expression for default value of ${valueParameter.name}" - ) - ) - else -> null - } - } - annotationGenerator.generate(this, valueParameter) - } - } - localStorage.putParameter(valueParameter, irParameter) - return irParameter - } - - private fun createIrParameterFromContextReceiver( - contextReceiver: FirContextReceiver, - index: Int, - ): IrValueParameter = convertCatching(contextReceiver) { - val type = contextReceiver.typeRef.toIrType() - return contextReceiver.convertWithOffsets { startOffset, endOffset -> - irFactory.createValueParameter( - startOffset = startOffset, - endOffset = endOffset, - origin = IrDeclarationOrigin.DEFINED, - name = NameUtils.contextReceiverName(index), - type = type, - isAssignable = false, - symbol = IrValueParameterSymbolImpl(), - index = index, - varargElementType = null, - isCrossinline = false, - isNoinline = false, - isHidden = false, - ) - } - } - - // TODO: KT-58686 - private var lastTemporaryIndex: Int = 0 - private fun nextTemporaryIndex(): Int = lastTemporaryIndex++ - - private fun getNameForTemporary(nameHint: String?): String { - val index = nextTemporaryIndex() - return if (nameHint != null) "tmp${index}_$nameHint" else "tmp$index" - } - - private fun declareIrVariable( - startOffset: Int, endOffset: Int, - origin: IrDeclarationOrigin, name: Name, type: IrType, - isVar: Boolean, isConst: Boolean, isLateinit: Boolean - ): IrVariable = - IrVariableImpl( - startOffset, endOffset, origin, IrVariableSymbolImpl(), name, type, - isVar, isConst, isLateinit - ) - - fun createIrVariable( - variable: FirVariable, - irParent: IrDeclarationParent, - givenOrigin: IrDeclarationOrigin? = null - ): IrVariable = convertCatching(variable) { - val type = variable.irTypeForPotentiallyComponentCall() - // Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them. - val origin = when { - givenOrigin != null -> givenOrigin - variable.name == SpecialNames.ITERATOR -> IrDeclarationOrigin.FOR_LOOP_ITERATOR - variable.name.isSpecial -> IrDeclarationOrigin.IR_TEMPORARY_VARIABLE - else -> IrDeclarationOrigin.DEFINED - } - val isLateInit = if (variable is FirProperty) variable.isLateInit else false - val irVariable = variable.convertWithOffsets { startOffset, endOffset -> - declareIrVariable( - startOffset, endOffset, origin, - variable.name, type, variable.isVar, isConst = false, isLateinit = isLateInit - ) - } - irVariable.parent = irParent - localStorage.putVariable(variable, irVariable) - return irVariable - } - - fun createIrLocalDelegatedProperty( - property: FirProperty, - irParent: IrDeclarationParent - ): IrLocalDelegatedProperty = convertCatching(property) { - val type = property.returnTypeRef.toIrType() - val origin = IrDeclarationOrigin.DEFINED - val symbol = IrLocalDelegatedPropertySymbolImpl() - val irProperty = property.convertWithOffsets { startOffset, endOffset -> - irFactory.createLocalDelegatedProperty( - startOffset = startOffset, - endOffset = endOffset, - origin = origin, - name = property.name, - symbol = symbol, - type = type, - isVar = property.isVar - ) - }.apply { - parent = irParent - metadata = FirMetadataSource.Property(property) - enterScope(this.symbol) - delegate = declareIrVariable( - startOffset, endOffset, IrDeclarationOrigin.PROPERTY_DELEGATE, - NameUtils.propertyDelegateName(property.name), property.delegate!!.resolvedType.toIrType(), - isVar = false, isConst = false, isLateinit = false - ).also { - delegateVariableForPropertyCache[symbol] = it.symbol - } - delegate.parent = irParent - getter = createIrPropertyAccessor( - property.getter, property, this, type, irParent, false, - IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true - ).also { - getterForPropertyCache[symbol] = it.symbol - } - if (property.isVar) { - setter = createIrPropertyAccessor( - property.setter, property, this, type, irParent, true, - IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true - ).also { - setterForPropertyCache[symbol] = it.symbol - } - } - annotationGenerator.generate(this, property) - leaveScope(this.symbol) - } - localStorage.putDelegatedProperty(property, irProperty) - return irProperty - } - - fun declareTemporaryVariable(base: IrExpression, nameHint: String? = null): IrVariable { - return declareIrVariable( - base.startOffset, base.endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE, - Name.identifier(getNameForTemporary(nameHint)), base.type, - isVar = false, isConst = false, isLateinit = false - ).apply { - initializer = base - } - } - fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol { val fir = firConstructorSymbol.fir return getIrCallableSymbol( @@ -1640,7 +679,7 @@ class Fir2IrDeclarationStorage( fakeOverrideOwnerLookupTag = null, getCachedIrDeclaration = { constructor: FirConstructor, _, calculator -> getCachedIrConstructor(constructor, calculator) }, createIrDeclaration = { parent, origin -> - createIrConstructor(fir, parent as IrClass, predefinedOrigin = origin) + callablesGenerator.createIrConstructor(fir, parent as IrClass, predefinedOrigin = origin) }, createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> val symbol = Fir2IrConstructorSymbol(signature) @@ -1672,7 +711,7 @@ class Fir2IrDeclarationStorage( val irParent = findIrParent(fir) val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED val declarationOrigin = computeDeclarationOrigin(firFunctionSymbol, parentOrigin) - createIrFunction(fir, irParent, predefinedOrigin = declarationOrigin).symbol + callablesGenerator.createIrFunction(fir, irParent, predefinedOrigin = declarationOrigin).symbol } is FirSimpleFunction -> { val unmatchedOwner = fakeOverrideOwnerLookupTag != firFunctionSymbol.containingClassLookupTag() @@ -1684,14 +723,14 @@ class Fir2IrDeclarationStorage( fakeOverrideOwnerLookupTag, getCachedIrDeclaration = ::getCachedIrFunction, createIrDeclaration = { parent, origin -> - createIrFunction( + callablesGenerator.createIrFunction( fir, parent, predefinedOrigin = origin, fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag, ) }, createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> - createIrLazyFunction(fir, signature, lazyParent, declarationOrigin) + lazyDeclarationsGenerator.createIrLazyFunction(fir, signature, lazyParent, declarationOrigin) }, ) as IrFunctionSymbol if (unmatchedOwner && fakeOverrideOwnerLookupTag is ConeClassLookupTagWithFixedSymbol) { @@ -1708,29 +747,6 @@ class Fir2IrDeclarationStorage( } } - private fun createIrLazyFunction( - fir: FirSimpleFunction, - signature: IdSignature, - lazyParent: IrDeclarationParent, - declarationOrigin: IrDeclarationOrigin - ): IrSimpleFunction { - val symbol = symbolTable.referenceSimpleFunction(signature) - val irFunction = fir.convertWithOffsets { startOffset, endOffset -> - symbolTable.declareSimpleFunction(signature, { symbol }) { - val isFakeOverride = fir.isSubstitutionOrIntersectionOverride - Fir2IrLazySimpleFunction( - components, startOffset, endOffset, declarationOrigin, - fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol, isFakeOverride - ).apply { - this.parent = lazyParent - } - } - } - functionCache[fir] = irFunction - // NB: this is needed to prevent recursions in case of self bounds - (irFunction as Fir2IrLazySimpleFunction).prepareTypeParameters() - return irFunction - } @OptIn(IrSymbolInternals::class) fun getIrPropertySymbol( @@ -1752,12 +768,12 @@ class Fir2IrDeclarationStorage( fakeOverrideOwnerLookupTag = this, getCachedIrDeclaration = ::getCachedIrProperty, createIrDeclaration = { parent, origin -> - createIrProperty( + callablesGenerator.createIrProperty( fir, parent, predefinedOrigin = origin, fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag, ) }, createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> - createIrLazyProperty(fir, signature, lazyParent, declarationOrigin) + lazyDeclarationsGenerator.createIrLazyProperty(fir, signature, lazyParent, declarationOrigin) }, ) @@ -1785,51 +801,6 @@ class Fir2IrDeclarationStorage( } } - @OptIn(IrSymbolInternals::class) - private fun createIrLazyProperty( - fir: FirProperty, - signature: IdSignature, - lazyParent: IrDeclarationParent, - declarationOrigin: IrDeclarationOrigin - ): IrProperty { - val symbol = Fir2IrPropertySymbol(signature) - val firPropertySymbol = fir.symbol - - fun create(startOffset: Int, endOffset: Int): Fir2IrLazyProperty { - val isFakeOverride = - fir.isSubstitutionOrIntersectionOverride && - firPropertySymbol.dispatchReceiverClassLookupTagOrNull() != - firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassLookupTagOrNull() - return Fir2IrLazyProperty( - components, startOffset, endOffset, declarationOrigin, - fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol, isFakeOverride - ).apply { - this.parent = lazyParent - } - } - - val irProperty = fir.convertWithOffsets { startOffset, endOffset -> - if (fir.isStubPropertyForPureField == true) { - // Very special case when two similar properties can exist so conflicts in SymbolTable are possible. - // See javaCloseFieldAndKotlinProperty.kt in BB tests - symbolTable.declarePropertyWithSignature(signature, symbol) - create(startOffset, endOffset) - symbol.owner - } else { - symbolTable.declareProperty(signature, { symbol }) { - create(startOffset, endOffset) - } - } - } - propertyCache[fir] = irProperty - irProperty.getter?.symbol?.let { getterForPropertyCache[symbol] = it } - irProperty.setter?.symbol?.let { setterForPropertyCache[symbol] = it } - irProperty.backingField?.symbol?.let { - backingFieldForPropertyCache[symbol] = it - propertyForBackingFieldCache[it] = symbol - } - return irProperty - } @OptIn(IrSymbolInternals::class) private inline fun > ConeClassLookupTagWithFixedSymbol.findIrFakeOverride( @@ -1911,7 +882,7 @@ class Fir2IrDeclarationStorage( } } return createIrDeclaration(irParent, declarationOrigin).apply { - (this as IrDeclaration).setAndModifyParent(irParent) + callablesGenerator.setAndModifyParent((this as IrDeclaration), irParent) }.symbol } } @@ -1948,7 +919,7 @@ class Fir2IrDeclarationStorage( if (unwrapped !== fir) { return getIrFieldSymbol(unwrapped.symbol) } - return createIrField(fir, irParent).symbol + return callablesGenerator.createIrField(fir, irParent).symbol } fun getIrBackingFieldSymbol(firBackingFieldSymbol: FirBackingFieldSymbol): IrSymbol { @@ -1986,8 +957,8 @@ class Fir2IrDeclarationStorage( propertyCache[fir]?.let { return it.backingField!!.symbol } val irParent = findIrParent(fir) val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED - createIrProperty(fir, irParent, predefinedOrigin = parentOrigin).apply { - setAndModifyParent(irParent) + callablesGenerator.createIrProperty(fir, irParent, predefinedOrigin = parentOrigin).also { + callablesGenerator.setAndModifyParent(it, irParent) }.backingField!!.symbol } else -> { @@ -2030,15 +1001,6 @@ class Fir2IrDeclarationStorage( } } - private fun IrMutableAnnotationContainer.convertAnnotationsForNonDeclaredMembers( - firAnnotationContainer: FirAnnotationContainer, origin: IrDeclarationOrigin, - ) { - if ((firAnnotationContainer as? FirDeclaration)?.let { it.isFromLibrary || it.isPrecompiled } == true - || origin == IrDeclarationOrigin.FAKE_OVERRIDE - ) { - annotationGenerator.generate(this, firAnnotationContainer) - } - } companion object { internal val ENUM_SYNTHETIC_NAMES = mapOf( @@ -2048,25 +1010,17 @@ class Fir2IrDeclarationStorage( Name.special("") to IrSyntheticBodyKind.ENUM_ENTRIES ) } - - private inline fun convertCatching(element: FirElement, block: () -> R): R { - try { - return block() - } catch (e: ProcessCanceledException) { - throw e - } catch (e: Exception) { - errorWithAttachment("Exception was thrown during transformation of ${element::class.java}", cause = e) { - withFirEntry("element", element) - } - } - } - - private fun FirCallableDeclaration.isFakeOverride(fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?): Boolean { - if (isSubstitutionOrIntersectionOverride) return true - 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 - return fakeOverrideOwnerLookupTag != containingClassLookupTag() - } - } + +internal fun FirCallableDeclaration.isFakeOverride(fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?): Boolean { + if (isSubstitutionOrIntersectionOverride) return true + 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 + return fakeOverrideOwnerLookupTag != containingClassLookupTag() +} + + +private object IsStubPropertyForPureFieldKey : FirDeclarationDataKey() + +internal var FirProperty.isStubPropertyForPureField: Boolean? by FirDeclarationDataRegistry.data(IsStubPropertyForPureFieldKey) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 287cffff51c..28ab41b5e64 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -220,7 +220,11 @@ class Fir2IrVisitor( declarationStorage.enterScope(irScript.symbol) irScript.explicitCallParameters = script.parameters.map { parameter -> - declarationStorage.createIrVariable(parameter, irScript, givenOrigin = IrDeclarationOrigin.SCRIPT_CALL_PARAMETER) + callablesGenerator.createIrVariable( + parameter, + irScript, + givenOrigin = IrDeclarationOrigin.SCRIPT_CALL_PARAMETER + ) } // NOTE: index should correspond to one generated in the collectTowerDataElementsForScript @@ -274,7 +278,7 @@ class Fir2IrVisitor( irBuiltIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION ).also { it.statements.add( - declarationStorage.createIrVariable(statement, conversionScope.parentFromStack()).also { + callablesGenerator.createIrVariable(statement, conversionScope.parentFromStack()).also { it.initializer = statement.initializer?.toIrStatement() as? IrExpression } ) @@ -392,7 +396,7 @@ class Fir2IrVisitor( override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): IrElement = whileAnalysing(session, simpleFunction) { val irFunction = if (simpleFunction.visibility == Visibilities.Local) { - declarationStorage.createIrFunction( + callablesGenerator.createIrFunction( simpleFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, isLocal = true ) } else { @@ -414,7 +418,7 @@ class Fir2IrVisitor( data: Any? ): IrElement = whileAnalysing(session, anonymousFunction) { return anonymousFunction.convertWithOffsets { startOffset, endOffset -> - val irFunction = declarationStorage.createIrFunction( + val irFunction = callablesGenerator.createIrFunction( anonymousFunction, irParent = conversionScope.parent(), predefinedOrigin = IrDeclarationOrigin.LOCAL_FUNCTION, @@ -438,7 +442,7 @@ class Fir2IrVisitor( assert(variable.isLocal) val delegate = variable.delegate if (delegate != null) { - val irProperty = declarationStorage.createIrLocalDelegatedProperty(variable, conversionScope.parentFromStack()) + val irProperty = callablesGenerator.createIrLocalDelegatedProperty(variable, conversionScope.parentFromStack()) irProperty.delegate.initializer = convertToIrExpression(delegate, isDelegate = true) conversionScope.withFunction(irProperty.getter) { memberGenerator.convertFunctionContent(irProperty.getter, variable.getter, null) @@ -454,7 +458,7 @@ class Fir2IrVisitor( val isNextVariable = initializer is FirFunctionCall && initializer.calleeReference.toResolvedNamedFunctionSymbol()?.callableId?.isIteratorNext() == true && variable.source?.isChildOfForLoop == true - val irVariable = declarationStorage.createIrVariable( + val irVariable = callablesGenerator.createIrVariable( variable, conversionScope.parentFromStack(), if (isNextVariable) { if (variable.name.isSpecial && variable.name == SpecialNames.DESTRUCT) { @@ -1260,7 +1264,7 @@ class Fir2IrVisitor( return when { subjectVariable != null -> subjectVariable.accept(this, null) as IrVariable subjectExpression != null -> { - applyParentFromStackTo(declarationStorage.declareTemporaryVariable(convertToIrExpression(subjectExpression), "subject")) + applyParentFromStackTo(callablesGenerator.declareTemporaryVariable(convertToIrExpression(subjectExpression), "subject")) } else -> null } @@ -1419,7 +1423,7 @@ class Fir2IrVisitor( override fun visitCatch(catch: FirCatch, data: Any?): IrElement { return catch.convertWithOffsets { startOffset, endOffset -> - val catchParameter = declarationStorage.createIrVariable( + val catchParameter = callablesGenerator.createIrVariable( catch.parameter, conversionScope.parentFromStack(), IrDeclarationOrigin.CATCH_PARAMETER ) IrCatchImpl(startOffset, endOffset, catchParameter, catch.block.convertToIrBlock(forceUnitType = false)) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt index d89ac524d84..6a4159e44df 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DataClassMembersGenerator.kt @@ -293,7 +293,7 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon isOperator: Boolean = false, ): IrFunction { val signature = if (klass.symbol.classId.isLocal) null else components.signatureComposer.composeSignature(syntheticCounterpart) - return components.declarationStorage.declareIrSimpleFunction(signature) { symbol -> + return components.callablesGenerator.declareIrSimpleFunction(signature) { symbol -> components.irFactory.createSimpleFunction( startOffset = UNDEFINED_OFFSET, endOffset = UNDEFINED_OFFSET, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt index cfd0f9f9ded..ee66a1faf31 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt @@ -206,7 +206,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I delegateOverride: FirSimpleFunction ): IrSimpleFunction { val delegateFunction = - declarationStorage.createIrFunction( + callablesGenerator.createIrFunction( delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER, fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag() ) @@ -297,7 +297,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I firDelegateProperty: FirProperty ): IrProperty { val delegateProperty = - declarationStorage.createIrProperty( + callablesGenerator.createIrProperty( firDelegateProperty, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER, fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag() ) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index 171c04c6411..4efbf7b4ab6 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -122,7 +122,7 @@ class FakeOverrideGenerator( createFakeOverriddenIfNeeded( firClass, irClass, isLocal, functionSymbol, declarationStorage::getCachedIrFunction, - declarationStorage::createIrFunction, + callablesGenerator::createIrFunction, createFakeOverrideSymbol = { firFunction, callableSymbol -> val symbol = FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId) FirFakeOverrideGenerator.createSubstitutionOverrideFunction( @@ -150,7 +150,7 @@ class FakeOverrideGenerator( createFakeOverriddenIfNeeded( firClass, irClass, isLocal, propertyOrFieldSymbol, declarationStorage::getCachedIrProperty, - declarationStorage::createIrProperty, + callablesGenerator::createIrProperty, createFakeOverrideSymbol = { firProperty, callableSymbol -> val symbolForOverride = FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId) @@ -180,7 +180,7 @@ class FakeOverrideGenerator( firClass, irClass, isLocal, propertyOrFieldSymbol, { field, _, _ -> declarationStorage.getCachedIrFieldStaticFakeOverrideByDeclaration(field) }, { field, irParent, _, _ -> - declarationStorage.createIrField(field, irParent) + callablesGenerator.createIrField(field, irParent) }, createFakeOverrideSymbol = { firField, _ -> FirFakeOverrideGenerator.createSubstitutionOverrideField( 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 new file mode 100644 index 00000000000..94688cce164 --- /dev/null +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt @@ -0,0 +1,1020 @@ +/* + * 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.fir.backend.generators + +import com.intellij.openapi.progress.ProcessCanceledException +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.backend.* +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter +import org.jetbrains.kotlin.fir.declarations.utils.* +import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor +import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor +import org.jetbrains.kotlin.fir.expressions.FirConstExpression +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub +import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass +import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty +import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol +import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject +import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke +import org.jetbrains.kotlin.fir.symbols.* +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry +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.impl.IrExternalPackageFragmentImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.impl.* +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.NameUtils +import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.utils.addToStdlib.runUnless +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment + +class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components { + internal fun createExternalPackageFragment(fqName: FqName, moduleDescriptor: FirModuleDescriptor): IrExternalPackageFragment { + return createExternalPackageFragment(FirPackageFragmentDescriptor(fqName, moduleDescriptor)) + } + + internal fun createExternalPackageFragment(packageFragmentDescriptor: PackageFragmentDescriptor): IrExternalPackageFragment { + val symbol = IrExternalPackageFragmentSymbolImpl(packageFragmentDescriptor) + return IrExternalPackageFragmentImpl(symbol, packageFragmentDescriptor.fqName) + } + + /** + * [firCallable] is function or property (if [irFunction] is a property accessor) for + * which [irFunction] was build + * + * It is needed to determine proper dispatch receiver type if this declaration is fake-override + */ + private fun computeDispatchReceiverType( + irFunction: IrSimpleFunction, + firCallable: FirCallableDeclaration?, + parent: IrDeclarationParent?, + ): IrType? { + /* + * If some function is not fake-override, then its type should be just + * default type of containing class + * For fake overrides the default type calculated in the following way: + * 1. Find first overridden function, which is not fake override + * 2. Take its containing class + * 3. Find supertype of current containing class with type constructor of + * class from step 2 + */ + if (firCallable is FirProperty && firCallable.isLocal) return null + val containingClass = computeContainingClass(parent) ?: return null + val defaultType = containingClass.defaultType + if (firCallable == null) return defaultType + if (irFunction.origin != IrDeclarationOrigin.FAKE_OVERRIDE) return defaultType + + val originalCallable = firCallable.unwrapFakeOverrides() + val containerOfOriginalCallable = originalCallable.containingClassLookupTag() ?: return defaultType + val containerOfFakeOverride = firCallable.dispatchReceiverType ?: return defaultType + val correspondingSupertype = AbstractTypeChecker.findCorrespondingSupertypes( + session.typeContext.newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false), + containerOfFakeOverride, + containerOfOriginalCallable + ).firstOrNull() as ConeKotlinType? ?: return defaultType + return correspondingSupertype.toIrType() + } + + private fun computeContainingClass(parent: IrDeclarationParent?): IrClass? { + return if (parent is IrClass && parent !is Fir2IrDeclarationStorage.NonCachedSourceFileFacadeClass) { + parent + } else { + null + } + } + + fun setAndModifyParent(declaration: IrDeclaration, irParent: IrDeclarationParent?) { + if (irParent != null) { + declaration.parent = irParent + if (irParent is IrExternalPackageFragment) { + irParent.declarations += declaration + } + } + } + + private fun T.declareDefaultSetterParameter(type: IrType, firValueParameter: FirValueParameter?): T { + valueParameters = listOf( + createDefaultSetterParameter(startOffset, endOffset, type, parent = this, firValueParameter) + ) + return this + } + + internal fun createDefaultSetterParameter( + startOffset: Int, + endOffset: Int, + type: IrType, + parent: IrFunction, + firValueParameter: FirValueParameter?, + name: Name? = null, + isCrossinline: Boolean = false, + isNoinline: Boolean = false, + ): IrValueParameter { + return irFactory.createValueParameter( + startOffset = startOffset, + endOffset = endOffset, + origin = IrDeclarationOrigin.DEFINED, + name = name ?: SpecialNames.IMPLICIT_SET_PARAMETER, + type = type, + isAssignable = false, + symbol = IrValueParameterSymbolImpl(), + index = parent.contextReceiverParametersCount, + varargElementType = null, + isCrossinline = isCrossinline, + isNoinline = isNoinline, + isHidden = false, + ).apply { + this.parent = parent + if (firValueParameter != null) { + annotationGenerator.generate(this, firValueParameter) + } + } + } + + fun addContextReceiverParametersTo( + contextReceivers: List, + parent: IrFunction, + result: MutableList, + ) { + contextReceivers.mapIndexedTo(result) { index, contextReceiver -> + createIrParameterFromContextReceiver(contextReceiver, index).apply { + this.parent = parent + } + } + } + + /* + * In perfect world dispatchReceiverType should always be the default type of containing class + * But fake-overrides for members from Any have special rules for type of dispatch receiver + */ + private fun IrFunction.declareParameters( + function: FirFunction?, + irParent: IrDeclarationParent?, + dispatchReceiverType: IrType?, // has no sense for constructors + isStatic: Boolean, + forSetter: Boolean, + // Can be not-null only for property accessors + parentPropertyReceiver: FirReceiverParameter? = null + ) { + val containingClass = computeContainingClass(irParent) + val parent = this + if (function is FirSimpleFunction || function is FirConstructor) { + with(classifierStorage) { + setTypeParameters(function) + } + } + val typeOrigin = if (forSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT + if (function is FirDefaultPropertySetter) { + val valueParameter = function.valueParameters.first() + val type = valueParameter.returnTypeRef.toIrType(ConversionTypeOrigin.SETTER) + declareDefaultSetterParameter(type, valueParameter) + } else if (function != null) { + val contextReceivers = function.contextReceiversForFunctionOrContainingProperty() + + contextReceiverParametersCount = contextReceivers.size + valueParameters = buildList { + addContextReceiverParametersTo(contextReceivers, parent, this) + + function.valueParameters.mapIndexedTo(this) { index, valueParameter -> + createIrParameter( + valueParameter, index + contextReceiverParametersCount, + useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum"), + typeOrigin, + skipDefaultParameter = isFakeOverride || origin == IrDeclarationOrigin.DELEGATED_MEMBER + ).apply { + this.parent = parent + } + } + } + } + + val thisOrigin = IrDeclarationOrigin.DEFINED + if (function !is FirConstructor) { + val receiver: FirReceiverParameter? = + if (function !is FirPropertyAccessor && function != null) function.receiverParameter + else parentPropertyReceiver + if (receiver != null) { + extensionReceiverParameter = receiver.convertWithOffsets { startOffset, endOffset -> + val name = (function as? FirAnonymousFunction)?.label?.name?.let { + val suffix = it.takeIf(Name::isValidIdentifier) ?: "\$receiver" + Name.identifier("\$this\$$suffix") + } ?: SpecialNames.THIS + declareThisReceiverParameter( + thisType = receiver.typeRef.toIrType(typeOrigin), + thisOrigin = thisOrigin, + startOffset = startOffset, + endOffset = endOffset, + name = name, + explicitReceiver = receiver, + ) + } + } + // See [LocalDeclarationsLowering]: "local function must not have dispatch receiver." + val isLocal = function is FirSimpleFunction && function.isLocal + if (function !is FirAnonymousFunction && dispatchReceiverType != null && !isStatic && !isLocal) { + dispatchReceiverParameter = declareThisReceiverParameter( + thisType = dispatchReceiverType, + thisOrigin = thisOrigin + ) + } + } else { + // Set dispatch receiver parameter for inner class's constructor. + val outerClass = containingClass?.parentClassOrNull + if (containingClass?.isInner == true && outerClass != null) { + dispatchReceiverParameter = declareThisReceiverParameter( + thisType = outerClass.thisReceiver!!.type, + thisOrigin = thisOrigin + ) + } + } + } + + internal fun declareIrSimpleFunction( + signature: IdSignature?, + factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction + ): IrSimpleFunction = + if (signature == null) { + factory(IrSimpleFunctionSymbolImpl()) + } else { + symbolTable.declareSimpleFunction(signature, { Fir2IrSimpleFunctionSymbol(signature) }, factory) + } + + fun createIrFunction( + function: FirFunction, + irParent: IrDeclarationParent?, + predefinedOrigin: IrDeclarationOrigin? = null, + isLocal: Boolean = false, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, + ): IrSimpleFunction = convertCatching(function) { + val simpleFunction = function as? FirSimpleFunction + val isLambda = function is FirAnonymousFunction && function.isLambda + val updatedOrigin = when { + isLambda -> IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA + function.symbol.callableId.isKFunctionInvoke() -> IrDeclarationOrigin.FAKE_OVERRIDE + simpleFunction?.isStatic == true && simpleFunction.name in Fir2IrDeclarationStorage.ENUM_SYNTHETIC_NAMES -> IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER + + // Kotlin built-in class and Java originated method (Collection.forEach, etc.) + // It's necessary to understand that such methods do not belong to DefaultImpls but actually generated as default + // 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) + } + // We don't generate signatures for local classes + // We attempt to avoid signature generation for non-local classes, with the following exceptions: + // - special mode (generateSignatures) oriented on special backend modes + // - lazy classes (they still use signatures) + // - primitive types (they can be from built-ins and don't have FIR counterpart) + // - overrides and fake overrides (sometimes we perform "receiver replacement" in FIR2IR breaking FIR->IR relation, + // or FIR counterpart can be just created on the fly) + val signature = + runUnless( + isLocal || + !configuration.linkViaSignatures && irParent !is Fir2IrLazyClass && + function.dispatchReceiverType?.isPrimitive != true && function.containerSource == null && + updatedOrigin != IrDeclarationOrigin.FAKE_OVERRIDE && !function.isOverride + ) { + signatureComposer.composeSignature(function, fakeOverrideOwnerLookupTag) + } + if (irParent is Fir2IrLazyClass && signature != null) { + // For private functions signature is null, fallback to non-lazy function + return lazyDeclarationsGenerator.createIrLazyFunction(function as FirSimpleFunction, signature, irParent, updatedOrigin) + } + val name = simpleFunction?.name + ?: if (isLambda) SpecialNames.ANONYMOUS else SpecialNames.NO_NAME_PROVIDED + val visibility = simpleFunction?.visibility ?: Visibilities.Local + val isSuspend = + if (isLambda) ((function as FirAnonymousFunction).typeRef as? FirResolvedTypeRef)?.type?.isSuspendOrKSuspendFunctionType(session) == true + else function.isSuspend + val created = function.convertWithOffsets { startOffset, endOffset -> + val result = declareIrSimpleFunction(signature) { symbol -> + classifierStorage.preCacheTypeParameters(function, symbol) + irFactory.createSimpleFunction( + startOffset = if (updatedOrigin == IrDeclarationOrigin.DELEGATED_MEMBER) SYNTHETIC_OFFSET else startOffset, + endOffset = if (updatedOrigin == IrDeclarationOrigin.DELEGATED_MEMBER) SYNTHETIC_OFFSET else endOffset, + origin = updatedOrigin, + name = name, + visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), + isInline = simpleFunction?.isInline == true, + isExpect = simpleFunction?.isExpect == true, + returnType = function.returnTypeRef.toIrType(), + modality = simpleFunction?.modality ?: Modality.FINAL, + symbol = symbol, + isTailrec = simpleFunction?.isTailRec == true, + isSuspend = isSuspend, + isOperator = simpleFunction?.isOperator == true, + isInfix = simpleFunction?.isInfix == true, + isExternal = simpleFunction?.isExternal == true, + containerSource = simpleFunction?.containerSource, + ).apply { + metadata = FirMetadataSource.Function(function) + enterScope(this.symbol) + setAndModifyParent(this, irParent) + declareParameters( + function, irParent, + dispatchReceiverType = computeDispatchReceiverType(this, simpleFunction, irParent), + isStatic = simpleFunction?.isStatic == true, + forSetter = false, + ) + convertAnnotationsForNonDeclaredMembers(function, origin) + leaveScope(this.symbol) + } + } + result + } + + if (visibility == Visibilities.Local) { + localStorage.putLocalFunction(function, created) + return created + } + if (function.symbol.callableId.isKFunctionInvoke()) { + (function.symbol.originalForSubstitutionOverride as? FirNamedFunctionSymbol)?.let { + created.overriddenSymbols += declarationStorage.getIrFunctionSymbol(it) as IrSimpleFunctionSymbol + } + } + if (function.isFakeOverride(fakeOverrideOwnerLookupTag)) { + val originalFunction = function.unwrapFakeOverrides() + val key = Fir2IrDeclarationStorage.FakeOverrideIdentifier( + originalFunction.symbol, + fakeOverrideOwnerLookupTag ?: function.containingClassLookupTag()!! + ) + irFakeOverridesForFirFakeOverrideMap[key] = created + } else { + functionCache[function] = created + } + return created + } + + fun createIrAnonymousInitializer( + anonymousInitializer: FirAnonymousInitializer, + irParent: IrClass + ): IrAnonymousInitializer = convertCatching(anonymousInitializer) { + return anonymousInitializer.convertWithOffsets { startOffset, endOffset -> + symbolTable.descriptorExtension.declareAnonymousInitializer( + startOffset, + endOffset, + IrDeclarationOrigin.DEFINED, + irParent.descriptor + ).apply { + this.parent = irParent + initializerCache[anonymousInitializer] = this + } + } + } + + private fun declareIrConstructor(signature: IdSignature?, factory: (IrConstructorSymbol) -> IrConstructor): IrConstructor = + if (signature == null) + factory(IrConstructorSymbolImpl()) + else + symbolTable.declareConstructor(signature, { Fir2IrConstructorSymbol(signature) }, factory) + + + fun createIrConstructor( + constructor: FirConstructor, + irParent: IrClass, + predefinedOrigin: IrDeclarationOrigin? = null, + isLocal: Boolean = false, + ): IrConstructor = convertCatching(constructor) { + val origin = constructor.computeIrOrigin(predefinedOrigin) + val isPrimary = constructor.isPrimary + val signature = + runUnless(isLocal || !configuration.linkViaSignatures) { + signatureComposer.composeSignature(constructor) + } + val visibility = if (irParent.isAnonymousObject) Visibilities.Public else constructor.visibility + return constructor.convertWithOffsets { startOffset, endOffset -> + declareIrConstructor(signature) { symbol -> + classifierStorage.preCacheTypeParameters(constructor, symbol) + irFactory.createConstructor( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = SpecialNames.INIT, + visibility = components.visibilityConverter.convertToDescriptorVisibility(visibility), + isInline = false, + isExpect = constructor.isExpect, + returnType = constructor.returnTypeRef.toIrType(), + symbol = symbol, + isPrimary = isPrimary, + isExternal = false, + ).apply { + metadata = FirMetadataSource.Function(constructor) + // Add to cache before generating parameters to prevent an infinite loop when an annotation value parameter is annotated + // with the annotation itself. + constructorCache[constructor] = this + enterScope(this.symbol) + setAndModifyParent(this, irParent) + declareParameters(constructor, irParent, dispatchReceiverType = null, isStatic = false, forSetter = false) + leaveScope(this.symbol) + } + } + } + } + + private fun declareIrAccessor( + signature: IdSignature?, + factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction + ): IrSimpleFunction = + if (signature == null) + factory(IrSimpleFunctionSymbolImpl()) + else + symbolTable.declareSimpleFunction(signature, { Fir2IrSimpleFunctionSymbol(signature) }, factory) + + private fun createIrPropertyAccessor( + propertyAccessor: FirPropertyAccessor?, + property: FirProperty, + correspondingProperty: IrDeclarationWithName, + propertyType: IrType, + irParent: IrDeclarationParent?, + isSetter: Boolean, + origin: IrDeclarationOrigin, + startOffset: Int, + endOffset: Int, + dontUseSignature: Boolean = false, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, + propertyAccessorForAnnotations: FirPropertyAccessor? = propertyAccessor, + ): IrSimpleFunction = convertCatching(propertyAccessor ?: property) { + val prefix = if (isSetter) "set" else "get" + val signature = + runUnless(dontUseSignature) { + signatureComposer.composeAccessorSignature(property, isSetter, fakeOverrideOwnerLookupTag) + } + val containerSource = (correspondingProperty as? IrProperty)?.containerSource + return declareIrAccessor( + signature + ) { symbol -> + val accessorReturnType = if (isSetter) irBuiltIns.unitType else propertyType + val visibility = propertyAccessor?.visibility?.let { + components.visibilityConverter.convertToDescriptorVisibility(it) + } + irFactory.createSimpleFunction( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = Name.special("<$prefix-${correspondingProperty.name}>"), + visibility = visibility ?: (correspondingProperty as IrDeclarationWithVisibility).visibility, + isInline = propertyAccessor?.isInline == true, + isExpect = false, + returnType = accessorReturnType, + modality = (correspondingProperty as? IrOverridableMember)?.modality ?: Modality.FINAL, + symbol = symbol, + isTailrec = false, + isSuspend = false, + isOperator = false, + isInfix = false, + isExternal = propertyAccessor?.isExternal == true, + containerSource = containerSource, + ).apply { + correspondingPropertySymbol = (correspondingProperty as? IrProperty)?.symbol + if (propertyAccessor != null) { + metadata = FirMetadataSource.Function(propertyAccessor) + // Note that deserialized annotations are stored in the accessor, not the property. + convertAnnotationsForNonDeclaredMembers(propertyAccessor, origin) + } + + if (propertyAccessorForAnnotations != null) { + convertAnnotationsForNonDeclaredMembers(propertyAccessorForAnnotations, origin) + } + with(classifierStorage) { + setTypeParameters( + property, if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT + ) + } + // NB: we should enter accessor' scope before declaring its parameters + // (both setter default and receiver ones, if any) + enterScope(this.symbol) + if (propertyAccessor == null && isSetter) { + declareDefaultSetterParameter( + property.returnTypeRef.toIrType(ConversionTypeOrigin.SETTER), + firValueParameter = null + ) + } + setAndModifyParent(this, irParent) + val dispatchReceiverType = computeDispatchReceiverType(this, property, irParent) + declareParameters( + propertyAccessor, irParent, dispatchReceiverType, + isStatic = irParent !is IrClass || propertyAccessor?.isStatic == true, forSetter = isSetter, + parentPropertyReceiver = property.receiverParameter, + ) + leaveScope(this.symbol) + if (correspondingProperty is Fir2IrLazyProperty && correspondingProperty.containingClass != null && !isFakeOverride && dispatchReceiverType != null) { + this.overriddenSymbols = correspondingProperty.fir.generateOverriddenAccessorSymbols( + correspondingProperty.containingClass, !isSetter + ) + } + } + } + } + + internal fun createBackingField( + irProperty: IrProperty, + firProperty: FirProperty, + origin: IrDeclarationOrigin, + visibility: DescriptorVisibility, + name: Name, + isFinal: Boolean, + firInitializerExpression: FirExpression?, + type: IrType? = null + ): IrField = convertCatching(firProperty) { + val inferredType = type ?: firInitializerExpression!!.resolvedType.toIrType() + return declareIrField { symbol -> + irFactory.createField( + startOffset = irProperty.startOffset, + endOffset = irProperty.endOffset, + origin = origin, + name = name, + visibility = visibility, + symbol = symbol, + type = inferredType, + isFinal = isFinal, + isStatic = firProperty.isStatic || !(irProperty.parent is IrClass || irProperty.parent is IrScript), + isExternal = firProperty.isExternal, + ).also { + it.correspondingPropertySymbol = irProperty.symbol + }.apply { + metadata = FirMetadataSource.Property(firProperty) + convertAnnotationsForNonDeclaredMembers(firProperty, origin) + } + } + } + + private val FirProperty.fieldVisibility: Visibility + get() = when { + hasExplicitBackingField -> backingField?.visibility ?: status.visibility + isLateInit -> setter?.visibility ?: status.visibility + isConst -> status.visibility + hasJvmFieldAnnotation(session) -> status.visibility + origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty -> status.visibility + else -> Visibilities.Private + } + + private fun declareIrProperty( + signature: IdSignature?, + factory: (IrPropertySymbol) -> IrProperty + ): IrProperty = + if (signature == null) + factory(IrPropertySymbolImpl()) + else + symbolTable.declareProperty(signature, { Fir2IrPropertySymbol(signature) }, factory) + + private fun declareIrField(factory: (IrFieldSymbol) -> IrField): IrField = + factory(IrFieldSymbolImpl()) + + fun createIrProperty( + property: FirProperty, + irParent: IrDeclarationParent?, + predefinedOrigin: IrDeclarationOrigin? = null, + isLocal: Boolean = false, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, + ): IrProperty = convertCatching(property) { + val origin = + if (property.isStatic && property.name in Fir2IrDeclarationStorage.ENUM_SYNTHETIC_NAMES) IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER + else property.computeIrOrigin(predefinedOrigin) + // See similar comments in createIrFunction above + val signature = + runUnless( + isLocal || + !configuration.linkViaSignatures && irParent !is Fir2IrLazyClass && + property.dispatchReceiverType?.isPrimitive != true && property.containerSource == null && + origin != IrDeclarationOrigin.FAKE_OVERRIDE && !property.isOverride + ) { + signatureComposer.composeSignature(property, fakeOverrideOwnerLookupTag) + } + if (irParent is Fir2IrLazyClass && signature != null) { + // For private functions signature is null, fallback to non-lazy property + return lazyDeclarationsGenerator.createIrLazyProperty(property, signature, irParent, origin) + } + return property.convertWithOffsets { startOffset, endOffset -> + val result = declareIrProperty(signature) { symbol -> + classifierStorage.preCacheTypeParameters(property, symbol) + irFactory.createProperty( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = property.name, + visibility = components.visibilityConverter.convertToDescriptorVisibility(property.visibility), + modality = property.modality!!, + symbol = symbol, + isVar = property.isVar, + isConst = property.isConst, + isLateinit = property.isLateInit, + isDelegated = property.delegate != null, + isExternal = property.isExternal, + containerSource = property.containerSource, + isExpect = property.isExpect, + ).apply { + metadata = FirMetadataSource.Property(property) + convertAnnotationsForNonDeclaredMembers(property, origin) + enterScope(this.symbol) + if (irParent != null) { + parent = irParent + } + val type = property.returnTypeRef.toIrType() + val delegate = property.delegate + val getter = property.getter + val setter = property.setter + if (delegate != null || property.hasBackingField) { + val backingField = if (delegate != null) { + ((delegate as? FirQualifiedAccessExpression)?.calleeReference?.toResolvedBaseSymbol()?.fir as? FirTypeParameterRefsOwner)?.let { + classifierStorage.preCacheTypeParameters(it, symbol) + } + createBackingField( + this, + property, + IrDeclarationOrigin.PROPERTY_DELEGATE, + components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), + NameUtils.propertyDelegateName(property.name), + true, + delegate + ) + } else { + val initializer = getEffectivePropertyInitializer(property, resolveIfNeeded = true) + // There are cases when we get here for properties + // that have no backing field. For example, in the + // funExpression.kt test there's an attempt + // to access the `javaClass` property of the `foo0`'s + // `block` argument + val typeToUse = property.backingField?.returnTypeRef?.toIrType() ?: type + createBackingField( + this, + property, + IrDeclarationOrigin.PROPERTY_BACKING_FIELD, + components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), + property.name, + property.isVal, + initializer, + typeToUse + ).also { field -> + if (initializer is FirConstExpression<*>) { + val constType = initializer.resolvedType.toIrType() + field.initializer = factory.createExpressionBody(initializer.toIrConst(constType)) + } + } + } + backingField.symbol.let { + backingFieldForPropertyCache[symbol] = it + propertyForBackingFieldCache[it] = symbol + } + this.backingField = backingField + } + if (irParent != null) { + backingField?.parent = irParent + } + this.getter = createIrPropertyAccessor( + getter, property, this, type, irParent, false, + when { + origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin + origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> origin + delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR + origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin + origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin + getter == null || getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR + else -> origin + }, + startOffset, endOffset, + dontUseSignature = signature == null, fakeOverrideOwnerLookupTag, + property.unwrapFakeOverrides().getter, + ).also { + getterForPropertyCache[symbol] = it.symbol + } + if (property.isVar) { + this.setter = createIrPropertyAccessor( + setter, property, this, type, irParent, true, + when { + delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR + origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin + origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin + setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR + else -> origin + }, + startOffset, endOffset, + dontUseSignature = signature == null, fakeOverrideOwnerLookupTag, + property.unwrapFakeOverrides().setter, + ).also { + setterForPropertyCache[symbol] = it.symbol + } + } + leaveScope(this.symbol) + } + } + if (property.isFakeOverride(fakeOverrideOwnerLookupTag)) { + val originalProperty = property.unwrapFakeOverrides() + val key = Fir2IrDeclarationStorage.FakeOverrideIdentifier( + originalProperty.symbol, + fakeOverrideOwnerLookupTag ?: property.containingClassLookupTag()!! + ) + irFakeOverridesForFirFakeOverrideMap[key] = result + } else { + propertyCache[property] = result + } + result + } + } + + /** + * In partial module compilation (see [org.jetbrains.kotlin.analysis.api.fir.components.KtFirCompilerFacility]), + * referenced properties might be resolved only up to [FirResolvePhase.CONTRACTS], + * however the backend requires the exact initializer type. + */ + private fun getEffectivePropertyInitializer(property: FirProperty, resolveIfNeeded: Boolean): FirExpression? { + val initializer = property.backingField?.initializer ?: property.initializer + + if (resolveIfNeeded && initializer is FirConstExpression<*>) { + property.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) + return getEffectivePropertyInitializer(property, resolveIfNeeded = false) + } + + return initializer + } + + fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? { + // Either take a corresponding constructor property backing field, + // or create a separate delegate field + val irField = declarationStorage.getOrCreateDelegateIrField(field, owner, irClass) + delegatedMemberGenerator.generate(irField, field, owner, irClass) + if (owner.isLocalClassOrAnonymousObject()) { + delegatedMemberGenerator.generateBodies() + } + // If it's a property backing field, it should not be added to the class in Fir2IrConverter, so it's not returned + return irField.takeIf { it.correspondingPropertySymbol == null } + } + + internal fun createIrField( + field: FirField, + irParent: IrDeclarationParent?, + type: ConeKotlinType = field.returnTypeRef.coneType, + origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB + ): IrField = convertCatching(field) { + val irType = type.toIrType() + val classId = (irParent as? IrClass)?.classId + val containingClassLookupTag = classId?.toLookupTag() + val signature = signatureComposer.composeSignature(field, containingClassLookupTag) + return field.convertWithOffsets { startOffset, endOffset -> + if (signature != null) { + symbolTable.declareField( + signature, symbolFactory = { IrFieldPublicSymbolImpl(signature) } + ) { symbol -> + irFactory.createField( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = field.name, + visibility = components.visibilityConverter.convertToDescriptorVisibility(field.visibility), + symbol = symbol, + type = irType, + isFinal = field.modality == Modality.FINAL, + isStatic = field.isStatic, + isExternal = false + ) + } + } else { + irFactory.createField( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = field.name, + visibility = components.visibilityConverter.convertToDescriptorVisibility(field.visibility), + symbol = IrFieldSymbolImpl(), + type = irType, + isFinal = field.modality == Modality.FINAL, + isStatic = field.isStatic, + isExternal = false + ) + }.apply { + metadata = FirMetadataSource.Field(field) + val staticFakeOverrideKey = getFieldStaticFakeOverrideKey(field, containingClassLookupTag) + if (staticFakeOverrideKey == null) { + fieldCache[field] = this + } else { + fieldStaticOverrideCache[staticFakeOverrideKey] = this + } + val initializer = field.unwrapFakeOverrides().initializer + if (initializer is FirConstExpression<*>) { + this.initializer = factory.createExpressionBody(initializer.toIrConst(irType)) + } + setAndModifyParent(this, irParent) + } + } + } + + internal fun createIrParameter( + valueParameter: FirValueParameter, + index: Int = UNDEFINED_PARAMETER_INDEX, + useStubForDefaultValueStub: Boolean = true, + typeOrigin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT, + skipDefaultParameter: Boolean = false, + // Use this parameter if you want to insert the actual default value instead of the stub (overrides useStubForDefaultValueStub parameter). + // This parameter is intended to be used for default values of annotation parameters where they are needed and + // may produce incorrect results for values that may be encountered outside annotations. + // Does not do anything if valueParameter.defaultValue is already FirExpressionStub. + forcedDefaultValueConversion: Boolean = false, + ): IrValueParameter = convertCatching(valueParameter) { + val origin = valueParameter.computeIrOrigin() + val type = valueParameter.returnTypeRef.toIrType(typeOrigin) + val irParameter = valueParameter.convertWithOffsets { startOffset, endOffset -> + irFactory.createValueParameter( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = valueParameter.name, + type = type, + isAssignable = false, + symbol = IrValueParameterSymbolImpl(), + index = index, + varargElementType = valueParameter.varargElementType?.toIrType(typeOrigin), + isCrossinline = valueParameter.isCrossinline, + isNoinline = valueParameter.isNoinline, + isHidden = false, + ).apply { + val defaultValue = valueParameter.defaultValue + if (!skipDefaultParameter && defaultValue != null) { + this.defaultValue = when { + forcedDefaultValueConversion && defaultValue !is FirExpressionStub -> + defaultValue.asCompileTimeIrInitializer(components) + useStubForDefaultValueStub || defaultValue !is FirExpressionStub -> + factory.createExpressionBody( + IrErrorExpressionImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, + "Stub expression for default value of ${valueParameter.name}" + ) + ) + else -> null + } + } + annotationGenerator.generate(this, valueParameter) + } + } + localStorage.putParameter(valueParameter, irParameter) + return irParameter + } + + private fun createIrParameterFromContextReceiver( + contextReceiver: FirContextReceiver, + index: Int, + ): IrValueParameter = convertCatching(contextReceiver) { + val type = contextReceiver.typeRef.toIrType() + return contextReceiver.convertWithOffsets { startOffset, endOffset -> + irFactory.createValueParameter( + startOffset = startOffset, + endOffset = endOffset, + origin = IrDeclarationOrigin.DEFINED, + name = NameUtils.contextReceiverName(index), + type = type, + isAssignable = false, + symbol = IrValueParameterSymbolImpl(), + index = index, + varargElementType = null, + isCrossinline = false, + isNoinline = false, + isHidden = false, + ) + } + } + + // TODO: KT-58686 + private var lastTemporaryIndex: Int = 0 + private fun nextTemporaryIndex(): Int = lastTemporaryIndex++ + + private fun getNameForTemporary(nameHint: String?): String { + val index = nextTemporaryIndex() + return if (nameHint != null) "tmp${index}_$nameHint" else "tmp$index" + } + + private fun declareIrVariable( + startOffset: Int, endOffset: Int, + origin: IrDeclarationOrigin, name: Name, type: IrType, + isVar: Boolean, isConst: Boolean, isLateinit: Boolean + ): IrVariable = + IrVariableImpl( + startOffset, endOffset, origin, IrVariableSymbolImpl(), name, type, + isVar, isConst, isLateinit + ) + + fun createIrVariable( + variable: FirVariable, + irParent: IrDeclarationParent, + givenOrigin: IrDeclarationOrigin? = null + ): IrVariable = convertCatching(variable) { + val type = variable.irTypeForPotentiallyComponentCall() + // Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them. + val origin = when { + givenOrigin != null -> givenOrigin + variable.name == SpecialNames.ITERATOR -> IrDeclarationOrigin.FOR_LOOP_ITERATOR + variable.name.isSpecial -> IrDeclarationOrigin.IR_TEMPORARY_VARIABLE + else -> IrDeclarationOrigin.DEFINED + } + val isLateInit = if (variable is FirProperty) variable.isLateInit else false + val irVariable = variable.convertWithOffsets { startOffset, endOffset -> + declareIrVariable( + startOffset, endOffset, origin, + variable.name, type, variable.isVar, isConst = false, isLateinit = isLateInit + ) + } + irVariable.parent = irParent + localStorage.putVariable(variable, irVariable) + return irVariable + } + + fun createIrLocalDelegatedProperty( + property: FirProperty, + irParent: IrDeclarationParent + ): IrLocalDelegatedProperty = convertCatching(property) { + val type = property.returnTypeRef.toIrType() + val origin = IrDeclarationOrigin.DEFINED + val symbol = IrLocalDelegatedPropertySymbolImpl() + val irProperty = property.convertWithOffsets { startOffset, endOffset -> + irFactory.createLocalDelegatedProperty( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = property.name, + symbol = symbol, + type = type, + isVar = property.isVar + ) + }.apply { + parent = irParent + metadata = FirMetadataSource.Property(property) + enterScope(this.symbol) + delegate = declareIrVariable( + startOffset, endOffset, IrDeclarationOrigin.PROPERTY_DELEGATE, + NameUtils.propertyDelegateName(property.name), property.delegate!!.resolvedType.toIrType(), + isVar = false, isConst = false, isLateinit = false + ).also { + delegateVariableForPropertyCache[symbol] = it.symbol + } + delegate.parent = irParent + getter = createIrPropertyAccessor( + property.getter, property, this, type, irParent, false, + IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true + ).also { + getterForPropertyCache[symbol] = it.symbol + } + if (property.isVar) { + setter = createIrPropertyAccessor( + property.setter, property, this, type, irParent, true, + IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true + ).also { + setterForPropertyCache[symbol] = it.symbol + } + } + annotationGenerator.generate(this, property) + leaveScope(this.symbol) + } + localStorage.putDelegatedProperty(property, irProperty) + return irProperty + } + + fun declareTemporaryVariable(base: IrExpression, nameHint: String? = null): IrVariable { + return declareIrVariable( + base.startOffset, base.endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE, + Name.identifier(getNameForTemporary(nameHint)), base.type, + isVar = false, isConst = false, isLateinit = false + ).apply { + initializer = base + } + } + + private fun IrMutableAnnotationContainer.convertAnnotationsForNonDeclaredMembers( + firAnnotationContainer: FirAnnotationContainer, origin: IrDeclarationOrigin, + ) { + if ((firAnnotationContainer as? FirDeclaration)?.let { it.isFromLibrary || it.isPrecompiled } == true + || origin == IrDeclarationOrigin.FAKE_OVERRIDE + ) { + annotationGenerator.generate(this, firAnnotationContainer) + } + } + + private inline fun convertCatching(element: FirElement, block: () -> R): R { + try { + return block() + } catch (e: ProcessCanceledException) { + throw e + } catch (e: Exception) { + errorWithAttachment("Exception was thrown during transformation of ${element::class.java}", cause = e) { + withFirEntry("element", element) + } + } + } +} diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt new file mode 100644 index 00000000000..1bd5e56b8c9 --- /dev/null +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrLazyDeclarationsGenerator.kt @@ -0,0 +1,98 @@ +/* + * 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.fir.backend.generators + +import org.jetbrains.kotlin.fir.backend.Fir2IrComponents +import org.jetbrains.kotlin.fir.backend.convertWithOffsets +import org.jetbrains.kotlin.fir.backend.isStubPropertyForPureField +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.dispatchReceiverClassLookupTagOrNull +import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride +import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass +import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty +import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction +import org.jetbrains.kotlin.fir.originalForSubstitutionOverride +import org.jetbrains.kotlin.fir.symbols.Fir2IrPropertySymbol +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent +import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals +import org.jetbrains.kotlin.ir.util.IdSignature + +class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2IrComponents by components { + internal fun createIrLazyFunction( + fir: FirSimpleFunction, + signature: IdSignature, + lazyParent: IrDeclarationParent, + declarationOrigin: IrDeclarationOrigin + ): IrSimpleFunction { + val symbol = symbolTable.referenceSimpleFunction(signature) + val irFunction = fir.convertWithOffsets { startOffset, endOffset -> + symbolTable.declareSimpleFunction(signature, { symbol }) { + val isFakeOverride = fir.isSubstitutionOrIntersectionOverride + Fir2IrLazySimpleFunction( + components, startOffset, endOffset, declarationOrigin, + fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol, isFakeOverride + ).apply { + this.parent = lazyParent + } + } + } + functionCache[fir] = irFunction + // NB: this is needed to prevent recursions in case of self bounds + (irFunction as Fir2IrLazySimpleFunction).prepareTypeParameters() + return irFunction + } + + @OptIn(IrSymbolInternals::class) + internal fun createIrLazyProperty( + fir: FirProperty, + signature: IdSignature, + lazyParent: IrDeclarationParent, + declarationOrigin: IrDeclarationOrigin + ): IrProperty { + val symbol = Fir2IrPropertySymbol(signature) + val firPropertySymbol = fir.symbol + + fun create(startOffset: Int, endOffset: Int): Fir2IrLazyProperty { + val isFakeOverride = + fir.isSubstitutionOrIntersectionOverride && + firPropertySymbol.dispatchReceiverClassLookupTagOrNull() != + firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassLookupTagOrNull() + return Fir2IrLazyProperty( + components, startOffset, endOffset, declarationOrigin, + fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol, isFakeOverride + ).apply { + this.parent = lazyParent + } + } + + val irProperty = fir.convertWithOffsets { startOffset, endOffset -> + if (fir.isStubPropertyForPureField == true) { + // Very special case when two similar properties can exist so conflicts in SymbolTable are possible. + // See javaCloseFieldAndKotlinProperty.kt in BB tests + symbolTable.declarePropertyWithSignature(signature, symbol) + create(startOffset, endOffset) + symbol.owner + } else { + symbolTable.declareProperty(signature, { symbol }) { + create(startOffset, endOffset) + } + } + } + propertyCache[fir] = irProperty + irProperty.getter?.symbol?.let { getterForPropertyCache[symbol] = it } + irProperty.setter?.symbol?.let { setterForPropertyCache[symbol] = it } + irProperty.backingField?.symbol?.let { + backingFieldForPropertyCache[symbol] = it + propertyForBackingFieldCache[it] = symbol + } + return irProperty + } + +} diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt index 48a64a7d466..351117e9436 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyConstructor.kt @@ -102,17 +102,17 @@ class Fir2IrLazyConstructor( declarationStorage.enterScope(this.symbol) buildList { - declarationStorage.addContextReceiverParametersTo( + callablesGenerator.addContextReceiverParametersTo( fir.contextReceivers, this@Fir2IrLazyConstructor, - this@buildList, + this@buildList ) fir.valueParameters.mapIndexedTo(this) { index, valueParameter -> - declarationStorage.createIrParameter( + callablesGenerator.createIrParameter( valueParameter, index + contextReceiverParametersCount, useStubForDefaultValueStub = (parent as? IrClass)?.name != Name.identifier("Enum"), - forcedDefaultValueConversion = (parent as? IrClass)?.isAnnotationClass == true, + forcedDefaultValueConversion = (parent as? IrClass)?.isAnnotationClass == true ).apply { this.parent = this@Fir2IrLazyConstructor } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt index b9014635cc6..7fa2e10b8d7 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyProperty.kt @@ -115,7 +115,8 @@ class Fir2IrLazyProperty( } val initializer = fir.backingField?.initializer ?: fir.initializer val visibility = fir.backingField?.visibility ?: fir.visibility - createBackingField( + callablesGenerator.createBackingField( + this@Fir2IrLazyProperty, fir, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, components.visibilityConverter.convertToDescriptorVisibility(visibility), @@ -130,9 +131,14 @@ class Fir2IrLazyProperty( } fir.hasBackingField && origin != IrDeclarationOrigin.FAKE_OVERRIDE -> { with(declarationStorage) { - createBackingField( - fir, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, - components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), fir.name, fir.isVal, fir.initializer, + callablesGenerator.createBackingField( + this@Fir2IrLazyProperty, + fir, + IrDeclarationOrigin.PROPERTY_BACKING_FIELD, + components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), + fir.name, + fir.isVal, + fir.initializer, type ).also { field -> field.initializer = toIrInitializer(fir.initializer) @@ -141,10 +147,14 @@ class Fir2IrLazyProperty( } fir.delegate != null -> { with(declarationStorage) { - createBackingField( - fir, IrDeclarationOrigin.PROPERTY_DELEGATE, + callablesGenerator.createBackingField( + this@Fir2IrLazyProperty, + fir, + IrDeclarationOrigin.PROPERTY_DELEGATE, components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), - NameUtils.propertyDelegateName(fir.name), true, fir.delegate + NameUtils.propertyDelegateName(fir.name), + true, + fir.delegate ) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt index da07ef1b821..af1fa9b20c2 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazyPropertyAccessor.kt @@ -81,16 +81,16 @@ class Fir2IrLazyPropertyAccessor( declarationStorage.enterScope(this.symbol) buildList { - declarationStorage.addContextReceiverParametersTo( + callablesGenerator.addContextReceiverParametersTo( fir.contextReceiversForFunctionOrContainingProperty(), this@Fir2IrLazyPropertyAccessor, - this@buildList, + this@buildList ) if (isSetter) { val valueParameter = firAccessor?.valueParameters?.firstOrNull() add( - declarationStorage.createDefaultSetterParameter( + callablesGenerator.createDefaultSetterParameter( startOffset, endOffset, (valueParameter?.returnTypeRef ?: firParentProperty.returnTypeRef).toIrType( typeConverter, conversionTypeContext diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt index 5988da81731..0ec04c1ce09 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt @@ -69,14 +69,14 @@ class Fir2IrLazySimpleFunction( declarationStorage.enterScope(this.symbol) buildList { - declarationStorage.addContextReceiverParametersTo( + callablesGenerator.addContextReceiverParametersTo( fir.contextReceiversForFunctionOrContainingProperty(), this@Fir2IrLazySimpleFunction, - this@buildList, + this@buildList ) fir.valueParameters.mapIndexedTo(this) { index, valueParameter -> - declarationStorage.createIrParameter( + callablesGenerator.createIrParameter( valueParameter, index + contextReceiverParametersCount, skipDefaultParameter = isFakeOverride ).apply { this.parent = this@Fir2IrLazySimpleFunction