Cache getResolvedLibrary() results for priority libraries.

Bug: https://github.com/dart-lang/sdk/issues/47968
Change-Id: I123e8cea6ed629dd3fc1379e7e3a86ae5685d65e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306302
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index faa3e5e..fa35d6c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -223,6 +223,10 @@
   /// Cached results for [_priorityFiles].
   final Map<String, ResolvedUnitResult> _priorityResults = {};
 
+  /// Cached results of [getResolvedLibrary].
+  final Map<LibraryFileKind, ResolvedLibraryResultImpl> _resolvedLibraryCache =
+      {};
+
   /// The controller for the [exceptions] stream.
   final StreamController<ExceptionResult> _exceptionController =
       StreamController<ExceptionResult>();
@@ -484,6 +488,7 @@
     }
     if (file_paths.isDart(resourceProvider.pathContext, path)) {
       _priorityResults.clear();
+      _resolvedLibraryCache.clear();
       _pendingFileChanges.add(
         _FileChange(path, _FileChangeKind.add),
       );
@@ -575,6 +580,7 @@
     }
     if (file_paths.isDart(resourceProvider.pathContext, path)) {
       _priorityResults.clear();
+      _resolvedLibraryCache.clear();
       _pendingFileChanges.add(
         _FileChange(path, _FileChangeKind.change),
       );
@@ -1219,6 +1225,7 @@
     if (file_paths.isDart(resourceProvider.pathContext, path)) {
       _lastProducedSignatures.remove(path);
       _priorityResults.clear();
+      _resolvedLibraryCache.clear();
       _pendingFileChanges.add(
         _FileChange(path, _FileChangeKind.remove),
       );
@@ -1438,6 +1445,11 @@
   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++;
@@ -1466,11 +1478,17 @@
         );
       }
 
-      return ResolvedLibraryResultImpl(
+      final result = ResolvedLibraryResultImpl(
         session: currentSession,
         element: resolvedUnits.first.libraryElement,
         units: resolvedUnits,
       );
+
+      if (_isLibraryWithPriorityFile(library)) {
+        _resolvedLibraryCache[library] = result;
+      }
+
+      return result;
     });
   }
 
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 740dcac..13e0062 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1957,6 +1957,28 @@
     expect(result.units[0].errors, isEmpty);
   }
 
+  test_getResolvedLibrary_cachePriority() async {
+    final a = newFile('/test/lib/a.dart', '');
+
+    driver.priorityFiles = [a.path];
+
+    final result1 = await driver.getResolvedLibrary(a.path);
+    result1 as ResolvedLibraryResult;
+
+    final testView = driver.testView!;
+    await waitForIdleWithoutExceptions();
+    testView.numOfAnalyzedLibraries = 0;
+    allResults.clear();
+
+    // Ask again, the same cache instance should be returned.
+    final result2 = await driver.getResolvedLibrary(a.path);
+    expect(result2, same(result1));
+
+    // No new analysis, no results into the stream.
+    expect(testView.numOfAnalyzedLibraries, isZero);
+    expect(allResults, isEmpty);
+  }
+
   test_getResolvedLibrary_invalidPath_notAbsolute() async {
     var result = await driver.getResolvedLibrary('not_absolute.dart');
     expect(result, isA<InvalidPathResult>());