Optimize retaining most specific methods in LazyJavaScope

See 62a55b7b00
Previously, it was working for O(n^2)
Now, we first group it by jvm descriptor,
then for each groups of size g_i finding the most specific for O(g_i^2)

It should help for the cases when we have a lot of overloads with
different JVM descriptors (modulo return type)
NB: Having the same JVM descriptors is rather rare, because
in Java one cannot generate such a class.

Looks like it's only possible for Scala or some other JVM languages (KT-17560)

It should help a lot for KT-35135
This commit is contained in:
Denis Zharkov
2020-02-14 15:10:59 +03:00
parent d06e35b061
commit 842e2dc02f
5 changed files with 44 additions and 25 deletions
@@ -66,12 +66,7 @@ fun <H : Any> Collection<H>.selectMostSpecificInEachOverridableGroup(
continue
}
val mostSpecific = OverridingUtil.selectMostSpecificMember(overridableGroup, descriptorByHandle)
val mostSpecificDescriptor = mostSpecific.descriptorByHandle()
overridableGroup.filterNotTo(conflictedHandles) {
OverridingUtil.isMoreSpecific(mostSpecificDescriptor, it.descriptorByHandle())
}
val mostSpecific = mostSpecific(overridableGroup, conflictedHandles, descriptorByHandle)
if (conflictedHandles.isNotEmpty()) {
result.addAll(conflictedHandles)
@@ -82,8 +77,23 @@ fun <H : Any> Collection<H>.selectMostSpecificInEachOverridableGroup(
return result
}
fun <D : CallableDescriptor> MutableCollection<D>.retainMostSpecificInEachOverridableGroup() {
val newResult = selectMostSpecificInEachOverridableGroup { this }
if (size == newResult.size) return
retainAll(newResult)
private fun <H : Any> mostSpecific(
overridableGroup: Collection<H>,
conflictedHandles: MutableSet<H>,
descriptorByHandle: H.() -> CallableDescriptor
): H {
val mostSpecific = OverridingUtil.selectMostSpecificMember(overridableGroup, descriptorByHandle)
val mostSpecificDescriptor = mostSpecific.descriptorByHandle()
overridableGroup.filterNotTo(conflictedHandles) {
OverridingUtil.isMoreSpecific(mostSpecificDescriptor, it.descriptorByHandle())
}
return mostSpecific
}
// Return multiple elements in case of conflicts
fun <D : CallableDescriptor> Collection<D>.selectMostSpecificFromOverridableGroup(): Collection<D> {
val result = mutableSetOf<D>()
result.add(mostSpecific(this, conflictedHandles = result) { this })
return result
}