Got rid of duplicates in resolveFakeOverrides implementations
This commit is contained in:
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
val IrDeclaration.isReal: Boolean get() = !isFakeOverride
|
||||||
|
|
||||||
|
val IrDeclaration.isFakeOverride: Boolean
|
||||||
|
get() = when (this) {
|
||||||
|
is IrSimpleFunction -> isFakeOverride
|
||||||
|
is IrProperty -> isFakeOverride
|
||||||
|
is IrField -> isFakeOverride
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrSimpleFunction.target: IrSimpleFunction
|
||||||
|
get() = if (modality == Modality.ABSTRACT)
|
||||||
|
this
|
||||||
|
else
|
||||||
|
resolveFakeOverride() ?: error("Could not resolveFakeOverride() for ${this.render()}")
|
||||||
|
|
||||||
|
val IrFunction.target: IrFunction get() = when (this) {
|
||||||
|
is IrSimpleFunction -> this.target
|
||||||
|
is IrConstructor -> this
|
||||||
|
else -> error(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrField.resolveFakeOverride(): IrField? {
|
||||||
|
var toVisit = setOf(this)
|
||||||
|
val nonOverridden = mutableSetOf<IrField>()
|
||||||
|
while (toVisit.isNotEmpty()) {
|
||||||
|
nonOverridden += toVisit.filter { it.overriddenSymbols.isEmpty() }
|
||||||
|
toVisit = toVisit.flatMap { it.overriddenSymbols }.map { it.owner }.toSet()
|
||||||
|
}
|
||||||
|
return nonOverridden.singleOrNull()
|
||||||
|
}
|
||||||
|
fun IrSimpleFunction.collectRealOverrides(toSkip: (IrSimpleFunction) -> Boolean = { false }): Set<IrSimpleFunction> {
|
||||||
|
if (isReal && !toSkip(this)) return setOf(this)
|
||||||
|
|
||||||
|
val visited = mutableSetOf<IrSimpleFunction>()
|
||||||
|
val realOverrides = mutableSetOf<IrSimpleFunction>()
|
||||||
|
|
||||||
|
fun collectRealOverrides(func: IrSimpleFunction) {
|
||||||
|
if (!visited.add(func)) return
|
||||||
|
|
||||||
|
if (func.isReal && !toSkip(func)) {
|
||||||
|
realOverrides += func
|
||||||
|
} else {
|
||||||
|
func.overriddenSymbols.forEach { collectRealOverrides(it.owner) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overriddenSymbols.forEach { collectRealOverrides(it.owner) }
|
||||||
|
|
||||||
|
fun excludeRepeated(func: IrSimpleFunction) {
|
||||||
|
if (!visited.add(func)) return
|
||||||
|
|
||||||
|
func.overriddenSymbols.forEach {
|
||||||
|
realOverrides.remove(it.owner)
|
||||||
|
excludeRepeated(it.owner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visited.clear()
|
||||||
|
realOverrides.toList().forEach { excludeRepeated(it) }
|
||||||
|
|
||||||
|
return realOverrides
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use this implementation instead of any other
|
||||||
|
fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false, toSkip: (IrSimpleFunction) -> Boolean = { false }): IrSimpleFunction? {
|
||||||
|
val reals = collectRealOverrides(toSkip)
|
||||||
|
return if (allowAbstract) {
|
||||||
|
if (reals.isEmpty()) error("No real overrides for ${this.render()}")
|
||||||
|
reals.first()
|
||||||
|
} else {
|
||||||
|
reals
|
||||||
|
.filter { it.modality != Modality.ABSTRACT }
|
||||||
|
.let { realOverrides ->
|
||||||
|
// Kotlin forbids conflicts between overrides, but they may trickle down from Java.
|
||||||
|
realOverrides.singleOrNull { it.parent.safeAs<IrClass>()?.isInterface != true }
|
||||||
|
// TODO: We take firstOrNull instead of singleOrNull here because of KT-36188.
|
||||||
|
?: realOverrides.firstOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -236,16 +236,6 @@ val IrClass.defaultType: IrSimpleType
|
|||||||
|
|
||||||
val IrSimpleFunction.isSynthesized: Boolean get() = descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
|
val IrSimpleFunction.isSynthesized: Boolean get() = descriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||||
|
|
||||||
val IrDeclaration.isReal: Boolean get() = !isFakeOverride
|
|
||||||
|
|
||||||
val IrDeclaration.isFakeOverride: Boolean
|
|
||||||
get() = when (this) {
|
|
||||||
is IrSimpleFunction -> isFakeOverride
|
|
||||||
is IrProperty -> isFakeOverride
|
|
||||||
is IrField -> isFakeOverride
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrClass.isSubclassOf(ancestor: IrClass): Boolean {
|
fun IrClass.isSubclassOf(ancestor: IrClass): Boolean {
|
||||||
|
|
||||||
val alreadyVisited = mutableSetOf<IrClass>()
|
val alreadyVisited = mutableSetOf<IrClass>()
|
||||||
@@ -262,50 +252,6 @@ fun IrClass.isSubclassOf(ancestor: IrClass): Boolean {
|
|||||||
return this.hasAncestorInSuperTypes()
|
return this.hasAncestorInSuperTypes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrSimpleFunction.collectRealOverrides(toSkip: (IrSimpleFunction) -> Boolean = { false }): Set<IrSimpleFunction> {
|
|
||||||
if (isReal && !toSkip(this)) return setOf(this)
|
|
||||||
|
|
||||||
val visited = mutableSetOf<IrSimpleFunction>()
|
|
||||||
val realOverrides = mutableSetOf<IrSimpleFunction>()
|
|
||||||
|
|
||||||
fun collectRealOverrides(func: IrSimpleFunction) {
|
|
||||||
if (!visited.add(func)) return
|
|
||||||
|
|
||||||
if (func.isReal && !toSkip(func)) {
|
|
||||||
realOverrides += func
|
|
||||||
} else {
|
|
||||||
func.overriddenSymbols.forEach { collectRealOverrides(it.owner) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
overriddenSymbols.forEach { collectRealOverrides(it.owner) }
|
|
||||||
|
|
||||||
fun excludeRepeated(func: IrSimpleFunction) {
|
|
||||||
if (!visited.add(func)) return
|
|
||||||
|
|
||||||
func.overriddenSymbols.forEach {
|
|
||||||
realOverrides.remove(it.owner)
|
|
||||||
excludeRepeated(it.owner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visited.clear()
|
|
||||||
realOverrides.toList().forEach { excludeRepeated(it) }
|
|
||||||
|
|
||||||
return realOverrides
|
|
||||||
}
|
|
||||||
|
|
||||||
// This implementation is from kotlin-native
|
|
||||||
// TODO: use this implementation instead of any other
|
|
||||||
fun IrSimpleFunction.resolveFakeOverride(toSkip: (IrSimpleFunction) -> Boolean = { false }): IrSimpleFunction? {
|
|
||||||
return collectRealOverrides(toSkip)
|
|
||||||
.filter { it.modality != Modality.ABSTRACT }
|
|
||||||
.let { realOverrides ->
|
|
||||||
// Kotlin forbids conflicts between overrides, but they may trickle down from Java.
|
|
||||||
realOverrides.singleOrNull { it.parent.safeAs<IrClass>()?.isInterface != true } ?: realOverrides.singleOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrSimpleFunction.isOrOverridesSynthesized(): Boolean {
|
fun IrSimpleFunction.isOrOverridesSynthesized(): Boolean {
|
||||||
if (isSynthesized) return true
|
if (isSynthesized) return true
|
||||||
|
|
||||||
@@ -322,16 +268,6 @@ fun IrSimpleFunction.findInterfaceImplementation(): IrSimpleFunction? {
|
|||||||
return resolveFakeOverride()?.run { if (parentAsClass.isInterface) this else null }
|
return resolveFakeOverride()?.run { if (parentAsClass.isInterface) this else null }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrField.resolveFakeOverride(): IrField? {
|
|
||||||
var toVisit = setOf(this)
|
|
||||||
val nonOverridden = mutableSetOf<IrField>()
|
|
||||||
while (toVisit.isNotEmpty()) {
|
|
||||||
nonOverridden += toVisit.filter { it.overriddenSymbols.isEmpty() }
|
|
||||||
toVisit = toVisit.flatMap { it.overriddenSymbols }.map { it.owner }.toSet()
|
|
||||||
}
|
|
||||||
return nonOverridden.singleOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user