From 7ef62f36553bf0cd1b69f58ed6642564347cbc8d Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 27 Dec 2011 15:55:33 +0100 Subject: [PATCH] IDEA-69897 Smart complete missing enum values in switch/case statements --- ...erenceExpressionCompletionContributor.java | 36 +++++++++++++++++-- .../smartType/CaseMissingEnumValue-out.java | 10 ++++++ .../smartType/CaseMissingEnumValue.java | 10 ++++++ .../smartType/CaseMissingEnumValue2-out.java | 10 ++++++ .../smartType/CaseMissingEnumValue2.java | 10 ++++++ .../completion/SmartTypeCompletionTest.java | 3 ++ 6 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue-out.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2-out.java create mode 100644 java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index 279c8e58b912..7b6bab380d82 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -19,7 +19,6 @@ import com.intellij.codeInsight.lookup.ExpressionLookupItem; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.featureStatistics.FeatureUsageTracker; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -47,6 +46,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashSet; import java.util.Set; import static com.intellij.patterns.PsiJavaPatterns.psiElement; @@ -149,6 +149,8 @@ public class ReferenceExpressionCompletionContributor { private static Set completeFinalReference(final PsiElement element, PsiReference reference, ElementFilter filter, final JavaSmartCompletionParameters parameters) { + final Set used = findConstantsToSkip(element, parameters); + final Set elements = JavaSmartCompletionContributor.completeReference(element, reference, new AndFilter(filter, new ElementFilter() { public boolean isAcceptable(Object o, PsiElement context) { @@ -161,6 +163,11 @@ public class ReferenceExpressionCompletionContributor { return member instanceof PsiMethod; } + //noinspection SuspiciousMethodCalls + if (member instanceof PsiEnumConstant && used.contains(member)) { + return false; + } + return AssignableFromFilter.isAcceptable(member, element, expectedType, info.getSubstitutor()); } return false; @@ -176,7 +183,8 @@ public class ReferenceExpressionCompletionContributor { assert item != null; final PsiMethod method = (PsiMethod)lookupElement.getObject(); if (SmartCompletionDecorator.hasUnboundTypeParams(method, parameters.getExpectedType())) { - item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, parameters.getExpectedType()), element); + item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, parameters.getExpectedType()), + element); } } } @@ -184,6 +192,30 @@ public class ReferenceExpressionCompletionContributor { return elements; } + private static Set findConstantsToSkip(PsiElement element, JavaSmartCompletionParameters parameters) { + final Set used = new HashSet(); + if (parameters.getParameters().getInvocationCount() < 2 && + psiElement().withSuperParent(2, psiElement(PsiSwitchLabelStatement.class).withSuperParent(2, PsiSwitchStatement.class)) + .accepts(element)) { + PsiSwitchStatement sw = PsiTreeUtil.getParentOfType(element, PsiSwitchStatement.class); + assert sw != null; + final PsiCodeBlock body = sw.getBody(); + assert body != null; + for (PsiStatement statement : body.getStatements()) { + if (statement instanceof PsiSwitchLabelStatement) { + final PsiExpression value = ((PsiSwitchLabelStatement)statement).getCaseValue(); + if (value instanceof PsiReferenceExpression) { + final PsiElement target = ((PsiReferenceExpression)value).resolve(); + if (target instanceof PsiEnumConstant) { + used.add((PsiEnumConstant)target); + } + } + } + } + } + return used; + } + private static void addSingleArrayElementAccess(PsiElement element, LookupElement item, JavaSmartCompletionParameters parameters, Consumer result) { if (item.getObject() instanceof PsiLocalVariable) { diff --git a/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue-out.java b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue-out.java new file mode 100644 index 000000000000..25f5e69762db --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue-out.java @@ -0,0 +1,10 @@ +class A { + A(MyEnum e) { + switch (e) { + case bar: return; + case foo: + } + } +} + +enum MyEnum { foo, bar } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue.java b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue.java new file mode 100644 index 000000000000..056dfbded4a0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue.java @@ -0,0 +1,10 @@ +class A { + A(MyEnum e) { + switch (e) { + case bar: return; + case + } + } +} + +enum MyEnum { foo, bar } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2-out.java b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2-out.java new file mode 100644 index 000000000000..b13e612df3a5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2-out.java @@ -0,0 +1,10 @@ +class A { + A(MyEnum e) { + switch (e) { + case foo: + case bar: return; + } + } +} + +enum MyEnum { foo, bar } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2.java b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2.java new file mode 100644 index 000000000000..b1acd4c064eb --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/CaseMissingEnumValue2.java @@ -0,0 +1,10 @@ +class A { + A(MyEnum e) { + switch (e) { + case + case bar: return; + } + } +} + +enum MyEnum { foo, bar } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index 4623705d0f42..f9b0ffd9eab6 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -1011,6 +1011,9 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase { public void testCheckStaticImportsType() throws Throwable { doAntiTest(); } public void testThisFieldAssignedToItself() throws Throwable { doAntiTest(); } + public void testCaseMissingEnumValue() throws Throwable { doTest(); } + public void testCaseMissingEnumValue2() throws Throwable { doTest(); } + public void testTypeVariableInstanceOf() throws Throwable { configureByTestName(); performAction();