Fir2Ir: fix deserializing IR for property accessors

1. Need to register Fir2IrLazyPropertyAccessors in symbol table.
2. Need to set their bodies.
This commit is contained in:
Georgy Bronnikov
2022-01-12 15:03:50 +03:00
committed by Alexander Udalov
parent f94b0bbcea
commit 1fbd79e310
7 changed files with 66 additions and 71 deletions
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.symbols.Fir2IrBindableSymbol
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrFactory
@@ -19,11 +17,10 @@ import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator
import kotlin.properties.ReadWriteProperty
interface AbstractFir2IrLazyDeclaration<F, D : IrDeclaration> :
IrDeclaration, IrLazyDeclarationBase, Fir2IrComponents where F : FirMemberDeclaration, F : FirAnnotationContainer {
interface AbstractFir2IrLazyDeclaration<F> :
IrDeclaration, IrLazyDeclarationBase, Fir2IrComponents where F : FirAnnotationContainer {
val fir: F
override val symbol: Fir2IrBindableSymbol<*, D>
override val factory: IrFactory
get() = irFactory
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunctionBase
@@ -21,7 +20,9 @@ import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.ir.util.isFacadeClass
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.name.ClassId
@@ -33,9 +34,9 @@ abstract class AbstractFir2IrLazyFunction<F : FirCallableDeclaration>(
override val startOffset: Int,
override val endOffset: Int,
override var origin: IrDeclarationOrigin,
override val symbol: Fir2IrSimpleFunctionSymbol,
override val symbol: IrSimpleFunctionSymbol,
override val isFakeOverride: Boolean
) : IrSimpleFunction(), AbstractFir2IrLazyDeclaration<F, IrSimpleFunction>, Fir2IrTypeParametersContainer, IrLazyFunctionBase,
) : IrSimpleFunction(), AbstractFir2IrLazyDeclaration<F>, Fir2IrTypeParametersContainer, IrLazyFunctionBase,
Fir2IrComponents by components {
override lateinit var typeParameters: List<IrTypeParameter>
@@ -66,9 +67,9 @@ abstract class AbstractFir2IrLazyFunction<F : FirCallableDeclaration>(
override val isExpect: Boolean
get() = fir.isExpect
override var body: IrBody?
get() = null
set(_) = error("We should never need to store body of external functions.")
override var body: IrBody? by lazyVar(lock) {
if (tryLoadIr()) body else null
}
override var visibility: DescriptorVisibility by lazyVar(lock) {
components.visibilityConverter.convertToDescriptorVisibility(fir.visibility)
@@ -107,6 +108,21 @@ abstract class AbstractFir2IrLazyFunction<F : FirCallableDeclaration>(
return super<AbstractFir2IrLazyDeclaration>.createLazyAnnotations()
}
private fun tryLoadIr(): Boolean {
if (!isInline || isFakeOverride) return false
if (!extensions.irNeedsDeserialization) return false
val toplevel = getToplevel()
return (toplevel as? DeserializableClass)?.loadIr() ?: false
}
private fun getToplevel(): IrDeclaration {
var current: IrDeclaration = this
while (current.parent !is IrPackageFragment) {
current = current.parent as IrDeclaration
}
return current
}
companion object {
private val JVM_STATIC_CLASS_ID = ClassId.topLevel(JVM_STATIC_ANNOTATION_FQ_NAME)
}
@@ -41,7 +41,7 @@ class Fir2IrLazyClass(
override var origin: IrDeclarationOrigin,
override val fir: FirRegularClass,
override val symbol: Fir2IrClassSymbol,
) : IrClass(), AbstractFir2IrLazyDeclaration<FirRegularClass, IrClass>, Fir2IrTypeParametersContainer,
) : IrClass(), AbstractFir2IrLazyDeclaration<FirRegularClass>, Fir2IrTypeParametersContainer,
IrMaybeDeserializedClass, DeserializableClass, Fir2IrComponents by components {
init {
symbol.bind(this)
@@ -35,7 +35,7 @@ class Fir2IrLazyConstructor(
override var origin: IrDeclarationOrigin,
override val fir: FirConstructor,
override val symbol: Fir2IrConstructorSymbol,
) : IrConstructor(), AbstractFir2IrLazyDeclaration<FirConstructor, IrConstructor>, Fir2IrTypeParametersContainer,
) : IrConstructor(), AbstractFir2IrLazyDeclaration<FirConstructor>, Fir2IrTypeParametersContainer,
Fir2IrComponents by components {
init {
symbol.bind(this)
@@ -42,7 +42,7 @@ class Fir2IrLazyProperty(
internal val containingClass: FirRegularClass?,
override val symbol: Fir2IrPropertySymbol,
override val isFakeOverride: Boolean
) : IrProperty(), AbstractFir2IrLazyDeclaration<FirProperty, IrProperty>, Fir2IrComponents by components {
) : IrProperty(), AbstractFir2IrLazyDeclaration<FirProperty>, Fir2IrComponents by components {
init {
symbol.bind(this)
classifierStorage.preCacheTypeParameters(fir)
@@ -160,20 +160,19 @@ class Fir2IrLazyProperty(
override var getter: IrSimpleFunction? by lazyVar(lock) {
if (fir.isConst) return@lazyVar null
Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
when {
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin
fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
fir.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
else -> origin
},
fir.getter, isSetter = false, fir, containingClass,
Fir2IrSimpleFunctionSymbol(
signatureComposer.composeAccessorSignature(fir, isSetter = false, containingClass?.symbol?.toLookupTag())!!
),
isFakeOverride
).apply {
val signature = signatureComposer.composeAccessorSignature(fir, isSetter = false, containingClass?.symbol?.toLookupTag())!!
symbolTable.declareSimpleFunction(signature, symbolFactory = { Fir2IrSimpleFunctionSymbol(signature) }) { symbol ->
Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
when {
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin
fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
fir.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
else -> origin
},
fir.getter, isSetter = false, fir, containingClass, symbol, isFakeOverride
)
}.apply {
parent = this@Fir2IrLazyProperty.parent
correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol
with(classifierStorage) {
@@ -188,29 +187,31 @@ class Fir2IrLazyProperty(
}
override var setter: IrSimpleFunction? by lazyVar(lock) {
if (!fir.isVar) null else Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
when {
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin
fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
fir.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
else -> origin
},
fir.setter, isSetter = true, fir, containingClass,
Fir2IrSimpleFunctionSymbol(
signatureComposer.composeAccessorSignature(fir, isSetter = true, containingClass?.symbol?.toLookupTag())!!
),
isFakeOverride
).apply {
parent = this@Fir2IrLazyProperty.parent
correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol
with(classifierStorage) {
setTypeParameters(
this@Fir2IrLazyProperty.fir, ConversionTypeContext(
definitelyNotNull = false,
origin = ConversionTypeOrigin.SETTER
)
)
if (!fir.isVar) null
else {
val signature = signatureComposer.composeAccessorSignature(fir, isSetter = true, containingClass?.symbol?.toLookupTag())!!
symbolTable.declareSimpleFunction(signature, symbolFactory = { Fir2IrSimpleFunctionSymbol(signature) }) { symbol ->
Fir2IrLazyPropertyAccessor(
components, startOffset, endOffset,
when {
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB -> origin
fir.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
fir.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
else -> origin
},
fir.setter, isSetter = true, fir, containingClass, symbol, isFakeOverride
).apply {
parent = this@Fir2IrLazyProperty.parent
correspondingPropertySymbol = this@Fir2IrLazyProperty.symbol
with(classifierStorage) {
setTypeParameters(
this@Fir2IrLazyProperty.fir, ConversionTypeContext(
definitelyNotNull = false,
origin = ConversionTypeOrigin.SETTER
)
)
}
}
}
}
}
@@ -34,7 +34,7 @@ class Fir2IrLazyPropertyAccessor(
private val isSetter: Boolean,
private val firParentProperty: FirProperty,
firParentClass: FirRegularClass?,
symbol: Fir2IrSimpleFunctionSymbol,
symbol: IrSimpleFunctionSymbol,
isFakeOverride: Boolean
) : AbstractFir2IrLazyFunction<FirCallableDeclaration>(components, startOffset, endOffset, origin, symbol, isFakeOverride) {
init {
@@ -51,10 +51,6 @@ class Fir2IrLazySimpleFunction(
fir.returnTypeRef.toIrType(typeConverter)
}
override var body: IrBody? by lazyVar(lock) {
if (tryLoadIr()) body else null
}
override var dispatchReceiverParameter: IrValueParameter? by lazyVar(lock) {
val containingClass = parent as? IrClass
if (containingClass != null && shouldHaveDispatchReceiver(containingClass, fir)) {
@@ -110,19 +106,4 @@ class Fir2IrLazySimpleFunction(
override val containerSource: DeserializedContainerSource?
get() = fir.containerSource
private fun tryLoadIr(): Boolean {
if (!isInline || isFakeOverride) return false
if (!extensions.irNeedsDeserialization) return false
val toplevel = getToplevel()
return (toplevel as? DeserializableClass)?.loadIr() ?: false
}
private fun getToplevel(): IrDeclaration {
var current: IrDeclaration = this
while (current.parent !is IrPackageFragment) {
current = current.parent as IrDeclaration
}
return current
}
}