mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-69328 Code completion in switch...case: complete other possible values from already ref'd class
This commit is contained in:
@@ -526,8 +526,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
|
||||
if (JavaSmartCompletionContributor.INSIDE_EXPRESSION.accepts(position) &&
|
||||
!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position) &&
|
||||
!(position.getParent() instanceof PsiLiteralExpression) &&
|
||||
!(position.getParent().getParent() instanceof PsiSwitchLabelStatement)) {
|
||||
!(position.getParent() instanceof PsiLiteralExpression)) {
|
||||
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
new JavaMembersGetter(info.getDefaultType(), position).addMembers(position, parameters.getInvocationCount() > 1, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
|
||||
+1
-4
@@ -354,10 +354,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
boolean quick,
|
||||
Consumer<LookupElement> consumer) {
|
||||
PsiElement position = params.getPosition();
|
||||
final PsiElement parent = position.getParent();
|
||||
if (!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position) &&
|
||||
parent != null &&
|
||||
!(parent.getParent() instanceof PsiSwitchLabelStatement)) {
|
||||
if (!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position)) {
|
||||
for (ExpectedTypeInfo info : mergedInfos) {
|
||||
new JavaMembersGetter(info.getType(), position).addMembers(position, !quick, consumer);
|
||||
if (!info.getDefaultType().equals(info.getType())) {
|
||||
|
||||
+8
-9
@@ -46,6 +46,7 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -149,7 +150,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
|
||||
private static Set<LookupElement> completeFinalReference(final PsiElement element, PsiReference reference, ElementFilter filter,
|
||||
final JavaSmartCompletionParameters parameters) {
|
||||
final Set<PsiEnumConstant> used = findConstantsToSkip(element, parameters);
|
||||
final Set<PsiField> used = parameters.getParameters().getInvocationCount() < 2 ? findConstantsUsedInSwitch(element) : Collections.<PsiField>emptySet();
|
||||
|
||||
final Set<LookupElement> elements =
|
||||
JavaSmartCompletionContributor.completeReference(element, reference, new AndFilter(filter, new ElementFilter() {
|
||||
@@ -164,7 +165,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
}
|
||||
|
||||
//noinspection SuspiciousMethodCalls
|
||||
if (member instanceof PsiEnumConstant && used.contains(member)) {
|
||||
if (member instanceof PsiEnumConstant && used.contains(CompletionUtil.getOriginalOrSelf(member))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -192,11 +193,9 @@ public class ReferenceExpressionCompletionContributor {
|
||||
return elements;
|
||||
}
|
||||
|
||||
private static Set<PsiEnumConstant> findConstantsToSkip(PsiElement element, JavaSmartCompletionParameters parameters) {
|
||||
final Set<PsiEnumConstant> used = new HashSet<PsiEnumConstant>();
|
||||
if (parameters.getParameters().getInvocationCount() < 2 &&
|
||||
psiElement().withSuperParent(2, psiElement(PsiSwitchLabelStatement.class).withSuperParent(2, PsiSwitchStatement.class))
|
||||
.accepts(element)) {
|
||||
public static Set<PsiField> findConstantsUsedInSwitch(PsiElement element) {
|
||||
final Set<PsiField> used = new HashSet<PsiField>();
|
||||
if (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();
|
||||
@@ -206,8 +205,8 @@ public class ReferenceExpressionCompletionContributor {
|
||||
final PsiExpression value = ((PsiSwitchLabelStatement)statement).getCaseValue();
|
||||
if (value instanceof PsiReferenceExpression) {
|
||||
final PsiElement target = ((PsiReferenceExpression)value).resolve();
|
||||
if (target instanceof PsiEnumConstant) {
|
||||
used.add((PsiEnumConstant)target);
|
||||
if (target instanceof PsiField) {
|
||||
used.add(CompletionUtil.getOriginalOrSelf((PsiField)target));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,19 +15,26 @@
|
||||
*/
|
||||
package com.intellij.psi.filters.getters;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.codeInsight.completion.JavaMethodCallElement;
|
||||
import com.intellij.codeInsight.completion.ReferenceExpressionCompletionContributor;
|
||||
import com.intellij.codeInsight.completion.SmartCompletionDecorator;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||
import com.intellij.codeInsight.lookup.VariableLookupItem;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -40,15 +47,39 @@ public class JavaMembersGetter extends MembersGetter {
|
||||
myExpectedType = JavaCompletionUtil.originalize(expectedType);
|
||||
}
|
||||
|
||||
public void addMembers(PsiElement position, boolean searchInheritors, Consumer<LookupElement> results) {
|
||||
public void addMembers(PsiElement position, boolean searchInheritors, final Consumer<LookupElement> results) {
|
||||
if (myExpectedType instanceof PsiPrimitiveType && PsiType.DOUBLE.isAssignableFrom(myExpectedType)) {
|
||||
addConstantsFromTargetClass(position, results, searchInheritors);
|
||||
addConstantsFromReferencedClassesInSwitch(position, results);
|
||||
}
|
||||
|
||||
if (position.getParent().getParent() instanceof PsiSwitchLabelStatement) {
|
||||
return; //non-enum values are processed above, enum values will be suggested by reference completion
|
||||
}
|
||||
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(myExpectedType);
|
||||
processMembers(position, results, psiClass, PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) != null, searchInheritors);
|
||||
}
|
||||
|
||||
private void addConstantsFromReferencedClassesInSwitch(PsiElement position, final Consumer<LookupElement> results) {
|
||||
final Set<PsiField> fields = ReferenceExpressionCompletionContributor.findConstantsUsedInSwitch(position);
|
||||
final Set<PsiClass> classes = new HashSet<PsiClass>();
|
||||
for (PsiField field : fields) {
|
||||
ContainerUtil.addIfNotNull(classes, field.getContainingClass());
|
||||
}
|
||||
for (PsiClass aClass : classes) {
|
||||
processMembers(position, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
if (!fields.contains(element.getObject())) {
|
||||
results.consume(TailTypeDecorator.withTail(element, TailType.CASE_COLON));
|
||||
}
|
||||
}
|
||||
}, aClass, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void addConstantsFromTargetClass(PsiElement position, Consumer<LookupElement> results, boolean searchInheritors) {
|
||||
PsiElement parent = position.getParent();
|
||||
if (!(parent instanceof PsiReferenceExpression)) {
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Foo {
|
||||
void foo(int i) {
|
||||
switch (i) {
|
||||
case Constants.BAR0: return;
|
||||
case B<caret>:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Constants {
|
||||
int BAR0 = 0;
|
||||
int BAR1 = 1;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Foo {
|
||||
void foo(int i) {
|
||||
switch (i) {
|
||||
case Constants.BAR0: return;
|
||||
case Constants.BAR1:<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Constants {
|
||||
int BAR0 = 0;
|
||||
int BAR1 = 1;
|
||||
}
|
||||
+2
@@ -985,6 +985,8 @@ public class ListUtils {
|
||||
public void testNewGenericInterface() throws Throwable { doTest() }
|
||||
public void testEnumPrivateFinal() throws Throwable { doTest() }
|
||||
|
||||
public void testSwitchConstantsFromReferencedClass() throws Throwable { doTest('\n') }
|
||||
|
||||
public void testUnfinishedMethodTypeParameter() throws Throwable {
|
||||
configure()
|
||||
assertStringItems("MyParameter", "MySecondParameter")
|
||||
|
||||
Reference in New Issue
Block a user