in psi/src/com/intellij/r/psi/classes/s4/RS4Resolver.kt [76:118]
fun resolveS4GenericOrMethods(element: PsiElement,
name: String,
result: MutableList<ResolveResult>,
globalSearchScope: GlobalSearchScope) {
val call = element.parent as? RCallExpression ?: return
RS4GenericIndex.findDefinitionsByName(name, element.project, globalSearchScope).map { generic ->
val genericInfo = generic.associatedS4GenericInfo ?: return@map generic
val argumentInfo = RArgumentInfo.getArgumentInfo(call.argumentList, genericInfo.signature.parameters)
val types = argumentInfo.toS4MethodParameters(false)
val methodName = generic.methodName ?: return@map generic
val methodsWithDistance = RS4MethodsIndex.findDefinitionsByName(methodName, generic.project, globalSearchScope)
.mapNotNull { def ->
val info = def.associatedS4MethodInfo?.getParameters(globalSearchScope)
?.sortedBy { it.name }
?.takeIf { it.isNotEmpty() }
?: return@mapNotNull null
if (info.size != types.size || info.zip(types).any { (a, b) -> a.name != b.name }) return@mapNotNull null
def to info.zip(types).map { (a, b) ->
RS4ClassInfoUtil.lookupDistanceBetweenClasses(b.type, a.type, element.project, globalSearchScope)
}
}
val anyDistance = methodsWithDistance.maxOfOrNull { methodWithDistance ->
methodWithDistance.second.maxOfOrNull { if (it is RS4OrdDistance) it.distance else 0 } ?: 0
} ?: 0 + 1
methodsWithDistance.map { methodWithDistance ->
methodWithDistance.first to methodWithDistance.second.sumOf {
when (it) {
RS4DistanceToANY -> anyDistance
RS4InfDistance -> 100_000
is RS4OrdDistance -> it.distance
}
}
}.minByOrNull { it.second }?.first ?: generic
}.forEach {
val target = when (val methodNameIdentifier = it.methodNameIdentifier) {
null -> it
is RStringLiteralExpression -> RPomTarget.createStringLiteralTarget(methodNameIdentifier)
else -> methodNameIdentifier
}
result.add(PsiElementResolveResult(target))
}
}