mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-17 21:43:33 +07:00
optimizations for find usages of method with common name
This commit is contained in:
@@ -78,8 +78,8 @@ public class PsiSuperMethodImplUtil {
|
||||
|
||||
@NotNull
|
||||
private static List<MethodSignatureBackedByPsiMethod> findSuperMethodSignatures(PsiMethod method,
|
||||
PsiClass parentClass,
|
||||
boolean allowStaticMethod) {
|
||||
PsiClass parentClass,
|
||||
boolean allowStaticMethod) {
|
||||
|
||||
return new ArrayList<MethodSignatureBackedByPsiMethod>(SuperMethodsSearch.search(method, parentClass, true, allowStaticMethod).findAll());
|
||||
}
|
||||
@@ -306,4 +306,58 @@ public class PsiSuperMethodImplUtil {
|
||||
private static Map<MethodSignature, HierarchicalMethodSignature> getSignaturesMap(final PsiClass aClass) {
|
||||
return SIGNATURES_KEY.getValue(aClass);
|
||||
}
|
||||
|
||||
|
||||
// uses hierarchy signature tree if available, traverses class structure by itself otherwise
|
||||
public static boolean isSuperMethodSmart(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
|
||||
//boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod);
|
||||
|
||||
if (method == superMethod) return false;
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
PsiClass superClass = superMethod.getContainingClass();
|
||||
|
||||
if (aClass == null || superClass == null || superClass == aClass) return false;
|
||||
|
||||
if (!canHaveSuperMethod(method, true, false)) return false;
|
||||
|
||||
PsiMethod[] superMethods = null;
|
||||
Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_KEY.getCachedValueOrNull(aClass);
|
||||
if (cachedMap != null) {
|
||||
HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY));
|
||||
if (signature != null) {
|
||||
superMethods = MethodSignatureUtil.convertMethodSignaturesToMethods(signature.getSuperSignatures());
|
||||
}
|
||||
}
|
||||
if (superMethods == null) {
|
||||
PsiClassType[] directSupers = aClass.getSuperTypes();
|
||||
List<PsiMethod> found = null;
|
||||
boolean canceled = false;
|
||||
for (PsiClassType directSuper : directSupers) {
|
||||
PsiClassType.ClassResolveResult resolveResult = directSuper.resolveGenerics();
|
||||
if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) {
|
||||
// generics
|
||||
canceled = true;
|
||||
break;
|
||||
}
|
||||
PsiClass directSuperClass = resolveResult.getElement();
|
||||
if (directSuperClass == null) continue;
|
||||
PsiMethod[] candidates = directSuperClass.findMethodsBySignature(method, false);
|
||||
if (candidates.length != 0) {
|
||||
if (found == null) found = new ArrayList<PsiMethod>();
|
||||
for (PsiMethod candidate : candidates) {
|
||||
if (PsiUtil.canBeOverriden(candidate)) found.add(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
superMethods = canceled ? null : found == null ? PsiMethod.EMPTY_ARRAY : found.toArray(new PsiMethod[found.size()]);
|
||||
}
|
||||
if (superMethods == null) {
|
||||
superMethods = MethodSignatureUtil.convertMethodSignaturesToMethods(method.getHierarchicalMethodSignature().getSuperSignatures());
|
||||
}
|
||||
|
||||
for (PsiMethod superCandidate : superMethods) {
|
||||
if (superMethod.equals(superCandidate) || isSuperMethodSmart(superCandidate, superMethod)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -332,6 +332,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
IElementType i = getLastChildNode().getElementType();
|
||||
boolean resolvingToMethod = element instanceof PsiMethod;
|
||||
if (i == JavaTokenType.IDENTIFIER) {
|
||||
if (!(element instanceof PsiPackage)) {
|
||||
if (!(element instanceof PsiNamedElement)) return false;
|
||||
@@ -341,10 +342,15 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
}
|
||||
}
|
||||
else if (i == JavaTokenType.SUPER_KEYWORD || i == JavaTokenType.THIS_KEYWORD) {
|
||||
if (!(element instanceof PsiMethod)) return false;
|
||||
if (!resolvingToMethod) return false;
|
||||
if (!((PsiMethod)element).isConstructor()) return false;
|
||||
}
|
||||
|
||||
PsiElement parent = getParent();
|
||||
boolean parentIsMethodCall = parent instanceof PsiMethodCallExpression;
|
||||
// optimization: methodCallExpression should resolve to a method
|
||||
if (parentIsMethodCall != resolvingToMethod) return false;
|
||||
|
||||
return element.getManager().areElementsEquivalent(element, resolve());
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.PsiConflictResolver;
|
||||
@@ -150,7 +151,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
for (int k=i-1; k>=0; k--) {
|
||||
PsiMethod existingMethod = (PsiMethod)conflicts.get(k).getElement();
|
||||
if (PsiSuperMethodUtil.isSuperMethod(existingMethod, method)) {
|
||||
if (PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
|
||||
conflicts.remove(i);
|
||||
i--;
|
||||
continue nextConflict;
|
||||
@@ -189,12 +190,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
// filter out methods with incorrect inferred bounds (for unrelated methods only)
|
||||
boolean existingTypeParamAgree = areTypeParametersAgree(existing);
|
||||
boolean infoTypeParamAgree = areTypeParametersAgree(info);
|
||||
if (existingTypeParamAgree && !infoTypeParamAgree && !PsiSuperMethodUtil.isSuperMethod(method, existingMethod)) {
|
||||
if (existingTypeParamAgree && !infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(method, existingMethod)) {
|
||||
conflicts.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
else if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodUtil.isSuperMethod(existingMethod, method)) {
|
||||
else if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
|
||||
signatures.put(signature, info);
|
||||
int index = conflicts.indexOf(existing);
|
||||
conflicts.remove(index);
|
||||
|
||||
Reference in New Issue
Block a user