process class names just once in completion

This commit is contained in:
peter
2014-04-21 22:21:20 +02:00
parent 094f040cc5
commit d9aed3f444
2 changed files with 48 additions and 37 deletions
@@ -22,20 +22,20 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.search.AllClassesSearchExecutor;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.AllClassesSearch;
import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashSet;
import java.util.Set;
/**
@@ -184,18 +184,17 @@ public class AllClassesGetter {
@NotNull Project project,
@NotNull GlobalSearchScope scope,
@NotNull Processor<PsiClass> processor) {
AllClassesSearch.search(scope, project, new Condition<String>() {
final Set<String> names = new THashSet<String>(10000);
AllClassesSearchExecutor.processClassNames(project, scope, new Consumer<String>() {
@Override
public boolean value(String s) {
return prefixMatcher.isStartMatch(s);
public void consume(String s) {
if (prefixMatcher.prefixMatches(s)) {
names.add(s);
}
}
}).forEach(processor);
AllClassesSearch.search(scope, project, new Condition<String>() {
@Override
public boolean value(String s) {
return prefixMatcher.prefixMatches(s);
}
}).forEach(processor);
});
LinkedHashSet<String> sorted = CompletionUtil.sortMatching(prefixMatcher, names);
AllClassesSearchExecutor.processClassesByNames(project, scope, sorted, processor);
}
@@ -30,6 +30,7 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.AllClassesSearch;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import com.intellij.util.indexing.IdFilter;
@@ -57,39 +58,28 @@ public class AllClassesSearchExecutor implements QueryExecutor<PsiClass, AllClas
private static boolean processAllClassesInGlobalScope(@NotNull final GlobalSearchScope scope,
@NotNull final AllClassesSearch.SearchParameters parameters,
@NotNull Processor<PsiClass> processor) {
Project project = parameters.getProject();
final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
final Set<String> names = new THashSet<String>(10000);
cache.processAllClassNames(new Processor<String>() {
int i = 0;
processClassNames(parameters.getProject(), scope, new Consumer<String>() {
@Override
public boolean process(String s) {
if (indicator != null && i++ % 512 == 0) {
indicator.checkCanceled();
}
public void consume(String s) {
if (parameters.nameMatches(s)) {
names.add(s);
}
return true;
}
}, scope, IdFilter.getProjectIdFilter(project, true));
if (indicator != null) {
indicator.checkCanceled();
}
List<String> sorted = new ArrayList<String>(names);
Collections.sort(sorted, new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return o1.compareToIgnoreCase(o2);
}
});
for (final String name : sorted) {
List<String> sorted = new ArrayList<String>(names);
Collections.sort(sorted, String.CASE_INSENSITIVE_ORDER);
return processClassesByNames(parameters.getProject(), scope, sorted, processor);
}
public static boolean processClassesByNames(Project project,
final GlobalSearchScope scope,
Collection<String> names,
Processor<PsiClass> processor) {
final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
for (final String name : names) {
ProgressIndicatorProvider.checkCanceled();
final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
@Override
@@ -107,6 +97,28 @@ public class AllClassesSearchExecutor implements QueryExecutor<PsiClass, AllClas
return true;
}
public static Project processClassNames(Project project, GlobalSearchScope scope, final Consumer<String> consumer) {
final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
PsiShortNamesCache.getInstance(project).processAllClassNames(new Processor<String>() {
int i = 0;
@Override
public boolean process(String s) {
if (indicator != null && i++ % 512 == 0) {
indicator.checkCanceled();
}
consumer.consume(s);
return true;
}
}, scope, IdFilter.getProjectIdFilter(project, true));
if (indicator != null) {
indicator.checkCanceled();
}
return project;
}
private static boolean processScopeRootForAllClasses(@NotNull final PsiElement scopeRoot, @NotNull final Processor<PsiClass> processor) {
final boolean[] stopped = {false};