method info: walk up for resolved candidate (IDEA-181445)

This commit is contained in:
Anna.Kozlova
2017-11-28 18:53:45 +01:00
parent 5998dfed1f
commit 873b4402da
3 changed files with 51 additions and 9 deletions

View File

@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.Inlay;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -245,7 +246,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
CandidateInfo candidate = (CandidateInfo)candidates[i];
PsiMethod method = (PsiMethod)candidate.getElement();
if (!method.isValid()) continue;
PsiSubstitutor substitutor = getCandidateInfoSubstitutor(o, candidate);
PsiSubstitutor substitutor = getCandidateInfoSubstitutor(o, candidate, method == realResolve);
assert substitutor != null;
if (!method.isValid() || !substitutor.isValid()) {
@@ -381,11 +382,17 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
}
}
private static PsiSubstitutor getCandidateInfoSubstitutor(PsiElement argList, CandidateInfo candidate) {
return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(ObjectUtils.notNull(argList, candidate.getElement()), false,
() -> candidate instanceof MethodCandidateInfo && ((MethodCandidateInfo)candidate).isInferencePossible()
? ((MethodCandidateInfo)candidate).inferTypeArguments(CompletionParameterTypeInferencePolicy.INSTANCE, true)
: candidate.getSubstitutor());
private static PsiSubstitutor getCandidateInfoSubstitutor(PsiElement argList, CandidateInfo candidate, boolean resolveResult) {
Computable<PsiSubstitutor> computeSubstitutor =
() -> candidate instanceof MethodCandidateInfo && ((MethodCandidateInfo)candidate).isInferencePossible()
? ((MethodCandidateInfo)candidate).inferTypeArguments(CompletionParameterTypeInferencePolicy.INSTANCE, true)
: candidate.getSubstitutor();
if (resolveResult && candidate instanceof MethodCandidateInfo && ((MethodCandidateInfo)candidate).isInferencePossible()) {
return computeSubstitutor.compute();
}
return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(ObjectUtils.notNull(argList, candidate.getElement()),
false,
computeSubstitutor);
}
private static boolean isAssignableParametersBeforeGivenIndex(final PsiParameter[] parms,
@@ -689,7 +696,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
return;
}
updateMethodPresentation(method, getCandidateInfoSubstitutor(context.getParameterOwner(), info), context);
updateMethodPresentation(method, getCandidateInfoSubstitutor(context.getParameterOwner(), info, false), context);
}
else {
updateMethodPresentation((PsiMethod)p, null, context);

View File

@@ -0,0 +1,10 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
class Test {
void m(Map<String, String> s) {
s.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, <caret>Map.Entry::getValue));
}
}

View File

@@ -17,6 +17,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.*;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.EditorHintFixture;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext;
@@ -34,6 +35,12 @@ public class ParameterInfoTest extends LightCodeInsightFixtureTestCase {
public void testPrivateMethodOfEnclosingClass() { doTest(); }
public void testNotAccessible() { doTest(); }
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_8;
}
private void doTest() {
myFixture.configureByFile(getTestName(false) + ".java");
@@ -109,6 +116,24 @@ public class ParameterInfoTest extends LightCodeInsightFixtureTestCase {
assertEquals("<html><b>String s</b>, int... p</html>", hintFixture.getCurrentHintText());
}
public void testPreselectionOfCandidatesInNestedMethod() {
myFixture.configureByFile(getTestName(false) + ".java");
MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
PsiExpressionList list = handler.findElementForParameterInfo(context);
assertNotNull(list);
Object[] itemsToShow = context.getItemsToShow();
assertNotNull(itemsToShow);
assertEquals(3, itemsToShow.length);
assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, -1);
MockUpdateParameterInfoContext updateParameterInfoContext = updateParameterInfo(handler, list, itemsToShow);
assertTrue(updateParameterInfoContext.isUIComponentEnabled(0) ||
updateParameterInfoContext.isUIComponentEnabled(1) ||
updateParameterInfoContext.isUIComponentEnabled(2));
}
private void doTest2CandidatesWithPreselection() {
myFixture.configureByFile(getTestName(false) + ".java");
@@ -279,7 +304,7 @@ public class ParameterInfoTest extends LightCodeInsightFixtureTestCase {
"Bar(boolean a);" +
"Bar(String a);" +
"Bar(int a);" +
"}; " +
"} " +
"class Bar2 {}");
myFixture.configureByText("a.java", "class Foo {{ new Bar<caret> }}");
LookupElement[] elements = myFixture.completeBasic();
@@ -297,7 +322,7 @@ public class ParameterInfoTest extends LightCodeInsightFixtureTestCase {
public void testNoStrikeoutForSingleDeprecatedMethod() {
myFixture.configureByText(JavaFileType.INSTANCE, "class C { void m() { System.runFinalizersOnExit(true<caret>); } }");
assertEquals("<html>boolean value</html>", parameterPresentation(-1));
assertEquals("<html>boolean b</html>", parameterPresentation(-1));
}
private void checkHighlighted(int lineIndex) {