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
@@ -35,12 +35,11 @@ import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument
import org.jetbrains.kotlin.resolve.retainMostSpecificInEachOverridableGroup
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -116,13 +115,23 @@ abstract class LazyJavaScope(
private val functions = c.storageManager.createMemoizedFunction<Name, Collection<SimpleFunctionDescriptor>> { name ->
val result = LinkedHashSet<SimpleFunctionDescriptor>(declaredFunctions(name))
result.retainMostSpecificInEachOverridableGroup()
result.retainMostSpecificMethods()
computeNonDeclaredFunctions(result, name)
c.components.signatureEnhancement.enhanceSignatures(c, result).toList()
}
private fun MutableSet<SimpleFunctionDescriptor>.retainMostSpecificMethods() {
val groups = groupBy { it.computeJvmDescriptor(withReturnType = false) }.values
for (group in groups) {
if (group.size == 1) continue
val mostSpecificMethods = group.selectMostSpecificFromOverridableGroup()
removeAll(group)
addAll(mostSpecificMethods)
}
}
protected open fun JavaMethodDescriptor.isVisibleAsFunction() = true
protected data class MethodSignatureData(