Revert "AnalysisDriver. Produce results for all files of a library."

This reverts commit 89bd370e95c0695250a4f0111be3134b9936eadd.

Reason for revert: causes Flutter roll issues.

Apparently https://github.com/dart-lang/sdk/issues/54577 is more serious.

Original change's description:
> AnalysisDriver. Produce results for all files of a library.
>
> Change-Id: I0118ccdbd4a9059eb3809cb3b6a694731621d809
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/345363
> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>

Change-Id: I9d7b98fa18a7d19853b03aeec7094f7769bc13f0
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/345780
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart
index 95b4a50..4c0b3cd 100644
--- a/pkg/analysis_server/test/integration/analysis/error_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/error_test.dart
@@ -28,15 +28,8 @@
     await sendServerSetSubscriptions([ServerService.STATUS]);
     await sendAnalysisUpdateContent({filePath: AddContentOverlay(content)});
     await sendAnalysisSetAnalysisRoots([packagePath], []);
-
     await analysisFinished;
 
-    // TODO(scheglov): https://github.com/dart-lang/sdk/issues/54577
-    // `await analysisFinished` should be enough, but was not promised.
-    while (currentAnalysisErrors[filePath] == null) {
-      await pumpEventQueue();
-    }
-
     expect(currentAnalysisErrors[filePath], isList);
     var errors = existingErrorsForFile(filePath);
     expect(errors, hasLength(1));
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 46d83ee..0cc35b4 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -54,12 +54,12 @@
 import 'package:analyzer/src/utilities/extensions/collection.dart';
 import 'package:analyzer/src/utilities/uri_cache.dart';
 
-/// This class computes analysis results for Dart files.
+/// This class computes [AnalysisResult]s for Dart files.
 ///
 /// Let the set of "explicitly analyzed files" denote the set of paths that have
 /// been passed to [addFile] but not subsequently passed to [removeFile]. Let
 /// the "current analysis results" denote the map from the set of explicitly
-/// analyzed files to the most recent analysis result delivered to [results]
+/// analyzed files to the most recent [AnalysisResult] delivered to [results]
 /// for each file. Let the "current file state" represent a map from file path
 /// to the file contents most recently read from that file, or fetched from the
 /// content cache (considering all possible file paths, regardless of
@@ -90,7 +90,7 @@
 // TODO(scheglov): Clean up the list of implicitly analyzed files.
 class AnalysisDriver {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 327;
+  static const int DATA_VERSION = 326;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
@@ -427,8 +427,7 @@
   /// Return the [ResourceProvider] that is used to access the file system.
   ResourceProvider get resourceProvider => _resourceProvider;
 
-  /// Return the [Stream] that produces [ErrorsResult]s and
-  /// [ResolvedUnitResult]s for added files.
+  /// Return the [Stream] that produces [AnalysisResult]s for added files.
   ///
   /// Note that the stream supports only one single subscriber.
   ///
@@ -1165,7 +1164,7 @@
         final result = await _resolveForCompletion(request);
         request.completer.complete(result);
       } catch (exception, stackTrace) {
-        _reportException(request.path, exception, stackTrace, null);
+        _reportException(request.path, exception, stackTrace);
         request.completer.completeError(exception, stackTrace);
         _clearLibraryContextAfterException();
       }
@@ -1175,28 +1174,61 @@
     // Analyze a requested file.
     if (_requestedFiles.isNotEmpty) {
       final path = _requestedFiles.keys.first;
-      await _analyzeFile(path);
+      final completers = _requestedFiles.remove(path)!;
+      _fileTracker.fileWasAnalyzed(path);
+      try {
+        final result = await _computeAnalysisResult(path, withUnit: true);
+        final unitResult = result.unitResult!;
+        for (final completer in completers) {
+          completer.complete(unitResult);
+        }
+        _resultController.add(unitResult);
+      } catch (exception, stackTrace) {
+        _reportException(path, exception, stackTrace);
+        for (final completer in completers) {
+          completer.completeError(exception, stackTrace);
+        }
+        _clearLibraryContextAfterException();
+      }
       return;
     }
 
     // Analyze a requested library.
     if (_requestedLibraries.isNotEmpty) {
       final library = _requestedLibraries.keys.first;
-      await _getResolvedLibrary(library);
+      try {
+        var result = await _computeResolvedLibrary(library);
+        for (var completer in _requestedLibraries.remove(library)!) {
+          completer.complete(result);
+        }
+      } catch (exception, stackTrace) {
+        for (var completer in _requestedLibraries.remove(library)!) {
+          completer.completeError(exception, stackTrace);
+        }
+        _clearLibraryContextAfterException();
+      }
       return;
     }
 
     // Process an error request.
     if (_errorsRequestedFiles.isNotEmpty) {
-      final path = _errorsRequestedFiles.keys.first;
-      await _getErrors(path);
+      var path = _errorsRequestedFiles.keys.first;
+      var completers = _errorsRequestedFiles.remove(path)!;
+      var analysisResult = await _computeAnalysisResult(path, withUnit: false);
+      var result = analysisResult.errorsResult!;
+      for (var completer in completers) {
+        completer.complete(result);
+      }
       return;
     }
 
     // Process an index request.
     if (_indexRequestedFiles.isNotEmpty) {
-      final path = _indexRequestedFiles.keys.first;
-      await _getIndex(path);
+      String path = _indexRequestedFiles.keys.first;
+      final index = await _computeIndex(path);
+      for (var completer in _indexRequestedFiles.remove(path)!) {
+        completer.complete(index);
+      }
       return;
     }
 
@@ -1243,7 +1275,15 @@
     if (_priorityFiles.isNotEmpty) {
       for (String path in _priorityFiles) {
         if (_fileTracker.isFilePending(path)) {
-          await _analyzeFile(path);
+          try {
+            var result = await _computeAnalysisResult(path, withUnit: true);
+            _resultController.add(result.unitResult!);
+          } catch (exception, stackTrace) {
+            _reportException(path, exception, stackTrace);
+            _clearLibraryContextAfterException();
+          } finally {
+            _fileTracker.fileWasAnalyzed(path);
+          }
           return;
         }
       }
@@ -1252,7 +1292,22 @@
     // Analyze a general file.
     if (_fileTracker.hasPendingFiles) {
       String path = _fileTracker.anyPendingFile;
-      await _produceErrors(path);
+      try {
+        var result = await _computeAnalysisResult(path,
+            withUnit: false, skipIfSameSignature: true);
+        if (result.isUnchangedErrors) {
+          // We found that the set of errors is the same as we produced the
+          // last time, so we don't need to produce it again now.
+        } else {
+          _resultController.add(result.errorsResult!);
+          _lastProducedSignatures[path] = result._signature;
+        }
+      } catch (exception, stackTrace) {
+        _reportException(path, exception, stackTrace);
+        _clearLibraryContextAfterException();
+      } finally {
+        _fileTracker.fileWasAnalyzed(path);
+      }
       return;
     }
   }
@@ -1311,174 +1366,6 @@
     }
   }
 
-  Future<void> _analyzeFile(String path) async {
-    // We will produce the result for this file, at least.
-    // And for any other files of the same library.
-    _fileTracker.fileWasAnalyzed(path);
-
-    final file = _fsState.getFileForPath(path);
-
-    // Prepare the library - the file itself, or the known library.
-    final kind = file.kind;
-    final library = kind.library ?? kind.asLibrary;
-
-    // We need the fully resolved unit, or the result is not cached.
-    return _logger.runAsync('Compute analysis result for $path', () async {
-      _logger.writeln('Work in $name');
-      try {
-        testView?.numOfAnalyzedLibraries++;
-        _resultController.add(
-          events.AnalyzeFile(
-            file: file,
-            library: library,
-          ),
-        );
-
-        if (!_hasLibraryByUri('dart:core')) {
-          _errorsRequestedFiles.completeAll(
-            path,
-            _newMissingDartLibraryResult(file, 'dart:core'),
-          );
-          return;
-        }
-
-        if (!_hasLibraryByUri('dart:async')) {
-          _errorsRequestedFiles.completeAll(
-            path,
-            _newMissingDartLibraryResult(file, 'dart:async'),
-          );
-          return;
-        }
-
-        await libraryContext.load(
-          targetLibrary: library,
-          performance: OperationPerformanceImpl('<root>'),
-        );
-
-        var options = libraryContext.analysisContext
-            .getAnalysisOptionsForFile(file.resource);
-
-        var results = LibraryAnalyzer(
-          options,
-          declaredVariables,
-          libraryContext.elementFactory.libraryOfUri2(library.file.uri),
-          libraryContext.elementFactory.analysisSession.inheritanceManager,
-          library,
-          resourceProvider.pathContext,
-          testingData: testingData,
-        ).analyze();
-
-        final isLibraryWithPriorityFile = _isLibraryWithPriorityFile(library);
-
-        final resolvedUnits = <ResolvedUnitResultImpl>[];
-        for (var unitResult in results) {
-          var unitFile = unitResult.file;
-
-          final index = enableIndex
-              ? indexUnit(unitResult.unit)
-              : AnalysisDriverUnitIndexBuilder();
-
-          final resolvedUnit = _createResolvedUnitImpl(
-            file: unitFile,
-            unitResult: unitResult,
-          );
-          resolvedUnits.add(resolvedUnit);
-
-          // getResolvedUnit()
-          _requestedFiles.completeAll(unitFile.path, resolvedUnit);
-
-          // getErrors()
-          _errorsRequestedFiles.completeAll(
-            unitFile.path,
-            _createErrorsResultImpl(
-              file: file,
-              errors: unitResult.errors,
-            ),
-          );
-
-          // getIndex()
-          _indexRequestedFiles.completeAll(unitFile.path, index);
-
-          final unitSignature = _getResolvedUnitSignature(library, unitFile);
-          {
-            final unitKey = _getResolvedUnitKey(unitSignature);
-            final unitBytes = AnalysisDriverResolvedUnitBuilder(
-              errors: unitResult.errors.map((error) {
-                return ErrorEncoding.encode(error);
-              }).toList(),
-              index: index,
-            ).toBuffer();
-            _byteStore.putGet(unitKey, unitBytes);
-          }
-
-          _fileTracker.fileWasAnalyzed(unitFile.path);
-          _lastProducedSignatures[path] = unitSignature;
-          _resultController.add(resolvedUnit);
-
-          if (isLibraryWithPriorityFile) {
-            _priorityResults[unitFile.path] = resolvedUnit;
-          }
-
-          _updateHasErrorOrWarningFlag(file, resolvedUnit.errors);
-        }
-
-        final libraryResult = ResolvedLibraryResultImpl(
-          session: currentSession,
-          element: resolvedUnits.first.libraryElement,
-          units: resolvedUnits,
-        );
-
-        if (isLibraryWithPriorityFile) {
-          _resolvedLibraryCache[library] = libraryResult;
-        }
-
-        // getResolvedLibrary()
-        {
-          final completers = _requestedLibraries.remove(library);
-          if (completers != null) {
-            for (final completer in completers) {
-              completer.complete(libraryResult);
-            }
-          }
-        }
-
-        // Return the result, full or partial.
-        _logger.writeln('Computed new analysis result.');
-        // return result;
-      } catch (exception, stackTrace) {
-        final contextKey =
-            _storeExceptionContext(path, library, exception, stackTrace);
-        _reportException(path, exception, stackTrace, contextKey);
-
-        // Complete all related requests with an error.
-        void completeWithError<T>(List<Completer<T>>? completers) {
-          if (completers != null) {
-            for (final completer in completers) {
-              completer.completeError(exception, stackTrace);
-            }
-          }
-        }
-
-        // TODO(scheglov): write tests
-        for (final file in library.files) {
-          // getResolvedUnit()
-          completeWithError(
-            _requestedFiles.remove(file.path),
-          );
-          // getErrors()
-          completeWithError(
-            _errorsRequestedFiles.remove(file.path),
-          );
-        }
-        // getResolvedLibrary()
-        completeWithError(
-          _requestedLibraries.remove(library),
-        );
-        _clearLibraryContextAfterException();
-      }
-    });
-  }
-
   void _applyPendingFileChanges() {
     var accumulatedAffected = <String>{};
     for (var fileChange in _pendingFileChanges) {
@@ -1522,6 +1409,230 @@
     _resolvedLibraryCache.clear();
   }
 
+  /// Return the cached or newly computed analysis result of the file with the
+  /// given [path].
+  ///
+  /// The [withUnit] flag control which result will be returned.
+  /// When `true`, [AnalysisResult.unitResult] will be set.
+  /// Otherwise [AnalysisResult.errorsResult] will be set.
+  ///
+  /// Return [AnalysisResult._UNCHANGED] if [skipIfSameSignature] is `true` and
+  /// the resolved signature of the file in its library is the same as the one
+  /// that was the most recently produced to the client.
+  Future<AnalysisResult> _computeAnalysisResult(String path,
+      {required bool withUnit, bool skipIfSameSignature = false}) async {
+    FileState file = _fsState.getFileForPath(path);
+
+    // Prepare the library - the file itself, or the known library.
+    final kind = file.kind;
+    final library = kind.library ?? kind.asLibrary;
+
+    // Prepare the signature and key.
+    String signature = _getResolvedUnitSignature(library, file);
+    String key = _getResolvedUnitKey(signature);
+
+    // Skip reading if the signature, so errors, are the same as the last time.
+    if (skipIfSameSignature) {
+      assert(!withUnit);
+      if (_lastProducedSignatures[path] == signature) {
+        return AnalysisResult.unchangedErrors(signature);
+      }
+    }
+
+    // If we don't need the fully resolved unit, check for the cached result.
+    if (!withUnit) {
+      var bytes = _byteStore.get(key);
+      if (bytes != null) {
+        final unit = AnalysisDriverResolvedUnit.fromBuffer(bytes);
+        final errors = _getErrorsFromSerialized(file, unit.errors);
+        _updateHasErrorOrWarningFlag(file, errors);
+        final index = unit.index!;
+        final errorsResult = _createErrorsResultImpl(
+          file: file,
+          errors: errors,
+        );
+        return AnalysisResult.errors(signature, errorsResult, index);
+      }
+    }
+
+    // We need the fully resolved unit, or the result is not cached.
+    return _logger.runAsync('Compute analysis result for $path', () async {
+      _logger.writeln('Work in $name');
+      try {
+        testView?.numOfAnalyzedLibraries++;
+        _resultController.add(
+          events.ComputeAnalysis(
+            file: file,
+            library: library,
+          ),
+        );
+
+        if (!_hasLibraryByUri('dart:core')) {
+          return _newMissingDartLibraryResult(file, 'dart:core');
+        }
+
+        if (!_hasLibraryByUri('dart:async')) {
+          return _newMissingDartLibraryResult(file, 'dart:async');
+        }
+
+        await libraryContext.load(
+          targetLibrary: library,
+          performance: OperationPerformanceImpl('<root>'),
+        );
+
+        var options = libraryContext.analysisContext
+            .getAnalysisOptionsForFile(file.resource);
+
+        var results = LibraryAnalyzer(
+          options,
+          declaredVariables,
+          libraryContext.elementFactory.libraryOfUri2(library.file.uri),
+          libraryContext.elementFactory.analysisSession.inheritanceManager,
+          library,
+          resourceProvider.pathContext,
+          testingData: testingData,
+        ).analyze();
+
+        final isLibraryWithPriorityFile = _isLibraryWithPriorityFile(library);
+
+        late AnalysisResult result;
+        final resolvedUnits = <ResolvedUnitResultImpl>[];
+        for (var unitResult in results) {
+          var unitFile = unitResult.file;
+
+          final index = enableIndex
+              ? indexUnit(unitResult.unit)
+              : AnalysisDriverUnitIndexBuilder();
+
+          final unitBytes = AnalysisDriverResolvedUnitBuilder(
+            errors: unitResult.errors.map((error) {
+              return ErrorEncoding.encode(error);
+            }).toList(),
+            index: index,
+          ).toBuffer();
+
+          final resolvedUnit = _createResolvedUnitImpl(
+            file: unitFile,
+            unitResult: unitResult,
+          );
+          resolvedUnits.add(resolvedUnit);
+
+          if (isLibraryWithPriorityFile) {
+            _priorityResults[unitFile.path] = resolvedUnit;
+          }
+
+          String unitSignature = _getResolvedUnitSignature(library, unitFile);
+          String unitKey = _getResolvedUnitKey(unitSignature);
+          _byteStore.putGet(unitKey, unitBytes);
+
+          _updateHasErrorOrWarningFlag(file, resolvedUnit.errors);
+
+          if (unitFile == file) {
+            if (withUnit) {
+              result = AnalysisResult.unit(signature, resolvedUnit, index);
+            } else {
+              result = AnalysisResult.errors(
+                signature,
+                _createErrorsResultImpl(
+                  file: unitFile,
+                  errors: unitResult.errors,
+                ),
+                index,
+              );
+            }
+          }
+        }
+
+        if (isLibraryWithPriorityFile) {
+          final libraryResult = ResolvedLibraryResultImpl(
+            session: currentSession,
+            element: resolvedUnits.first.libraryElement,
+            units: resolvedUnits,
+          );
+          _resolvedLibraryCache[library] = libraryResult;
+        }
+
+        // Return the result, full or partial.
+        _logger.writeln('Computed new analysis result.');
+        return result;
+      } catch (exception, stackTrace) {
+        String? contextKey =
+            _storeExceptionContext(path, library, exception, stackTrace);
+        throw _ExceptionState(exception, stackTrace, contextKey);
+      }
+    });
+  }
+
+  Future<AnalysisDriverUnitIndex> _computeIndex(String path) async {
+    var analysisResult = await _computeAnalysisResult(path, withUnit: false);
+    return analysisResult._index!;
+  }
+
+  /// Return the newly computed resolution result of the library with the
+  /// given [path].
+  Future<ResolvedLibraryResultImpl> _computeResolvedLibrary(
+    LibraryFileKind library,
+  ) async {
+    final cached = _resolvedLibraryCache[library];
+    if (cached != null) {
+      return cached;
+    }
+
+    final path = library.file.path;
+    return _logger.runAsync('Compute resolved library $path', () async {
+      testView?.numOfAnalyzedLibraries++;
+      await libraryContext.load(
+        targetLibrary: library,
+        performance: OperationPerformanceImpl('<root>'),
+      );
+
+      _resultController.add(
+        events.ComputeResolvedLibrary(
+          library: library,
+        ),
+      );
+
+      var analysisOptions = libraryContext.analysisContext
+          .getAnalysisOptionsForFile(library.file.resource);
+
+      var unitResults = LibraryAnalyzer(
+              analysisOptions,
+              declaredVariables,
+              libraryContext.elementFactory.libraryOfUri2(library.file.uri),
+              libraryContext.elementFactory.analysisSession.inheritanceManager,
+              library,
+              resourceProvider.pathContext,
+              testingData: testingData)
+          .analyze();
+      var resolvedUnits = <ResolvedUnitResult>[];
+
+      final isLibraryWithPriorityFile = _isLibraryWithPriorityFile(library);
+      for (final unitResult in unitResults) {
+        final unitFile = unitResult.file;
+        final resolvedUnit = _createResolvedUnitImpl(
+          file: unitFile,
+          unitResult: unitResult,
+        );
+        resolvedUnits.add(resolvedUnit);
+        if (isLibraryWithPriorityFile) {
+          _priorityResults[unitFile.path] = resolvedUnit;
+        }
+      }
+
+      final result = ResolvedLibraryResultImpl(
+        session: currentSession,
+        element: resolvedUnits.first.libraryElement,
+        units: resolvedUnits,
+      );
+
+      if (isLibraryWithPriorityFile) {
+        _resolvedLibraryCache[library] = result;
+      }
+
+      return result;
+    });
+  }
+
   Future<UnitElementResult?> _computeUnitElement(String path) async {
     FileState file = _fsState.getFileForPath(path);
 
@@ -1691,39 +1802,6 @@
     _saltForUnlinked = buffer.toUint32List();
   }
 
-  Future<void> _getErrors(String path) async {
-    final file = _fsState.getFileForPath(path);
-
-    // Prepare the library - the file itself, or the known library.
-    final kind = file.kind;
-    final library = kind.library ?? kind.asLibrary;
-
-    // Prepare the signature and key.
-    final signature = _getResolvedUnitSignature(library, file);
-    final key = _getResolvedUnitKey(signature);
-
-    final bytes = _byteStore.get(key);
-    if (bytes != null) {
-      _resultController.add(
-        events.GetErrorsFromBytes(
-          file: file,
-          library: library,
-        ),
-      );
-      final unit = AnalysisDriverResolvedUnit.fromBuffer(bytes);
-      final errors = _getErrorsFromSerialized(file, unit.errors);
-      _updateHasErrorOrWarningFlag(file, errors);
-      final result = _createErrorsResultImpl(
-        file: file,
-        errors: errors,
-      );
-      _errorsRequestedFiles.completeAll(path, result);
-      return;
-    }
-
-    await _analyzeFile(path);
-  }
-
   /// Return [AnalysisError]s for the given [serialized] errors.
   List<AnalysisError> _getErrorsFromSerialized(
       FileState file, List<AnalysisDriverUnitError> serialized) {
@@ -1737,38 +1815,6 @@
     return errors;
   }
 
-  Future<void> _getIndex(String path) async {
-    final file = _fsState.getFileForPath(path);
-
-    // Prepare the library - the file itself, or the known library.
-    final kind = file.kind;
-    final library = kind.library ?? kind.asLibrary;
-
-    // Prepare the signature and key.
-    final signature = _getResolvedUnitSignature(library, file);
-    final key = _getResolvedUnitKey(signature);
-
-    final bytes = _byteStore.get(key);
-    if (bytes != null) {
-      final unit = AnalysisDriverResolvedUnit.fromBuffer(bytes);
-      _indexRequestedFiles.completeAll(path, unit.index!);
-      return;
-    }
-
-    await _analyzeFile(path);
-  }
-
-  /// Completes the [getResolvedLibrary] request.
-  Future<void> _getResolvedLibrary(LibraryFileKind library) async {
-    final cached = _resolvedLibraryCache[library];
-    if (cached != null) {
-      _requestedLibraries.completeAll(library, cached);
-      return;
-    }
-
-    await _analyzeFile(library.file.path);
-  }
-
   /// Return the key to store fully resolved results for the [signature].
   String _getResolvedUnitKey(String signature) {
     return '$signature.resolved';
@@ -1822,10 +1868,10 @@
 
   /// We detected that one of the required `dart` libraries is missing.
   /// Return the empty analysis result with the error.
-  ErrorsResultImpl _newMissingDartLibraryResult(
+  AnalysisResult _newMissingDartLibraryResult(
       FileState file, String missingUri) {
     // TODO(scheglov): Find a better way to report this.
-    return ErrorsResultImpl(
+    var errorsResult = ErrorsResultImpl(
       session: currentSession,
       file: file.resource,
       lineInfo: file.lineInfo,
@@ -1844,6 +1890,8 @@
         ),
       ],
     );
+    return AnalysisResult.errors(
+        'missing', errorsResult, AnalysisDriverUnitIndexBuilder());
   }
 
   void _onNewFile(FileState file) {
@@ -1857,24 +1905,6 @@
     }
   }
 
-  Future<void> _produceErrors(String path) async {
-    final file = _fsState.getFileForPath(path);
-
-    // Prepare the library - the file itself, or the known library.
-    final kind = file.kind;
-    final library = kind.library ?? kind.asLibrary;
-
-    // Don't produce errors if the signature is the same.
-    final signature = _getResolvedUnitSignature(library, file);
-    if (_lastProducedSignatures[path] == signature) {
-      _fileTracker.fileWasAnalyzed(path);
-      return;
-    }
-
-    // Analyze, will produce a result into the stream.
-    await _analyzeFile(path);
-  }
-
   void _removePotentiallyAffectedLibraries(
     Set<String> accumulatedAffected,
     String path,
@@ -1899,8 +1929,15 @@
     );
   }
 
-  void _reportException(String path, Object exception, StackTrace stackTrace,
-      String? contextKey) {
+  void _reportException(String path, Object exception, StackTrace stackTrace) {
+    String? contextKey;
+    if (exception is _ExceptionState) {
+      var state = exception;
+      exception = exception.exception;
+      stackTrace = state.stackTrace;
+      contextKey = state.contextKey;
+    }
+
     CaughtException caught = CaughtException(exception, stackTrace);
 
     var fileContentMap = <String, String>{};
@@ -2299,6 +2336,53 @@
   }
 }
 
+/// The result of analyzing of a single file.
+///
+/// These results are self-consistent, i.e. the file content, line info, the
+/// resolved unit correspond to each other. All referenced elements, even
+/// external ones, are also self-consistent. But none of the results is
+/// guaranteed to be consistent with the state of the files.
+///
+/// Every result is independent, and is not guaranteed to be consistent with
+/// any previously returned result, even inside of the same library.
+class AnalysisResult {
+  /// The signature of the result based on the content of the file, and the
+  /// transitive closure of files imported and exported by the library of
+  /// the requested file.
+  final String _signature;
+
+  final bool isUnchangedErrors;
+
+  /// Is not `null` if this result is a result with errors.
+  /// Otherwise is `null`, and usually [unitResult] is set.
+  final ErrorsResultImpl? errorsResult;
+
+  /// Is not `null` if this result is a result with a resolved unit.
+  /// Otherwise is `null`, and usually [errorsResult] is set.
+  final ResolvedUnitResultImpl? unitResult;
+
+  /// The index of the unit.
+  final AnalysisDriverUnitIndex? _index;
+
+  AnalysisResult.errors(
+      this._signature, this.errorsResult, AnalysisDriverUnitIndex index)
+      : isUnchangedErrors = false,
+        unitResult = null,
+        _index = index;
+
+  AnalysisResult.unchangedErrors(this._signature)
+      : isUnchangedErrors = true,
+        errorsResult = null,
+        unitResult = null,
+        _index = null;
+
+  AnalysisResult.unit(
+      this._signature, this.unitResult, AnalysisDriverUnitIndex index)
+      : isUnchangedErrors = false,
+        errorsResult = null,
+        _index = index;
+}
+
 /// An object that watches for the creation and removal of analysis drivers.
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -2532,6 +2616,21 @@
   }
 }
 
+/// Information about an exception and its context.
+class _ExceptionState {
+  final Object exception;
+  final StackTrace stackTrace;
+
+  /// The key under which the context of the exception was stored, or `null`
+  /// if unknown, the maximum number of context to store was reached, etc.
+  final String? contextKey;
+
+  _ExceptionState(this.exception, this.stackTrace, this.contextKey);
+
+  @override
+  String toString() => '$exception\n$stackTrace';
+}
+
 class _FileChange {
   final String path;
   final _FileChangeKind kind;
@@ -2668,14 +2767,3 @@
     required this.performance,
   });
 }
-
-extension<K, V> on Map<K, List<Completer<V>>> {
-  void completeAll(K key, V value) {
-    final completers = remove(key);
-    if (completers != null) {
-      for (final completer in completers) {
-        completer.complete(value);
-      }
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_event.dart b/pkg/analyzer/lib/src/dart/analysis/driver_event.dart
index b713c86..d0c90ae 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_event.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_event.dart
@@ -8,22 +8,20 @@
 /// An event that happened inside the [AnalysisDriver].
 sealed class AnalysisDriverEvent {}
 
-final class AnalyzeFile extends AnalysisDriverEvent {
+final class ComputeAnalysis extends AnalysisDriverEvent {
   final FileState file;
   final LibraryFileKind library;
 
-  AnalyzeFile({
+  ComputeAnalysis({
     required this.file,
     required this.library,
   });
 }
 
-final class GetErrorsFromBytes extends AnalysisDriverEvent {
-  final FileState file;
+final class ComputeResolvedLibrary extends AnalysisDriverEvent {
   final LibraryFileKind library;
 
-  GetErrorsFromBytes({
-    required this.file,
+  ComputeResolvedLibrary({
     required this.library,
   });
 }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
index 5747ad2..8ef6b84 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
@@ -449,7 +449,7 @@
     var analysisDriver = driverFor(a);
 
     var userErrors = analysisDriver.results
-        .whereType<ResolvedUnitResult>()
+        .whereType<ErrorsResult>()
         .where((event) => event.path == user.path);
 
     // We get errors when the file is added.
@@ -507,7 +507,7 @@
     var analysisDriver = driverFor(a);
 
     var userErrors = analysisDriver.results
-        .whereType<ResolvedUnitResult>()
+        .whereType<ErrorsResult>()
         .where((event) => event.path == user.path);
 
     // We get errors when the file is added.
@@ -546,7 +546,7 @@
     var analysisDriver = driverFor(user);
 
     var userErrors = analysisDriver.results
-        .whereType<ResolvedUnitResult>()
+        .whereType<ErrorsResult>()
         .where((event) => event.path == user.path);
 
     // We get errors when the file is added.
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 87eeb88..5e83170 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -19,7 +19,6 @@
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/source.dart'
     show DartUriResolver, SourceFactory;
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:linter/src/rules.dart';
@@ -164,25 +163,19 @@
     driver.addFile2(b);
     driver.addFile2(a);
 
-    // The files are analyzed in the order of adding.
+    // The results are reported in the order of adding.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -203,22 +196,16 @@
     // Initial analysis, `b` does not use `a`, so there is a hint.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
     errors
       7 +8 UNUSED_IMPORT
 [status] idle
@@ -239,14 +226,11 @@
     // `b` was analyzed, no more hints.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #2
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -272,33 +256,25 @@
     driver.priorityFiles2 = [b];
 
     // 1. The priority file is produced first.
-    // 2. Each analyzed file produces `ResolvedUnitResult`.
+    // 2. We get full `ResolvedUnitResult`.
+    // 3. For other files we get only `ErrorsResult`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
   ResolvedUnitResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/c.dart
-  library: /home/test/lib/c.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #2
     path: /home/test/lib/c.dart
     uri: package:test/c.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -335,14 +311,11 @@
     // So, only `b` was analyzed.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -359,9 +332,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -404,9 +374,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -424,9 +391,6 @@
     collector.getResolvedUnit('A2', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A2
   ResolvedUnitResult #1
@@ -444,9 +408,6 @@
     collector.getResolvedUnit('A3', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A3
   ResolvedUnitResult #2
@@ -455,14 +416,11 @@
     flags: exists isLibrary
 [stream]
   ResolvedUnitResult #2
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #3
+  ErrorsResult #3
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -472,9 +430,6 @@
     collector.getResolvedUnit('A4', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A4
   ResolvedUnitResult #4
@@ -500,9 +455,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -528,9 +480,6 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B1
   ResolvedUnitResult #1
@@ -556,9 +505,6 @@
     collector.getResolvedUnit('A3', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A3
   ResolvedUnitResult #2
@@ -581,9 +527,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -599,9 +542,6 @@
     collector.getResolvedUnit('A2', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A2
   ResolvedUnitResult #1
@@ -632,9 +572,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -643,16 +580,11 @@
     flags: exists isLibrary
 [stream]
   ResolvedUnitResult #0
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
 [status] idle
 ''');
 
     // Verify that the results for `a` and `b` are cached.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedUnit('A2', a);
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
@@ -662,10 +594,13 @@
 [future] getResolvedUnit
   name: B1
   ResolvedUnitResult #1
+    path: /home/test/lib/b.dart
+    uri: package:test/b.dart
+    flags: exists isPart
 ''');
 
     // Ask for resolved library.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedLibrary('L1', a);
     await assertEventsText(collector, r'''
 [future] getResolvedLibrary
@@ -696,40 +631,35 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedUnit
   name: B1
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
 [stream]
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
 [status] idle
 ''');
 
     // Verify that the results for `a` and `b` are cached.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedUnit('A1', a);
     collector.getResolvedUnit('B2', b);
     await assertEventsText(collector, r'''
 [future] getResolvedUnit
   name: A1
-  ResolvedUnitResult #0
+  ResolvedUnitResult #1
+    path: /home/test/lib/a.dart
+    uri: package:test/a.dart
+    flags: exists isLibrary
 [future] getResolvedUnit
   name: B2
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
 ''');
 
     // Ask for resolved library.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedLibrary('L1', a);
     await assertEventsText(collector, r'''
 [future] getResolvedLibrary
@@ -737,8 +667,8 @@
   ResolvedLibraryResult #2
     element: package:test/a.dart
     units
-      ResolvedUnitResult #0
       ResolvedUnitResult #1
+      ResolvedUnitResult #0
 ''');
   }
 
@@ -760,40 +690,35 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedUnit
   name: B1
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
 [stream]
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
 [status] idle
 ''');
 
     // Verify that the results for `a` and `b` are cached.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedUnit('A1', a);
     collector.getResolvedUnit('B2', b);
     await assertEventsText(collector, r'''
 [future] getResolvedUnit
   name: A1
-  ResolvedUnitResult #0
+  ResolvedUnitResult #1
+    path: /home/test/lib/a.dart
+    uri: package:test/a.dart
+    flags: exists isLibrary
 [future] getResolvedUnit
   name: B2
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
 ''');
 
     // Ask for resolved library.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedLibrary('L1', a);
     await assertEventsText(collector, r'''
 [future] getResolvedLibrary
@@ -801,8 +726,8 @@
   ResolvedLibraryResult #2
     element: package:test/a.dart
     units
-      ResolvedUnitResult #0
       ResolvedUnitResult #1
+      ResolvedUnitResult #0
 ''');
   }
 
@@ -831,9 +756,6 @@
     // The type of `B` is `int`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #0
     path: /home/test/lib/a.dart
@@ -857,9 +779,6 @@
     // The type of `B` is now `double`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #1
     path: /home/test/lib/a.dart
@@ -894,14 +813,11 @@
     // `b` is analyzed, has an error.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
     errors
       31 +8 URI_DOES_NOT_EXIST
 [status] idle
@@ -915,22 +831,16 @@
     // No errors anymore.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #2
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -947,14 +857,11 @@
     // Nothing interesting, "a" is analyzed.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -1157,9 +1064,6 @@
     // We have results for both "a" and "b".
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #0
     path: /home/test/lib/a.dart
@@ -1168,9 +1072,6 @@
     selectedVariableTypes
       A1: int
       A2: int
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
   ResolvedUnitResult #1
     path: /home/test/lib/b.dart
@@ -1193,9 +1094,6 @@
     // The results are consistent.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #2
     path: /home/test/lib/a.dart
@@ -1204,9 +1102,6 @@
     selectedVariableTypes
       A1: double
       A2: double
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
   ResolvedUnitResult #3
     path: /home/test/lib/b.dart
@@ -1242,9 +1137,6 @@
     // Initial analysis.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #0
     path: /home/test/lib/a.dart
@@ -1266,9 +1158,6 @@
     driver.changeFile2(a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #1
     path: /home/test/lib/a.dart
@@ -1358,7 +1247,7 @@
     final collector = DriverEventCollector(driver);
 
     // Not cached.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getCachedResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [future] getCachedResolvedUnit
@@ -1370,9 +1259,6 @@
     collector.getResolvedUnit('A2', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A2
   ResolvedUnitResult #0
@@ -1385,7 +1271,7 @@
 ''');
 
     // Has cached.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getCachedResolvedUnit('A3', a);
     await assertEventsText(collector, r'''
 [future] getCachedResolvedUnit
@@ -1404,9 +1290,6 @@
 
     collector.getErrors('A1', a);
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getErrors
   name: A1
   ErrorsResult #0
@@ -1415,74 +1298,6 @@
     flags: isLibrary
     errors
       8 +1 EXPECTED_TOKEN
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-    errors
-      8 +1 EXPECTED_TOKEN
-''');
-
-    // The result is produced from bytes.
-    collector.getErrors('A2', a);
-    await assertEventsText(collector, r'''
-[operation] GetErrorsFromBytes
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getErrors
-  name: A2
-  ErrorsResult #2
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: isLibrary
-    errors
-      8 +1 EXPECTED_TOKEN
-''');
-  }
-
-  test_getErrors_library_part() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-part 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-part of 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getErrors('A1', a);
-    collector.getErrors('B1', b);
-
-    // Note, both `getErrors()` returned during the library analysis.
-    await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getErrors
-  name: A1
-  ErrorsResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: isLibrary
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[future] getErrors
-  name: B1
-  ErrorsResult #2
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: isLibrary
-[stream]
-  ResolvedUnitResult #3
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
 ''');
   }
 
@@ -1684,9 +1499,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -1713,9 +1525,6 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B1
   ResolvedUnitResult #1
@@ -1743,9 +1552,6 @@
     collector.getResolvedUnit('B2', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B2
   ResolvedUnitResult #2
@@ -1783,7 +1589,7 @@
   }
 
   test_getIndex() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
+    newFile(testFile.path, r'''
 void foo() {}
 
 void f() {
@@ -1792,30 +1598,16 @@
 ''');
 
     final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
+    driver.addFile2(testFile);
 
-    unawaited(collector.getIndex('A1', a).then((index) {
-      index!;
+    final index = await driver.getIndex2(testFile);
+    index!;
 
-      final unitId = index.strings.indexOf('package:test/a.dart');
-      expect(unitId, isNonNegative);
+    final unitId = index.strings.indexOf('package:test/test.dart');
+    expect(unitId, isNonNegative);
 
-      final fooId = index.strings.indexOf('foo');
-      expect(fooId, isNonNegative);
-    }));
-
-    await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getIndex
-  name: A1
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-''');
+    final fooId = index.strings.indexOf('foo');
+    expect(fooId, isNonNegative);
   }
 
   test_getIndex_notAbsolutePath() async {
@@ -2019,22 +1811,24 @@
     final driver = driverFor(testFile);
     final collector = DriverEventCollector(driver);
 
-    collector.getResolvedLibrary('A1', a);
+    configuration.libraryConfiguration.unitConfiguration.withContentPredicate =
+        (_) => true;
+
+    collector.getResolvedLibrary('X', a);
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedLibrary
-  name: A1
-  ResolvedLibraryResult #1
+  name: X
+  ResolvedLibraryResult #0
     element: package:test/a.dart
     units
-      ResolvedUnitResult #0
+      ResolvedUnitResult #1
+        path: /home/test/lib/a.dart
+        uri: package:test/a.dart
+        flags: exists isLibrary
+        content
+---
+class A {}
+---
 ''');
   }
 
@@ -2054,48 +1848,41 @@
 
     collector.getResolvedLibrary('A1', a);
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedLibrary
   name: A1
-  ResolvedLibraryResult #1
+  ResolvedLibraryResult #0
     element: package:test/a.dart
     units
-      ResolvedUnitResult #0
+      ResolvedUnitResult #1
+        path: /home/test/lib/a.dart
+        uri: package:test/a.dart
+        flags: exists isLibrary
       ResolvedUnitResult #2
         path: /home/test/lib/b.dart
         uri: package:test/b.dart
         flags: exists isPart
-[stream]
-  ResolvedUnitResult #2
 ''');
 
     // Ask again, the same cached instance should be returned.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedLibrary('A2', a);
     await assertEventsText(collector, r'''
 [future] getResolvedLibrary
   name: A2
-  ResolvedLibraryResult #1
+  ResolvedLibraryResult #0
 ''');
 
     // Ask `a`, returns cached.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedUnit('A3', a);
     await assertEventsText(collector, r'''
 [future] getResolvedUnit
   name: A3
-  ResolvedUnitResult #0
+  ResolvedUnitResult #1
 ''');
 
     // Ask `b`, returns cached.
-    // Note, operation 'AnalyzeFile'.
+    // Note, no status analyzing.
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [future] getResolvedUnit
@@ -2154,20 +1941,15 @@
     collector.getResolvedLibraryByUri('A1', uri);
 
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedLibraryByUri
   name: A1
-  ResolvedLibraryResult #1
+  ResolvedLibraryResult #0
     element: package:test/a.dart
     units
-      ResolvedUnitResult #0
+      ResolvedUnitResult #1
+        path: /home/test/lib/a.dart
+        uri: package:test/a.dart
+        flags: exists isLibrary
 ''');
   }
 
@@ -2198,15 +1980,24 @@
 
     final collector = DriverEventCollector(driver);
     collector.getResolvedUnit('A1', a);
-    collector.getResolvedUnit('B1', b);
+    collector.getResolvedUnit('B2', b);
 
     final uri = Uri.parse('package:test/a.dart');
     collector.getResolvedLibraryByUri('A2', uri);
 
-    // Note, the library is resolved only once.
+    configuration.withOperations = true;
+
+    // Note, that the `get` events are reported before `stream` events.
+    // TODO(scheglov): The current state is not optimal.
+    // We resolve `a.dart` separately as `analysisId: 0`.
+    // And then again `b.dart` as `analysisId: 1`.
+    // But actually we always resolve the whole library `a.dart`.
+    // So, we resolved it twice.
+    // Even worse, for `getResolvedLibraryByUri` we resolve it again.
+    // Theoretically we could have just one resolution overall.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/a.dart
   library: /home/test/lib/a.dart
 [future] getResolvedUnit
@@ -2217,22 +2008,33 @@
     flags: exists isLibrary
 [stream]
   ResolvedUnitResult #0
+[operation] computeAnalysisResult
+  file: /home/test/lib/b.dart
+  library: /home/test/lib/a.dart
 [future] getResolvedUnit
-  name: B1
+  name: B2
   ResolvedUnitResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
+[stream]
+  ResolvedUnitResult #1
+[status] idle
+[operation] computeResolvedLibrary
+  library: /home/test/lib/a.dart
 [future] getResolvedLibraryByUri
   name: A2
   ResolvedLibraryResult #2
     element: package:test/a.dart
     units
-      ResolvedUnitResult #0
-      ResolvedUnitResult #1
-[stream]
-  ResolvedUnitResult #1
-[status] idle
+      ResolvedUnitResult #3
+        path: /home/test/lib/a.dart
+        uri: package:test/a.dart
+        flags: exists isLibrary
+      ResolvedUnitResult #4
+        path: /home/test/lib/b.dart
+        uri: package:test/b.dart
+        flags: exists isPart
 ''');
   }
 
@@ -2311,9 +2113,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -2326,74 +2125,6 @@
 ''');
   }
 
-  test_getResolvedUnit_added() async {
-    final a = newFile('$testPackageLibPath/a.dart', '');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    driver.addFile2(a);
-    collector.getResolvedUnit('A1', a);
-
-    // Note, no separate `ErrorsResult`.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #0
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_augmentation_library() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-import augment 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-library augment 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getResolvedUnit('B1', b);
-    collector.getResolvedUnit('A1', a);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #0
-[future] getResolvedUnit
-  name: B1
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isAugmentation
-[stream]
-  ResolvedUnitResult #1
-[status] idle
-''');
-  }
-
   test_getResolvedUnit_importLibrary_thenRemoveIt() async {
     final a = newFile('$testPackageLibPath/a.dart', r'''
 class A {}''');
@@ -2413,9 +2144,6 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B1
   ResolvedUnitResult #0
@@ -2424,14 +2152,11 @@
     flags: exists isLibrary
 [stream]
   ResolvedUnitResult #0
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -2443,9 +2168,6 @@
     collector.getResolvedUnit('B2', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B2
   ResolvedUnitResult #2
@@ -2468,9 +2190,6 @@
     collector.getResolvedUnit('B2', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B2
   ResolvedUnitResult #3
@@ -2479,180 +2198,11 @@
     flags: exists isLibrary
 [stream]
   ResolvedUnitResult #3
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #4
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_library_added_part() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-part 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-part of 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    driver.addFile2(a);
-    driver.addFile2(b);
-    collector.getResolvedUnit('A1', a);
-
-    // Note, the library is resolved only once.
-    // Note, no separate `ErrorsResult` for `a` or `b`.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #0
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_library_augmentation() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-import augment 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-library augment 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getResolvedUnit('A1', a);
-    collector.getResolvedUnit('B1', b);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #0
-[future] getResolvedUnit
-  name: B1
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isAugmentation
-[stream]
-  ResolvedUnitResult #1
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_library_part() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-part 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-part of 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getResolvedUnit('A1', a);
-    collector.getResolvedUnit('B1', b);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #0
-[future] getResolvedUnit
-  name: B1
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
-[stream]
-  ResolvedUnitResult #1
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_library_pending_getErrors_part() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-part 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-part of 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getErrors('B1', b);
-    collector.getResolvedUnit('A1', a);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #0
-[future] getErrors
-  name: B1
-  ErrorsResult #1
+  ErrorsResult #4
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
     flags: isLibrary
-[stream]
-  ResolvedUnitResult #2
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
 [status] idle
 ''');
   }
@@ -2677,9 +2227,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.txt
-  library: /home/test/lib/a.txt
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -2764,186 +2311,6 @@
     ]);
   }
 
-  test_getResolvedUnit_part_library() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-part 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-part of 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getResolvedUnit('B1', b);
-    collector.getResolvedUnit('A1', a);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #0
-[future] getResolvedUnit
-  name: B1
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
-[stream]
-  ResolvedUnitResult #1
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_part_pending_getErrors_library() async {
-    final a = newFile('$testPackageLibPath/a.dart', r'''
-part 'b.dart';
-''');
-
-    final b = newFile('$testPackageLibPath/b.dart', r'''
-part of 'a.dart';
-''');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getErrors('A1', a);
-    collector.getResolvedUnit('B1', b);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/a.dart
-[future] getErrors
-  name: A1
-  ErrorsResult #0
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: isPart
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[future] getResolvedUnit
-  name: B1
-  ResolvedUnitResult #2
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
-[stream]
-  ResolvedUnitResult #2
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_pending_getErrors() async {
-    final a = newFile('$testPackageLibPath/a.dart', '');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getResolvedUnit('A1', a);
-    collector.getErrors('A2', a);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A1
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[future] getErrors
-  name: A2
-  ErrorsResult #1
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: isLibrary
-[stream]
-  ResolvedUnitResult #0
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_pending_getErrors2() async {
-    final a = newFile('$testPackageLibPath/a.dart', '');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    collector.getErrors('A1', a);
-    collector.getResolvedUnit('A2', a);
-
-    // Note, the library is resolved only once.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A2
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[future] getErrors
-  name: A1
-  ErrorsResult #1
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: isLibrary
-[stream]
-  ResolvedUnitResult #0
-[status] idle
-''');
-  }
-
-  test_getResolvedUnit_pending_getIndex() async {
-    final a = newFile('$testPackageLibPath/a.dart', '');
-
-    final driver = driverFor(testFile);
-    final collector = DriverEventCollector(driver);
-
-    unawaited(collector.getIndex('A1', a));
-    collector.getResolvedUnit('A2', a);
-
-    // Note, no separate `getIndex` result.
-    await assertEventsText(collector, r'''
-[status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[future] getResolvedUnit
-  name: A2
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-[future] getIndex
-  name: A1
-[stream]
-  ResolvedUnitResult #0
-[status] idle
-''');
-  }
-
   test_getResolvedUnit_thenRemove() async {
     final a = newFile('$testPackageLibPath/a.dart', '');
 
@@ -2959,9 +2326,6 @@
     // The future with the result still completes.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -2987,9 +2351,6 @@
     // Both futures complete.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -3041,22 +2402,17 @@
 
     collector.getResolvedLibrary('A1', a);
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
-    errors
-      7 +21 URI_DOES_NOT_EXIST
 [future] getResolvedLibrary
   name: A1
-  ResolvedLibraryResult #1
+  ResolvedLibraryResult #0
     element: package:test/a.dart
     units
-      ResolvedUnitResult #0
+      ResolvedUnitResult #1
+        path: /home/test/lib/a.dart
+        uri: package:test/a.dart
+        flags: exists isLibrary
+        errors
+          7 +21 URI_DOES_NOT_EXIST
 ''');
 
     collector.getUnitElement('A2', a);
@@ -3089,6 +2445,7 @@
     final driver = driverFor(testFile);
     final collector = DriverEventCollector(driver);
 
+    configuration.withOperations = true;
     configuration.libraryConfiguration.unitConfiguration.variableTypesSelector =
         (result) {
       switch (result.uriStr) {
@@ -3104,24 +2461,19 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedUnit
   name: B1
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
     selectedVariableTypes
       B: int
 [stream]
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
 [status] idle
 ''');
 
@@ -3136,24 +2488,19 @@
     collector.getResolvedUnit('B2', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #2
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedUnit
   name: B2
-  ResolvedUnitResult #3
+  ResolvedUnitResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
     selectedVariableTypes
       B: int
 [stream]
-  ResolvedUnitResult #3
+  ResolvedUnitResult #1
 [status] idle
 ''');
   }
@@ -3265,9 +2612,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -3299,9 +2643,6 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B1
   ResolvedUnitResult #1
@@ -3331,9 +2672,6 @@
     collector.getResolvedUnit('B2', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [future] getResolvedUnit
   name: B2
   ResolvedUnitResult #2
@@ -3429,36 +2767,20 @@
     // Process `a` so that we know that it's a library for `b`.
     collector.getErrors('A1', a);
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
-  file: /home/test/lib/hidden/a.dart
-  library: /home/test/lib/hidden/a.dart
 [future] getErrors
   name: A1
   ErrorsResult #0
     path: /home/test/lib/hidden/a.dart
     uri: package:test/hidden/a.dart
     flags: isLibrary
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/hidden/a.dart
-    uri: package:test/hidden/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #2
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
 ''');
 
     // `b` does not have errors in the context of `a`.
     collector.getErrors('B1', b);
     await assertEventsText(collector, r'''
-[operation] GetErrorsFromBytes
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/hidden/a.dart
 [future] getErrors
   name: B1
-  ErrorsResult #3
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: isPart
@@ -3484,30 +2806,32 @@
     driver.addFile2(a);
     driver.addFile2(b);
 
+    configuration.withOperations = true;
+
     // Because `a` is added, we know how to analyze `b`.
     // So, it has no errors.
     collector.getErrors('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/hidden/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/hidden/a.dart
-    uri: package:test/hidden/a.dart
-    flags: exists isLibrary
 [future] getErrors
   name: B1
-  ErrorsResult #1
+  ErrorsResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: isPart
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #1
+    path: /home/test/lib/hidden/a.dart
+    uri: package:test/hidden/a.dart
+    flags: isLibrary
+[stream]
+  ErrorsResult #2
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isPart
+    flags: isPart
 [status] idle
 ''');
   }
@@ -3527,30 +2851,22 @@
     final driver = driverFor(testFile);
     final collector = DriverEventCollector(driver);
 
+    configuration.withOperations = true;
+
     // We discover sibling files as libraries.
     // So, we know that `a` is the library of `b`.
     // So, no errors.
     collector.getErrors('B1', b);
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getErrors
   name: B1
-  ErrorsResult #1
+  ErrorsResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: isPart
-[stream]
-  ResolvedUnitResult #2
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
 ''');
   }
 
@@ -3569,11 +2885,13 @@
     final driver = driverFor(testFile);
     final collector = DriverEventCollector(driver);
 
+    configuration.withOperations = true;
+
     // We don't know that `a` is the library of `b`.
     // So, we treat it as its own library, has errors.
     collector.getErrors('B1', b);
     await assertEventsText(collector, r'''
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/b.dart
 [future] getErrors
@@ -3584,13 +2902,6 @@
     flags: isPart
     errors
       25 +1 CREATION_WITH_NON_TYPE
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
-    errors
-      25 +1 CREATION_WITH_NON_TYPE
 ''');
   }
 
@@ -3613,9 +2924,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/hidden/a.dart
-  library: /home/test/lib/hidden/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -3624,34 +2932,26 @@
     flags: exists isLibrary
 [stream]
   ResolvedUnitResult #0
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
 [status] idle
 ''');
 
+    configuration.withOperations = true;
+
     // We know that `b` is analyzed as part of `a`.
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/hidden/a.dart
-[stream]
-  ResolvedUnitResult #2
-    path: /home/test/lib/hidden/a.dart
-    uri: package:test/hidden/a.dart
-    flags: exists isLibrary
 [future] getResolvedUnit
   name: B1
-  ResolvedUnitResult #3
+  ResolvedUnitResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
 [stream]
-  ResolvedUnitResult #3
+  ResolvedUnitResult #1
 [status] idle
 ''');
   }
@@ -3675,26 +2975,28 @@
     driver.addFile2(a);
     driver.addFile2(b);
 
+    configuration.withOperations = true;
+
     // Because `a` is added, we know how to analyze `b`.
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/hidden/a.dart
-[stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/hidden/a.dart
-    uri: package:test/hidden/a.dart
-    flags: exists isLibrary
 [future] getResolvedUnit
   name: B1
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
 [stream]
-  ResolvedUnitResult #1
+  ResolvedUnitResult #0
+[stream]
+  ErrorsResult #1
+    path: /home/test/lib/hidden/a.dart
+    uri: package:test/hidden/a.dart
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -3714,12 +3016,14 @@
     final driver = driverFor(testFile);
     final collector = DriverEventCollector(driver);
 
+    configuration.withOperations = true;
+
     // We don't know that `a` is the library of `b`.
     // So, we treat it as its own library.
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/b.dart
 [future] getResolvedUnit
@@ -3750,14 +3054,11 @@
     // Analyze the library without the part.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
     errors
       26 +8 URI_DOES_NOT_EXIST
       7 +12 UNUSED_IMPORT
@@ -3777,22 +3078,19 @@
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/a.dart
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/a.dart
-    uri: package:test/a.dart
-    flags: exists isLibrary
 [future] getResolvedUnit
   name: B1
-  ResolvedUnitResult #2
+  ResolvedUnitResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
 [stream]
-  ResolvedUnitResult #2
+  ResolvedUnitResult #1
+[stream]
+  ErrorsResult #2
+    path: /home/test/lib/a.dart
+    uri: package:test/a.dart
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -3813,11 +3111,13 @@
     // Discover the library.
     driver.getFileSync2(a);
 
+    configuration.withOperations = true;
+
     // There is no library which `b` is a part of, so `A` is unresolved.
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/b.dart
 [future] getResolvedUnit
@@ -3843,11 +3143,13 @@
     final driver = driverFor(testFile);
     final collector = DriverEventCollector(driver);
 
+    configuration.withOperations = true;
+
     // There is no library which `b` is a part of, so `A` is unresolved.
     collector.getResolvedUnit('B1', b);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/b.dart
 [future] getResolvedUnit
@@ -3883,9 +3185,6 @@
     collector.getResolvedUnit('A1', a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/hidden/a.dart
-  library: /home/test/lib/hidden/a.dart
 [future] getResolvedUnit
   name: A1
   ResolvedUnitResult #0
@@ -3894,11 +3193,6 @@
     flags: exists isLibrary
 [stream]
   ResolvedUnitResult #0
-[stream]
-  ResolvedUnitResult #1
-    path: /home/test/lib/b.dart
-    uri: package:test/b.dart
-    flags: exists isPart
 [status] idle
 ''');
 
@@ -3932,6 +3226,8 @@
     driver.addFile2(a);
     driver.addFile2(b);
 
+    configuration.withOperations = true;
+
     // Because `a` is added, we know how to analyze `b`.
     collector.getUnitElement('B1', b);
     await assertEventsText(collector, r'''
@@ -3941,19 +3237,19 @@
   uri: package:test/b.dart
   flags: isPart
   enclosing: package:test/hidden/a.dart
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/hidden/a.dart
   library: /home/test/lib/hidden/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/hidden/a.dart
     uri: package:test/hidden/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isPart
+    flags: isPart
 [status] idle
 ''');
   }
@@ -3967,6 +3263,8 @@
     final driver = driverFor(testFile);
     final collector = DriverEventCollector(driver);
 
+    configuration.withOperations = true;
+
     // We don't know the library for `b`.
     // So, we treat it as its own library.
     collector.getUnitElement('B1', b);
@@ -4001,23 +3299,25 @@
     driver.addFile2(a);
     driver.addFile2(b);
 
+    configuration.withOperations = true;
+
     // We discover all added libraries.
     // So, we know that `a` is the library of `b`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/hidden/a.dart
   library: /home/test/lib/hidden/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/hidden/a.dart
     uri: package:test/hidden/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isPart
+    flags: isPart
 [status] idle
 ''');
   }
@@ -4044,23 +3344,25 @@
     driver.addFile2(b);
     driver.addFile2(a);
 
+    configuration.withOperations = true;
+
     // We discover all added libraries.
     // So, we know that `a` is the library of `b`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/hidden/a.dart
 [stream]
-  ResolvedUnitResult #0
-    path: /home/test/lib/hidden/a.dart
-    uri: package:test/hidden/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #1
+  ErrorsResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isPart
+    flags: isPart
+[stream]
+  ErrorsResult #1
+    path: /home/test/lib/hidden/a.dart
+    uri: package:test/hidden/a.dart
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -4088,23 +3390,25 @@
     driver.addFile2(a);
     driver.priorityFiles2 = [b];
 
+    configuration.withOperations = true;
+
     // We discover all added libraries.
     // So, we know that `a` is the library of `b`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/hidden/a.dart
 [stream]
   ResolvedUnitResult #0
-    path: /home/test/lib/hidden/a.dart
-    uri: package:test/hidden/a.dart
-    flags: exists isLibrary
-[stream]
-  ResolvedUnitResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
     flags: exists isPart
+[stream]
+  ErrorsResult #1
+    path: /home/test/lib/hidden/a.dart
+    uri: package:test/hidden/a.dart
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -4120,18 +3424,20 @@
 
     driver.addFile2(b);
 
+    configuration.withOperations = true;
+
     // There is no library for `b`.
     // So, we analyze `b` as its own library.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isPart
+    flags: isPart
     errors
       25 +1 CREATION_WITH_NON_TYPE
 [status] idle
@@ -4150,11 +3456,13 @@
     driver.addFile2(b);
     driver.priorityFiles2 = [b];
 
+    configuration.withOperations = true;
+
     // There is no library for `b`.
     // So, we analyze `b` as its own library.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
+[operation] computeAnalysisResult
   file: /home/test/lib/b.dart
   library: /home/test/lib/b.dart
 [stream]
@@ -4179,14 +3487,11 @@
     // Initial analysis.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -4196,14 +3501,11 @@
     // We analyze `a` again.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -4244,9 +3546,6 @@
     // We have results for both `a` and `b`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #0
     path: /home/test/lib/a.dart
@@ -4254,9 +3553,6 @@
     flags: exists isLibrary
     selectedVariableTypes
       A: int
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
   ResolvedUnitResult #1
     path: /home/test/lib/b.dart
@@ -4279,9 +3575,6 @@
     // But the change causes `a` to be reanalyzed.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
   ResolvedUnitResult #2
     path: /home/test/lib/a.dart
@@ -4332,22 +3625,16 @@
     // No errors in `b`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -4356,14 +3643,11 @@
     driver.removeFile2(a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #2
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
     errors
       7 +8 URI_DOES_NOT_EXIST
       31 +1 CREATION_WITH_NON_TYPE
@@ -4422,54 +3706,36 @@
     // Note, `f` has an error.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/c.dart
-  library: /home/test/lib/c.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #2
     path: /home/test/lib/c.dart
     uri: package:test/c.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/d.dart
-  library: /home/test/lib/d.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #3
+  ErrorsResult #3
     path: /home/test/lib/d.dart
     uri: package:test/d.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/e.dart
-  library: /home/test/lib/e.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #4
+  ErrorsResult #4
     path: /home/test/lib/e.dart
     uri: package:test/e.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/f.dart
-  library: /home/test/lib/f.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #5
+  ErrorsResult #5
     path: /home/test/lib/f.dart
     uri: package:test/f.dart
-    flags: exists isLibrary
+    flags: isLibrary
     errors
       57 +1 EXTENDS_NON_CLASS
 [status] idle
@@ -4487,56 +3753,38 @@
     // 4. Then the rest, in order of adding.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
 [stream]
-  ResolvedUnitResult #6
+  ErrorsResult #6
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/d.dart
-  library: /home/test/lib/d.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #7
+  ErrorsResult #7
     path: /home/test/lib/d.dart
     uri: package:test/d.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/f.dart
-  library: /home/test/lib/f.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #8
+  ErrorsResult #8
     path: /home/test/lib/f.dart
     uri: package:test/f.dart
-    flags: exists isLibrary
+    flags: isLibrary
     errors
       57 +1 EXTENDS_NON_CLASS
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #9
+  ErrorsResult #9
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/c.dart
-  library: /home/test/lib/c.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #10
+  ErrorsResult #10
     path: /home/test/lib/c.dart
     uri: package:test/c.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/e.dart
-  library: /home/test/lib/e.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #11
+  ErrorsResult #11
     path: /home/test/lib/e.dart
     uri: package:test/e.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -4575,46 +3823,31 @@
     // Initial analysis, all files analyzed in order of adding.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/c.dart
-  library: /home/test/lib/c.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #2
     path: /home/test/lib/c.dart
     uri: package:test/c.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/d.dart
-  library: /home/test/lib/d.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #3
+  ErrorsResult #3
     path: /home/test/lib/d.dart
     uri: package:test/d.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/e.dart
-  library: /home/test/lib/e.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #4
+  ErrorsResult #4
     path: /home/test/lib/e.dart
     uri: package:test/e.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -4632,38 +3865,26 @@
     // Then `d` and `e` because they import `a` and `b`.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #5
+  ErrorsResult #5
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #6
+  ErrorsResult #6
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/d.dart
-  library: /home/test/lib/d.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #7
+  ErrorsResult #7
     path: /home/test/lib/d.dart
     uri: package:test/d.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/e.dart
-  library: /home/test/lib/e.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #8
+  ErrorsResult #8
     path: /home/test/lib/e.dart
     uri: package:test/e.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -4683,14 +3904,11 @@
     // Initial analysis.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -4705,14 +3923,11 @@
     driver.changeFile2(a);
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
     errors
       10 +1 EXPECTED_TOKEN
 [status] idle
@@ -4737,22 +3952,16 @@
     // Initial analysis.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
-[operation] AnalyzeFile
-  file: /home/test/lib/b.dart
-  library: /home/test/lib/b.dart
+    flags: isLibrary
 [stream]
-  ResolvedUnitResult #1
+  ErrorsResult #1
     path: /home/test/lib/b.dart
     uri: package:test/b.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
 
@@ -4765,14 +3974,11 @@
     // Only `a` is analyzed, `b` is not affected.
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #2
+  ErrorsResult #2
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -4787,14 +3993,11 @@
 
     await assertEventsText(collector, r'''
 [status] analyzing
-[operation] AnalyzeFile
-  file: /home/test/lib/a.dart
-  library: /home/test/lib/a.dart
 [stream]
-  ResolvedUnitResult #0
+  ErrorsResult #0
     path: /home/test/lib/a.dart
     uri: package:test/a.dart
-    flags: exists isLibrary
+    flags: isLibrary
 [status] idle
 ''');
   }
@@ -5153,17 +4356,6 @@
     }));
   }
 
-  Future<AnalysisDriverUnitIndex?> getIndex(String name, File file) async {
-    final value = await driver.getIndex(file.path);
-    events.add(
-      GetIndexEvent(
-        name: name,
-        result: value,
-      ),
-    );
-    return value;
-  }
-
   void getLibraryByUri(String name, String uriStr) {
     final future = driver.getLibraryByUri(uriStr);
     unawaited(future.then((value) {
diff --git a/pkg/analyzer/test/src/dart/analysis/result_printer.dart b/pkg/analyzer/test/src/dart/analysis/result_printer.dart
index bfb5252..7233658 100644
--- a/pkg/analyzer/test/src/dart/analysis/result_printer.dart
+++ b/pkg/analyzer/test/src/dart/analysis/result_printer.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/src/dart/analysis/driver_event.dart' as events;
 import 'package:analyzer/src/dart/analysis/results.dart';
 import 'package:analyzer/src/dart/analysis/status.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/utilities/extensions/file_system.dart';
 import 'package:test/test.dart';
 
@@ -83,8 +82,6 @@
         _writeGetCachedResolvedUnit(event);
       case GetErrorsEvent():
         _writeErrorsEvent(event);
-      case GetIndexEvent():
-        _writeIndexEvent(event);
       case GetLibraryByUriEvent():
         _writeGetLibraryByUriEvent(event);
       case GetResolvedLibraryEvent():
@@ -161,13 +158,6 @@
     });
   }
 
-  void _writeIndexEvent(GetIndexEvent event) {
-    sink.writelnWithIndent('[future] getIndex');
-    sink.withIndent(() {
-      sink.writelnWithIndent('name: ${event.name}');
-    });
-  }
-
   void _writeLibraryElementResult(SomeLibraryElementResult result) {
     switch (result) {
       case CannotResolveUriResult():
@@ -218,27 +208,32 @@
   void _writeResultStreamEvent(ResultStreamEvent event) {
     final object = event.object;
     switch (object) {
-      case events.AnalyzeFile():
-        sink.writelnWithIndent('[operation] AnalyzeFile');
+      case events.ComputeAnalysis():
+        if (!configuration.withOperations) {
+          return;
+        }
+        sink.writelnWithIndent('[operation] computeAnalysisResult');
         sink.withIndent(() {
           final file = object.file.resource;
           sink.writelnWithIndent('file: ${file.posixPath}');
           final libraryFile = object.library.file.resource;
           sink.writelnWithIndent('library: ${libraryFile.posixPath}');
         });
+      case events.ComputeResolvedLibrary():
+        if (!configuration.withOperations) {
+          return;
+        }
+        sink.writelnWithIndent('[operation] computeResolvedLibrary');
+        sink.withIndent(() {
+          final fileState = object.library.file;
+          final file = fileState.resource;
+          sink.writelnWithIndent('library: ${file.posixPath}');
+        });
       case ErrorsResult():
         sink.writelnWithIndent('[stream]');
         sink.withIndent(() {
           _writeErrorsResult(object);
         });
-      case events.GetErrorsFromBytes():
-        sink.writelnWithIndent('[operation] GetErrorsFromBytes');
-        sink.withIndent(() {
-          final file = object.file.resource;
-          sink.writelnWithIndent('file: ${file.posixPath}');
-          final libraryFile = object.library.file.resource;
-          sink.writelnWithIndent('library: ${libraryFile.posixPath}');
-        });
       case ResolvedUnitResult():
         sink.writelnWithIndent('[stream]');
         sink.withIndent(() {
@@ -288,6 +283,7 @@
 }
 
 class DriverEventsPrinterConfiguration {
+  var withOperations = false;
   var libraryConfiguration = ResolvedLibraryResultPrinterConfiguration();
   var unitElementConfiguration = UnitElementPrinterConfiguration();
 }
@@ -314,17 +310,6 @@
   });
 }
 
-/// The result of `getIndex`.
-final class GetIndexEvent extends DriverEvent {
-  final String name;
-  final AnalysisDriverUnitIndex? result;
-
-  GetIndexEvent({
-    required this.name,
-    required this.result,
-  });
-}
-
 /// The result of `getLibraryByUri`.
 final class GetLibraryByUriEvent extends DriverEvent {
   final String name;