mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
MagicCompletionContributor & android ResourceTypeCompletionContributor: extract duplicated code into one place
This commit is contained in:
+57
-30
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user