mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-55146 Autocomplete case inside switch
This commit is contained in:
@@ -462,6 +462,8 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
result.addElement(element);
|
||||
}
|
||||
});
|
||||
|
||||
JavaKeywordCompletion.addEnumCases(result, parameters.getPosition());
|
||||
}
|
||||
|
||||
static boolean isClassNamePossible(CompletionParameters parameters) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.LambdaHighlightingUtil;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -42,6 +41,8 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.openapi.util.Conditions.notInstanceOf;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.*;
|
||||
import static com.intellij.patterns.StandardPatterns.not;
|
||||
@@ -295,12 +296,34 @@ public class JavaKeywordCompletion {
|
||||
}
|
||||
|
||||
private static void addCaseDefault(Consumer<LookupElement> result, PsiElement position) {
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class, false, PsiMember.class) != null) {
|
||||
if (getSwitchFromLabelPosition(position) != null) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.CASE), TailType.INSERT_SPACE));
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.CASE_COLON));
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiSwitchStatement getSwitchFromLabelPosition(PsiElement position) {
|
||||
return PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class, false, PsiMember.class, PsiSwitchLabelStatement.class);
|
||||
}
|
||||
|
||||
static void addEnumCases(CompletionResultSet result, PsiElement position) {
|
||||
PsiSwitchStatement switchStatement = getSwitchFromLabelPosition(position);
|
||||
PsiExpression expression = switchStatement == null ? null : switchStatement.getExpression();
|
||||
PsiClass switchType = expression == null ? null : PsiUtil.resolveClassInClassTypeOnly(expression.getType());
|
||||
if (switchType == null || !switchType.isEnum()) return;
|
||||
|
||||
Set<PsiField> used = ReferenceExpressionCompletionContributor.findConstantsUsedInSwitch(switchStatement);
|
||||
for (PsiField field : switchType.getAllFields()) {
|
||||
String name = field.getName();
|
||||
if (!(field instanceof PsiEnumConstant) || used.contains(field) || name == null) {
|
||||
continue;
|
||||
}
|
||||
String prefix = "case ";
|
||||
String suffix = name + ":";
|
||||
result.addElement(LookupElementBuilder.create(field, prefix + suffix).bold().withPresentableText(prefix).withTailText(suffix).withLookupString(name));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFinal(Consumer<LookupElement> result, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
PsiStatement statement = PsiTreeUtil.getParentOfType(position, PsiExpressionStatement.class);
|
||||
if (statement == null) {
|
||||
|
||||
+20
-16
@@ -28,6 +28,7 @@ import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -178,26 +179,29 @@ public class ReferenceExpressionCompletionContributor {
|
||||
|
||||
@NotNull
|
||||
public static Set<PsiField> findConstantsUsedInSwitch(@Nullable PsiElement position) {
|
||||
if (IN_SWITCH_LABEL.accepts(position)) {
|
||||
Set<PsiField> used = ContainerUtil.newLinkedHashSet();
|
||||
PsiSwitchStatement sw = PsiTreeUtil.getParentOfType(position, 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 PsiField) {
|
||||
used.add(CompletionUtil.getOriginalOrSelf((PsiField)target));
|
||||
}
|
||||
return IN_SWITCH_LABEL.accepts(position)
|
||||
? findConstantsUsedInSwitch(ObjectUtils.assertNotNull(PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class)))
|
||||
: Collections.emptySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<PsiField> findConstantsUsedInSwitch(@NotNull PsiSwitchStatement sw) {
|
||||
final PsiCodeBlock body = sw.getBody();
|
||||
if (body == null) return Collections.emptySet();
|
||||
|
||||
Set<PsiField> used = ContainerUtil.newLinkedHashSet();
|
||||
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 PsiField) {
|
||||
used.add(CompletionUtil.getOriginalOrSelf((PsiField)target));
|
||||
}
|
||||
}
|
||||
}
|
||||
return used;
|
||||
}
|
||||
return Collections.emptySet();
|
||||
return used;
|
||||
}
|
||||
|
||||
static PsiExpression createExpression(String text, PsiElement element) {
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class A extends Base{
|
||||
void foo(){
|
||||
B x = null;
|
||||
switch(x){
|
||||
GOO<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum B{
|
||||
FOO, BAR, GOO
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class A extends Base{
|
||||
void foo(){
|
||||
B x = null;
|
||||
switch(x){
|
||||
case GOO:<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum B{
|
||||
FOO, BAR, GOO
|
||||
}
|
||||
|
||||
+2
@@ -290,6 +290,8 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
assertEquals(3, myItems.length);
|
||||
}
|
||||
|
||||
public void testSwitchCaseWithEnumConstant() { doTest() }
|
||||
|
||||
public void testMethodInAnnotation() throws Exception {
|
||||
configureByFile("Annotation.java");
|
||||
checkResultByFile("Annotation_after.java");
|
||||
|
||||
Reference in New Issue
Block a user