IDEA-116497 UI hang during index update [r=Eugene.Zhuravlev]

This commit is contained in:
Maxim.Mossienko
2013-11-22 17:46:23 +01:00
parent 64636bb9ef
commit c12b687f53
@@ -19,6 +19,7 @@ import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.navigation.ChooseByNameContributorEx;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
@@ -30,13 +31,11 @@ import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
import com.intellij.util.indexing.FindSymbolParameters;
import com.intellij.util.indexing.IdFilter;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.*;
public class DefaultSymbolNavigationContributor implements ChooseByNameContributorEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor");
@@ -111,27 +110,40 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut
IdFilter filter = parameters.getIdFilter();
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(scope.getProject());
//noinspection UnusedDeclaration
boolean dummy = cache.processFieldsWithName(name, new Processor<PsiField>() {
final Set<PsiMethod> collectedMethods = new THashSet<PsiMethod>();
boolean success = cache.processFieldsWithName(name, new Processor<PsiField>() {
@Override
public boolean process(PsiField field) {
if (isOpenable(field)) return processor.process(field);
return true;
}
}, scope, filter) &&
cache.processMethodsWithName(name, new Processor<PsiMethod>() {
@Override
public boolean process(PsiMethod method) {
if(!method.isConstructor() && isOpenable(method) && !hasSuperMethod(method)) return processor.process(method);
return true;
}
}, scope, filter) &&
cache.processClassesWithName(name, new Processor<PsiClass>() {
@Override
public boolean process(PsiClass aClass) {
if (isOpenable(aClass)) return processor.process(aClass);
return true;
}
}, scope, filter) &&
cache.processMethodsWithName(name, new Processor<PsiMethod>() {
@Override
public boolean process(PsiMethod method) {
if(!method.isConstructor() && isOpenable(method)) {
collectedMethods.add(method);
}
return true;
}
}, scope, filter);
if (success) {
// hashSuperMethod accesses index and can not be invoked without risk of the deadlock in processMethodsWithName
Iterator<PsiMethod> iterator = collectedMethods.iterator();
while(iterator.hasNext()) {
PsiMethod method = iterator.next();
if (!hasSuperMethod(method) && !processor.process(method)) return;
ProgressManager.checkCanceled();
iterator.remove();
}
}
}
private static class MyComparator implements Comparator<PsiModifierListOwner>{