[name hints] show hints when resolve returns multiple overloaded methods, for parameter names which are the same

This commit is contained in:
Yaroslav Lepenkin
2016-12-08 18:00:40 +03:00
parent 9eebef8658
commit 2beb632fce
4 changed files with 63 additions and 3 deletions
@@ -17,17 +17,46 @@ package com.intellij.codeInsight.hints
import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings
import com.intellij.psi.*
import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
import com.intellij.psi.util.TypeConversionUtil
object JavaInlayHintsProvider {
fun createHints(callExpression: PsiCallExpression): Set<InlayInfo> {
val (element, substitutor) = callExpression.resolveMethodGenerics().let { it.element to it.substitutor }
val resolveResult = callExpression.resolveMethodGenerics()
val hints = createHintsForResolvedMethod(callExpression, resolveResult)
if (hints.isNotEmpty()) return hints
return when (callExpression) {
is PsiMethodCallExpressionImpl -> createMergedHints(callExpression, callExpression.methodExpression.multiResolve(false))
is PsiNewExpressionImpl -> createMergedHints(callExpression, callExpression.constructorFakeReference.multiResolve(false))
else -> emptySet()
}
}
private fun createMergedHints(callExpression: PsiCallExpression,
results: Array<out ResolveResult>): Set<InlayInfo> {
val resultSet = results
.filter { it.element != null }
.map { createHintsForResolvedMethod(callExpression, it) }
if (resultSet.isEmpty() || resultSet.any { it.isEmpty() }) return emptySet()
return resultSet.reduce { left, right -> left.intersect(right) }
}
private fun createHintsForResolvedMethod(callExpression: PsiCallExpression, resolveResult: ResolveResult): Set<InlayInfo> {
val element = resolveResult.element
val substitutor = (resolveResult as? JavaResolveResult)?.substitutor ?: PsiSubstitutor.EMPTY
if (element is PsiMethod && isMethodToShow(element, callExpression)) {
val info = getCallInfo(callExpression, element)
return createHintSet(info, substitutor)
}
return emptySet()
}
@@ -134,7 +134,7 @@ public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNew
return resolveConstructor();
}
private PsiPolyVariantCachingReference getConstructorFakeReference() {
public PsiPolyVariantCachingReference getConstructorFakeReference() {
return new PsiPolyVariantCachingReference() {
@Override
@NotNull
@@ -844,4 +844,35 @@ class Test {
onLineStartingWith("test").assertInlays("parent->c", "child->d", "vx->v", "vy->v")
}
fun `test show ambigous`() {
setup("""
class Test {
void main() {
test(10, x);
}
void test(int a, String bS) {}
void test(int a, int bI) {}
}
""")
onLineStartingWith("test").assertInlays("a->10")
}
fun `test show ambigous constructor`() {
setup("""
class Test {
void main() {
new X(10, x);
}
}
class X {
X(int a, int bI) {}
X(int a, String bS) {}
}
""")
onLineStartingWith("new").assertInlays("a->10")
}
}
@@ -116,7 +116,7 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
List<InlayInfo> hints = provider.getParameterHints(element);
if (hints.isEmpty()) return;
MethodInfo info = provider.getMethodInfo(element);
if (info != null && !isMatchedByAny(info, blackListMatchers)) {
if (info == null || !isMatchedByAny(info, blackListMatchers)) {
hints.forEach((h) -> myAnnotations.put(h.getOffset(), h.getText()));
}
}