[FIR2IR] Cache delegatable members properly
This commit is contained in:
@@ -217,7 +217,7 @@ class Fir2IrConverter(
|
||||
}
|
||||
is FirField -> {
|
||||
if (declaration.isSynthetic) {
|
||||
declarationStorage.createIrFieldAndDelegatedMembers(declaration, parent as IrClass)
|
||||
declarationStorage.createIrFieldAndDelegatedMembers(declaration, containingClass!!, parent as IrClass)
|
||||
} else {
|
||||
throw AssertionError("Unexpected non-synthetic field: ${declaration::class}")
|
||||
}
|
||||
|
||||
+11
-3
@@ -370,6 +370,10 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun cacheIrSimpleFunction(function: FirSimpleFunction, irFunction: IrSimpleFunction) {
|
||||
functionCache[function] = irFunction
|
||||
}
|
||||
|
||||
internal fun declareIrSimpleFunction(
|
||||
signature: IdSignature?,
|
||||
containerSource: DeserializedContainerSource?,
|
||||
@@ -737,12 +741,16 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
fun getCachedIrProperty(property: FirProperty): IrProperty? = propertyCache[property]
|
||||
|
||||
internal fun cacheIrProperty(property: FirProperty, irProperty: IrProperty) {
|
||||
propertyCache[property] = irProperty
|
||||
}
|
||||
|
||||
fun getCachedIrField(field: FirField): IrField? = fieldCache[field]
|
||||
|
||||
fun createIrFieldAndDelegatedMembers(field: FirField, parent: IrClass): IrField {
|
||||
fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass<*>, irClass: IrClass): IrField {
|
||||
val irField = createIrField(field, origin = IrDeclarationOrigin.DELEGATE)
|
||||
irField.setAndModifyParent(parent)
|
||||
delegatedMemberGenerator.generate(irField, parent)
|
||||
irField.setAndModifyParent(irClass)
|
||||
delegatedMemberGenerator.generate(irField, owner, irClass)
|
||||
return irField
|
||||
}
|
||||
|
||||
|
||||
+40
-10
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameterCopy
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
@@ -54,7 +55,7 @@ internal class DelegatedMemberGenerator(
|
||||
) : Fir2IrComponents by components {
|
||||
|
||||
// Generate delegated members for [subClass]. The synthetic field [irField] has the super interface type.
|
||||
fun generate(irField: IrField, subClass: IrClass) {
|
||||
fun generate(irField: IrField, firSubClass: FirClass<*>, subClass: IrClass) {
|
||||
val delegateClass = (irField.type as IrSimpleTypeImpl).classOrNull?.owner ?: return
|
||||
val subClasses = mutableMapOf(delegateClass to mutableListOf(subClass))
|
||||
DFS.dfs(
|
||||
@@ -73,21 +74,50 @@ internal class DelegatedMemberGenerator(
|
||||
)
|
||||
|
||||
for ((superClass, mayOverride) in subClasses) {
|
||||
val classId = superClass.classId ?: continue
|
||||
if (classId == irBuiltIns.anyClass.owner.classId) continue
|
||||
val superClassId = superClass.classId ?: continue
|
||||
if (superClassId == irBuiltIns.anyClass.owner.classId) continue
|
||||
for (member in superClass.declarations) {
|
||||
val delegatable = member.isDelegatable() && !DFS.ifAny(mayOverride, { subClasses[it] ?: emptyList() }) {
|
||||
// Delegate to the most specific version of each member.
|
||||
it.declarations.any { !it.isFakeOverride && it.overrides(member) }
|
||||
}
|
||||
if (!delegatable) continue
|
||||
val scope = firSubClass.unsubstitutedScope(session, scopeSession)
|
||||
if (member is IrSimpleFunction) {
|
||||
val firFunction = declarationStorage.findOverriddenFirFunction(member, classId) ?: return
|
||||
val function = generateDelegatedFunction(subClass, irField, member, firFunction)
|
||||
subClass.addMember(function)
|
||||
val firSuperFunction = declarationStorage.findOverriddenFirFunction(member, superClassId) ?: return
|
||||
var firSubFunction: FirSimpleFunction? = null
|
||||
scope.processFunctionsByName(member.name) {
|
||||
if (it.callableId.classId == firSubClass.classId) {
|
||||
var overriddenFunctionSymbol = it.overriddenSymbol
|
||||
while (overriddenFunctionSymbol != null) {
|
||||
if (overriddenFunctionSymbol.fir == firSuperFunction) {
|
||||
firSubFunction = it.fir as FirSimpleFunction
|
||||
break
|
||||
}
|
||||
overriddenFunctionSymbol = overriddenFunctionSymbol.overriddenSymbol
|
||||
}
|
||||
}
|
||||
}
|
||||
val irSubFunction = generateDelegatedFunction(subClass, irField, member, firSuperFunction)
|
||||
firSubFunction?.let { declarationStorage.cacheIrSimpleFunction(it, irSubFunction) }
|
||||
subClass.addMember(irSubFunction)
|
||||
} else if (member is IrProperty) {
|
||||
val firProperty = declarationStorage.findOverriddenFirProperty(member, classId) ?: return
|
||||
generateDelegatedProperty(subClass, irField, member, firProperty)
|
||||
val firSuperProperty = declarationStorage.findOverriddenFirProperty(member, superClassId) ?: return
|
||||
var firSubProperty: FirProperty? = null
|
||||
scope.processPropertiesByName(member.name) {
|
||||
if (it.callableId.classId == firSubClass.classId) {
|
||||
var overriddenPropertySymbol = it.overriddenSymbol
|
||||
while (overriddenPropertySymbol != null) {
|
||||
if (overriddenPropertySymbol.fir == firSuperProperty) {
|
||||
firSubProperty = it.fir as FirProperty
|
||||
break
|
||||
}
|
||||
overriddenPropertySymbol = overriddenPropertySymbol.overriddenSymbol
|
||||
}
|
||||
}
|
||||
}
|
||||
val irSubProperty = generateDelegatedProperty(subClass, irField, member, firSuperProperty)
|
||||
firSubProperty?.let { declarationStorage.cacheIrProperty(it, irSubProperty) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,12 +335,12 @@ internal class DelegatedMemberGenerator(
|
||||
irField: IrField,
|
||||
superProperty: IrProperty,
|
||||
firSuperProperty: FirProperty
|
||||
) {
|
||||
): IrProperty {
|
||||
val startOffset = irField.startOffset
|
||||
val endOffset = irField.endOffset
|
||||
val descriptor = WrappedPropertyDescriptor()
|
||||
val modality = if (superProperty.modality == Modality.ABSTRACT) Modality.OPEN else superProperty.modality
|
||||
symbolTable.declareProperty(
|
||||
return symbolTable.declareProperty(
|
||||
startOffset, endOffset,
|
||||
IrDeclarationOrigin.DELEGATED_MEMBER, descriptor, superProperty.isDelegated
|
||||
) { symbol ->
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface A<T> {
|
||||
fun id(t: T): T
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface A<T> {
|
||||
var zzzValue : T
|
||||
fun zzz() : T
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
inline class Wrapper(val id: Int)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: -AdditionalBuiltInsMembers
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// SKIP_JDK6
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface Tr<T> {
|
||||
val prop: T
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user