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