make Query#forEach thread-safe by default

We have too many usages which don't suspect the consumer might be called concurrently on different threads and don't guard against that. And in most cases having mutually-exclusive processing is fine.
This commit is contained in:
peter
2019-02-25 11:51:06 +01:00
parent 4066dac71d
commit 8bb9a4222b
13 changed files with 67 additions and 17 deletions

View File

@@ -114,7 +114,7 @@ class ConstructorReferencesSearchHelper {
return true;
};
return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2);
return ClassInheritorsSearch.search(containingClass, searchScope, false).allowParallelProcessing().forEach(processor2);
}
private static boolean processEnumReferences(@NotNull final Processor<? super PsiReference> processor,

View File

@@ -46,6 +46,6 @@ public class JavaAllOverridingMethodsSearcher implements QueryExecutor<Pair<PsiM
return true;
};
return ClassInheritorsSearch.search(psiClass, scope, true).forEach(inheritorsProcessor);
return ClassInheritorsSearch.search(psiClass, scope, true).allowParallelProcessing().forEach(inheritorsProcessor);
}
}

View File

@@ -60,7 +60,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, Cla
final SearchScope searchScope = parameters.getScope();
Project project = PsiUtilCore.getProjectInReadAction(baseClass);
if (isJavaLangObject(baseClass)) {
AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(aClass -> {
AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).allowParallelProcessing().forEach(aClass -> {
ProgressManager.checkCanceled();
return isJavaLangObject(aClass) || consumer.process(aClass);
});
@@ -105,7 +105,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, Cla
boolean isPhysical = ReadAction.compute(baseClass::isPhysical);
SearchScope scopeToUse = isPhysical ? GlobalSearchScope.allScope(project) : searchScopeForNonPhysical;
LazyConcurrentCollection.MoreElementsGenerator<PsiAnchor, PsiClass> generator = (candidate, processor) ->
DirectClassInheritorsSearch.search(candidate, scopeToUse).forEach(subClass -> {
DirectClassInheritorsSearch.search(candidate, scopeToUse).allowParallelProcessing().forEach(subClass -> {
ProgressManager.checkCanceled();
PsiAnchor pointer = ReadAction.compute(() -> PsiAnchor.create(subClass));
// append found result to subClasses as early as possible to allow other waiting threads to continue

View File

@@ -46,7 +46,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
final Project project = PsiUtilCore.getProjectInReadAction(baseClass);
if (JavaClassInheritorsSearcher.isJavaLangObject(baseClass)) {
SearchScope useScope = ReadAction.compute(baseClass::getUseScope);
return AllClassesSearch.search(useScope, project).forEach(psiClass -> {
return AllClassesSearch.search(useScope, project).allowParallelProcessing().forEach(psiClass -> {
ProgressManager.checkCanceled();
if (psiClass.isInterface()) {
return consumer.process(psiClass);

View File

@@ -124,7 +124,7 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor<PsiMethod, O
// use wider scope to handle public method defined in package-private class which is subclassed by public class in the same package which is subclassed by public class from another package with redefined method
SearchScope allScope = GlobalSearchScope.allScope(project);
boolean success = ClassInheritorsSearch.search(containingClass, allScope, true).forEach(inheritorsProcessor);
boolean success = ClassInheritorsSearch.search(containingClass, allScope, true).allowParallelProcessing().forEach(inheritorsProcessor);
assert success;
return result;
}