diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java index fa3cd31c2546..243ecb220419 100644 --- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java +++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java @@ -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() { + final Set collectedMethods = new THashSet(); + boolean success = cache.processFieldsWithName(name, new Processor() { @Override public boolean process(PsiField field) { if (isOpenable(field)) return processor.process(field); return true; } }, scope, filter) && - cache.processMethodsWithName(name, new Processor() { - @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() { @Override public boolean process(PsiClass aClass) { if (isOpenable(aClass)) return processor.process(aClass); return true; } + }, scope, filter) && + cache.processMethodsWithName(name, new Processor() { + @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 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{