IDEA-143786 Switch over enum completion - do not prefer just typed variants

This commit is contained in:
peter
2015-08-13 18:22:52 +02:00
parent 8e779e25bd
commit ec71fb4d28
5 changed files with 52 additions and 18 deletions
@@ -44,7 +44,8 @@ public class JavaCompletionStatistician extends CompletionStatistician{
return StatisticsInfo.EMPTY;
}
if (SUPER_CALL.accepts(location.getCompletionParameters().getPosition())) {
PsiElement position = location.getCompletionParameters().getPosition();
if (SUPER_CALL.accepts(position) || ReferenceExpressionCompletionContributor.IN_SWITCH_LABEL.accepts(position)) {
return StatisticsInfo.EMPTY;
}
@@ -59,6 +59,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.intellij.codeInsight.completion.ReferenceExpressionCompletionContributor.*;
import static com.intellij.patterns.PlatformPatterns.psiElement;
public class JavaCompletionUtil {
@@ -498,15 +499,14 @@ public class JavaCompletionUtil {
@NotNull LookupElement item,
@NotNull Object object,
@NotNull PsiElement place) {
if (object instanceof PsiMember &&
Java15APIUsageInspectionBase.isForbiddenApiUsage((PsiMember)object, PsiUtil.getLanguageLevel(place))) {
return LookupElementDecorator.withRenderer(item, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
if (shouldMarkRed(object, place)) {
return PrioritizedLookupElement.withExplicitProximity(LookupElementDecorator.withRenderer(item, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
@Override
public void renderElement(LookupElementDecorator<LookupElement> element, LookupElementPresentation presentation) {
element.getDelegate().renderElement(presentation);
presentation.setItemTextForeground(JBColor.RED);
}
});
}), -1);
}
if (containsMember(qualifierType, object)) {
LookupElementRenderer<LookupElementDecorator<LookupElement>> boldRenderer =
@@ -522,6 +522,16 @@ public class JavaCompletionUtil {
return item;
}
private static boolean shouldMarkRed(@NotNull Object object, @NotNull PsiElement place) {
if (!(object instanceof PsiMember)) return false;
if (Java15APIUsageInspectionBase.isForbiddenApiUsage((PsiMember)object, PsiUtil.getLanguageLevel(place))) return true;
if (object instanceof PsiEnumConstant) {
return findConstantsUsedInSwitch(place).contains(CompletionUtil.getOriginalOrSelf((PsiEnumConstant)object));
}
return false;
}
public static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object) {
if (qualifierType instanceof PsiArrayType && object instanceof PsiMember) { //length and clone()
PsiFile file = ((PsiMember)object).getContainingFile();
@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiMethodPattern;
import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.*;
@@ -42,12 +43,12 @@ import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ContainerUtil;
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.LinkedHashSet;
import java.util.Set;
@@ -74,9 +75,8 @@ public class ReferenceExpressionCompletionContributor {
return this;
}
};
private ReferenceExpressionCompletionContributor() {
}
public static final ElementPattern<PsiElement> IN_SWITCH_LABEL =
psiElement().withSuperParent(2, psiElement(PsiSwitchLabelStatement.class).withSuperParent(2, PsiSwitchStatement.class));
@NotNull
private static ElementFilter getReferenceFilter(PsiElement element, boolean allowRecursion) {
@@ -219,10 +219,11 @@ public class ReferenceExpressionCompletionContributor {
return elements;
}
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);
@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;
@@ -237,8 +238,9 @@ public class ReferenceExpressionCompletionContributor {
}
}
}
return used;
}
return used;
return Collections.emptySet();
}
@Nullable
@@ -0,0 +1,11 @@
class Foo {
public void get(MyEnum e) {
switch (e) {
case <caret>
}
}
}
enum MyEnum {
FOO, BAR, GOO
}
@@ -14,9 +14,7 @@
* limitations under the License.
*/
package com.intellij.codeInsight.completion;
package com.intellij.codeInsight.completion
import com.intellij.JavaTestUtil
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.lookup.LookupElement
@@ -24,11 +22,12 @@ import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor
import com.intellij.ide.ui.UISettings
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiField
import com.intellij.psi.PsiMethod
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.psi.statistics.StatisticsManager
import com.intellij.ui.JBColor
public class NormalCompletionOrderingTest extends CompletionSortingTestCase {
private static final String BASE_PATH = "/codeInsight/completion/normalSorting";
@@ -681,4 +680,15 @@ interface TxANotAnno {}
checkPreferredItems 0, 'event', 'equals'
}
public void testDispreferJustUsedEnumConstantsInSwitch() {
checkPreferredItems 0, 'BAR', 'FOO', 'GOO'
myFixture.type('\nbreak;\ncase ')
def items = myFixture.completeBasic()
assertPreferredItems 0, 'FOO', 'GOO', 'BAR'
assert LookupElementPresentation.renderElement(items[0]).itemTextForeground == JBColor.foreground()
assert LookupElementPresentation.renderElement(items.find { it.lookupString == 'BAR' }).itemTextForeground == JBColor.RED
}
}