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 6c21a639852..c353a70b8cb 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 @@ -13,9 +13,7 @@ import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty -import org.jetbrains.kotlin.fir.declarations.utils.isStatic -import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName -import org.jetbrains.kotlin.fir.declarations.utils.visibility +import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.descriptors.FirBuiltInsPackageFragment import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression @@ -27,19 +25,14 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.coneType -import org.jetbrains.kotlin.fir.types.resolvedType -import org.jetbrains.kotlin.fir.types.toLookupTag +import org.jetbrains.kotlin.fir.types.* 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.IrClassImpl import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.classId import org.jetbrains.kotlin.ir.util.createParameterDeclarations @@ -543,11 +536,54 @@ class Fir2IrDeclarationStorage( ): IrProperty { @Suppress("NAME_SHADOWING") val property = prepareProperty(property) - val irProperty = callablesGenerator.createIrProperty(property, irParent, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag) + + val signature = runIf(!isLocal && configuration.linkViaSignatures) { + signatureComposer.composeSignature(property, fakeOverrideOwnerLookupTag) + } + + val symbols = createPropertySymbols(signature, property, fakeOverrideOwnerLookupTag) + val irProperty = callablesGenerator.createIrProperty( + property, irParent, symbols, predefinedOrigin, isLocal, fakeOverrideOwnerLookupTag + ) cacheIrProperty(property, irProperty, fakeOverrideOwnerLookupTag) return irProperty } + private fun createPropertySymbols( + signature: IdSignature?, + property: FirProperty, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, + ): PropertySymbols { + val propertySymbol = when { + signature != null -> when (property.isStubPropertyForPureField) { + // Very special case when two similar properties can exist so conflicts in SymbolTable are possible. + // See javaCloseFieldAndKotlinProperty.kt in BB tests + true -> IrPropertyPublicSymbolImpl(signature).also { + symbolTable.declarePropertyWithSignature(signature, it) + } + else -> symbolTable.referenceProperty(signature) + } + else -> IrPropertySymbolImpl() + } + val getterSignature = runIf(signature != null) { + signatureComposer.composeAccessorSignature(property, isSetter = false, fakeOverrideOwnerLookupTag) + } + val getterSymbol = createFunctionSymbol(getterSignature) + + val setterSymbol = runIf(property.isVar) { + val setterSignature = runIf(signature != null) { + signatureComposer.composeAccessorSignature(property, isSetter = true, fakeOverrideOwnerLookupTag) + } + createFunctionSymbol(setterSignature) + } + + val backingFieldSymbol = runIf(property.delegate != null || property.hasBackingField) { + createFieldSymbol() + } + + return PropertySymbols(propertySymbol, getterSymbol, setterSymbol, backingFieldSymbol) + } + private fun cacheIrProperty( property: FirProperty, irProperty: IrProperty, @@ -773,6 +809,10 @@ class Fir2IrDeclarationStorage( return irField } + private fun createFieldSymbol(): IrFieldSymbol { + return IrFieldSymbolImpl() + } + // 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 || @@ -825,7 +865,8 @@ class Fir2IrDeclarationStorage( property: FirProperty, irParent: IrDeclarationParent ): IrLocalDelegatedProperty { - val irProperty = callablesGenerator.createIrLocalDelegatedProperty(property, irParent) + val symbols = createLocalDelegatedPropertySymbols(property) + val irProperty = callablesGenerator.createIrLocalDelegatedProperty(property, irParent, symbols) val symbol = irProperty.symbol delegateVariableForPropertyCache[symbol] = irProperty.delegate.symbol getterForPropertyCache[symbol] = irProperty.getter.symbol @@ -834,6 +875,15 @@ class Fir2IrDeclarationStorage( return irProperty } + private fun createLocalDelegatedPropertySymbols(property: FirProperty): LocalDelegatedPropertySymbols { + val propertySymbol = IrLocalDelegatedPropertySymbolImpl() + val getterSymbol = createFunctionSymbol(signature = null) + val setterSymbol = runIf(property.isVar) { + createFunctionSymbol(signature = null) + } + return LocalDelegatedPropertySymbols(propertySymbol, getterSymbol, setterSymbol) + } + // ------------------------------------ variables ------------------------------------ fun createAndCacheIrVariable( @@ -1244,3 +1294,16 @@ annotation class GetOrCreateSensitiveAPI internal fun IrBindableSymbol<*, D>.ownerIfBound(): D? { return runIf(isBound) { owner } } + +data class PropertySymbols( + val propertySymbol: IrPropertySymbol, + val getterSymbol: IrSimpleFunctionSymbol, + val setterSymbol: IrSimpleFunctionSymbol?, + val backingFieldSymbol: IrFieldSymbol?, +) + +data class LocalDelegatedPropertySymbols( + val propertySymbol: IrLocalDelegatedPropertySymbol, + val getterSymbol: IrSimpleFunctionSymbol, + val setterSymbol: IrSimpleFunctionSymbol?, +) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt index ff11c81d3a5..f22fe3b78e7 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt @@ -70,17 +70,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi // ------------------------------------ functions ------------------------------------ - internal fun declareIrSimpleFunction( - signature: IdSignature?, - factory: (IrSimpleFunctionSymbol) -> IrSimpleFunction - ): IrSimpleFunction { - return if (signature == null) { - factory(IrSimpleFunctionSymbolImpl()) - } else { - symbolTable.declareSimpleFunction(signature, { IrSimpleFunctionPublicSymbolImpl(signature) }, factory) - } - } - fun createIrFunction( function: FirFunction, irParent: IrDeclarationParent?, @@ -228,19 +217,10 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi // ------------------------------------ properties ------------------------------------ - private fun declareIrProperty( - signature: IdSignature?, - factory: (IrPropertySymbol) -> IrProperty - ): IrProperty { - return if (signature == null) - factory(IrPropertySymbolImpl()) - else - symbolTable.declareProperty(signature, { IrPropertyPublicSymbolImpl(signature) }, factory) - } - fun createIrProperty( property: FirProperty, irParent: IrDeclarationParent?, + symbols: PropertySymbols, predefinedOrigin: IrDeclarationOrigin? = null, isLocal: Boolean = false, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, @@ -270,118 +250,115 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi } if (parentIsExternal && signature != null) { // For private functions signature is null, fallback to non-lazy property - return lazyDeclarationsGenerator.createIrLazyProperty(property, signature, irParent!!, origin) + return lazyDeclarationsGenerator.createIrLazyProperty(property, irParent!!, symbols, 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) - declarationStorage.withScope(symbol) { - // IrProperty is never created for local variables - setParent(irParent) - addDeclarationToParent(this, 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)) - } + classifierStorage.preCacheTypeParameters(property, symbols.propertySymbol) + irFactory.createProperty( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = property.name, + visibility = components.visibilityConverter.convertToDescriptorVisibility(property.visibility), + modality = property.modality!!, + symbol = symbols.propertySymbol, + 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) + declarationStorage.withScope(symbol) { + // IrProperty is never created for local variables + setParent(irParent) + addDeclarationToParent(this, 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, + symbols.backingFieldSymbol!!, + 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, + symbols.backingFieldSymbol!!, + 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)) } } - this.backingField = backingField } - if (irParent != null) { - backingField?.parent = irParent - } - this.getter = getter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset -> + this.backingField = backingField + } + if (irParent != null) { + backingField?.parent = irParent + } + this.getter = getter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset -> + createIrPropertyAccessor( + getter, property, this, symbols.getterSymbol, 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, + property.unwrapFakeOverrides().getter, + ) + } + if (property.isVar) { + this.setter = setter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset -> createIrPropertyAccessor( - getter, property, this, type, irParent, false, + setter, property, this, symbols.setterSymbol!!, type, irParent, true, 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 + setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR else -> origin }, startOffset, endOffset, - dontUseSignature = signature == null, fakeOverrideOwnerLookupTag, - property.unwrapFakeOverrides().getter, + property.unwrapFakeOverrides().setter, ) } - if (property.isVar) { - this.setter = setter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset -> - 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, - ) - } - } } } } - result } } @@ -439,82 +416,75 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi propertyAccessor: FirPropertyAccessor?, property: FirProperty, correspondingProperty: IrDeclarationWithName, + symbol: IrSimpleFunctionSymbol, 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 declareIrSimpleFunction(signature) { symbol -> - val accessorReturnType = if (isSetter) irBuiltIns.unitType else propertyType - val visibility = propertyAccessor?.visibility?.let { - components.visibilityConverter.convertToDescriptorVisibility(it) + val accessorReturnType = if (isSetter) irBuiltIns.unitType else propertyType + val visibility = propertyAccessor?.visibility?.let { + components.visibilityConverter.convertToDescriptorVisibility(it) + } + return 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) } - 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) + if (propertyAccessorForAnnotations != null) { + convertAnnotationsForNonDeclaredMembers(propertyAccessorForAnnotations, origin) + } + classifiersGenerator.setTypeParameters( + this, property, if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT + ) + val dispatchReceiverType = computeDispatchReceiverType(this, property, irParent) + // NB: we should enter accessor' scope before declaring its parameters + // (both setter default and receiver ones, if any) + declarationStorage.withScope(symbol) { + if (propertyAccessor == null && isSetter) { + declareDefaultSetterParameter( + property.returnTypeRef.toIrType(ConversionTypeOrigin.SETTER), + firValueParameter = null + ) } - classifiersGenerator.setTypeParameters( - this, property, if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT + // property accessors does not belong to declarations of class/file, but are referenced via property, + // so there is no need to add accessor to list of parents declarations + setParent(irParent) + declareParameters( + propertyAccessor, irParent, dispatchReceiverType, + isStatic = irParent !is IrClass || propertyAccessor?.isStatic == true, forSetter = isSetter, + parentPropertyReceiver = property.receiverParameter, + ) + } + if (correspondingProperty is Fir2IrLazyProperty && correspondingProperty.containingClass != null && !isFakeOverride && dispatchReceiverType != null) { + this.overriddenSymbols = correspondingProperty.fir.generateOverriddenAccessorSymbols( + correspondingProperty.containingClass, !isSetter ) - val dispatchReceiverType = computeDispatchReceiverType(this, property, irParent) - // NB: we should enter accessor' scope before declaring its parameters - // (both setter default and receiver ones, if any) - declarationStorage.withScope(symbol) { - if (propertyAccessor == null && isSetter) { - declareDefaultSetterParameter( - property.returnTypeRef.toIrType(ConversionTypeOrigin.SETTER), - firValueParameter = null - ) - } - // property accessors does not belong to declarations of class/file, but are referenced via property, - // so there is no need to add accessor to list of parents declarations - setParent(irParent) - declareParameters( - propertyAccessor, irParent, dispatchReceiverType, - isStatic = irParent !is IrClass || propertyAccessor?.isStatic == true, forSetter = isSetter, - parentPropertyReceiver = property.receiverParameter, - ) - } - if (correspondingProperty is Fir2IrLazyProperty && correspondingProperty.containingClass != null && !isFakeOverride && dispatchReceiverType != null) { - this.overriddenSymbols = correspondingProperty.fir.generateOverriddenAccessorSymbols( - correspondingProperty.containingClass, !isSetter - ) - } } } } @@ -525,6 +495,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi irProperty: IrProperty, firProperty: FirProperty, origin: IrDeclarationOrigin, + symbol: IrFieldSymbol, visibility: DescriptorVisibility, name: Name, isFinal: Boolean, @@ -532,25 +503,23 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi type: IrType? = null ): IrField = convertCatching(firProperty) { val inferredType = type ?: firInitializerExpression!!.resolvedType.toIrType() - return declareIrField { symbol -> - (firProperty.delegate ?: firProperty.backingField ?: firProperty).convertWithOffsets { startOffset: Int, endOffset: Int -> - irFactory.createField( - startOffset = startOffset, - endOffset = 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) - } + return (firProperty.delegate ?: firProperty.backingField ?: firProperty).convertWithOffsets { startOffset: Int, endOffset: Int -> + irFactory.createField( + startOffset = startOffset, + endOffset = 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) } } } @@ -565,10 +534,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi else -> Visibilities.Private } - private fun declareIrField(factory: (IrFieldSymbol) -> IrField): IrField { - return factory(IrFieldSymbolImpl()) - } - fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? { // Either take a corresponding constructor property backing field, // or create a separate delegate field @@ -866,18 +831,18 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi fun createIrLocalDelegatedProperty( property: FirProperty, - irParent: IrDeclarationParent + irParent: IrDeclarationParent, + symbols: LocalDelegatedPropertySymbols ): 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, + symbol = symbols.propertySymbol, type = type, isVar = property.isVar ) @@ -892,13 +857,13 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi ) delegate.parent = irParent getter = createIrPropertyAccessor( - property.getter, property, this, type, irParent, false, - IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true + property.getter, property, this, symbols.getterSymbol, type, irParent, false, + IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset ) if (property.isVar) { setter = createIrPropertyAccessor( - property.setter, property, this, type, irParent, true, - IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true + property.setter, property, this, symbols.setterSymbol!!, type, irParent, true, + IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset ) } annotationGenerator.generate(this, property) @@ -1106,4 +1071,3 @@ internal fun addDeclarationToParent(declaration: IrDeclaration, irParent: IrDecl else -> error("Can't add declaration ${declaration.render()} to parent ${irParent.render()}") } } - 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 index 2752662f777..195181557a3 100644 --- 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 @@ -6,9 +6,8 @@ package org.jetbrains.kotlin.fir.backend.generators import org.jetbrains.kotlin.fir.* -import org.jetbrains.kotlin.fir.backend.Fir2IrComponents +import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.convertWithOffsets -import org.jetbrains.kotlin.fir.backend.irOrigin import org.jetbrains.kotlin.fir.backend.isStubPropertyForPureField import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.lazy.* @@ -16,9 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldPublicSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrPropertyPublicSymbolImpl import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.utils.addToStdlib.runIf @@ -50,39 +47,24 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir internal fun createIrLazyProperty( fir: FirProperty, - signature: IdSignature, lazyParent: IrDeclarationParent, + symbols: PropertySymbols, declarationOrigin: IrDeclarationOrigin ): IrProperty { - val symbol = IrPropertyPublicSymbolImpl(signature) - fun create(startOffset: Int, endOffset: Int, isPropertyForField: Boolean): Fir2IrLazyProperty { - val firContainingClass = (lazyParent as? Fir2IrLazyClass)?.fir - val isFakeOverride = !isPropertyForField && fir.isFakeOverride(firContainingClass) - // It is really required to create those properties with DEFINED origin - // Using `declarationOrigin` here (IR_EXTERNAL_JAVA_DECLARATION_STUB in particular) causes some tests to fail, including - // FirPsiBlackBoxCodegenTestGenerated.Reflection.Properties.testJavaStaticField - val originForProperty = if (isPropertyForField) IrDeclarationOrigin.DEFINED else declarationOrigin - return Fir2IrLazyProperty( - components, startOffset, endOffset, originForProperty, - fir, firContainingClass, symbol, isFakeOverride + val isPropertyForField = fir.isStubPropertyForPureField == true + val firContainingClass = (lazyParent as? Fir2IrLazyClass)?.fir + val isFakeOverride = !isPropertyForField && fir.isFakeOverride(firContainingClass) + // It is really required to create those properties with DEFINED origin + // Using `declarationOrigin` here (IR_EXTERNAL_JAVA_DECLARATION_STUB in particular) causes some tests to fail, including + // FirPsiBlackBoxCodegenTestGenerated.Reflection.Properties.testJavaStaticField + val originForProperty = if (isPropertyForField) IrDeclarationOrigin.DEFINED else declarationOrigin + return fir.convertWithOffsets { startOffset, endOffset -> + Fir2IrLazyProperty( + components, startOffset, endOffset, originForProperty, fir, firContainingClass, symbols, 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, isPropertyForField = true) - } else { - symbolTable.declareProperty(signature, { symbol }) { - create(startOffset, endOffset, isPropertyForField = false) - } - } - } - return irProperty } fun createIrLazyConstructor( 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 5ec59cf8a28..7a6c18bf9ae 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 @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol -import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionPublicSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.NameUtils @@ -39,9 +38,11 @@ class Fir2IrLazyProperty( override var origin: IrDeclarationOrigin, override val fir: FirProperty, val containingClass: FirRegularClass?, - override val symbol: IrPropertySymbol, + symbols: PropertySymbols, override var isFakeOverride: Boolean ) : IrProperty(), AbstractFir2IrLazyDeclaration, Fir2IrComponents by components { + override val symbol: IrPropertySymbol = symbols.propertySymbol + init { symbol.bind(this) classifierStorage.preCacheTypeParameters(fir, symbol) @@ -111,54 +112,51 @@ class Fir2IrLazyProperty( override var backingField: IrField? by lazyVar(lock) { when { fir.hasExplicitBackingField -> { - with(declarationStorage) { - val backingFieldType = with(typeConverter) { - fir.backingField?.returnTypeRef?.toIrType() - } - val initializer = fir.backingField?.initializer ?: fir.initializer - val visibility = fir.backingField?.visibility ?: fir.visibility - callablesGenerator.createBackingField( - this@Fir2IrLazyProperty, - fir, - IrDeclarationOrigin.PROPERTY_BACKING_FIELD, - components.visibilityConverter.convertToDescriptorVisibility(visibility), - fir.name, - fir.isVal, - initializer, - backingFieldType - ).also { field -> - field.initializer = toIrInitializer(initializer) - } + val backingFieldType = with(typeConverter) { + fir.backingField?.returnTypeRef?.toIrType() + } + val initializer = fir.backingField?.initializer ?: fir.initializer + val visibility = fir.backingField?.visibility ?: fir.visibility + callablesGenerator.createBackingField( + this@Fir2IrLazyProperty, + fir, + IrDeclarationOrigin.PROPERTY_BACKING_FIELD, + symbols.backingFieldSymbol!!, + components.visibilityConverter.convertToDescriptorVisibility(visibility), + fir.name, + fir.isVal, + initializer, + backingFieldType + ).also { field -> + field.initializer = toIrInitializer(initializer) } } extensions.hasBackingField(fir, session) && origin != IrDeclarationOrigin.FAKE_OVERRIDE -> { - with(declarationStorage) { - 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) - } + callablesGenerator.createBackingField( + this@Fir2IrLazyProperty, + fir, + IrDeclarationOrigin.PROPERTY_BACKING_FIELD, + symbols.backingFieldSymbol!!, + components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), + fir.name, + fir.isVal, + fir.initializer, + type + ).also { field -> + field.initializer = toIrInitializer(fir.initializer) } } fir.delegate != null -> { - with(declarationStorage) { - callablesGenerator.createBackingField( - this@Fir2IrLazyProperty, - fir, - IrDeclarationOrigin.PROPERTY_DELEGATE, - components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), - NameUtils.propertyDelegateName(fir.name), - true, - fir.delegate - ) - } + callablesGenerator.createBackingField( + this@Fir2IrLazyProperty, + fir, + IrDeclarationOrigin.PROPERTY_DELEGATE, + symbols.backingFieldSymbol!!, + components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), + NameUtils.propertyDelegateName(fir.name), + true, + fir.delegate + ) } else -> { null @@ -172,25 +170,18 @@ class Fir2IrLazyProperty( } override var getter: IrSimpleFunction? by lazyVar(lock) { - val signature = signatureComposer.composeAccessorSignature( - fir, - isSetter = false, - containingClass?.symbol?.toLookupTag() - )!! - symbolTable.declareSimpleFunction(signature, symbolFactory = { IrSimpleFunctionPublicSymbolImpl(signature) }) { symbol -> - Fir2IrLazyPropertyAccessor( - components, startOffset, endOffset, - when { - origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin - fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR - origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin - origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin - fir.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR - else -> origin - }, - fir.getter, isSetter = false, fir, containingClass, symbol, isFakeOverride, this.symbol - ) - }.apply { + Fir2IrLazyPropertyAccessor( + components, startOffset, endOffset, + when { + origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin + fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR + origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin + origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin + fir.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR + else -> origin + }, + fir.getter, isSetter = false, fir, containingClass, symbols.getterSymbol, isFakeOverride, this.symbol + ).apply { parent = this@Fir2IrLazyProperty.parent correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol classifiersGenerator.setTypeParameters(this, this@Fir2IrLazyProperty.fir, ConversionTypeOrigin.DEFAULT) @@ -198,31 +189,22 @@ class Fir2IrLazyProperty( } override var setter: IrSimpleFunction? by lazyVar(lock) { - if (!fir.isVar) null - else { - val signature = signatureComposer.composeAccessorSignature( - fir, - isSetter = true, - containingClass?.symbol?.toLookupTag() - )!! - symbolTable.declareSimpleFunction(signature, symbolFactory = { IrSimpleFunctionPublicSymbolImpl(signature) }) { symbol -> - Fir2IrLazyPropertyAccessor( - components, startOffset, endOffset, - when { - origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin - fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR - origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin - origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin - fir.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR - else -> origin - }, - fir.setter, isSetter = true, fir, containingClass, symbol, isFakeOverride, this.symbol - ).apply { - parent = this@Fir2IrLazyProperty.parent - correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol - classifiersGenerator.setTypeParameters(this, this@Fir2IrLazyProperty.fir, ConversionTypeOrigin.SETTER) - } - } + if (!fir.isVar) return@lazyVar null + Fir2IrLazyPropertyAccessor( + components, startOffset, endOffset, + when { + origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin + fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR + origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin + origin == IrDeclarationOrigin.DELEGATED_MEMBER -> origin + fir.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR + else -> origin + }, + fir.setter, isSetter = true, fir, containingClass, symbols.setterSymbol!!, isFakeOverride, this.symbol + ).apply { + parent = this@Fir2IrLazyProperty.parent + correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol + classifiersGenerator.setTypeParameters(this, this@Fir2IrLazyProperty.fir, ConversionTypeOrigin.SETTER) } }