FIR2IR: delay generation of delegated member bodies
Before this commit, we generated delegated member bodies eagerly at the moment when delegated member itself was generated. However, in fact delegated member may access e.g. fake override inside its body, so to work properly, we must delay body generation.
This commit is contained in:
@@ -103,6 +103,7 @@ class Fir2IrConverter(
|
|||||||
|
|
||||||
// 5. Body processing
|
// 5. Body processing
|
||||||
// If we encounter local class / anonymous object here, then we perform all (1)-(5) stages immediately
|
// If we encounter local class / anonymous object here, then we perform all (1)-(5) stages immediately
|
||||||
|
delegatedMemberGenerator.generateBodies()
|
||||||
for (firFile in allFirFiles) {
|
for (firFile in allFirFiles) {
|
||||||
firFile.accept(fir2irVisitor, null)
|
firFile.accept(fir2irVisitor, null)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor
|
|||||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
|
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
|
||||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction
|
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
|
||||||
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke
|
import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
@@ -949,7 +950,10 @@ class Fir2IrDeclarationStorage(
|
|||||||
fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField {
|
fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField {
|
||||||
val irField = createIrField(field, origin = IrDeclarationOrigin.DELEGATE)
|
val irField = createIrField(field, origin = IrDeclarationOrigin.DELEGATE)
|
||||||
irField.setAndModifyParent(irClass)
|
irField.setAndModifyParent(irClass)
|
||||||
components.delegatedMemberGenerator.generate(irField, field, owner, irClass)
|
delegatedMemberGenerator.generate(irField, field, owner, irClass)
|
||||||
|
if (owner.isLocalClassOrAnonymousObject()) {
|
||||||
|
delegatedMemberGenerator.generateBodies()
|
||||||
|
}
|
||||||
return irField
|
return irField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+42
-21
@@ -50,6 +50,40 @@ class DelegatedMemberGenerator(
|
|||||||
private val baseFunctionSymbols = mutableMapOf<IrFunction, List<FirNamedFunctionSymbol>>()
|
private val baseFunctionSymbols = mutableMapOf<IrFunction, List<FirNamedFunctionSymbol>>()
|
||||||
private val basePropertySymbols = mutableMapOf<IrProperty, List<FirPropertySymbol>>()
|
private val basePropertySymbols = mutableMapOf<IrProperty, List<FirPropertySymbol>>()
|
||||||
|
|
||||||
|
private data class DeclarationBodyInfo(
|
||||||
|
val declaration: IrDeclaration,
|
||||||
|
val field: IrField,
|
||||||
|
val delegateToSymbol: FirCallableSymbol<*>
|
||||||
|
)
|
||||||
|
|
||||||
|
private val bodiesInfo = mutableListOf<DeclarationBodyInfo>()
|
||||||
|
|
||||||
|
fun generateBodies() {
|
||||||
|
for ((declaration, irField, delegateToSymbol) in bodiesInfo) {
|
||||||
|
when (declaration) {
|
||||||
|
is IrSimpleFunction -> {
|
||||||
|
val member = declarationStorage.getIrFunctionSymbol(
|
||||||
|
delegateToSymbol as FirNamedFunctionSymbol
|
||||||
|
).owner as? IrSimpleFunction ?: continue
|
||||||
|
val body = createDelegateBody(irField, declaration, member)
|
||||||
|
declaration.body = body
|
||||||
|
}
|
||||||
|
is IrProperty -> {
|
||||||
|
val member = declarationStorage.getIrPropertySymbol(
|
||||||
|
delegateToSymbol as FirPropertySymbol
|
||||||
|
).owner as? IrProperty ?: continue
|
||||||
|
val getter = declaration.getter!!
|
||||||
|
getter.body = createDelegateBody(irField, getter, member.getter!!)
|
||||||
|
if (declaration.isVar) {
|
||||||
|
val setter = declaration.setter!!
|
||||||
|
setter.body = createDelegateBody(irField, setter, member.setter!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bodiesInfo.clear()
|
||||||
|
}
|
||||||
|
|
||||||
// Generate delegated members for [subClass]. The synthetic field [irField] has the super interface type.
|
// Generate delegated members for [subClass]. The synthetic field [irField] has the super interface type.
|
||||||
fun generate(irField: IrField, firField: FirField, firSubClass: FirClass, subClass: IrClass) {
|
fun generate(irField: IrField, firField: FirField, firSubClass: FirClass, subClass: IrClass) {
|
||||||
val subClassLookupTag = firSubClass.symbol.toLookupTag()
|
val subClassLookupTag = firSubClass.symbol.toLookupTag()
|
||||||
@@ -61,18 +95,14 @@ class DelegatedMemberGenerator(
|
|||||||
.unwrapDelegateTarget(subClassLookupTag, firField)
|
.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||||
?: return@processAllFunctions
|
?: return@processAllFunctions
|
||||||
|
|
||||||
val member =
|
|
||||||
declarationStorage.getIrFunctionSymbol(unwrapped.symbol).owner as? IrSimpleFunction
|
|
||||||
?: return@processAllFunctions
|
|
||||||
|
|
||||||
if (shouldSkipDelegationFor(unwrapped)) {
|
if (shouldSkipDelegationFor(unwrapped)) {
|
||||||
return@processAllFunctions
|
return@processAllFunctions
|
||||||
}
|
}
|
||||||
|
|
||||||
val irSubFunction = generateDelegatedFunction(
|
val irSubFunction = generateDelegatedFunction(
|
||||||
subClass, firSubClass, irField, member, functionSymbol.fir
|
subClass, firSubClass, functionSymbol.fir
|
||||||
)
|
)
|
||||||
|
bodiesInfo += DeclarationBodyInfo(irSubFunction, irField, unwrapped.symbol)
|
||||||
declarationStorage.cacheDelegationFunction(functionSymbol.fir, irSubFunction)
|
declarationStorage.cacheDelegationFunction(functionSymbol.fir, irSubFunction)
|
||||||
subClass.addMember(irSubFunction)
|
subClass.addMember(irSubFunction)
|
||||||
}
|
}
|
||||||
@@ -85,17 +115,14 @@ class DelegatedMemberGenerator(
|
|||||||
.unwrapDelegateTarget(subClassLookupTag, firField)
|
.unwrapDelegateTarget(subClassLookupTag, firField)
|
||||||
?: return@processAllProperties
|
?: return@processAllProperties
|
||||||
|
|
||||||
val member = declarationStorage.getIrPropertySymbol(unwrapped.symbol).owner as? IrProperty
|
|
||||||
?: return@processAllProperties
|
|
||||||
|
|
||||||
if (shouldSkipDelegationFor(unwrapped)) {
|
if (shouldSkipDelegationFor(unwrapped)) {
|
||||||
return@processAllProperties
|
return@processAllProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
val irSubProperty = generateDelegatedProperty(
|
val irSubProperty = generateDelegatedProperty(
|
||||||
subClass, firSubClass, irField, member, propertySymbol.fir
|
subClass, firSubClass, propertySymbol.fir
|
||||||
)
|
)
|
||||||
|
bodiesInfo += DeclarationBodyInfo(irSubProperty, irField, unwrapped.symbol)
|
||||||
declarationStorage.cacheDelegatedProperty(propertySymbol.fir, irSubProperty)
|
declarationStorage.cacheDelegatedProperty(propertySymbol.fir, irSubProperty)
|
||||||
subClass.addMember(irSubProperty)
|
subClass.addMember(irSubProperty)
|
||||||
}
|
}
|
||||||
@@ -146,8 +173,6 @@ class DelegatedMemberGenerator(
|
|||||||
private fun generateDelegatedFunction(
|
private fun generateDelegatedFunction(
|
||||||
subClass: IrClass,
|
subClass: IrClass,
|
||||||
firSubClass: FirClass,
|
firSubClass: FirClass,
|
||||||
irField: IrField,
|
|
||||||
superFunction: IrSimpleFunction,
|
|
||||||
delegateOverride: FirSimpleFunction
|
delegateOverride: FirSimpleFunction
|
||||||
): IrSimpleFunction {
|
): IrSimpleFunction {
|
||||||
val delegateFunction =
|
val delegateFunction =
|
||||||
@@ -164,8 +189,6 @@ class DelegatedMemberGenerator(
|
|||||||
baseFunctionSymbols[delegateFunction] = baseSymbols
|
baseFunctionSymbols[delegateFunction] = baseSymbols
|
||||||
annotationGenerator.generate(delegateFunction, delegateOverride)
|
annotationGenerator.generate(delegateFunction, delegateOverride)
|
||||||
|
|
||||||
val body = createDelegateBody(irField, delegateFunction, superFunction)
|
|
||||||
delegateFunction.body = body
|
|
||||||
return delegateFunction
|
return delegateFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,8 +249,6 @@ class DelegatedMemberGenerator(
|
|||||||
private fun generateDelegatedProperty(
|
private fun generateDelegatedProperty(
|
||||||
subClass: IrClass,
|
subClass: IrClass,
|
||||||
firSubClass: FirClass,
|
firSubClass: FirClass,
|
||||||
irField: IrField,
|
|
||||||
superProperty: IrProperty,
|
|
||||||
firDelegateProperty: FirProperty
|
firDelegateProperty: FirProperty
|
||||||
): IrProperty {
|
): IrProperty {
|
||||||
val delegateProperty =
|
val delegateProperty =
|
||||||
@@ -244,8 +265,8 @@ class DelegatedMemberGenerator(
|
|||||||
basePropertySymbols[delegateProperty] = baseSymbols
|
basePropertySymbols[delegateProperty] = baseSymbols
|
||||||
annotationGenerator.generate(delegateProperty, firDelegateProperty)
|
annotationGenerator.generate(delegateProperty, firDelegateProperty)
|
||||||
|
|
||||||
delegateProperty.getter!!.body = createDelegateBody(irField, delegateProperty.getter!!, superProperty.getter!!)
|
val getter = delegateProperty.getter!!
|
||||||
delegateProperty.getter!!.overriddenSymbols =
|
getter.overriddenSymbols =
|
||||||
firDelegateProperty.generateOverriddenAccessorSymbols(
|
firDelegateProperty.generateOverriddenAccessorSymbols(
|
||||||
firSubClass,
|
firSubClass,
|
||||||
isGetter = true,
|
isGetter = true,
|
||||||
@@ -256,8 +277,8 @@ class DelegatedMemberGenerator(
|
|||||||
)
|
)
|
||||||
annotationGenerator.generate(delegateProperty.getter!!, firDelegateProperty)
|
annotationGenerator.generate(delegateProperty.getter!!, firDelegateProperty)
|
||||||
if (delegateProperty.isVar) {
|
if (delegateProperty.isVar) {
|
||||||
delegateProperty.setter!!.body = createDelegateBody(irField, delegateProperty.setter!!, superProperty.setter!!)
|
val setter = delegateProperty.setter!!
|
||||||
delegateProperty.setter!!.overriddenSymbols =
|
setter.overriddenSymbols =
|
||||||
firDelegateProperty.generateOverriddenAccessorSymbols(
|
firDelegateProperty.generateOverriddenAccessorSymbols(
|
||||||
firSubClass, isGetter = false, session, scopeSession, declarationStorage, fakeOverrideGenerator
|
firSubClass, isGetter = false, session, scopeSession, declarationStorage, fakeOverrideGenerator
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user