mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
some movements
This commit is contained in:
@@ -20,16 +20,13 @@ import com.intellij.codeInsight.ExpectedTypeInfoImpl;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementWeigher;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -85,15 +82,12 @@ public class JavaCompletionSorting {
|
||||
|
||||
@Nullable
|
||||
private static LookupElementWeigher recursion(CompletionParameters parameters, final ExpectedTypeInfo[] expectedInfos) {
|
||||
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiMethod positionMethod = PsiTreeUtil.getParentOfType(position, PsiMethod.class, false);
|
||||
final ElementFilter filter = JavaCompletionUtil.recursionFilter(position);
|
||||
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 null;
|
||||
|
||||
return new RecursionWeigher(filter, position, reference, expression, positionMethod, expectedInfos);
|
||||
return new RecursionWeigher(position, reference, expression, expectedInfos);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -315,96 +309,6 @@ public class JavaCompletionSorting {
|
||||
|
||||
}
|
||||
|
||||
private static class RecursionWeigher extends LookupElementWeigher {
|
||||
private final ElementFilter myFilter;
|
||||
private final PsiElement myPosition;
|
||||
private final PsiReferenceExpression myReference;
|
||||
private final PsiMethodCallExpression myExpression;
|
||||
private final PsiMethod myPositionMethod;
|
||||
private final ExpectedTypeInfo[] myExpectedInfos;
|
||||
private final PsiExpression myQualifier;
|
||||
private final boolean myDelegate;
|
||||
|
||||
public RecursionWeigher(ElementFilter filter,
|
||||
PsiElement position,
|
||||
@NotNull PsiReferenceExpression reference,
|
||||
PsiMethodCallExpression expression,
|
||||
PsiMethod positionMethod, ExpectedTypeInfo[] expectedInfos) {
|
||||
super("recursion");
|
||||
myFilter = filter;
|
||||
myPosition = position;
|
||||
myReference = reference;
|
||||
myExpression = expression;
|
||||
myPositionMethod = positionMethod;
|
||||
myExpectedInfos = expectedInfos;
|
||||
myQualifier = myReference.getQualifierExpression();
|
||||
myDelegate = myQualifier != null && !(myQualifier instanceof PsiThisExpression);
|
||||
}
|
||||
|
||||
private enum Result {
|
||||
delegation,
|
||||
normal,
|
||||
passingObjectToItself,
|
||||
recursive,
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Result weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
if (!(object instanceof PsiMethod || object instanceof PsiVariable || object instanceof PsiExpression)) return Result.normal;
|
||||
|
||||
if (myFilter != null && !myFilter.isAcceptable(object, myPosition)) {
|
||||
return Result.recursive;
|
||||
}
|
||||
|
||||
if (isPassingObjectToItself(object)) {
|
||||
return Result.passingObjectToItself;
|
||||
}
|
||||
|
||||
if (myExpression != null && myPositionMethod != null) {
|
||||
if (myExpectedInfos != null) {
|
||||
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
|
||||
if (itemType != null) {
|
||||
for (final ExpectedTypeInfo expectedInfo : myExpectedInfos) {
|
||||
if (myPositionMethod.equals(expectedInfo.getCalledMethod()) && expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
return myDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
if (object instanceof PsiMethod && myPositionMethod != null) {
|
||||
final PsiMethod method = (PsiMethod)object;
|
||||
if (PsiTreeUtil.isAncestor(myReference, myPosition, false) &&
|
||||
Comparing.equal(method.getName(), myPositionMethod.getName())) {
|
||||
if (!myDelegate && findDeepestSuper(method).equals(findDeepestSuper(myPositionMethod))) {
|
||||
return Result.recursive;
|
||||
}
|
||||
return Result.delegation;
|
||||
}
|
||||
}
|
||||
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
private boolean isPassingObjectToItself(Object object) {
|
||||
if (object instanceof PsiThisExpression) {
|
||||
return !myDelegate || myQualifier instanceof PsiSuperExpression;
|
||||
}
|
||||
return myQualifier instanceof PsiReferenceExpression &&
|
||||
object.equals(((PsiReferenceExpression)myQualifier).advancedResolve(true).getElement());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiMethod findDeepestSuper(@NotNull final PsiMethod method) {
|
||||
final PsiMethod first = DeepestSuperMethodsSearch.search(method).findFirst();
|
||||
return first == null ? method : first;
|
||||
}
|
||||
}
|
||||
|
||||
private enum ExpectedTypeMatching {
|
||||
ofDefaultType,
|
||||
expected,
|
||||
|
||||
@@ -677,23 +677,6 @@ public class JavaCompletionUtil {
|
||||
return containsMethodCalls(getQualifier(qualifier));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static ElementFilter recursionFilter(PsiElement element) {
|
||||
if (PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.RETURN).inside(PsiReturnStatement.class).accepts(element)) {
|
||||
return new ExcludeDeclaredFilter(ElementClassFilter.METHOD);
|
||||
}
|
||||
|
||||
if (PsiJavaPatterns.psiElement().inside(
|
||||
PsiJavaPatterns.or(
|
||||
PsiJavaPatterns.psiElement(PsiAssignmentExpression.class),
|
||||
PsiJavaPatterns.psiElement(PsiVariable.class))).
|
||||
andNot(PsiJavaPatterns.psiElement().afterLeaf(".")).accepts(element)) {
|
||||
return new AndFilter(new ExcludeSillyAssignment(),
|
||||
new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void insertClassReference(@NotNull PsiClass psiClass, @NotNull PsiFile file, int offset) {
|
||||
insertClassReference(psiClass, file, offset, offset);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementWeigher;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.AndFilter;
|
||||
import com.intellij.psi.filters.ClassFilter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
|
||||
import com.intellij.psi.filters.element.ExcludeSillyAssignment;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class RecursionWeigher extends LookupElementWeigher {
|
||||
private final ElementFilter myFilter;
|
||||
private final PsiElement myPosition;
|
||||
private final PsiReferenceExpression myReference;
|
||||
@Nullable private final PsiMethodCallExpression myExpression;
|
||||
private final PsiMethod myPositionMethod;
|
||||
private final ExpectedTypeInfo[] myExpectedInfos;
|
||||
private final PsiExpression myQualifier;
|
||||
private final boolean myDelegate;
|
||||
|
||||
public RecursionWeigher(PsiElement position,
|
||||
@NotNull PsiReferenceExpression reference,
|
||||
PsiMethodCallExpression expression,
|
||||
ExpectedTypeInfo[] expectedInfos) {
|
||||
super("recursion");
|
||||
myFilter = recursionFilter(position);
|
||||
myPosition = position;
|
||||
myReference = reference;
|
||||
myExpression = expression;
|
||||
myPositionMethod = PsiTreeUtil.getParentOfType(position, PsiMethod.class, false);
|
||||
myExpectedInfos = expectedInfos;
|
||||
myQualifier = myReference.getQualifierExpression();
|
||||
myDelegate = myQualifier != null && !(myQualifier instanceof PsiThisExpression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static ElementFilter recursionFilter(PsiElement element) {
|
||||
if (PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.RETURN).inside(PsiReturnStatement.class).accepts(element)) {
|
||||
return new ExcludeDeclaredFilter(ElementClassFilter.METHOD);
|
||||
}
|
||||
|
||||
if (PsiJavaPatterns.psiElement().inside(
|
||||
PsiJavaPatterns.or(
|
||||
PsiJavaPatterns.psiElement(PsiAssignmentExpression.class),
|
||||
PsiJavaPatterns.psiElement(PsiVariable.class))).
|
||||
andNot(PsiJavaPatterns.psiElement().afterLeaf(".")).accepts(element)) {
|
||||
return new AndFilter(new ExcludeSillyAssignment(),
|
||||
new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private enum Result {
|
||||
delegation,
|
||||
normal,
|
||||
passingObjectToItself,
|
||||
recursive,
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Result weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
if (!(object instanceof PsiMethod || object instanceof PsiVariable || object instanceof PsiExpression)) return Result.normal;
|
||||
|
||||
if (myFilter != null && !myFilter.isAcceptable(object, myPosition)) {
|
||||
return Result.recursive;
|
||||
}
|
||||
|
||||
if (isPassingObjectToItself(object)) {
|
||||
return Result.passingObjectToItself;
|
||||
}
|
||||
|
||||
if (myExpression != null && myPositionMethod != null) {
|
||||
if (myExpectedInfos != null) {
|
||||
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
|
||||
if (itemType != null) {
|
||||
for (final ExpectedTypeInfo expectedInfo : myExpectedInfos) {
|
||||
if (myPositionMethod.equals(expectedInfo.getCalledMethod()) && expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
return myDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
if (object instanceof PsiMethod && myPositionMethod != null) {
|
||||
final PsiMethod method = (PsiMethod)object;
|
||||
if (PsiTreeUtil.isAncestor(myReference, myPosition, false) &&
|
||||
Comparing.equal(method.getName(), myPositionMethod.getName())) {
|
||||
if (!myDelegate && findDeepestSuper(method).equals(findDeepestSuper(myPositionMethod))) {
|
||||
return Result.recursive;
|
||||
}
|
||||
return Result.delegation;
|
||||
}
|
||||
}
|
||||
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
private boolean isPassingObjectToItself(Object object) {
|
||||
if (object instanceof PsiThisExpression) {
|
||||
return !myDelegate || myQualifier instanceof PsiSuperExpression;
|
||||
}
|
||||
return myQualifier instanceof PsiReferenceExpression &&
|
||||
object.equals(((PsiReferenceExpression)myQualifier).advancedResolve(true).getElement());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiMethod findDeepestSuper(@NotNull final PsiMethod method) {
|
||||
final PsiMethod first = DeepestSuperMethodsSearch.search(method).findFirst();
|
||||
return first == null ? method : first;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -97,7 +97,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
}
|
||||
|
||||
if (!allowRecursion) {
|
||||
final ElementFilter filter = JavaCompletionUtil.recursionFilter(element);
|
||||
final ElementFilter filter = RecursionWeigher.recursionFilter(element);
|
||||
if (filter != null) {
|
||||
return new ElementExtractorFilter(filter);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user