IR: simplify IrFakeOverrideBuilder.isMoreSpecific
Using the logic from `OverridingUtil.isMoreSpecific` as a reference.
This commit is contained in:
committed by
Space Team
parent
5c64832c0f
commit
9a7d7483a3
+16
-55
@@ -374,65 +374,26 @@ class IrFakeOverrideBuilder(
|
|||||||
return AbstractTypeChecker.isSubtypeOf(typeCheckerState, a.returnType, b.returnType)
|
return AbstractTypeChecker.isSubtypeOf(typeCheckerState, a.returnType, b.returnType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isMoreSpecific(
|
private fun isMoreSpecific(a: IrOverridableMember, b: IrOverridableMember): Boolean {
|
||||||
a: IrOverridableMember,
|
if (!isVisibilityMoreSpecific(a, b)) return false
|
||||||
b: IrOverridableMember
|
|
||||||
): Boolean {
|
if (a is IrProperty) {
|
||||||
return a >= b
|
check(b is IrProperty) { "b is not a property: $b" }
|
||||||
|
if (!isAccessorMoreSpecific(a.setter, b.setter)) return false
|
||||||
|
if (!a.isVar && b.isVar) return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return isReturnTypeIsSubtypeOfOtherReturnType(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on compareTo from FirOverrideService.kt
|
private fun isVisibilityMoreSpecific(a: IrOverridableMember, b: IrOverridableMember): Boolean {
|
||||||
private operator fun IrOverridableMember.compareTo(other: IrOverridableMember): Int {
|
val result = DescriptorVisibilities.compare(a.visibility, b.visibility)
|
||||||
fun merge(preferA: Boolean, preferB: Boolean, previous: Int): Int = when {
|
return result == null || result >= 0
|
||||||
preferA == preferB -> previous
|
|
||||||
preferA && previous >= 0 -> 1
|
|
||||||
preferB && previous <= 0 -> -1
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val aIr = this@compareTo
|
|
||||||
val bIr = other
|
|
||||||
val byVisibility = DescriptorVisibilities.compare(aIr.visibility, bIr.visibility) ?: 0
|
|
||||||
val aReturnType = aIr.returnType
|
|
||||||
val bReturnType = bIr.returnType
|
|
||||||
|
|
||||||
val aSubtypesB = isReturnTypeIsSubtypeOfOtherReturnType(aIr, bIr)
|
|
||||||
val bSubtypesA = isReturnTypeIsSubtypeOfOtherReturnType(bIr, aIr)
|
|
||||||
|
|
||||||
val byVisibilityAndType = when {
|
|
||||||
// Could be that one of them is flexible, in which case the types are not equal but still subtypes of one another;
|
|
||||||
// make the inflexible one more specific.
|
|
||||||
aSubtypesB && bSubtypesA -> merge(!aReturnType.isFlexible(), !bReturnType.isFlexible(), byVisibility)
|
|
||||||
aSubtypesB && byVisibility >= 0 -> 1
|
|
||||||
bSubtypesA && byVisibility <= 0 -> -1
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return when (aIr) {
|
|
||||||
is IrSimpleFunction -> byVisibilityAndType
|
|
||||||
is IrProperty -> {
|
|
||||||
require(bIr is IrProperty)
|
|
||||||
val settersComparison = if (aIr.isVar && bIr.isVar) {
|
|
||||||
val aSetter = aIr.setter
|
|
||||||
val bSetter = bIr.setter
|
|
||||||
when {
|
|
||||||
aSetter != null && bSetter != null -> aSetter.compareTo(bSetter)
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
val bySetters = merge(
|
|
||||||
preferA = settersComparison >= 0,
|
|
||||||
preferB = settersComparison <= 0,
|
|
||||||
byVisibilityAndType
|
|
||||||
)
|
|
||||||
merge(aIr.isVar, bIr.isVar, bySetters)
|
|
||||||
}
|
|
||||||
else -> error("Unexpected type: $aIr")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isAccessorMoreSpecific(a: IrSimpleFunction?, b: IrSimpleFunction?): Boolean =
|
||||||
|
a == null || b == null || isVisibilityMoreSpecific(a, b)
|
||||||
|
|
||||||
private fun IrType.isFlexible(): Boolean {
|
private fun IrType.isFlexible(): Boolean {
|
||||||
return with(typeSystem) { isFlexible() }
|
return with(typeSystem) { isFlexible() }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user