MagicCompletionContributor & android ResourceTypeCompletionContributor: extract duplicated code into one place

This commit is contained in:
peter
2015-09-25 14:59:31 +02:00
parent 0efe119333
commit 243448a1d1
@@ -17,17 +17,24 @@ package com.intellij.codeInspection.magicConstant;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.LookupItemUtil;
import com.intellij.codeInsight.lookup.VariableLookupItem;
import com.intellij.openapi.util.Pair;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -50,15 +57,37 @@ public class MagicCompletionContributor extends CompletionContributor {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
//if (parameters.getCompletionType() != CompletionType.SMART) return;
PsiElement pos = parameters.getPosition();
MagicConstantInspection.AllowedValues allowedValues = null;
if (JavaKeywordCompletion.AFTER_DOT.accepts(pos)) {
return;
}
MagicConstantInspection.AllowedValues allowedValues = getAllowedValues(pos);
if (allowedValues == null) return;
addCompletionVariants(parameters, result, pos, allowedValues);
}
@Nullable
private static MagicConstantInspection.AllowedValues getAllowedValues(@NotNull PsiElement pos) {
MagicConstantInspection.AllowedValues allowedValues = null;
for (Pair<PsiModifierListOwner, PsiType> pair : getMembersWithAllowedValues(pos)) {
MagicConstantInspection.AllowedValues values = MagicConstantInspection.getAllowedValues(pair.first, pair.second, null);
if (values == null) continue;
if (allowedValues == null) {
allowedValues = values;
continue;
}
if (!allowedValues.equals(values)) return null;
}
return allowedValues;
}
@NotNull
public static List<Pair<PsiModifierListOwner, PsiType>> getMembersWithAllowedValues(@NotNull PsiElement pos) {
List<Pair<PsiModifierListOwner, PsiType>> result = ContainerUtil.newArrayList();
if (IN_METHOD_CALL_ARGUMENT.accepts(pos)) {
PsiCall call = PsiTreeUtil.getParentOfType(pos, PsiCall.class);
if (!(call instanceof PsiExpression)) return;
if (!(call instanceof PsiExpression)) return Collections.emptyList();
PsiType type = ((PsiExpression)call).getType();
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(call.getProject()).getResolveHelper();
@@ -69,7 +98,7 @@ public class MagicCompletionContributor extends CompletionContributor {
: JavaResolveResult.EMPTY_ARRAY;
for (JavaResolveResult resolveResult : methods) {
PsiElement element = resolveResult.getElement();
if (!(element instanceof PsiMethod)) return;
if (!(element instanceof PsiMethod)) return Collections.emptyList();
PsiMethod method = (PsiMethod)element;
if (!resolveHelper.isAccessible(method, call, null)) continue;
PsiElement argument = pos;
@@ -80,14 +109,7 @@ public class MagicCompletionContributor extends CompletionContributor {
PsiParameter[] params = method.getParameterList().getParameters();
if (i >= params.length) continue;
PsiParameter parameter = params[i];
MagicConstantInspection.AllowedValues values =
parameter == null ? null : MagicConstantInspection.getAllowedValues(parameter, parameter.getType(), null);
if (values == null) continue;
if (allowedValues == null) {
allowedValues = values;
continue;
}
if (!allowedValues.equals(values)) return;
result.add(new Pair<PsiModifierListOwner, PsiType>(parameter, parameter.getType()));
}
}
else if (IN_BINARY_COMPARISON.accepts(pos)) {
@@ -96,11 +118,11 @@ public class MagicCompletionContributor extends CompletionContributor {
PsiExpression l = exp.getLOperand();
PsiElement resolved;
if (l instanceof PsiReferenceExpression && (resolved = ((PsiReferenceExpression)l).resolve()) instanceof PsiModifierListOwner) {
allowedValues = MagicConstantInspection.getAllowedValues((PsiModifierListOwner)resolved, l.getType(), null);
result.add(Pair.create((PsiModifierListOwner)resolved, l.getType()));
}
PsiExpression r = exp.getROperand();
if (allowedValues == null && r instanceof PsiReferenceExpression && (resolved = ((PsiReferenceExpression)r).resolve()) instanceof PsiModifierListOwner) {
allowedValues = MagicConstantInspection.getAllowedValues((PsiModifierListOwner)resolved, r.getType(), null);
if (result.isEmpty() && r instanceof PsiReferenceExpression && (resolved = ((PsiReferenceExpression)r).resolve()) instanceof PsiModifierListOwner) {
result.add(Pair.create((PsiModifierListOwner)resolved, r.getType()));
}
}
}
@@ -109,7 +131,7 @@ public class MagicCompletionContributor extends CompletionContributor {
PsiElement resolved;
PsiExpression l = assignment == null ? null : assignment.getLExpression();
if (assignment != null && PsiTreeUtil.isAncestor(assignment.getRExpression(), pos, false) && l instanceof PsiReferenceExpression && (resolved = ((PsiReferenceExpression)l).resolve()) instanceof PsiModifierListOwner) {
allowedValues = MagicConstantInspection.getAllowedValues((PsiModifierListOwner)resolved, l.getType(), null);
result.add(Pair.create((PsiModifierListOwner)resolved, l.getType()));
}
}
else if (IN_RETURN.accepts(pos)) {
@@ -117,28 +139,33 @@ public class MagicCompletionContributor extends CompletionContributor {
PsiExpression l = statement == null ? null : statement.getReturnValue();
PsiElement element = PsiTreeUtil.getParentOfType(l, PsiMethod.class, PsiLambdaExpression.class);
if (element instanceof PsiMethod) {
allowedValues = MagicConstantInspection.getAllowedValues((PsiMethod)element, ((PsiMethod)element).getReturnType(), null);
}
result.add(Pair.create((PsiModifierListOwner)element, ((PsiMethod)element).getReturnType()));
}
else if (element instanceof PsiLambdaExpression) {
final PsiType interfaceType = ((PsiLambdaExpression)element).getFunctionalInterfaceType();
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType);
if (interfaceMethod != null) {
allowedValues = MagicConstantInspection.getAllowedValues(interfaceMethod, LambdaUtil.getFunctionalInterfaceReturnType(interfaceType), null);
result.add(Pair.create((PsiModifierListOwner)interfaceMethod, LambdaUtil.getFunctionalInterfaceReturnType(interfaceType)));
}
}
}
else if (IN_ANNOTATION_INITIALIZER.accepts(pos)) {
PsiNameValuePair pair = (PsiNameValuePair)pos.getParent().getParent();
PsiAnnotationMemberValue value = pair.getValue();
if (!(value instanceof PsiExpression)) return;
PsiReference ref = pair.getReference();
if (ref == null) return;
PsiMethod method = (PsiMethod)ref.resolve();
if (method == null) return;
allowedValues = MagicConstantInspection.getAllowedValues(method, method.getReturnType(), null);
if (pair.getValue() instanceof PsiExpression) {
PsiReference ref = pair.getReference();
PsiMethod method = ref == null ? null : (PsiMethod)ref.resolve();
if (method != null) {
result.add(new Pair<PsiModifierListOwner, PsiType>(method, method.getReturnType()));
}
}
}
if (allowedValues == null) return;
return result;
}
private static void addCompletionVariants(@NotNull final CompletionParameters parameters,
@NotNull final CompletionResultSet result,
PsiElement pos,
MagicConstantInspection.AllowedValues allowedValues) {
final Set<PsiElement> allowed = new THashSet<PsiElement>(new TObjectHashingStrategy<PsiElement>() {
@Override
public int computeHashCode(PsiElement object) {
@@ -153,7 +180,7 @@ public class MagicCompletionContributor extends CompletionContributor {
if (allowedValues.canBeOred) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(pos.getProject());
PsiExpression zero = factory.createExpressionFromText("0", pos);
result.addElement(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(zero,"0"), PRIORITY-1));
result.addElement(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(zero, "0"), PRIORITY - 1));
PsiExpression minusOne = factory.createExpressionFromText("-1", pos);
result.addElement(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(minusOne,"-1"), PRIORITY-1));
allowed.add(zero);
@@ -202,5 +229,5 @@ public class MagicCompletionContributor extends CompletionContributor {
return element;
}
}