mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-17 16:19:58 +07:00
usage view group speed optimisation
This commit is contained in:
@@ -23,6 +23,7 @@ import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -314,6 +315,52 @@ public class PsiSuperMethodImplUtil {
|
||||
}
|
||||
|
||||
|
||||
// uses hierarchy signature tree if available, traverses class structure by itself otherwise
|
||||
public static boolean processDirectSuperMethodsSmart(@NotNull PsiMethod method, @NotNull Processor<PsiMethod> superMethodProcessor) {
|
||||
//boolean old = PsiSuperMethodUtil.isSuperMethod(method, superMethod);
|
||||
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
if (aClass == null) return false;
|
||||
|
||||
if (!canHaveSuperMethod(method, true, false)) return false;
|
||||
|
||||
Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_KEY.getCachedValueOrNull(aClass);
|
||||
if (cachedMap != null) {
|
||||
HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY));
|
||||
if (signature != null) {
|
||||
List<HierarchicalMethodSignature> superSignatures = signature.getSuperSignatures();
|
||||
for (HierarchicalMethodSignature superSignature : superSignatures) {
|
||||
if (!superMethodProcessor.process(superSignature.getMethod())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PsiClassType[] directSupers = aClass.getSuperTypes();
|
||||
for (PsiClassType directSuper : directSupers) {
|
||||
PsiClassType.ClassResolveResult resolveResult = directSuper.resolveGenerics();
|
||||
if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) {
|
||||
// generics
|
||||
break;
|
||||
}
|
||||
PsiClass directSuperClass = resolveResult.getElement();
|
||||
if (directSuperClass == null) continue;
|
||||
PsiMethod[] candidates = directSuperClass.findMethodsBySignature(method, false);
|
||||
for (PsiMethod candidate : candidates) {
|
||||
if (PsiUtil.canBeOverriden(candidate)) {
|
||||
if (!superMethodProcessor.process(candidate)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
List<HierarchicalMethodSignature> superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
|
||||
for (HierarchicalMethodSignature superSignature : superSignatures) {
|
||||
if (!superMethodProcessor.process(superSignature.getMethod())) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -6,36 +6,35 @@ import com.intellij.util.QueryExecutor;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class MethodDeepestSuperSearcher implements QueryExecutor<PsiMethod, PsiMethod> {
|
||||
public boolean execute(@NotNull final PsiMethod method, @NotNull final Processor<PsiMethod> consumer) {
|
||||
final Set<PsiMethod> methods = new LinkedHashSet<PsiMethod>();
|
||||
findDeepestSuperOrSelfSignature(method, methods, null);
|
||||
for (final PsiMethod psiMethod : methods) {
|
||||
if (psiMethod != method && !consumer.process(psiMethod)) {
|
||||
return false;
|
||||
public boolean execute(@NotNull PsiMethod method, @NotNull Processor<PsiMethod> consumer) {
|
||||
final Set<PsiMethod> methods = new THashSet<PsiMethod>();
|
||||
methods.add(method);
|
||||
return findDeepestSuperOrSelfSignature(method, methods, null, consumer);
|
||||
}
|
||||
|
||||
private static boolean findDeepestSuperOrSelfSignature(PsiMethod method,
|
||||
Set<PsiMethod> set,
|
||||
Set<PsiMethod> guard,
|
||||
Processor<PsiMethod> processor) {
|
||||
if (guard != null && !guard.add(method)) return true;
|
||||
PsiMethod[] supers = method.findSuperMethods();
|
||||
|
||||
if (supers.length == 0 && set.add(method) && !processor.process(method)) {
|
||||
return false;
|
||||
}
|
||||
for (PsiMethod superMethod : supers) {
|
||||
if (guard == null) {
|
||||
guard = new THashSet<PsiMethod>();
|
||||
guard.add(method);
|
||||
}
|
||||
if (!findDeepestSuperOrSelfSignature(superMethod, set, guard, processor)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void findDeepestSuperOrSelfSignature(PsiMethod method, final Set<PsiMethod> set, Set<PsiMethod> guard) {
|
||||
if (guard != null && !guard.add(method)) return;
|
||||
PsiMethod[] supers = method.findSuperMethods();
|
||||
|
||||
if (supers.length == 0) {
|
||||
set.add(method);
|
||||
}
|
||||
else {
|
||||
for (PsiMethod superMethod : supers) {
|
||||
if (guard == null) guard = new THashSet<PsiMethod>();
|
||||
findDeepestSuperOrSelfSignature(superMethod, set, guard);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,17 @@
|
||||
package com.intellij.usages.impl.rules;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.Processor;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -51,6 +55,9 @@ public class JavaUsageTypeProvider implements UsageTypeProvider {
|
||||
if (p instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)p;
|
||||
final PsiMethod calledMethod = callExpression.resolveMethod();
|
||||
if (calledMethod == containerMethod) {
|
||||
return UsageType.RECURSION;
|
||||
}
|
||||
if (qualifier != null && !(qualifier instanceof PsiThisExpression) && calledMethod != null) {
|
||||
if (haveCommonSuperMethod(containerMethod, calledMethod)) {
|
||||
boolean parametersDelegated = parametersDelegated(containerMethod, callExpression);
|
||||
@@ -63,9 +70,6 @@ public class JavaUsageTypeProvider implements UsageTypeProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (calledMethod == containerMethod) {
|
||||
return UsageType.RECURSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +98,40 @@ public class JavaUsageTypeProvider implements UsageTypeProvider {
|
||||
}
|
||||
|
||||
private static boolean haveCommonSuperMethod(@NotNull PsiMethod m1, @NotNull PsiMethod m2) {
|
||||
final Queue<PsiMethod> supers1Q = new ArrayDeque<PsiMethod>(); supers1Q.add(m1);
|
||||
final Queue<PsiMethod> supers2Q = new ArrayDeque<PsiMethod>(); supers2Q.add(m1);
|
||||
Set<PsiMethod> supers1 = new THashSet<PsiMethod>();
|
||||
Set<PsiMethod> supers2 = new THashSet<PsiMethod>();
|
||||
while (true) {
|
||||
PsiMethod me1;
|
||||
if ((me1 = supers1Q.poll()) != null) {
|
||||
if (supers2.contains(me1)) return true;
|
||||
supers1.add(me1);
|
||||
PsiSuperMethodImplUtil.processDirectSuperMethodsSmart(me1, new Processor<PsiMethod>() {
|
||||
@Override
|
||||
public boolean process(PsiMethod psiMethod) {
|
||||
supers1Q.add(psiMethod);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PsiMethod me2;
|
||||
if ((me2 = supers2Q.poll()) != null) {
|
||||
if (supers1.contains(me2)) return true;
|
||||
supers2.add(me2);
|
||||
PsiSuperMethodImplUtil.processDirectSuperMethodsSmart(me2, new Processor<PsiMethod>() {
|
||||
@Override
|
||||
public boolean process(PsiMethod psiMethod) {
|
||||
supers2Q.add(psiMethod);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (me1 == null && me2==null) break;
|
||||
}
|
||||
return false;
|
||||
/*
|
||||
HashSet<PsiMethod> s1 = new HashSet<PsiMethod>(Arrays.asList(m1.findDeepestSuperMethods()));
|
||||
s1.add(m1);
|
||||
|
||||
@@ -102,6 +140,7 @@ public class JavaUsageTypeProvider implements UsageTypeProvider {
|
||||
|
||||
s1.retainAll(s2);
|
||||
return !s1.isEmpty();
|
||||
*/
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user