From b2f3dd449b3271d45324862095bd354833e6c493 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Thu, 25 May 2017 17:47:08 +0300 Subject: [PATCH] IDEA-173444 Parameter hints in completion: incorrect behavior on value inserting before hint --- .../completion/JavaMethodCallElement.java | 5 ++ .../codeInsight/hints/JavaHintUtils.kt | 5 +- .../completion/CompletionHintsTest.java | 61 ++++++++++++------- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java index 834bfd72e025..6028aeb5bfcb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodCallElement.java @@ -359,6 +359,11 @@ public class JavaMethodCallElement extends LookupItem implements Type } } + public static boolean hasCompletionHints(@NotNull PsiCallExpression expression) { + PsiExpressionList argumentList = expression.getArgumentList(); + return argumentList != null && !ContainerUtil.isEmpty(argumentList.getUserData(COMPLETION_HINTS)); + } + private static void setupNonFilledArgumentRemoving(final Editor editor, final TemplateState templateState) { AtomicInteger maxEditedVariable = new AtomicInteger(-1); editor.getDocument().addDocumentListener(new DocumentListener() { diff --git a/java/java-impl/src/com/intellij/codeInsight/hints/JavaHintUtils.kt b/java/java-impl/src/com/intellij/codeInsight/hints/JavaHintUtils.kt index ee803064658a..da3b7607691c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hints/JavaHintUtils.kt +++ b/java/java-impl/src/com/intellij/codeInsight/hints/JavaHintUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.codeInsight.hints import com.intellij.codeInsight.completion.CompletionMemory +import com.intellij.codeInsight.completion.JavaMethodCallElement import com.intellij.psi.* import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl @@ -26,6 +27,8 @@ import com.intellij.psi.util.TypeConversionUtil object JavaInlayHintsProvider { fun hints(callExpression: PsiCallExpression): Set { + if (JavaMethodCallElement.hasCompletionHints(callExpression)) return emptySet() + val resolveResult = callExpression.resolveMethodGenerics() val hints = methodHints(callExpression, resolveResult) if (hints.isNotEmpty()) return hints 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 512e8cc5b754..60f026713042 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 @@ -30,6 +30,7 @@ import com.intellij.openapi.util.registry.RegistryValue; import com.intellij.util.ui.UIUtil; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.LockSupport; import java.util.stream.Stream; @@ -61,7 +62,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { myFixture.checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); // check that hints don't disappear after daemon highlighting passes - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); // test Tab/Shift+Tab navigation @@ -78,15 +79,14 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { myFixture.type("\"a"); myFixture.performEditorAction("NextParameter"); myFixture.type("\"b"); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { System.setProperty(\"a\", \"b\") } }"); // test hints disappearance when caret moves out of parameter list - myFixture.performEditorAction("EditorRight"); - myFixture.performEditorAction("EditorRight"); - ParameterInfoController.waitForDelayedActions(getEditor(), 10, TimeUnit.SECONDS); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { System.setProperty(\"a\", \"b\") } }"); } @@ -97,7 +97,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); // check that hints don't disappear after daemon highlighting passes - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); // test Tab/Shift+Tab navigation @@ -114,15 +114,14 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { myFixture.type("1"); myFixture.performEditorAction("NextParameter"); myFixture.type("2"); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(1, 2) } }"); // test hints don't disappear when caret moves out of parameter list - myFixture.performEditorAction("EditorRight"); - myFixture.performEditorAction("EditorRight"); - ParameterInfoController.waitForDelayedActions(getEditor(), 10, TimeUnit.SECONDS); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(1, 2) } }"); } @@ -136,7 +135,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { complete("forDigit"); myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); } finally { @@ -180,25 +179,25 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { "}"); } - public void testNestedCompletion() { + public void testNestedCompletion() throws Exception { myFixture.configureByText(JavaFileType.INSTANCE, "class C { void m() { System.setPro } }"); complete("setProperty"); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); myFixture.type("System.getPro"); complete("getProperty(String key, String def)"); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); } - public void testTabWithNestedCompletion() { + public void testTabWithNestedCompletion() throws Exception { myFixture.configureByText(JavaFileType.INSTANCE, "class C { void m() { System.setPro } }"); complete("setProperty"); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.type("System.getPro"); complete("getProperty(String key, String def)"); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); myFixture.performEditorAction("NextParameter"); myFixture.checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); @@ -221,8 +220,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { complete("getProperty(String key, String def)"); myFixture.checkResultWithInlays("class C { void m() { System.getProperty(, ) } }"); myFixture.performEditorAction(IdeActions.ACTION_EDITOR_DELETE); - ParameterInfoController.waitForDelayedActions(getEditor(), 1, TimeUnit.MINUTES); - runHintsPass(); + waitForAllAsyncStuff(); myFixture.checkResultWithInlays("class C { void m() { System.getProperty( ) } }"); } @@ -237,6 +235,24 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { getEditor().getCaretModel().getVisualPosition()); } + public void testNoHintsDuplicationWhenTypingToTheLeftOfHint() throws Exception { + myFixture.configureByText(JavaFileType.INSTANCE, "class C { void m() { Character.for } }"); + complete("forDigit"); + waitForAllAsyncStuff(); + type("1"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT); + type("2"); + waitForAllAsyncStuff(); + myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(1,2 ) } }"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_LINE_END); + waitForAllAsyncStuff(); + myFixture.checkResultWithInlays("class C { void m() { Character.forDigit(1,2 ) } }"); + } + + private void waitForParameterInfoUpdate() throws TimeoutException { + ParameterInfoController.waitForDelayedActions(getEditor(), 1, TimeUnit.MINUTES); + } + private void showParameterInfo() { myFixture.performEditorAction("ParameterInfo"); UIUtil.dispatchAllInvocationEvents(); @@ -261,7 +277,8 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { } } - private void runHintsPass() { + private void waitForAllAsyncStuff() throws TimeoutException { + waitForParameterInfoUpdate(); myFixture.doHighlighting(); waitTillAnimationCompletes(); }