JVM IR: remove obsolete isDefaultImplsBridge in findInterfaceImplementation

This commit is contained in:
Alexander Udalov
2020-11-19 23:20:10 +01:00
parent be03bc477d
commit d41d1bf64d
2 changed files with 15 additions and 30 deletions
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.* import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
@@ -260,22 +259,18 @@ private class InterfaceObjectCallsLowering(val context: JvmBackendContext) : IrE
* interface implementation should be generated into the class containing the fake override; or null if the given function is not a fake * interface implementation should be generated into the class containing the fake override; or null if the given function is not a fake
* override of any interface implementation or such method was already generated into the superclass or is a method from Any. * override of any interface implementation or such method was already generated into the superclass or is a method from Any.
*/ */
private fun isDefaultImplsBridge(f: IrSimpleFunction) =
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC
internal fun IrSimpleFunction.findInterfaceImplementation(jvmDefaultMode: JvmDefaultMode): IrSimpleFunction? { internal fun IrSimpleFunction.findInterfaceImplementation(jvmDefaultMode: JvmDefaultMode): IrSimpleFunction? {
if (!isFakeOverride) return null if (!isFakeOverride) return null
parent.let { if (it is IrClass && it.isJvmInterface) return null } parent.let { if (it is IrClass && it.isJvmInterface) return null }
val implementation = resolveFakeOverride(toSkip = ::isDefaultImplsBridge) ?: return null val implementation = resolveFakeOverride() ?: return null
// Only generate interface delegation for functions immediately inherited from an interface. // Only generate interface delegation for functions immediately inherited from an interface.
// (Otherwise, delegation will be present in the parent class) // (Otherwise, delegation will be present in the parent class)
if (overriddenSymbols.any { if (overriddenSymbols.any {
!it.owner.parentAsClass.isInterface && !it.owner.parentAsClass.isInterface &&
it.owner.modality != Modality.ABSTRACT && it.owner.modality != Modality.ABSTRACT &&
it.owner.resolveFakeOverride(toSkip = ::isDefaultImplsBridge) == implementation it.owner.resolveFakeOverride() == implementation
}) { }) {
return null return null
} }
@@ -24,36 +24,26 @@ val IrSimpleFunction.target: IrSimpleFunction
else else
resolveFakeOverride() ?: error("Could not resolveFakeOverride() for ${this.render()}") resolveFakeOverride() ?: error("Could not resolveFakeOverride() for ${this.render()}")
val IrFunction.target: IrFunction get() = when (this) { val IrFunction.target: IrFunction
is IrSimpleFunction -> this.target get() = when (this) {
is IrConstructor -> this is IrSimpleFunction -> this.target
else -> error(this) is IrConstructor -> this
} else -> error(this)
}
fun IrSimpleFunction.collectRealOverrides( fun IrSimpleFunction.collectRealOverrides(filter: (IrOverridableMember) -> Boolean = { false }): Set<IrSimpleFunction> {
toSkip: (IrSimpleFunction) -> Boolean = { false }, if (isReal) return setOf(this)
filter: (IrOverridableMember) -> Boolean = { false }
): Set<IrSimpleFunction> {
if (isReal && !toSkip(this)) return setOf(this)
return this.overriddenSymbols return this.overriddenSymbols
.map { it.owner } .map { it.owner }
.collectAndFilterRealOverrides( .collectAndFilterRealOverrides(filter)
{
require(it is IrSimpleFunction) { "Expected IrSimpleFunction: ${it.render()}" }
toSkip(it)
},
filter
)
.map { it as IrSimpleFunction } .map { it as IrSimpleFunction }
.toSet() .toSet()
} }
fun Collection<IrOverridableMember>.collectAndFilterRealOverrides( fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(
toSkip: (IrOverridableMember) -> Boolean = { false },
filter: (IrOverridableMember) -> Boolean = { false } filter: (IrOverridableMember) -> Boolean = { false }
): Set<IrOverridableMember> { ): Set<IrOverridableMember> {
val visited = mutableSetOf<IrOverridableMember>() val visited = mutableSetOf<IrOverridableMember>()
val realOverrides = mutableSetOf<IrOverridableMember>() val realOverrides = mutableSetOf<IrOverridableMember>()
@@ -68,7 +58,7 @@ fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(
fun collectRealOverrides(member: IrOverridableMember) { 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) {
realOverrides += member realOverrides += member
} else { } else {
overriddenSymbols(member).forEach { collectRealOverrides(it.owner as IrOverridableMember) } overriddenSymbols(member).forEach { collectRealOverrides(it.owner as IrOverridableMember) }
@@ -93,13 +83,13 @@ fun Collection<IrOverridableMember>.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 IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false): IrSimpleFunction? {
return if (allowAbstract) { return if (allowAbstract) {
val reals = collectRealOverrides(toSkip) val reals = collectRealOverrides()
if (reals.isEmpty()) error("No real overrides for ${this.render()}") if (reals.isEmpty()) error("No real overrides for ${this.render()}")
reals.first() reals.first()
} else { } else {
collectRealOverrides(toSkip, { it.modality == Modality.ABSTRACT }) collectRealOverrides { it.modality == Modality.ABSTRACT }
.let { realOverrides -> .let { realOverrides ->
// Kotlin forbids conflicts between overrides, but they may trickle down from Java. // Kotlin forbids conflicts between overrides, but they may trickle down from Java.
realOverrides.singleOrNull { it.parent.safeAs<IrClass>()?.isInterface != true } realOverrides.singleOrNull { it.parent.safeAs<IrClass>()?.isInterface != true }