From 8b23bed2b17b5398946fadc2672ffb2a93539b0a Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 8 Oct 2018 11:56:40 +0300 Subject: [PATCH] IDEA-198897 Parameter hints: Smart argument completion should insert comma if selected signature has more arguments --- .../codeInsight/ExpectedTypesProvider.java | 22 +++++++++++++++++++ .../AbstractParameterInfoTestCase.java | 17 +++++++++++++- .../completion/CompletionHintsTest.java | 12 ++++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java index 88153284482c..913e5c6c76d1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java @@ -15,6 +15,8 @@ */ package com.intellij.codeInsight; +import com.intellij.codeInsight.completion.CompletionMemory; +import com.intellij.codeInsight.completion.CompletionUtil; import com.intellij.codeInsight.daemon.impl.analysis.LambdaHighlightingUtil; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -955,6 +957,10 @@ public class ExpectedTypesProvider { return ExpectedTypeInfo.EMPTY_ARRAY; } + if (CodeInsightSettings.getInstance().SHOW_PARAMETER_NAME_HINTS_ON_COMPLETION) { + allCandidates = selectCandidateChosenOnCompletion(argumentList.getParent(), allCandidates); + } + PsiMethod toExclude = JavaPsiConstructorUtil.isConstructorCall(argumentList.getParent()) ? PsiTreeUtil.getParentOfType(argument, PsiMethod.class) : null; @@ -1039,6 +1045,22 @@ public class ExpectedTypesProvider { return array.toArray(ExpectedTypeInfo.EMPTY_ARRAY); } + @NotNull + private static CandidateInfo[] selectCandidateChosenOnCompletion(@Nullable PsiElement call, @NotNull CandidateInfo[] candidates) { + if (call instanceof PsiCall) { + PsiCall originalCall = CompletionUtil.getOriginalElement((PsiCall)call); + if (originalCall != null) { + PsiMethod method = CompletionMemory.getChosenMethod(originalCall); + if (method != null) { + for (CandidateInfo candidate : candidates) { + if (CompletionUtil.getOriginalOrSelf(candidate.getElement()) == method) return new CandidateInfo[]{candidate}; + } + } + } + } + return candidates; + } + @NotNull private static TailType getMethodArgumentTailType(@NotNull final PsiExpression argument, final int index, diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/AbstractParameterInfoTestCase.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/AbstractParameterInfoTestCase.java index 934e7f4e47a9..81968b1ca61e 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/AbstractParameterInfoTestCase.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/AbstractParameterInfoTestCase.java @@ -3,6 +3,7 @@ package com.intellij.java.codeInsight; import com.intellij.codeInsight.AutoPopupController; import com.intellij.codeInsight.CodeInsightSettings; +import com.intellij.codeInsight.completion.CompletionType; import com.intellij.codeInsight.completion.LightFixtureCompletionTestCase; import com.intellij.codeInsight.daemon.impl.ParameterHintsPresentationManager; import com.intellij.codeInsight.hint.ParameterInfoController; @@ -14,6 +15,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.testFramework.fixtures.EditorHintFixture; import com.intellij.util.ui.UIUtil; +import java.util.NoSuchElementException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.LockSupport; @@ -60,11 +62,24 @@ public abstract class AbstractParameterInfoTestCase extends LightFixtureCompleti public void complete(String partOfItemText) { LookupElement[] elements = myFixture.completeBasic(); + selectItem(elements, partOfItemText); + } + + public void completeSmart() { + myFixture.complete(CompletionType.SMART); + } + + public void completeSmart(String partOfItemText) { + LookupElement[] lookupElements = myFixture.complete(CompletionType.SMART); + selectItem(lookupElements, partOfItemText); + } + + private void selectItem(LookupElement[] elements, String partOfItemText) { LookupElement element = Stream.of(elements).filter(e -> { LookupElementPresentation p = new LookupElementPresentation(); e.renderElement(p); return (p.getItemText() + p.getTailText()).contains(partOfItemText); - }).findAny().get(); + }).findAny().orElseThrow(NoSuchElementException::new); selectItem(element); } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java index ba82acc619bb..0ebef13e220d 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java @@ -2,7 +2,6 @@ package com.intellij.java.codeInsight.completion; import com.intellij.codeInsight.CodeInsightSettings; -import com.intellij.codeInsight.completion.CompletionType; import com.intellij.codeInsight.completion.StaticallyImportable; import com.intellij.codeInsight.hints.JavaInlayParameterHintsProvider; import com.intellij.codeInsight.hints.Option; @@ -280,7 +279,7 @@ public class CompletionHintsTest extends AbstractParameterInfoTestCase { configureJava("class C { void m() { System.setPro } }"); complete("setProperty"); type("new String().trim"); - myFixture.complete(CompletionType.SMART); + completeSmart(); waitForAllAsyncStuff(); checkResultWithInlays("class C { void m() { System.setProperty(new String().trim(), ) } }"); } @@ -1653,6 +1652,15 @@ public class CompletionHintsTest extends AbstractParameterInfoTestCase { checkResultWithInlays("class C { void some(int a) {} void some(int a, int b) {} void m() { some(1, ); } }"); } + public void testCommaAfterSmartCompletionOfOverloadedMethodParameter() { + configureJava("class C { int codePoint = 123; void m() { Character.to } }"); + complete("toChars(int codePoint, char[] dst, int dstIndex)"); + type("codePoin"); + completeSmart("codePoint"); + waitForAllAsyncStuff(); + checkResultWithInlays("class C { int codePoint = 123; void m() { Character.toChars(codePoint, ) } }"); + } + private void checkResultWithInlays(String text) { myFixture.checkResultWithInlays(text); }