From 243448a1d13aee2c3a1e8da0d27dedf2d615ac0e Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 25 Sep 2015 14:48:57 +0200 Subject: [PATCH] MagicCompletionContributor & android ResourceTypeCompletionContributor: extract duplicated code into one place --- .../MagicCompletionContributor.java | 87 ++++++++++++------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java index 0b2f661c0675..d7949b719870 100644 --- a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java @@ -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 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> getMembersWithAllowedValues(@NotNull PsiElement pos) { + List> 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(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(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 allowed = new THashSet(new TObjectHashingStrategy() { @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; } } - +