[FIR2IR] Manage property symbols in declaration storage instead of declaration generator

This is needed to be able to implement creation of unbound symbols
  for references of corresponding declarations (KT-62856)
This commit is contained in:
Dmitriy Novozhilov
2023-11-03 14:52:45 +02:00
committed by Space Team
parent fe66f3a384
commit aadc9ce6d5
4 changed files with 329 additions and 338 deletions
@@ -13,9 +13,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.isStatic import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.descriptors.FirBuiltInsPackageFragment import org.jetbrains.kotlin.fir.descriptors.FirBuiltInsPackageFragment
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression 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.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toLookupTag
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.classId import org.jetbrains.kotlin.ir.util.classId
import org.jetbrains.kotlin.ir.util.createParameterDeclarations import org.jetbrains.kotlin.ir.util.createParameterDeclarations
@@ -543,11 +536,54 @@ class Fir2IrDeclarationStorage(
): IrProperty { ): IrProperty {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val property = prepareProperty(property) 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) cacheIrProperty(property, irProperty, fakeOverrideOwnerLookupTag)
return irProperty 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( private fun cacheIrProperty(
property: FirProperty, property: FirProperty,
irProperty: IrProperty, irProperty: IrProperty,
@@ -773,6 +809,10 @@ class Fir2IrDeclarationStorage(
return irField return irField
} }
private fun createFieldSymbol(): IrFieldSymbol {
return IrFieldSymbolImpl()
}
// This function returns null if this field/ownerClassId combination does not describe static fake override // This function returns null if this field/ownerClassId combination does not describe static fake override
private fun getFieldStaticFakeOverrideKey(field: FirField, ownerLookupTag: ConeClassLikeLookupTag?): FieldStaticOverrideKey? { private fun getFieldStaticFakeOverrideKey(field: FirField, ownerLookupTag: ConeClassLikeLookupTag?): FieldStaticOverrideKey? {
if (ownerLookupTag == null || !field.isStatic || if (ownerLookupTag == null || !field.isStatic ||
@@ -825,7 +865,8 @@ class Fir2IrDeclarationStorage(
property: FirProperty, property: FirProperty,
irParent: IrDeclarationParent irParent: IrDeclarationParent
): IrLocalDelegatedProperty { ): IrLocalDelegatedProperty {
val irProperty = callablesGenerator.createIrLocalDelegatedProperty(property, irParent) val symbols = createLocalDelegatedPropertySymbols(property)
val irProperty = callablesGenerator.createIrLocalDelegatedProperty(property, irParent, symbols)
val symbol = irProperty.symbol val symbol = irProperty.symbol
delegateVariableForPropertyCache[symbol] = irProperty.delegate.symbol delegateVariableForPropertyCache[symbol] = irProperty.delegate.symbol
getterForPropertyCache[symbol] = irProperty.getter.symbol getterForPropertyCache[symbol] = irProperty.getter.symbol
@@ -834,6 +875,15 @@ class Fir2IrDeclarationStorage(
return irProperty 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 ------------------------------------ // ------------------------------------ variables ------------------------------------
fun createAndCacheIrVariable( fun createAndCacheIrVariable(
@@ -1244,3 +1294,16 @@ annotation class GetOrCreateSensitiveAPI
internal fun <D : IrDeclaration> IrBindableSymbol<*, D>.ownerIfBound(): D? { internal fun <D : IrDeclaration> IrBindableSymbol<*, D>.ownerIfBound(): D? {
return runIf(isBound) { owner } 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?,
)
@@ -70,17 +70,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
// ------------------------------------ functions ------------------------------------ // ------------------------------------ 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( fun createIrFunction(
function: FirFunction, function: FirFunction,
irParent: IrDeclarationParent?, irParent: IrDeclarationParent?,
@@ -228,19 +217,10 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
// ------------------------------------ properties ------------------------------------ // ------------------------------------ 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( fun createIrProperty(
property: FirProperty, property: FirProperty,
irParent: IrDeclarationParent?, irParent: IrDeclarationParent?,
symbols: PropertySymbols,
predefinedOrigin: IrDeclarationOrigin? = null, predefinedOrigin: IrDeclarationOrigin? = null,
isLocal: Boolean = false, isLocal: Boolean = false,
fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null,
@@ -270,11 +250,10 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
} }
if (parentIsExternal && signature != null) { if (parentIsExternal && signature != null) {
// For private functions signature is null, fallback to non-lazy property // 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 -> return property.convertWithOffsets { startOffset, endOffset ->
val result = declareIrProperty(signature) { symbol -> classifierStorage.preCacheTypeParameters(property, symbols.propertySymbol)
classifierStorage.preCacheTypeParameters(property, symbol)
irFactory.createProperty( irFactory.createProperty(
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
@@ -282,7 +261,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
name = property.name, name = property.name,
visibility = components.visibilityConverter.convertToDescriptorVisibility(property.visibility), visibility = components.visibilityConverter.convertToDescriptorVisibility(property.visibility),
modality = property.modality!!, modality = property.modality!!,
symbol = symbol, symbol = symbols.propertySymbol,
isVar = property.isVar, isVar = property.isVar,
isConst = property.isConst, isConst = property.isConst,
isLateinit = property.isLateInit, isLateinit = property.isLateInit,
@@ -310,6 +289,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
this, this,
property, property,
IrDeclarationOrigin.PROPERTY_DELEGATE, IrDeclarationOrigin.PROPERTY_DELEGATE,
symbols.backingFieldSymbol!!,
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
NameUtils.propertyDelegateName(property.name), NameUtils.propertyDelegateName(property.name),
true, true,
@@ -327,6 +307,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
this, this,
property, property,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD, IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
symbols.backingFieldSymbol!!,
components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility),
property.name, property.name,
property.isVal, property.isVal,
@@ -346,7 +327,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
} }
this.getter = getter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset -> this.getter = getter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset ->
createIrPropertyAccessor( createIrPropertyAccessor(
getter, property, this, type, irParent, false, getter, property, this, symbols.getterSymbol, type, irParent, false,
when { when {
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin
origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> origin origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> origin
@@ -357,14 +338,13 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
else -> origin else -> origin
}, },
startOffset, endOffset, startOffset, endOffset,
dontUseSignature = signature == null, fakeOverrideOwnerLookupTag,
property.unwrapFakeOverrides().getter, property.unwrapFakeOverrides().getter,
) )
} }
if (property.isVar) { if (property.isVar) {
this.setter = setter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset -> this.setter = setter.convertWithOffsets(startOffset, endOffset) { startOffset, endOffset ->
createIrPropertyAccessor( createIrPropertyAccessor(
setter, property, this, type, irParent, true, setter, property, this, symbols.setterSymbol!!, type, irParent, true,
when { when {
delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin origin == IrDeclarationOrigin.FAKE_OVERRIDE -> origin
@@ -373,7 +353,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
else -> origin else -> origin
}, },
startOffset, endOffset, startOffset, endOffset,
dontUseSignature = signature == null, fakeOverrideOwnerLookupTag,
property.unwrapFakeOverrides().setter, property.unwrapFakeOverrides().setter,
) )
} }
@@ -381,8 +360,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
} }
} }
} }
result
}
} }
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
@@ -439,28 +416,22 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
propertyAccessor: FirPropertyAccessor?, propertyAccessor: FirPropertyAccessor?,
property: FirProperty, property: FirProperty,
correspondingProperty: IrDeclarationWithName, correspondingProperty: IrDeclarationWithName,
symbol: IrSimpleFunctionSymbol,
propertyType: IrType, propertyType: IrType,
irParent: IrDeclarationParent?, irParent: IrDeclarationParent?,
isSetter: Boolean, isSetter: Boolean,
origin: IrDeclarationOrigin, origin: IrDeclarationOrigin,
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
dontUseSignature: Boolean = false,
fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null,
propertyAccessorForAnnotations: FirPropertyAccessor? = propertyAccessor, propertyAccessorForAnnotations: FirPropertyAccessor? = propertyAccessor,
): IrSimpleFunction = convertCatching(propertyAccessor ?: property) { ): IrSimpleFunction = convertCatching(propertyAccessor ?: property) {
val prefix = if (isSetter) "set" else "get" val prefix = if (isSetter) "set" else "get"
val signature =
runUnless(dontUseSignature) {
signatureComposer.composeAccessorSignature(property, isSetter, fakeOverrideOwnerLookupTag)
}
val containerSource = (correspondingProperty as? IrProperty)?.containerSource val containerSource = (correspondingProperty as? IrProperty)?.containerSource
return declareIrSimpleFunction(signature) { symbol ->
val accessorReturnType = if (isSetter) irBuiltIns.unitType else propertyType val accessorReturnType = if (isSetter) irBuiltIns.unitType else propertyType
val visibility = propertyAccessor?.visibility?.let { val visibility = propertyAccessor?.visibility?.let {
components.visibilityConverter.convertToDescriptorVisibility(it) components.visibilityConverter.convertToDescriptorVisibility(it)
} }
irFactory.createSimpleFunction( return irFactory.createSimpleFunction(
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = origin, origin = origin,
@@ -517,7 +488,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
} }
} }
} }
}
// ------------------------------------ fields ------------------------------------ // ------------------------------------ fields ------------------------------------
@@ -525,6 +495,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
irProperty: IrProperty, irProperty: IrProperty,
firProperty: FirProperty, firProperty: FirProperty,
origin: IrDeclarationOrigin, origin: IrDeclarationOrigin,
symbol: IrFieldSymbol,
visibility: DescriptorVisibility, visibility: DescriptorVisibility,
name: Name, name: Name,
isFinal: Boolean, isFinal: Boolean,
@@ -532,8 +503,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
type: IrType? = null type: IrType? = null
): IrField = convertCatching(firProperty) { ): IrField = convertCatching(firProperty) {
val inferredType = type ?: firInitializerExpression!!.resolvedType.toIrType() val inferredType = type ?: firInitializerExpression!!.resolvedType.toIrType()
return declareIrField { symbol -> return (firProperty.delegate ?: firProperty.backingField ?: firProperty).convertWithOffsets { startOffset: Int, endOffset: Int ->
(firProperty.delegate ?: firProperty.backingField ?: firProperty).convertWithOffsets { startOffset: Int, endOffset: Int ->
irFactory.createField( irFactory.createField(
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
@@ -553,7 +523,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
} }
} }
} }
}
private val FirProperty.fieldVisibility: Visibility private val FirProperty.fieldVisibility: Visibility
get() = when { get() = when {
@@ -565,10 +534,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
else -> Visibilities.Private else -> Visibilities.Private
} }
private fun declareIrField(factory: (IrFieldSymbol) -> IrField): IrField {
return factory(IrFieldSymbolImpl())
}
fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? { fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField? {
// Either take a corresponding constructor property backing field, // Either take a corresponding constructor property backing field,
// or create a separate delegate field // or create a separate delegate field
@@ -866,18 +831,18 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
fun createIrLocalDelegatedProperty( fun createIrLocalDelegatedProperty(
property: FirProperty, property: FirProperty,
irParent: IrDeclarationParent irParent: IrDeclarationParent,
symbols: LocalDelegatedPropertySymbols
): IrLocalDelegatedProperty = convertCatching(property) { ): IrLocalDelegatedProperty = convertCatching(property) {
val type = property.returnTypeRef.toIrType() val type = property.returnTypeRef.toIrType()
val origin = IrDeclarationOrigin.DEFINED val origin = IrDeclarationOrigin.DEFINED
val symbol = IrLocalDelegatedPropertySymbolImpl()
val irProperty = property.convertWithOffsets { startOffset, endOffset -> val irProperty = property.convertWithOffsets { startOffset, endOffset ->
irFactory.createLocalDelegatedProperty( irFactory.createLocalDelegatedProperty(
startOffset = startOffset, startOffset = startOffset,
endOffset = endOffset, endOffset = endOffset,
origin = origin, origin = origin,
name = property.name, name = property.name,
symbol = symbol, symbol = symbols.propertySymbol,
type = type, type = type,
isVar = property.isVar isVar = property.isVar
) )
@@ -892,13 +857,13 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
) )
delegate.parent = irParent delegate.parent = irParent
getter = createIrPropertyAccessor( getter = createIrPropertyAccessor(
property.getter, property, this, type, irParent, false, property.getter, property, this, symbols.getterSymbol, type, irParent, false,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset
) )
if (property.isVar) { if (property.isVar) {
setter = createIrPropertyAccessor( setter = createIrPropertyAccessor(
property.setter, property, this, type, irParent, true, property.setter, property, this, symbols.setterSymbol!!, type, irParent, true,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset, dontUseSignature = true IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR, startOffset, endOffset
) )
} }
annotationGenerator.generate(this, property) 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()}") else -> error("Can't add declaration ${declaration.render()} to parent ${irParent.render()}")
} }
} }
@@ -6,9 +6,8 @@
package org.jetbrains.kotlin.fir.backend.generators package org.jetbrains.kotlin.fir.backend.generators
import org.jetbrains.kotlin.fir.* 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.convertWithOffsets
import org.jetbrains.kotlin.fir.backend.irOrigin
import org.jetbrains.kotlin.fir.backend.isStubPropertyForPureField import org.jetbrains.kotlin.fir.backend.isStubPropertyForPureField
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.lazy.* 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.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol 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.IrFieldPublicSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertyPublicSymbolImpl
import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -50,39 +47,24 @@ class Fir2IrLazyDeclarationsGenerator(val components: Fir2IrComponents) : Fir2Ir
internal fun createIrLazyProperty( internal fun createIrLazyProperty(
fir: FirProperty, fir: FirProperty,
signature: IdSignature,
lazyParent: IrDeclarationParent, lazyParent: IrDeclarationParent,
symbols: PropertySymbols,
declarationOrigin: IrDeclarationOrigin declarationOrigin: IrDeclarationOrigin
): IrProperty { ): IrProperty {
val symbol = IrPropertyPublicSymbolImpl(signature) val isPropertyForField = fir.isStubPropertyForPureField == true
fun create(startOffset: Int, endOffset: Int, isPropertyForField: Boolean): Fir2IrLazyProperty {
val firContainingClass = (lazyParent as? Fir2IrLazyClass)?.fir val firContainingClass = (lazyParent as? Fir2IrLazyClass)?.fir
val isFakeOverride = !isPropertyForField && fir.isFakeOverride(firContainingClass) val isFakeOverride = !isPropertyForField && fir.isFakeOverride(firContainingClass)
// It is really required to create those properties with DEFINED origin // 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 // Using `declarationOrigin` here (IR_EXTERNAL_JAVA_DECLARATION_STUB in particular) causes some tests to fail, including
// FirPsiBlackBoxCodegenTestGenerated.Reflection.Properties.testJavaStaticField // FirPsiBlackBoxCodegenTestGenerated.Reflection.Properties.testJavaStaticField
val originForProperty = if (isPropertyForField) IrDeclarationOrigin.DEFINED else declarationOrigin val originForProperty = if (isPropertyForField) IrDeclarationOrigin.DEFINED else declarationOrigin
return Fir2IrLazyProperty( return fir.convertWithOffsets { startOffset, endOffset ->
components, startOffset, endOffset, originForProperty, Fir2IrLazyProperty(
fir, firContainingClass, symbol, isFakeOverride components, startOffset, endOffset, originForProperty, fir, firContainingClass, symbols, isFakeOverride
).apply { ).apply {
this.parent = lazyParent 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( fun createIrLazyConstructor(
@@ -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.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol 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.ir.types.IrType
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.name.NameUtils
@@ -39,9 +38,11 @@ class Fir2IrLazyProperty(
override var origin: IrDeclarationOrigin, override var origin: IrDeclarationOrigin,
override val fir: FirProperty, override val fir: FirProperty,
val containingClass: FirRegularClass?, val containingClass: FirRegularClass?,
override val symbol: IrPropertySymbol, symbols: PropertySymbols,
override var isFakeOverride: Boolean override var isFakeOverride: Boolean
) : IrProperty(), AbstractFir2IrLazyDeclaration<FirProperty>, Fir2IrComponents by components { ) : IrProperty(), AbstractFir2IrLazyDeclaration<FirProperty>, Fir2IrComponents by components {
override val symbol: IrPropertySymbol = symbols.propertySymbol
init { init {
symbol.bind(this) symbol.bind(this)
classifierStorage.preCacheTypeParameters(fir, symbol) classifierStorage.preCacheTypeParameters(fir, symbol)
@@ -111,7 +112,6 @@ class Fir2IrLazyProperty(
override var backingField: IrField? by lazyVar(lock) { override var backingField: IrField? by lazyVar(lock) {
when { when {
fir.hasExplicitBackingField -> { fir.hasExplicitBackingField -> {
with(declarationStorage) {
val backingFieldType = with(typeConverter) { val backingFieldType = with(typeConverter) {
fir.backingField?.returnTypeRef?.toIrType() fir.backingField?.returnTypeRef?.toIrType()
} }
@@ -121,6 +121,7 @@ class Fir2IrLazyProperty(
this@Fir2IrLazyProperty, this@Fir2IrLazyProperty,
fir, fir,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD, IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
symbols.backingFieldSymbol!!,
components.visibilityConverter.convertToDescriptorVisibility(visibility), components.visibilityConverter.convertToDescriptorVisibility(visibility),
fir.name, fir.name,
fir.isVal, fir.isVal,
@@ -130,13 +131,12 @@ class Fir2IrLazyProperty(
field.initializer = toIrInitializer(initializer) field.initializer = toIrInitializer(initializer)
} }
} }
}
extensions.hasBackingField(fir, session) && origin != IrDeclarationOrigin.FAKE_OVERRIDE -> { extensions.hasBackingField(fir, session) && origin != IrDeclarationOrigin.FAKE_OVERRIDE -> {
with(declarationStorage) {
callablesGenerator.createBackingField( callablesGenerator.createBackingField(
this@Fir2IrLazyProperty, this@Fir2IrLazyProperty,
fir, fir,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD, IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
symbols.backingFieldSymbol!!,
components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), components.visibilityConverter.convertToDescriptorVisibility(fir.visibility),
fir.name, fir.name,
fir.isVal, fir.isVal,
@@ -146,20 +146,18 @@ class Fir2IrLazyProperty(
field.initializer = toIrInitializer(fir.initializer) field.initializer = toIrInitializer(fir.initializer)
} }
} }
}
fir.delegate != null -> { fir.delegate != null -> {
with(declarationStorage) {
callablesGenerator.createBackingField( callablesGenerator.createBackingField(
this@Fir2IrLazyProperty, this@Fir2IrLazyProperty,
fir, fir,
IrDeclarationOrigin.PROPERTY_DELEGATE, IrDeclarationOrigin.PROPERTY_DELEGATE,
symbols.backingFieldSymbol!!,
components.visibilityConverter.convertToDescriptorVisibility(fir.visibility), components.visibilityConverter.convertToDescriptorVisibility(fir.visibility),
NameUtils.propertyDelegateName(fir.name), NameUtils.propertyDelegateName(fir.name),
true, true,
fir.delegate fir.delegate
) )
} }
}
else -> { else -> {
null null
} }
@@ -172,12 +170,6 @@ class Fir2IrLazyProperty(
} }
override var getter: IrSimpleFunction? by lazyVar(lock) { 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( Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset, components, startOffset, endOffset,
when { when {
@@ -188,9 +180,8 @@ class Fir2IrLazyProperty(
fir.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR fir.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
else -> origin else -> origin
}, },
fir.getter, isSetter = false, fir, containingClass, symbol, isFakeOverride, this.symbol fir.getter, isSetter = false, fir, containingClass, symbols.getterSymbol, isFakeOverride, this.symbol
) ).apply {
}.apply {
parent = this@Fir2IrLazyProperty.parent parent = this@Fir2IrLazyProperty.parent
correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol
classifiersGenerator.setTypeParameters(this, this@Fir2IrLazyProperty.fir, ConversionTypeOrigin.DEFAULT) classifiersGenerator.setTypeParameters(this, this@Fir2IrLazyProperty.fir, ConversionTypeOrigin.DEFAULT)
@@ -198,14 +189,7 @@ class Fir2IrLazyProperty(
} }
override var setter: IrSimpleFunction? by lazyVar(lock) { override var setter: IrSimpleFunction? by lazyVar(lock) {
if (!fir.isVar) null if (!fir.isVar) return@lazyVar null
else {
val signature = signatureComposer.composeAccessorSignature(
fir,
isSetter = true,
containingClass?.symbol?.toLookupTag()
)!!
symbolTable.declareSimpleFunction(signature, symbolFactory = { IrSimpleFunctionPublicSymbolImpl(signature) }) { symbol ->
Fir2IrLazyPropertyAccessor( Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset, components, startOffset, endOffset,
when { when {
@@ -216,15 +200,13 @@ class Fir2IrLazyProperty(
fir.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR fir.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
else -> origin else -> origin
}, },
fir.setter, isSetter = true, fir, containingClass, symbol, isFakeOverride, this.symbol fir.setter, isSetter = true, fir, containingClass, symbols.setterSymbol!!, isFakeOverride, this.symbol
).apply { ).apply {
parent = this@Fir2IrLazyProperty.parent parent = this@Fir2IrLazyProperty.parent
correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol
classifiersGenerator.setTypeParameters(this, this@Fir2IrLazyProperty.fir, ConversionTypeOrigin.SETTER) classifiersGenerator.setTypeParameters(this, this@Fir2IrLazyProperty.fir, ConversionTypeOrigin.SETTER)
} }
} }
}
}
override var overriddenSymbols: List<IrPropertySymbol> by lazyVar(lock) { override var overriddenSymbols: List<IrPropertySymbol> by lazyVar(lock) {
if (containingClass == null) return@lazyVar emptyList() if (containingClass == null) return@lazyVar emptyList()