Minor: clean up FirTypeIntersectionScopeContext a bit more

This commit is contained in:
pyos
2022-10-13 13:59:55 +02:00
committed by teamcity
parent 1c2e25d727
commit 8f19291a35
@@ -156,23 +156,21 @@ class FirTypeIntersectionScopeContext(
val result = mutableListOf<ResultOfIntersection<D>>() val result = mutableListOf<ResultOfIntersection<D>>()
while (allMembersWithScope.size > 1) { while (allMembersWithScope.size > 1) {
val maxByVisibility = findMemberWithMaxVisibility(allMembersWithScope) val groupWithPrivate =
val extractBothWaysWithPrivate = overrideService.extractBothWaysOverridable(maxByVisibility, allMembersWithScope, overrideChecker) overrideService.extractBothWaysOverridable(allMembersWithScope.maxByVisibility(), allMembersWithScope, overrideChecker)
val extractedOverrides = extractBothWaysWithPrivate.filterNotTo(mutableListOf()) { val group = groupWithPrivate.filter { !Visibilities.isPrivate(it.member.fir.visibility) }.ifEmpty { groupWithPrivate }
Visibilities.isPrivate((it.member.fir as FirMemberDeclaration).visibility) val singleRealImplementation = group.size == 1 ||
}.takeIf { it.isNotEmpty() } ?: extractBothWaysWithPrivate group.mapTo(mutableSetOf()) { it.member.fir.unwrapSubstitutionOverrides().symbol }.size == 1
val singleRealMethod = extractedOverrides.size == 1 || val directOverrides = if (singleRealImplementation) group else group.onlyDirectlyInherited()
extractedOverrides.mapTo(mutableSetOf()) { it.member.fir.unwrapSubstitutionOverrides().symbol }.size == 1
val directOverrides = if (singleRealMethod) extractedOverrides else extractedOverrides.onlyDirectlyInherited()
val mostSpecific = overrideService.selectMostSpecificMembers(directOverrides, ReturnTypeCalculatorForFullBodyResolve) val mostSpecific = overrideService.selectMostSpecificMembers(directOverrides, ReturnTypeCalculatorForFullBodyResolve)
// Always create a non-trivial intersection override when the base methods come from different scopes, // Always create a non-trivial intersection override when the base methods come from different scopes,
// even if one of them is more specific than the others. This is necessary for proper reporting of // even if one of them is more specific than the others. This is necessary for proper reporting of
// MANY_{IMPL,INTERFACES}_MEMBER_NOT_IMPLEMENTED diagnostics. // MANY_{IMPL,INTERFACES}_MEMBER_NOT_IMPLEMENTED diagnostics.
if ((!forSubtyping && mostSpecific.size > 1) || (!singleRealMethod && directOverrides.size > 1)) { if ((!forSubtyping && mostSpecific.size > 1) || (!singleRealImplementation && directOverrides.size > 1)) {
result += ResultOfIntersection.NonTrivial(this, mostSpecific, extractedOverrides, containingScope = null) result += ResultOfIntersection.NonTrivial(this, mostSpecific, group, containingScope = null)
} else { } else {
val (member, containingScope) = mostSpecific.first() val (member, containingScope) = mostSpecific.first()
result += ResultOfIntersection.SingleMember(member, extractedOverrides, containingScope) result += ResultOfIntersection.SingleMember(member, group, containingScope)
} }
} }
@@ -205,35 +203,28 @@ class FirTypeIntersectionScopeContext(
} }
private fun <S : FirCallableSymbol<*>> List<MemberWithBaseScope<S>>.onlyDirectlyInherited(): List<MemberWithBaseScope<S>> { private fun <S : FirCallableSymbol<*>> List<MemberWithBaseScope<S>>.onlyDirectlyInherited(): List<MemberWithBaseScope<S>> {
val baseMembers = mutableSetOf<S>() val baseMembers = mutableSetOf<FirCallableSymbol<*>>()
for ((member, scope) in this) { for ((member, scope) in this) {
@Suppress("UNCHECKED_CAST") val unwrapped = member.fir.unwrapSubstitutionOverrides().symbol
val addIfDifferent = { it: FirCallableSymbol<*> ->
val symbol = it.fir.unwrapSubstitutionOverrides().symbol
if (symbol != unwrapped) {
baseMembers += symbol
}
ProcessorAction.NEXT
}
if (member is FirNamedFunctionSymbol) { if (member is FirNamedFunctionSymbol) {
scope.processOverriddenFunctions(member) { scope.processOverriddenFunctions(member, addIfDifferent)
val symbol = it.fir.unwrapSubstitutionOverrides().symbol
if (symbol != member.fir.unwrapSubstitutionOverrides().symbol) {
baseMembers += symbol as S
}
ProcessorAction.NEXT
}
} else if (member is FirPropertySymbol) { } else if (member is FirPropertySymbol) {
scope.processOverriddenProperties(member) { scope.processOverriddenProperties(member, addIfDifferent)
val symbol = it.fir.unwrapSubstitutionOverrides().symbol
if (symbol != member.fir.unwrapSubstitutionOverrides().symbol) {
baseMembers += symbol as S
}
ProcessorAction.NEXT
}
} }
} }
return filter { it.member.fir.unwrapSubstitutionOverrides().symbol !in baseMembers } return filter { it.member.fir.unwrapSubstitutionOverrides().symbol !in baseMembers }
} }
private fun <D : FirCallableSymbol<*>> findMemberWithMaxVisibility(members: Collection<MemberWithBaseScope<D>>): MemberWithBaseScope<D> { private fun <S : FirCallableSymbol<*>> Collection<MemberWithBaseScope<S>>.maxByVisibility(): MemberWithBaseScope<S> {
assert(members.isNotEmpty()) var member: MemberWithBaseScope<S>? = null
for (candidate in this) {
var member: MemberWithBaseScope<D>? = null
for (candidate in members) {
if (member == null) { if (member == null) {
member = candidate member = candidate
continue continue