From b3ca224f07e71168e734bc442c1c3ccea35a65ab Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 28 Jul 2016 12:38:54 +0200 Subject: [PATCH] IDEA-55146 Autocomplete case inside switch indent, remove duplicates, restore completion after 'case' (IDEA-CR-12610) --- .../completion/JavaCompletionContributor.java | 3 +-- .../completion/JavaKeywordCompletion.java | 17 ++++++++++++++--- .../keywords/noCaseInsideWhileInSwitch.java | 8 ++++++++ .../SecondSwitchCaseWithEnumConstant.java | 13 +++++++++++++ .../SecondSwitchCaseWithEnumConstant_after.java | 13 +++++++++++++ .../SwitchCaseWithEnumConstant_after.java | 2 +- .../completion/KeywordCompletionTest.java | 1 + .../completion/NormalCompletionTest.groovy | 1 + 8 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/keywords/noCaseInsideWhileInSwitch.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 0e1df098b117..320f286c71bb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -54,7 +54,6 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.DocumentUtil; -import com.intellij.util.PairConsumer; import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -845,7 +844,7 @@ public class JavaCompletionContributor extends CompletionContributor { return null; } - private static class IndentingDecorator extends LookupElementDecorator { + static class IndentingDecorator extends LookupElementDecorator { public IndentingDecorator(LookupElement delegate) { super(delegate); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java index 99336b31890e..c61f9ebab559 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java @@ -36,6 +36,7 @@ import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; +import com.intellij.util.ObjectUtils; import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -303,7 +304,11 @@ public class JavaKeywordCompletion { } private static PsiSwitchStatement getSwitchFromLabelPosition(PsiElement position) { - return PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class, false, PsiMember.class, PsiSwitchLabelStatement.class); + PsiStatement statement = PsiTreeUtil.getParentOfType(position, PsiStatement.class, false, PsiMember.class); + if (statement != null && !(statement instanceof PsiSwitchLabelStatement) && statement.getParent() instanceof PsiCodeBlock) { + return ObjectUtils.tryCast(statement.getParent().getParent(), PsiSwitchStatement.class); + } + return null; } static void addEnumCases(CompletionResultSet result, PsiElement position) { @@ -315,12 +320,18 @@ public class JavaKeywordCompletion { Set used = ReferenceExpressionCompletionContributor.findConstantsUsedInSwitch(switchStatement); for (PsiField field : switchType.getAllFields()) { String name = field.getName(); - if (!(field instanceof PsiEnumConstant) || used.contains(field) || name == null) { + if (!(field instanceof PsiEnumConstant) || used.contains(CompletionUtil.getOriginalOrSelf(field)) || name == null) { continue; } String prefix = "case "; String suffix = name + ":"; - result.addElement(LookupElementBuilder.create(field, prefix + suffix).bold().withPresentableText(prefix).withTailText(suffix).withLookupString(name)); + LookupElementBuilder caseConst = LookupElementBuilder + .create(field, prefix + suffix) + .bold() + .withPresentableText(prefix) + .withTailText(suffix) + .withLookupString(name); + result.addElement(new JavaCompletionContributor.IndentingDecorator(caseConst)); } } diff --git a/java/java-tests/testData/codeInsight/completion/keywords/noCaseInsideWhileInSwitch.java b/java/java-tests/testData/codeInsight/completion/keywords/noCaseInsideWhileInSwitch.java new file mode 100644 index 000000000000..091fbf815e8e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/noCaseInsideWhileInSwitch.java @@ -0,0 +1,8 @@ +public class StructuredConfigKey { + { + switch (x) { + case 2: + while (true) + } + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant.java b/java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant.java new file mode 100644 index 000000000000..c63de5ddc810 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant.java @@ -0,0 +1,13 @@ +class A extends Base{ + void foo(B b){ + switch(b) { + case FOO: + GOO + } + } +} + +enum B{ + FOO, BAR, GOO +} + diff --git a/java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant_after.java b/java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant_after.java new file mode 100644 index 000000000000..f387126c1b4c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SecondSwitchCaseWithEnumConstant_after.java @@ -0,0 +1,13 @@ +class A extends Base{ + void foo(B b){ + switch(b) { + case FOO: + case GOO: + } + } +} + +enum B{ + FOO, BAR, GOO +} + diff --git a/java/java-tests/testData/codeInsight/completion/normal/SwitchCaseWithEnumConstant_after.java b/java/java-tests/testData/codeInsight/completion/normal/SwitchCaseWithEnumConstant_after.java index 5092c27a2e8c..c6ed04eeda4e 100644 --- a/java/java-tests/testData/codeInsight/completion/normal/SwitchCaseWithEnumConstant_after.java +++ b/java/java-tests/testData/codeInsight/completion/normal/SwitchCaseWithEnumConstant_after.java @@ -2,7 +2,7 @@ class A extends Base{ void foo(){ B x = null; switch(x){ - case GOO: + case GOO: } } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java index 1cad2f0ed4b2..9eb6d550ec6e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/KeywordCompletionTest.java @@ -126,6 +126,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase { public void testFinalAfterParameterAnno() throws Exception { doTest(2, "final", "float", "class"); } public void testFinalAfterParameterAnno2() throws Exception { doTest(2, "final", "float", "class"); } public void testFinalAfterCase() { doTest(3, "final", "float", "class"); } + public void testNoCaseInsideWhileInSwitch() { doTest(0, "case", "default"); } public void testFinalInCatch() { doTest(1, "final"); } public void testFinalInIncompleteCatch() { doTest(1, "final"); } public void testFinalInTryWithResources() throws Exception { doTest(1, "final", "float", "class"); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index 874eb2a589b5..8a4e4e35a653 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -291,6 +291,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { } public void testSwitchCaseWithEnumConstant() { doTest() } + public void testSecondSwitchCaseWithEnumConstant() { doTest() } public void testMethodInAnnotation() throws Exception { configureByFile("Annotation.java");