IR: properly compute IrProperty.resolveFakeOverride()
Now that IrProperty has its own overriddenSymbols, we can generalize the search for fake overrides. Also works for fake override properties derived from Java fields.
This commit is contained in:
+2
-2
@@ -776,8 +776,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
|
||||
return this.overriddenSymbols
|
||||
.map { it.owner }
|
||||
.collectAndFilterRealOverrides(getOverriddenPropertySymbols = IrProperty::overriddenSymbols)
|
||||
.firstOrNull() as? IrProperty
|
||||
.collectAndFilterRealOverrides()
|
||||
.firstOrNull()
|
||||
?: throw AssertionError("No real override for ${this.render()}")
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,9 @@ interface IrDeclaration : IrStatement, IrSymbolOwner, IrMutableAnnotationContain
|
||||
|
||||
abstract class IrDeclarationBase : IrElementBase(), IrDeclaration
|
||||
|
||||
interface IrOverridableDeclaration<S : IrSymbol> : IrDeclaration {
|
||||
interface IrOverridableDeclaration<S : IrSymbol> : IrOverridableMember {
|
||||
override val symbol: S
|
||||
val isFakeOverride: Boolean
|
||||
var overriddenSymbols: List<S>
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
abstract class IrProperty :
|
||||
IrDeclarationBase(),
|
||||
IrPossiblyExternalDeclaration,
|
||||
IrOverridableMember,
|
||||
IrOverridableDeclaration<IrPropertySymbol>,
|
||||
IrMetadataSourceOwner,
|
||||
IrAttributeContainer,
|
||||
@@ -40,7 +39,7 @@ abstract class IrProperty :
|
||||
abstract val isLateinit: Boolean
|
||||
abstract val isDelegated: Boolean
|
||||
abstract val isExpect: Boolean
|
||||
abstract val isFakeOverride: Boolean
|
||||
abstract override val isFakeOverride: Boolean
|
||||
|
||||
abstract var backingField: IrField?
|
||||
abstract var getter: IrSimpleFunction?
|
||||
|
||||
@@ -12,14 +12,13 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
abstract class IrSimpleFunction :
|
||||
IrFunction(),
|
||||
IrOverridableDeclaration<IrSimpleFunctionSymbol>,
|
||||
IrOverridableMember,
|
||||
IrAttributeContainer {
|
||||
|
||||
abstract override val symbol: IrSimpleFunctionSymbol
|
||||
|
||||
abstract val isTailrec: Boolean
|
||||
abstract val isSuspend: Boolean
|
||||
abstract val isFakeOverride: Boolean
|
||||
abstract override val isFakeOverride: Boolean
|
||||
abstract val isOperator: Boolean
|
||||
abstract val isInfix: Boolean
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class IrLazyProperty(
|
||||
|
||||
override var overriddenSymbols: List<IrPropertySymbol> by lazyVar(stubGenerator.lock) {
|
||||
descriptor.overriddenDescriptors.mapTo(ArrayList()) {
|
||||
stubGenerator.generatePropertyStub(it).symbol
|
||||
stubGenerator.generatePropertyStub(it.original).symbol
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.collectAndFilterRealOverrides
|
||||
import org.jetbrains.kotlin.ir.util.isReal
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo
|
||||
@@ -36,9 +35,6 @@ abstract class FakeOverrideBuilderStrategy {
|
||||
|
||||
protected abstract fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction)
|
||||
protected abstract fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty)
|
||||
|
||||
// TODO: need to make IrProperty carry overriddenSymbols.
|
||||
val propertyOverriddenSymbols: MutableMap<IrOverridableMember, List<IrSymbol>> = mutableMapOf()
|
||||
}
|
||||
|
||||
fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember {
|
||||
@@ -89,35 +85,32 @@ class IrOverridingUtil(
|
||||
originalSuperTypes.clear()
|
||||
}
|
||||
|
||||
private var IrOverridableMember.overriddenSymbols: List<IrSymbol>
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> this.overriddenSymbols
|
||||
is IrProperty -> fakeOverrideBuilder.propertyOverriddenSymbols[this]
|
||||
?: error("No overridden symbols for ${this.render()}")
|
||||
private val IrOverridableMember.overriddenSymbols: List<IrSymbol>
|
||||
get() = (this as? IrOverridableDeclaration<*>)?.overriddenSymbols
|
||||
?: error("Unexpected IrOverridableMember: $this")
|
||||
|
||||
private fun IrOverridableMember.setOverriddenSymbols(value: List<IrSymbol>) {
|
||||
when (this) {
|
||||
is IrSimpleFunction -> this.overriddenSymbols =
|
||||
value.map { it as? IrSimpleFunctionSymbol ?: error("Unexpected function overridden symbol: $it") }
|
||||
is IrProperty -> {
|
||||
this.overriddenSymbols =
|
||||
value.map { it as? IrPropertySymbol ?: error("Unexpected property overridden symbol: $it") }
|
||||
val getter = this.getter ?: error("Property has no getter: ${render()}")
|
||||
getter.overriddenSymbols = value.map { (it.owner as IrProperty).getter!!.symbol }
|
||||
this.setter?.let { setter ->
|
||||
setter.overriddenSymbols = value.mapNotNull { (it.owner as IrProperty).setter?.symbol }
|
||||
}
|
||||
}
|
||||
else -> error("Unexpected declaration for overriddenSymbols: $this")
|
||||
}
|
||||
set(value) {
|
||||
when (this) {
|
||||
is IrSimpleFunction -> this.overriddenSymbols =
|
||||
value.map { it as? IrSimpleFunctionSymbol ?: error("Unexpected function overridden symbol: $it") }
|
||||
is IrProperty -> {
|
||||
fakeOverrideBuilder.propertyOverriddenSymbols[this] =
|
||||
value.map { it as? IrPropertySymbol ?: error("Unexpected property overridden symbol: $it") }
|
||||
val getter = this.getter ?: error("Property has no getter: ${render()}")
|
||||
getter.overriddenSymbols = value.map { (it.owner as IrProperty).getter!!.symbol }
|
||||
this.setter?.let { setter ->
|
||||
setter.overriddenSymbols = value.mapNotNull { (it.owner as IrProperty).setter?.symbol }
|
||||
}
|
||||
}
|
||||
else -> error("Unexpected declaration for overriddenSymbols: $this")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun buildFakeOverridesForClass(clazz: IrClass) {
|
||||
val superTypes = clazz.superTypes
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val fromCurrent = clazz.declarations.filter { it is IrOverridableMember } as List<IrOverridableMember>
|
||||
val fromCurrent = clazz.declarations.filterIsInstance<IrOverridableMember>()
|
||||
|
||||
val allFromSuper = superTypes.flatMap { superType ->
|
||||
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
|
||||
@@ -147,19 +140,8 @@ class IrOverridingUtil(
|
||||
clazz: IrClass,
|
||||
implementedMembers: List<IrOverridableMember> = emptyList()
|
||||
): List<IrOverridableMember> {
|
||||
fakeOverrideBuilder.propertyOverriddenSymbols.clear()
|
||||
|
||||
val overriddenMembers = (clazz.declarations.filterIsInstance<IrOverridableMember>() + implementedMembers)
|
||||
.flatMap {
|
||||
when (it) {
|
||||
is IrSimpleFunction -> it.overriddenSymbols.map { it.owner }
|
||||
// TODO: use IrProperty.overriddenSymbols instead: KT-47019
|
||||
is IrProperty -> (it.getter ?: it.setter)?.overriddenSymbols
|
||||
?.map { it.owner.correspondingPropertySymbol!!.owner }
|
||||
?: emptyList()
|
||||
else -> error("Unexpected IrOverridableMember: $it")
|
||||
}
|
||||
}
|
||||
.flatMap { member -> member.overriddenSymbols.map { it.owner } }
|
||||
.toSet()
|
||||
|
||||
val unoverriddenSuperMembers = clazz.superTypes.flatMap { superType ->
|
||||
@@ -242,7 +224,7 @@ class IrOverridingUtil(
|
||||
}
|
||||
}
|
||||
//strategy.setOverriddenDescriptors(fromCurrent, overridden)
|
||||
fromCurrent.overriddenSymbols = overridden.map { it.original.symbol }
|
||||
fromCurrent.setOverriddenSymbols(overridden.map { it.original.symbol })
|
||||
|
||||
return bound
|
||||
}
|
||||
@@ -400,7 +382,7 @@ class IrOverridingUtil(
|
||||
}
|
||||
}
|
||||
|
||||
fakeOverride.overriddenSymbols = effectiveOverridden.map { it.original.symbol }
|
||||
fakeOverride.setOverriddenSymbols(effectiveOverridden.map { it.original.symbol })
|
||||
|
||||
assert(
|
||||
fakeOverride.overriddenSymbols.isNotEmpty()
|
||||
|
||||
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
val IrDeclaration.isReal: Boolean get() = !isFakeOverride
|
||||
@@ -31,65 +31,50 @@ val IrFunction.target: IrFunction get() = when (this) {
|
||||
else -> error(this)
|
||||
}
|
||||
|
||||
fun IrSimpleFunction.collectRealOverrides(
|
||||
toSkip: (IrSimpleFunction) -> Boolean = { false },
|
||||
filter: (IrOverridableMember) -> Boolean = { false }
|
||||
): Set<IrSimpleFunction> {
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.collectRealOverrides(
|
||||
toSkip: (T) -> Boolean = { false },
|
||||
filter: (T) -> Boolean = { false }
|
||||
): Set<T> {
|
||||
if (isReal && !toSkip(this)) return setOf(this)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return this.overriddenSymbols
|
||||
.map { it.owner }
|
||||
.collectAndFilterRealOverrides(
|
||||
{
|
||||
require(it is IrSimpleFunction) { "Expected IrSimpleFunction: ${it.render()}" }
|
||||
toSkip(it)
|
||||
},
|
||||
filter
|
||||
) as Set<IrSimpleFunction>
|
||||
.map { it.owner as T }
|
||||
.collectAndFilterRealOverrides(toSkip, filter)
|
||||
}
|
||||
|
||||
fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(
|
||||
toSkip: (IrOverridableMember) -> Boolean = { false },
|
||||
filter: (IrOverridableMember) -> Boolean = { false },
|
||||
getOverriddenPropertySymbols: IrProperty.() -> List<IrPropertySymbol> = {
|
||||
// TODO: use IrProperty.overriddenSymbols instead: KT-47019
|
||||
// (at the moment it breaks K/N in at least :kotlin-native:backend.native:tests:coroutines_functionReference_eqeq_name)
|
||||
(getter ?: setter)?.overriddenSymbols?.mapNotNull { it.owner.correspondingPropertySymbol }.orEmpty()
|
||||
},
|
||||
): Set<IrOverridableMember> {
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> Collection<T>.collectAndFilterRealOverrides(
|
||||
toSkip: (T) -> Boolean = { false },
|
||||
filter: (T) -> Boolean = { false }
|
||||
): Set<T> {
|
||||
|
||||
val visited = mutableSetOf<IrOverridableMember>()
|
||||
val realOverrides = mutableMapOf<Any, IrOverridableMember>()
|
||||
val visited = mutableSetOf<T>()
|
||||
val realOverrides = mutableMapOf<Any, T>()
|
||||
|
||||
/*
|
||||
Due to IR copying in performByIrFile, overrides should only be distinguished up to their signatures.
|
||||
*/
|
||||
fun IrOverridableMember.toKey(): Any = symbol.signature ?: this
|
||||
fun T.toKey(): Any = symbol.signature ?: this
|
||||
|
||||
fun overriddenSymbols(declaration: IrOverridableMember) = when (declaration) {
|
||||
is IrSimpleFunction -> declaration.overriddenSymbols
|
||||
is IrProperty -> declaration.getOverriddenPropertySymbols()
|
||||
else -> error("Unexpected overridable member: ${declaration.render()}")
|
||||
}
|
||||
|
||||
fun collectRealOverrides(member: IrOverridableMember) {
|
||||
fun collectRealOverrides(member: T) {
|
||||
if (!visited.add(member) || filter(member)) return
|
||||
|
||||
if (member.isReal && !toSkip(member)) {
|
||||
realOverrides[member.toKey()] = member
|
||||
} else {
|
||||
overriddenSymbols(member).forEach { collectRealOverrides(it.owner as IrOverridableMember) }
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
member.overriddenSymbols.forEach { collectRealOverrides(it.owner as T) }
|
||||
}
|
||||
}
|
||||
|
||||
this.forEach { collectRealOverrides(it) }
|
||||
|
||||
fun excludeRepeated(member: IrOverridableMember) {
|
||||
fun excludeRepeated(member: T) {
|
||||
if (!visited.add(member)) return
|
||||
|
||||
overriddenSymbols(member).forEach {
|
||||
val owner = it.owner as IrOverridableMember
|
||||
member.overriddenSymbols.forEach {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val owner = it.owner as T
|
||||
realOverrides.remove(owner.toKey())
|
||||
excludeRepeated(owner)
|
||||
}
|
||||
@@ -101,8 +86,16 @@ fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(
|
||||
return realOverrides.values.toSet()
|
||||
}
|
||||
|
||||
fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(): Set<IrOverridableMember> =
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(this as Collection<IrOverridableDeclaration<*>>).collectAndFilterRealOverrides()
|
||||
|
||||
// TODO: use this implementation instead of any other
|
||||
fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false, toSkip: (IrSimpleFunction) -> Boolean = { false }): IrSimpleFunction? {
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverride(
|
||||
allowAbstract: Boolean = false,
|
||||
toSkip: (T) -> Boolean = { false }
|
||||
): T? {
|
||||
if (!isFakeOverride) return this
|
||||
return if (allowAbstract) {
|
||||
val reals = collectRealOverrides(toSkip)
|
||||
if (reals.isEmpty()) error("No real overrides for ${this.render()}")
|
||||
|
||||
@@ -248,8 +248,6 @@ fun IrSimpleFunction.findInterfaceImplementation(): IrSimpleFunction? {
|
||||
return resolveFakeOverride()?.run { if (parentAsClass.isInterface) this else null }
|
||||
}
|
||||
|
||||
fun IrProperty.resolveFakeOverride(): IrProperty? = getter?.resolveFakeOverride()?.correspondingPropertySymbol?.owner
|
||||
|
||||
val IrClass.isAnnotationClass get() = kind == ClassKind.ANNOTATION_CLASS
|
||||
val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS
|
||||
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
|
||||
|
||||
-1
@@ -159,7 +159,6 @@ class FakeOverrideBuilder(
|
||||
|
||||
private fun provideFakeOverrides(klass: IrClass) {
|
||||
buildFakeOverrideChainsForClass(klass)
|
||||
propertyOverriddenSymbols.clear()
|
||||
irOverridingUtil.clear()
|
||||
haveFakeOverrides.add(klass)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user