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 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 {
|
||||
|
||||
val alreadyVisited = mutableSetOf<IrClass>()
|
||||
@@ -262,50 +252,6 @@ fun IrClass.isSubclassOf(ancestor: IrClass): Boolean {
|
||||
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 {
|
||||
if (isSynthesized) return true
|
||||
|
||||
@@ -322,16 +268,6 @@ fun IrSimpleFunction.findInterfaceImplementation(): IrSimpleFunction? {
|
||||
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.isEnumClass get() = kind == ClassKind.ENUM_CLASS
|
||||
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
|
||||
|
||||
Reference in New Issue
Block a user