From 987368ccfdea0bb9bf63b7e590e4c5b841f91364 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 May 2018 18:00:49 +0200 Subject: [PATCH] IDEA-191883 "Tab" completion doesn't work as expected for inner classes --- .../completion/ConstructorInsertHandler.java | 13 ++------- .../JavaClassNameInsertHandler.java | 28 ++++++++++++++----- .../completion/JavaCompletionContributor.java | 8 ------ .../completion/JavaCompletionSession.java | 2 ++ .../completion/normal/TabOnNewInnerClass.java | 6 ++++ .../normal/TabOnNewInnerClass_after.java | 6 ++++ .../completion/NormalCompletionTest.groovy | 7 +++++ 7 files changed, 45 insertions(+), 25 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index d881c9369c86..cfb4a6f8d38b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -16,7 +16,6 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.Result; import com.intellij.openapi.application.TransactionGuard; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.UndoConfirmationPolicy; @@ -50,8 +49,6 @@ public class ConstructorInsertHandler implements InsertHandler= 0 && plEnd >= 0) { - context.getDocument().deleteString(plStart, plEnd); - } + if (Lookup.REPLACE_SELECT_CHAR == context.getCompletionChar()) { + JavaClassNameInsertHandler.overwriteTopmostReference(context); } context.commitDocument(); @@ -87,7 +80,7 @@ public class ConstructorInsertHandler implements InsertHandler context.getTailOffset() && context.getDocument().getCharsSequence().charAt(context.getTailOffset()) == '<') { - PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getTailOffset(), PsiJavaCodeReferenceElement.class, false); + PsiJavaCodeReferenceElement ref = JavaClassNameInsertHandler.findJavaReference(context.getFile(), context.getTailOffset()); if (ref != null) { PsiReferenceParameterList parameterList = ref.getParameterList(); if (parameterList != null && context.getTailOffset() == parameterList.getTextRange().getStartOffset()) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java index 6225358ebf41..73cd826d0793 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java @@ -47,8 +47,8 @@ class JavaClassNameInsertHandler implements InsertHandler 0) { - context.getOffsetMap().addOffset(ConstructorInsertHandler.PARAM_LIST_START, paramList.getTextRange().getStartOffset()); - context.getOffsetMap().addOffset(ConstructorInsertHandler.PARAM_LIST_END, paramList.getTextRange().getEndOffset()); - } - } - return; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSession.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSession.java index bb8b10b934f7..97203d7866d9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSession.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSession.java @@ -54,6 +54,8 @@ public class JavaCompletionSession { } public void addClassItem(LookupElement lookupElement) { + if (!myResult.getPrefixMatcher().prefixMatches(lookupElement)) return; + PsiClass psiClass = extractClass(lookupElement); if (psiClass != null) { registerClass(psiClass); diff --git a/java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass.java b/java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass.java new file mode 100644 index 000000000000..87c289927dca --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass.java @@ -0,0 +1,6 @@ +class Scratch { + interface Some {} + public static class Inner implements Some {} + + Some f = new Scratch.z(); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass_after.java b/java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass_after.java new file mode 100644 index 000000000000..cf33aa4659c9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/TabOnNewInnerClass_after.java @@ -0,0 +1,6 @@ +class Scratch { + interface Some {} + public static class Inner implements Some {} + + Some f = new Scratch.Inner(); +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy index fd4d816ddaa1..b129a2cead65 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy @@ -1852,4 +1852,11 @@ class Bar {{ void testSuggestGetInstanceMethodName() { doTest() } + void testTabOnNewInnerClass() { + configureByTestName() + lookup.currentItem = myFixture.lookupElements.find { it.lookupString.contains('Inner') } + myFixture.type('\t') + checkResult() + } + }