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
|
return this.overriddenSymbols
|
||||||
.map { it.owner }
|
.map { it.owner }
|
||||||
.collectAndFilterRealOverrides(getOverriddenPropertySymbols = IrProperty::overriddenSymbols)
|
.collectAndFilterRealOverrides()
|
||||||
.firstOrNull() as? IrProperty
|
.firstOrNull()
|
||||||
?: throw AssertionError("No real override for ${this.render()}")
|
?: throw AssertionError("No real override for ${this.render()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ interface IrDeclaration : IrStatement, IrSymbolOwner, IrMutableAnnotationContain
|
|||||||
|
|
||||||
abstract class IrDeclarationBase : IrElementBase(), IrDeclaration
|
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>
|
var overriddenSymbols: List<S>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
|||||||
abstract class IrProperty :
|
abstract class IrProperty :
|
||||||
IrDeclarationBase(),
|
IrDeclarationBase(),
|
||||||
IrPossiblyExternalDeclaration,
|
IrPossiblyExternalDeclaration,
|
||||||
IrOverridableMember,
|
|
||||||
IrOverridableDeclaration<IrPropertySymbol>,
|
IrOverridableDeclaration<IrPropertySymbol>,
|
||||||
IrMetadataSourceOwner,
|
IrMetadataSourceOwner,
|
||||||
IrAttributeContainer,
|
IrAttributeContainer,
|
||||||
@@ -40,7 +39,7 @@ abstract class IrProperty :
|
|||||||
abstract val isLateinit: Boolean
|
abstract val isLateinit: Boolean
|
||||||
abstract val isDelegated: Boolean
|
abstract val isDelegated: Boolean
|
||||||
abstract val isExpect: Boolean
|
abstract val isExpect: Boolean
|
||||||
abstract val isFakeOverride: Boolean
|
abstract override val isFakeOverride: Boolean
|
||||||
|
|
||||||
abstract var backingField: IrField?
|
abstract var backingField: IrField?
|
||||||
abstract var getter: IrSimpleFunction?
|
abstract var getter: IrSimpleFunction?
|
||||||
|
|||||||
@@ -12,14 +12,13 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
|||||||
abstract class IrSimpleFunction :
|
abstract class IrSimpleFunction :
|
||||||
IrFunction(),
|
IrFunction(),
|
||||||
IrOverridableDeclaration<IrSimpleFunctionSymbol>,
|
IrOverridableDeclaration<IrSimpleFunctionSymbol>,
|
||||||
IrOverridableMember,
|
|
||||||
IrAttributeContainer {
|
IrAttributeContainer {
|
||||||
|
|
||||||
abstract override val symbol: IrSimpleFunctionSymbol
|
abstract override val symbol: IrSimpleFunctionSymbol
|
||||||
|
|
||||||
abstract val isTailrec: Boolean
|
abstract val isTailrec: Boolean
|
||||||
abstract val isSuspend: Boolean
|
abstract val isSuspend: Boolean
|
||||||
abstract val isFakeOverride: Boolean
|
abstract override val isFakeOverride: Boolean
|
||||||
abstract val isOperator: Boolean
|
abstract val isOperator: Boolean
|
||||||
abstract val isInfix: Boolean
|
abstract val isInfix: Boolean
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class IrLazyProperty(
|
|||||||
|
|
||||||
override var overriddenSymbols: List<IrPropertySymbol> by lazyVar(stubGenerator.lock) {
|
override var overriddenSymbols: List<IrPropertySymbol> by lazyVar(stubGenerator.lock) {
|
||||||
descriptor.overriddenDescriptors.mapTo(ArrayList()) {
|
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.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
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.isReal
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo
|
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo
|
||||||
@@ -36,9 +35,6 @@ abstract class FakeOverrideBuilderStrategy {
|
|||||||
|
|
||||||
protected abstract fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction)
|
protected abstract fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction)
|
||||||
protected abstract fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty)
|
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 {
|
fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember {
|
||||||
@@ -89,35 +85,32 @@ class IrOverridingUtil(
|
|||||||
originalSuperTypes.clear()
|
originalSuperTypes.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var IrOverridableMember.overriddenSymbols: List<IrSymbol>
|
private val IrOverridableMember.overriddenSymbols: List<IrSymbol>
|
||||||
get() = when (this) {
|
get() = (this as? IrOverridableDeclaration<*>)?.overriddenSymbols
|
||||||
is IrSimpleFunction -> this.overriddenSymbols
|
?: error("Unexpected IrOverridableMember: $this")
|
||||||
is IrProperty -> fakeOverrideBuilder.propertyOverriddenSymbols[this]
|
|
||||||
?: error("No overridden symbols for ${this.render()}")
|
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")
|
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) {
|
fun buildFakeOverridesForClass(clazz: IrClass) {
|
||||||
val superTypes = clazz.superTypes
|
val superTypes = clazz.superTypes
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@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 allFromSuper = superTypes.flatMap { superType ->
|
||||||
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
|
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
|
||||||
@@ -147,19 +140,8 @@ class IrOverridingUtil(
|
|||||||
clazz: IrClass,
|
clazz: IrClass,
|
||||||
implementedMembers: List<IrOverridableMember> = emptyList()
|
implementedMembers: List<IrOverridableMember> = emptyList()
|
||||||
): List<IrOverridableMember> {
|
): List<IrOverridableMember> {
|
||||||
fakeOverrideBuilder.propertyOverriddenSymbols.clear()
|
|
||||||
|
|
||||||
val overriddenMembers = (clazz.declarations.filterIsInstance<IrOverridableMember>() + implementedMembers)
|
val overriddenMembers = (clazz.declarations.filterIsInstance<IrOverridableMember>() + implementedMembers)
|
||||||
.flatMap {
|
.flatMap { member -> member.overriddenSymbols.map { it.owner } }
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
val unoverriddenSuperMembers = clazz.superTypes.flatMap { superType ->
|
val unoverriddenSuperMembers = clazz.superTypes.flatMap { superType ->
|
||||||
@@ -242,7 +224,7 @@ class IrOverridingUtil(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//strategy.setOverriddenDescriptors(fromCurrent, overridden)
|
//strategy.setOverriddenDescriptors(fromCurrent, overridden)
|
||||||
fromCurrent.overriddenSymbols = overridden.map { it.original.symbol }
|
fromCurrent.setOverriddenSymbols(overridden.map { it.original.symbol })
|
||||||
|
|
||||||
return bound
|
return bound
|
||||||
}
|
}
|
||||||
@@ -400,7 +382,7 @@ class IrOverridingUtil(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fakeOverride.overriddenSymbols = effectiveOverridden.map { it.original.symbol }
|
fakeOverride.setOverriddenSymbols(effectiveOverridden.map { it.original.symbol })
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
fakeOverride.overriddenSymbols.isNotEmpty()
|
fakeOverride.overriddenSymbols.isNotEmpty()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.ir.util
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
val IrDeclaration.isReal: Boolean get() = !isFakeOverride
|
val IrDeclaration.isReal: Boolean get() = !isFakeOverride
|
||||||
@@ -31,65 +31,50 @@ val IrFunction.target: IrFunction get() = when (this) {
|
|||||||
else -> error(this)
|
else -> error(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrSimpleFunction.collectRealOverrides(
|
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.collectRealOverrides(
|
||||||
toSkip: (IrSimpleFunction) -> Boolean = { false },
|
toSkip: (T) -> Boolean = { false },
|
||||||
filter: (IrOverridableMember) -> Boolean = { false }
|
filter: (T) -> Boolean = { false }
|
||||||
): Set<IrSimpleFunction> {
|
): Set<T> {
|
||||||
if (isReal && !toSkip(this)) return setOf(this)
|
if (isReal && !toSkip(this)) return setOf(this)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return this.overriddenSymbols
|
return this.overriddenSymbols
|
||||||
.map { it.owner }
|
.map { it.owner as T }
|
||||||
.collectAndFilterRealOverrides(
|
.collectAndFilterRealOverrides(toSkip, filter)
|
||||||
{
|
|
||||||
require(it is IrSimpleFunction) { "Expected IrSimpleFunction: ${it.render()}" }
|
|
||||||
toSkip(it)
|
|
||||||
},
|
|
||||||
filter
|
|
||||||
) as Set<IrSimpleFunction>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(
|
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> Collection<T>.collectAndFilterRealOverrides(
|
||||||
toSkip: (IrOverridableMember) -> Boolean = { false },
|
toSkip: (T) -> Boolean = { false },
|
||||||
filter: (IrOverridableMember) -> Boolean = { false },
|
filter: (T) -> Boolean = { false }
|
||||||
getOverriddenPropertySymbols: IrProperty.() -> List<IrPropertySymbol> = {
|
): Set<T> {
|
||||||
// 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> {
|
|
||||||
|
|
||||||
val visited = mutableSetOf<IrOverridableMember>()
|
val visited = mutableSetOf<T>()
|
||||||
val realOverrides = mutableMapOf<Any, IrOverridableMember>()
|
val realOverrides = mutableMapOf<Any, T>()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Due to IR copying in performByIrFile, overrides should only be distinguished up to their signatures.
|
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) {
|
fun collectRealOverrides(member: T) {
|
||||||
is IrSimpleFunction -> declaration.overriddenSymbols
|
|
||||||
is IrProperty -> declaration.getOverriddenPropertySymbols()
|
|
||||||
else -> error("Unexpected overridable member: ${declaration.render()}")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun collectRealOverrides(member: IrOverridableMember) {
|
|
||||||
if (!visited.add(member) || filter(member)) return
|
if (!visited.add(member) || filter(member)) return
|
||||||
|
|
||||||
if (member.isReal && !toSkip(member)) {
|
if (member.isReal && !toSkip(member)) {
|
||||||
realOverrides[member.toKey()] = member
|
realOverrides[member.toKey()] = member
|
||||||
} else {
|
} else {
|
||||||
overriddenSymbols(member).forEach { collectRealOverrides(it.owner as IrOverridableMember) }
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
member.overriddenSymbols.forEach { collectRealOverrides(it.owner as T) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.forEach { collectRealOverrides(it) }
|
this.forEach { collectRealOverrides(it) }
|
||||||
|
|
||||||
fun excludeRepeated(member: IrOverridableMember) {
|
fun excludeRepeated(member: T) {
|
||||||
if (!visited.add(member)) return
|
if (!visited.add(member)) return
|
||||||
|
|
||||||
overriddenSymbols(member).forEach {
|
member.overriddenSymbols.forEach {
|
||||||
val owner = it.owner as IrOverridableMember
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val owner = it.owner as T
|
||||||
realOverrides.remove(owner.toKey())
|
realOverrides.remove(owner.toKey())
|
||||||
excludeRepeated(owner)
|
excludeRepeated(owner)
|
||||||
}
|
}
|
||||||
@@ -101,8 +86,16 @@ fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(
|
|||||||
return realOverrides.values.toSet()
|
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
|
// 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) {
|
return if (allowAbstract) {
|
||||||
val reals = collectRealOverrides(toSkip)
|
val reals = collectRealOverrides(toSkip)
|
||||||
if (reals.isEmpty()) error("No real overrides for ${this.render()}")
|
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 }
|
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.isAnnotationClass get() = kind == ClassKind.ANNOTATION_CLASS
|
||||||
val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS
|
val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS
|
||||||
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
|
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
|
||||||
|
|||||||
-1
@@ -159,7 +159,6 @@ class FakeOverrideBuilder(
|
|||||||
|
|
||||||
private fun provideFakeOverrides(klass: IrClass) {
|
private fun provideFakeOverrides(klass: IrClass) {
|
||||||
buildFakeOverrideChainsForClass(klass)
|
buildFakeOverrideChainsForClass(klass)
|
||||||
propertyOverriddenSymbols.clear()
|
|
||||||
irOverridingUtil.clear()
|
irOverridingUtil.clear()
|
||||||
haveFakeOverrides.add(klass)
|
haveFakeOverrides.add(klass)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user