[rev=Peter] in dumb mode avoid qsorting all classes in packages content when searching for particular class

This commit is contained in:
Maxim.Mossienko
2012-09-27 19:23:08 +02:00
parent 78fe434849
commit fcc87ab35f
4 changed files with 78 additions and 27 deletions
@@ -18,12 +18,14 @@ package com.intellij.psi;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
@@ -118,4 +120,36 @@ public abstract class PsiElementFinder {
public boolean processPackageDirectories(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope, @NotNull Processor<PsiDirectory> consumer) {
return true;
}
/**
* Returns the list of classes in the specified package and in the specified search scope.
*
* @param className short name of the class
* @param psiPackage the package to return the list of classes in.
* @param scope the scope in which classes are searched.
* @return the list of classes.
* @see PsiPackage#getClasses(GlobalSearchScope)
*/
@NotNull
public PsiClass[] getClasses(@Nullable String className, @NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
PsiClass[] allClasses = getClasses(psiPackage, scope);
if (className == null) return allClasses;
return filterByName(className, allClasses);
}
@NotNull
public static PsiClass[] filterByName(@NotNull String className, @NotNull PsiClass[] classes) {
if (classes.length == 0) return PsiClass.EMPTY_ARRAY;
if (classes.length == 1) {
return className.equals(classes[0].getName()) ? classes : PsiClass.EMPTY_ARRAY;
}
List<PsiClass> foundClasses = new SmartList<PsiClass>();
for (PsiClass psiClass : classes) {
if (className.equals(psiClass.getName())) {
foundClasses.add(psiClass);
}
}
return foundClasses.isEmpty() ? PsiClass.EMPTY_ARRAY : foundClasses.toArray(new PsiClass[foundClasses.size()]);
}
}
@@ -111,4 +111,7 @@ public interface PsiPackage extends PsiCheckedRenameElement, NavigationItem, Psi
String getName();
boolean containsClassNamed(String name);
@NotNull
PsiClass[] findClassByShortName(@NotNull String name, @NotNull GlobalSearchScope scope);
}
@@ -42,7 +42,9 @@ import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.messages.MessageBus;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
@@ -118,7 +120,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
if (pkg == null && packageName.length() < qualifiedName.length()) {
PsiClass[] containingClasses = findClassesInDumbMode(packageName, scope);
if (containingClasses.length == 1) {
return filterByName(className, containingClasses[0].getInnerClasses());
return PsiElementFinder.filterByName(className, containingClasses[0].getInnerClasses());
}
return PsiClass.EMPTY_ARRAY;
@@ -128,22 +130,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
return PsiClass.EMPTY_ARRAY;
}
return filterByName(className, pkg.getClasses(scope));
}
@NotNull
private static PsiClass[] filterByName(@NotNull String className, @NotNull PsiClass[] classes) {
if (classes.length == 0) return PsiClass.EMPTY_ARRAY;
if (classes.length == 1) {
return className.equals(classes[0].getName()) ? classes : PsiClass.EMPTY_ARRAY;
}
List<PsiClass> foundClasses = new SmartList<PsiClass>();
for (PsiClass psiClass : classes) {
if (className.equals(psiClass.getName())) {
foundClasses.add(psiClass);
}
}
return foundClasses.isEmpty() ? PsiClass.EMPTY_ARRAY : foundClasses.toArray(new PsiClass[foundClasses.size()]);
return pkg.findClassByShortName(className, scope);
}
@Override
@@ -235,7 +222,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
@NotNull
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
Set<String> result = new HashSet<String>();
Set<String> result = new THashSet<String>();
for (PsiElementFinder finder : filteredFinders()) {
result.addAll(finder.getClassNames(psiPackage, scope));
}
@@ -275,6 +262,18 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
return result.toArray(new PsiPackage[result.size()]);
}
public PsiClass[] findClassByShortName(String name, PsiPackage psiPackage, GlobalSearchScope scope) {
List<PsiClass> result = null;
for (PsiElementFinder finder : filteredFinders()) {
PsiClass[] classes = finder.getClasses(name, psiPackage, scope);
if (classes.length == 0) continue;
if (result == null) result = new ArrayList<PsiClass>();
ContainerUtil.addAll(result, classes);
}
return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]);
}
private class PsiElementFinderImpl extends PsiElementFinder implements DumbAware {
@Override
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
@@ -317,6 +316,12 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
@Override
@NotNull
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope) {
return getClasses(null, psiPackage, scope);
}
@Override
@NotNull
public PsiClass[] getClasses(@Nullable String shortName, @NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope) {
List<PsiClass> list = null;
String packageName = psiPackage.getQualifiedName();
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
@@ -328,21 +333,24 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
String qualifiedName = aClass.getQualifiedName();
if (qualifiedName != null) qualifiedName = StringUtil.getPackageName(qualifiedName);
if (Comparing.strEqual(qualifiedName, packageName)) {
list.add(aClass);
if (shortName == null || shortName.equals(aClass.getName())) list.add(aClass);
}
}
}
if (list == null) {
return PsiClass.EMPTY_ARRAY;
}
ContainerUtil.quickSort(list, new Comparator<PsiClass>() {
@Override
public int compare(PsiClass o1, PsiClass o2) {
VirtualFile file2 = PsiUtilCore.getVirtualFile(o2);
VirtualFile file1 = PsiUtilCore.getVirtualFile(o1);
return scope.compare(file2, file1);
}
});
if (list.size() > 1) {
ContainerUtil.quickSort(list, new Comparator<PsiClass>() {
@Override
public int compare(PsiClass o1, PsiClass o2) {
VirtualFile file2 = PsiUtilCore.getVirtualFile(o2);
VirtualFile file1 = PsiUtilCore.getVirtualFile(o1);
return scope.compare(file2, file1);
}
});
}
return list.toArray(new PsiClass[list.size()]);
}
@@ -183,6 +183,12 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
return getClassNamesCache().contains(name);
}
@NotNull
@Override
public PsiClass[] findClassByShortName(@NotNull String name, @NotNull GlobalSearchScope scope) {
return getFacade().findClassByShortName(name, this, scope);
}
@Nullable
private PsiPackage findSubPackageByName(String name) {
final String qName = getQualifiedName();