Issue 33412. Fix for race condition in knownFiles during search.

In theory discoverAvailableFiles() should wait for all possibly known
files to be discovered. But I think it is still possible to get the
set of known files changed, e.g. when are asking asynchronoiusly for
getIndex() and the user open a file that is not yet part of any driver.

Only the second hunk of the change (inside subtypes()) is required for fixing
the issue, the crucial change is toList() invocation. The switch from
_driver.knownFiles to _driver.fsState.knownFiles is done to avoid one extra
lookup for FileState.

The first hunk (inside declarations()) is done just for consistency.


Fixes https://github.com/dart-lang/sdk/issues/33412

R=paulberry@google.com

Change-Id: I652ef7a156eba4bf0298c7e863dcef2b7c9f2b0e
Reviewed-on: https://dart-review.googlesource.com/60142
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index d308de5..59dcb83 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -145,15 +145,15 @@
     await _driver.discoverAvailableFiles();
 
     try {
-      for (String path in _driver.knownFiles) {
-        if (onlyForFile != null && path != onlyForFile) {
+      List<FileState> knownFiles = _driver.fsState.knownFiles.toList();
+      for (FileState file in knownFiles) {
+        if (onlyForFile != null && file.path != onlyForFile) {
           continue;
         }
-        if (files.contains(path)) {
+        if (files.contains(file.path)) {
           continue;
         }
 
-        FileState file = _driver.fsState.getFileForPath(path);
         int fileIndex;
 
         void addDeclaration(String name, DeclarationKind kind, int offset,
@@ -380,10 +380,10 @@
     await _driver.discoverAvailableFiles();
 
     List<SubtypeResult> results = [];
-    for (String path in _driver.knownFiles) {
-      FileState file = _driver.fsState.getFileForPath(path);
+    List<FileState> knownFiles = _driver.fsState.knownFiles.toList();
+    for (FileState file in knownFiles) {
       if (file.subtypedNames.contains(name)) {
-        AnalysisDriverUnitIndex index = await _driver.getIndex(path);
+        AnalysisDriverUnitIndex index = await _driver.getIndex(file.path);
         if (index != null) {
           for (AnalysisDriverSubtype subtype in index.subtypes) {
             if (subtype.supertypes.contains(id)) {