Make copy of the drivers list in SearchEngineImpl2 to avoid ConcurrentModificationError.

I think this happens when a driver is disposed why search is in
progress. So, we need to make defensive copies.

This also makes me realize that we don't handle situations when
a driver instance is disposed, but it has pending requests, such as
getResult(), getIndex(), etc - actually any getXXX(), and search. As
it is now, I think we just leave these Future(s) and they never
complete.

R=brianwilkerson@google.com
BUG=

Review-Url: https://codereview.chromium.org/2818163003 .
This commit is contained in:
Konstantin Shcheglov 2017-04-17 09:41:49 -07:00
parent 0733810528
commit 124f874b4a

View file

@ -39,7 +39,8 @@ class SearchEngineImpl2 implements SearchEngine {
@override
Future<List<SearchMatch>> searchMemberDeclarations(String name) async {
List<SearchMatch> allDeclarations = [];
for (AnalysisDriver driver in _drivers) {
List<AnalysisDriver> drivers = _drivers.toList();
for (AnalysisDriver driver in drivers) {
List<Element> elements = await driver.search.classMembers(name);
allDeclarations.addAll(elements.map(_SearchMatch.forElement));
}
@ -49,7 +50,8 @@ class SearchEngineImpl2 implements SearchEngine {
@override
Future<List<SearchMatch>> searchMemberReferences(String name) async {
List<SearchResult> allResults = [];
for (AnalysisDriver driver in _drivers) {
List<AnalysisDriver> drivers = _drivers.toList();
for (AnalysisDriver driver in drivers) {
List<SearchResult> results =
await driver.search.unresolvedMemberReferences(name);
allResults.addAll(results);
@ -60,7 +62,8 @@ class SearchEngineImpl2 implements SearchEngine {
@override
Future<List<SearchMatch>> searchReferences(Element element) async {
List<SearchResult> allResults = [];
for (AnalysisDriver driver in _drivers) {
List<AnalysisDriver> drivers = _drivers.toList();
for (AnalysisDriver driver in drivers) {
List<SearchResult> results = await driver.search.references(element);
allResults.addAll(results);
}
@ -77,7 +80,8 @@ class SearchEngineImpl2 implements SearchEngine {
Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) async {
List<SearchMatch> allDeclarations = [];
RegExp regExp = new RegExp(pattern);
for (AnalysisDriver driver in _drivers) {
List<AnalysisDriver> drivers = _drivers.toList();
for (AnalysisDriver driver in drivers) {
List<Element> elements = await driver.search.topLevelElements(regExp);
allDeclarations.addAll(elements.map(_SearchMatch.forElement));
}
@ -86,7 +90,8 @@ class SearchEngineImpl2 implements SearchEngine {
Future<List<SearchResult>> _searchDirectSubtypes(ClassElement type) async {
List<SearchResult> allResults = [];
for (AnalysisDriver driver in _drivers) {
List<AnalysisDriver> drivers = _drivers.toList();
for (AnalysisDriver driver in drivers) {
List<SearchResult> results = await driver.search.subTypes(type);
allResults.addAll(results);
}