[FIR2IR] Move backing field creation in Fir2IrDeclarationStorage
This commit is contained in:
+72
-16
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.fir.backend
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.*
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.*
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||||
@@ -19,6 +16,7 @@ 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.descriptors.FirPackageFragmentDescriptor
|
import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
@@ -36,10 +34,12 @@ import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrErrorType
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.util.constructors
|
import org.jetbrains.kotlin.ir.util.constructors
|
||||||
import org.jetbrains.kotlin.ir.util.functions
|
import org.jetbrains.kotlin.ir.util.functions
|
||||||
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
import org.jetbrains.kotlin.ir.util.properties
|
import org.jetbrains.kotlin.ir.util.properties
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -564,6 +564,39 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrProperty.createBackingField(
|
||||||
|
property: FirProperty,
|
||||||
|
origin: IrDeclarationOrigin,
|
||||||
|
descriptor: PropertyDescriptor,
|
||||||
|
visibility: Visibility,
|
||||||
|
name: Name,
|
||||||
|
isFinal: Boolean,
|
||||||
|
firInitializerExpression: FirExpression?,
|
||||||
|
type: IrType? = null
|
||||||
|
): IrField {
|
||||||
|
val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType()
|
||||||
|
return symbolTable.declareField(
|
||||||
|
startOffset, endOffset, origin, descriptor, inferredType
|
||||||
|
) { symbol ->
|
||||||
|
IrFieldImpl(
|
||||||
|
startOffset, endOffset, origin, symbol,
|
||||||
|
name, inferredType,
|
||||||
|
visibility, isFinal = isFinal, isExternal = false,
|
||||||
|
isStatic = property.isStatic || parent !is IrClass,
|
||||||
|
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
||||||
|
).also {
|
||||||
|
it.correspondingPropertySymbol = this@createBackingField.symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirProperty.fieldVisibility: Visibility
|
||||||
|
get() = when {
|
||||||
|
isLateInit -> setter?.visibility ?: status.visibility
|
||||||
|
isConst -> status.visibility
|
||||||
|
else -> Visibilities.PRIVATE
|
||||||
|
}
|
||||||
|
|
||||||
fun createIrProperty(
|
fun createIrProperty(
|
||||||
property: FirProperty,
|
property: FirProperty,
|
||||||
irParent: IrDeclarationParent?,
|
irParent: IrDeclarationParent?,
|
||||||
@@ -597,28 +630,51 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
val type = property.returnTypeRef.toIrType()
|
val type = property.returnTypeRef.toIrType()
|
||||||
val initializer = property.initializer
|
val initializer = property.initializer
|
||||||
if (property.isConst && initializer is FirConstExpression<*>) {
|
val delegate = property.delegate
|
||||||
backingField = IrFieldImpl(startOffset, endOffset, origin, descriptor, type).also {
|
val getter = property.getter
|
||||||
it.initializer = IrExpressionBodyImpl(initializer.toIrConst(type))
|
val setter = property.setter
|
||||||
it.correspondingPropertySymbol = symbol
|
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
|
||||||
|
if (property.isConst || (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface))) {
|
||||||
|
if (initializer != null || getter is FirDefaultPropertyGetter ||
|
||||||
|
property.isVar && setter is FirDefaultPropertySetter
|
||||||
|
) {
|
||||||
|
backingField = createBackingField(
|
||||||
|
property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor,
|
||||||
|
property.fieldVisibility, property.name, property.isVal, initializer, type
|
||||||
|
).also { field ->
|
||||||
|
if (initializer is FirConstExpression<*>) {
|
||||||
|
// TODO: Normally we shouldn't have error type here
|
||||||
|
val constType = initializer.typeRef.toIrType().takeIf { it !is IrErrorType } ?: type
|
||||||
|
field.initializer = IrExpressionBodyImpl(initializer.toIrConst(constType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (delegate != null) {
|
||||||
|
backingField = createBackingField(
|
||||||
|
property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor,
|
||||||
|
property.fieldVisibility, Name.identifier("${property.name}\$delegate"), true, delegate
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
if (irParent != null) {
|
||||||
|
backingField?.parent = irParent
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
getter = createIrPropertyAccessor(
|
this.getter = createIrPropertyAccessor(
|
||||||
property.getter, property, this, type, irParent, false,
|
getter, property, this, type, irParent, false,
|
||||||
when {
|
when {
|
||||||
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin
|
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin
|
||||||
property.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
|
delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
|
||||||
property.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||||
else -> origin
|
else -> origin
|
||||||
},
|
},
|
||||||
startOffset, endOffset
|
startOffset, endOffset
|
||||||
)
|
)
|
||||||
if (property.isVar) {
|
if (property.isVar) {
|
||||||
setter = createIrPropertyAccessor(
|
this.setter = createIrPropertyAccessor(
|
||||||
property.setter, property, this, type, irParent, true,
|
setter, property, this, type, irParent, true,
|
||||||
when {
|
when {
|
||||||
property.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
|
delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
|
||||||
property.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||||
else -> origin
|
else -> origin
|
||||||
},
|
},
|
||||||
startOffset, endOffset
|
startOffset, endOffset
|
||||||
|
|||||||
+7
-57
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend.generators
|
package org.jetbrains.kotlin.fir.backend.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
|
||||||
import org.jetbrains.kotlin.fir.backend.*
|
import org.jetbrains.kotlin.fir.backend.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||||
@@ -20,10 +17,8 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
@@ -135,25 +130,8 @@ internal class ClassMemberGenerator(
|
|||||||
val descriptor = irProperty.descriptor
|
val descriptor = irProperty.descriptor
|
||||||
val initializer = property.initializer
|
val initializer = property.initializer
|
||||||
val delegate = property.delegate
|
val delegate = property.delegate
|
||||||
val irParent = irProperty.parent
|
|
||||||
val propertyType = property.returnTypeRef.toIrType()
|
val propertyType = property.returnTypeRef.toIrType()
|
||||||
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
|
irProperty.initializeBackingField(descriptor, initializerExpression = initializer ?: delegate)
|
||||||
// TODO (2): backing field should be created inside declaration storage
|
|
||||||
if (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface)) {
|
|
||||||
if (initializer != null || property.getter is FirDefaultPropertyGetter ||
|
|
||||||
property.isVar && property.setter is FirDefaultPropertySetter
|
|
||||||
) {
|
|
||||||
irProperty.backingField = irProperty.createBackingField(
|
|
||||||
property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor,
|
|
||||||
property.fieldVisibility, property.name, property.isVal, initializer, propertyType
|
|
||||||
)
|
|
||||||
} else if (delegate != null) {
|
|
||||||
irProperty.backingField = irProperty.createBackingField(
|
|
||||||
property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor,
|
|
||||||
property.fieldVisibility, Name.identifier("${property.name}\$delegate"), true, delegate
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
irProperty.getter?.setPropertyAccessorContent(
|
irProperty.getter?.setPropertyAccessorContent(
|
||||||
property.getter, irProperty, propertyType, property.getter is FirDefaultPropertyGetter
|
property.getter, irProperty, propertyType, property.getter is FirDefaultPropertyGetter
|
||||||
)
|
)
|
||||||
@@ -168,42 +146,14 @@ internal class ClassMemberGenerator(
|
|||||||
return irProperty
|
return irProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirProperty.fieldVisibility: Visibility
|
private fun IrProperty.initializeBackingField(descriptor: PropertyDescriptor, initializerExpression: FirExpression?) {
|
||||||
get() = when {
|
val irField = backingField ?: return
|
||||||
isLateInit -> setter?.visibility ?: status.visibility
|
conversionScope.withParent(irField) {
|
||||||
isConst -> status.visibility
|
|
||||||
else -> Visibilities.PRIVATE
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrProperty.createBackingField(
|
|
||||||
property: FirProperty,
|
|
||||||
origin: IrDeclarationOrigin,
|
|
||||||
descriptor: PropertyDescriptor,
|
|
||||||
visibility: Visibility,
|
|
||||||
name: Name,
|
|
||||||
isFinal: Boolean,
|
|
||||||
firInitializerExpression: FirExpression?,
|
|
||||||
type: IrType? = null
|
|
||||||
): IrField {
|
|
||||||
val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType()
|
|
||||||
val irField = symbolTable.declareField(
|
|
||||||
startOffset, endOffset, origin, descriptor, inferredType
|
|
||||||
) { symbol ->
|
|
||||||
IrFieldImpl(
|
|
||||||
startOffset, endOffset, origin, symbol,
|
|
||||||
name, inferredType,
|
|
||||||
visibility, isFinal = isFinal, isExternal = false,
|
|
||||||
isStatic = property.isStatic || parent !is IrClass,
|
|
||||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return conversionScope.withParent(applyParentFromStackTo(irField)) {
|
|
||||||
declarationStorage.enterScope(descriptor)
|
declarationStorage.enterScope(descriptor)
|
||||||
if (firInitializerExpression != null) {
|
// NB: initializer can be already converted
|
||||||
val initializerExpression = visitor.convertToIrExpression(firInitializerExpression)
|
if (initializer == null && initializerExpression != null) {
|
||||||
initializer = IrExpressionBodyImpl(initializerExpression)
|
initializer = IrExpressionBodyImpl(visitor.convertToIrExpression(initializerExpression))
|
||||||
}
|
}
|
||||||
correspondingPropertySymbol = this@createBackingField.symbol
|
|
||||||
declarationStorage.leaveScope(descriptor)
|
declarationStorage.leaveScope(descriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user