mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-08-28 04:37:32 +07:00
disprefer the variable item when completing inside its own initializer, unify recursiveCall and qualifierParameter weighers
This commit is contained in:
@@ -17,9 +17,14 @@ import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.AndFilter;
|
||||
import com.intellij.psi.filters.ClassFilter;
|
||||
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
|
||||
import com.intellij.psi.filters.element.ExcludeSillyAssignment;
|
||||
import com.intellij.psi.html.HtmlTag;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
@@ -28,6 +33,7 @@ import com.intellij.psi.javadoc.PsiDocToken;
|
||||
import com.intellij.psi.scope.BaseScopeProcessor;
|
||||
import com.intellij.psi.scope.ElementClassHint;
|
||||
import com.intellij.psi.scope.NameHint;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.statistics.JavaStatisticsManager;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.*;
|
||||
@@ -1031,4 +1037,21 @@ public class JavaCompletionUtil {
|
||||
if (qualifier instanceof PsiMethodCallExpression) return true;
|
||||
return containsMethodCalls(getQualifier(qualifier));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static ElementFilter recursionFilter(PsiElement element) {
|
||||
if (com.intellij.patterns.PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.RETURN).inside(PsiReturnStatement.class).accepts(element)) {
|
||||
return new ExcludeDeclaredFilter(ElementClassFilter.METHOD);
|
||||
}
|
||||
|
||||
if (com.intellij.patterns.PsiJavaPatterns.psiElement().inside(
|
||||
PsiJavaPatterns.or(
|
||||
PsiJavaPatterns.psiElement(PsiAssignmentExpression.class),
|
||||
PsiJavaPatterns.psiElement(PsiVariable.class))).
|
||||
andNot(com.intellij.patterns.PsiJavaPatterns.psiElement().afterLeaf(".")).accepts(element)) {
|
||||
return new AndFilter(new ExcludeSillyAssignment(),
|
||||
new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-10
@@ -8,6 +8,7 @@ import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -15,24 +16,41 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class RecursiveCallParameterWeigher extends CompletionWeigher {
|
||||
public class RecursionWeigher extends CompletionWeigher {
|
||||
|
||||
public Integer weigh(@NotNull final LookupElement element, final CompletionLocation location) {
|
||||
if (location.getCompletionType() != CompletionType.BASIC && location.getCompletionType() != CompletionType.SMART) return 0;
|
||||
private enum Result {
|
||||
recursive,
|
||||
passingObjectToItself,
|
||||
normal,
|
||||
delegation,
|
||||
}
|
||||
|
||||
public Result weigh(@NotNull final LookupElement element, final CompletionLocation location) {
|
||||
if (location.getCompletionType() != CompletionType.BASIC && location.getCompletionType() != CompletionType.SMART) return Result.normal;
|
||||
|
||||
final Object object = element.getObject();
|
||||
if (!(object instanceof PsiModifierListOwner) && !(object instanceof PsiExpression)) return 0;
|
||||
if (!(object instanceof PsiModifierListOwner) && !(object instanceof PsiExpression)) return Result.normal;
|
||||
|
||||
final PsiMethod positionMethod = JavaCompletionUtil.POSITION_METHOD.getValue(location);
|
||||
if (positionMethod == null) return 0;
|
||||
if (positionMethod == null) return Result.normal;
|
||||
|
||||
final PsiElement position = location.getCompletionParameters().getPosition();
|
||||
final ElementFilter filter = JavaCompletionUtil.recursionFilter(position);
|
||||
if (filter != null && !filter.isAcceptable(object, position)) {
|
||||
return Result.recursive;
|
||||
}
|
||||
|
||||
final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(position, PsiMethodCallExpression.class, true, PsiClass.class);
|
||||
final PsiReferenceExpression reference = expression != null ? expression.getMethodExpression() : PsiTreeUtil.getParentOfType(position, PsiReferenceExpression.class);
|
||||
if (reference == null) return 0;
|
||||
if (reference == null) return Result.normal;
|
||||
|
||||
final PsiExpression qualifier = reference.getQualifierExpression();
|
||||
boolean isDelegate = qualifier != null && !(qualifier instanceof PsiThisExpression);
|
||||
|
||||
if (isPassingObjectToItself(object, qualifier, isDelegate)) {
|
||||
return Result.passingObjectToItself;
|
||||
}
|
||||
|
||||
if (expression != null) {
|
||||
final ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (expectedInfos != null) {
|
||||
@@ -40,12 +58,12 @@ public class RecursiveCallParameterWeigher extends CompletionWeigher {
|
||||
if (itemType != null) {
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
if (positionMethod.equals(expectedInfo.getCalledMethod()) && expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
return isDelegate ? 2 : -1;
|
||||
return isDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
if (object instanceof PsiMethod) {
|
||||
@@ -54,12 +72,20 @@ public class RecursiveCallParameterWeigher extends CompletionWeigher {
|
||||
Comparing.equal(method.getName(), positionMethod.getName()) &&
|
||||
method.getParameterList().getParametersCount() == positionMethod.getParameterList().getParametersCount()) {
|
||||
if (findDeepestSuper(method).equals(findDeepestSuper(positionMethod))) {
|
||||
return isDelegate ? 2 : -1;
|
||||
return isDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
private static boolean isPassingObjectToItself(Object object, PsiExpression qualifier, boolean delegate) {
|
||||
if (object instanceof PsiThisExpression) {
|
||||
return !delegate || qualifier instanceof PsiSuperExpression;
|
||||
}
|
||||
return qualifier instanceof PsiReferenceExpression &&
|
||||
object.equals(((PsiReferenceExpression)qualifier).advancedResolve(true).getElement());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
+3
-14
@@ -23,11 +23,8 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.filters.*;
|
||||
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
|
||||
import com.intellij.psi.filters.element.ExcludeSillyAssignment;
|
||||
import com.intellij.psi.filters.element.ModifierFilter;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -69,17 +66,9 @@ public class ReferenceExpressionCompletionContributor extends ExpressionSmartCom
|
||||
}
|
||||
|
||||
if (!allowRecursion) {
|
||||
if (psiElement().afterLeaf(PsiKeyword.RETURN).inside(PsiReturnStatement.class).accepts(element)) {
|
||||
return new ElementExtractorFilter(new ExcludeDeclaredFilter(ElementClassFilter.METHOD));
|
||||
}
|
||||
|
||||
if (psiElement().inside(
|
||||
PsiJavaPatterns.or(
|
||||
PsiJavaPatterns.psiElement(PsiAssignmentExpression.class),
|
||||
PsiJavaPatterns.psiElement(PsiVariable.class))).
|
||||
andNot(psiElement().afterLeaf(".")).accepts(element)) {
|
||||
return new ElementExtractorFilter(new AndFilter(new ExcludeSillyAssignment(),
|
||||
new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class))));
|
||||
final ElementFilter filter = JavaCompletionUtil.recursionFilter(element);
|
||||
if (filter != null) {
|
||||
return new ElementExtractorFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user