Version 2.18.0-6.0.dev

Merge commit '178a147d0af3541ec60457db6623c4bbbed12d13' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
index f84c677..fce5689 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/file_state_filter.dart';
 
@@ -73,8 +74,13 @@
         continue;
       }
 
-      var element = await analysisDriver.getLibraryByFile(file);
-      if (element == null || importedLibraries.contains(element)) {
+      var elementResult = await analysisDriver.getLibraryByUri(file.uriStr);
+      if (elementResult is! LibraryElementResult) {
+        continue;
+      }
+
+      var element = elementResult.element;
+      if (importedLibraries.contains(element)) {
         continue;
       }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/dart/extensions.dart b/pkg/analysis_server/lib/src/services/correction/fix/dart/extensions.dart
index 54b4d6b..1a74734 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/dart/extensions.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/dart/extensions.dart
@@ -36,12 +36,12 @@
         continue;
       }
 
-      var libraryElement = await analysisDriver.getLibraryByFile(file);
-      if (libraryElement == null) {
+      var elementResult = await analysisDriver.getLibraryByUri(file.uriStr);
+      if (elementResult is! LibraryElementResult) {
         continue;
       }
 
-      yield libraryElement;
+      yield elementResult.element;
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart b/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
index 7d66ece..520fe28 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
@@ -39,12 +39,12 @@
         continue;
       }
 
-      var libraryElement = await analysisDriver.getLibraryByFile(file);
-      if (libraryElement == null) {
+      var elementResult = await analysisDriver.getLibraryByUri(file.uriStr);
+      if (elementResult is! LibraryElementResult) {
         continue;
       }
 
-      addElement(result, libraryElement, baseName);
+      addElement(result, elementResult.element, baseName);
     }
 
     return result;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 695ffbf..ff7217a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/exception/exception.dart';
@@ -83,7 +82,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 213;
+  static const int DATA_VERSION = 214;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
@@ -693,22 +692,6 @@
     return completer.future;
   }
 
-  /// Return [LibraryElementResult] for the given [file], or `null` if the
-  /// file is a part.
-  Future<LibraryElement?> getLibraryByFile(FileState file) async {
-    if (file.isPart) {
-      return null;
-    }
-
-    var element = libraryContext.getLibraryElementIfReady(file.uriStr);
-    if (element != null) {
-      return element;
-    }
-
-    await libraryContext.load(file);
-    return libraryContext.getLibraryElement(file.uri);
-  }
-
   /// Return a [Future] that completes with [LibraryElementResult] for the given
   /// [uri], which is either resynthesized from the provided external summary
   /// store, or built for a file to which the given [uri] is resolved.
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index ac46094..044b599 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -788,9 +788,9 @@
     var filesProcessed = 0;
     try {
       for (var file in knownFiles) {
-        var libraryElement = await driver.getLibraryByFile(file);
-        if (libraryElement != null) {
-          _addUnits(file, libraryElement.units);
+        var elementResult = await driver.getLibraryByUri(file.uriStr);
+        if (elementResult is LibraryElementResult) {
+          _addUnits(file, elementResult.element.units);
         }
 
         // Periodically yield and check cancellation token.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d6f24f4..c99be86 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -3622,6 +3622,8 @@
   @override
   late TypeSystemImpl typeSystem;
 
+  late final List<Reference> exportedReferences;
+
   LibraryElementLinkedData? linkedData;
 
   @override
@@ -3724,7 +3726,10 @@
     final linkedData = this.linkedData;
     if (linkedData != null) {
       var elements = linkedData.elementFactory;
-      return _exportNamespace = elements.buildExportNamespace(source.uri);
+      return _exportNamespace = elements.buildExportNamespace(
+        source.uri,
+        exportedReferences,
+      );
     }
 
     return _exportNamespace!;
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index b58c5c6..4fdbad0 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -409,8 +409,6 @@
   final Uint32List _classMembersLengths;
   int _classMembersLengthsIndex = 0;
 
-  late List<Reference> exports;
-
   LibraryReader._({
     required LinkedElementFactory elementFactory,
     required SummaryDataReader reader,
@@ -464,7 +462,7 @@
     }
 
     var exportsIndexList = _reader.readUInt30List();
-    exports = exportsIndexList
+    libraryElement.exportedReferences = exportsIndexList
         .map((index) => _referenceReader.referenceOfIndex(index))
         .toList();
 
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 6cc91be..7a4cbf6 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -91,10 +91,7 @@
     );
   }
 
-  void writeLibraryElement(
-    LibraryElementImpl libraryElement,
-    List<Reference> exports,
-  ) {
+  void writeLibraryElement(LibraryElementImpl libraryElement) {
     var libraryOffset = _sink.offset;
     _classMembersLengths = <int>[];
 
@@ -111,7 +108,7 @@
     for (var unitElement in libraryElement.units) {
       _writeUnitElement(unitElement);
     }
-    _writeReferences(exports);
+    _writeReferences(libraryElement.exportedReferences);
 
     _libraries.add(
       _Library(
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index ee3209b..323b31e 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -48,7 +48,6 @@
   final Scope exportScope = Scope.top();
 
   final List<Export> exporters = [];
-  late final List<Reference> exports;
 
   LibraryBuilder._({
     required this.linker,
@@ -82,13 +81,16 @@
       if (exportedBuilder != null) {
         exportedBuilder.exporters.add(export);
       } else {
-        var references = linker.elementFactory.exportsOfLibrary('$exportedUri');
-        for (var reference in references) {
-          var name = reference.name;
-          if (reference.isSetter) {
-            export.addToExportScope('$name=', reference);
-          } else {
-            export.addToExportScope(name, reference);
+        var exported = linker.elementFactory.libraryOfUri('$exportedUri');
+        if (exported != null) {
+          var exportedReferences = exported.exportedReferences;
+          for (var reference in exportedReferences) {
+            var name = reference.name;
+            if (reference.isSetter) {
+              export.addToExportScope('$name=', reference);
+            } else {
+              export.addToExportScope(name, reference);
+            }
           }
         }
       }
@@ -190,8 +192,7 @@
   }
 
   void storeExportScope() {
-    exports = exportScope.map.values.toList();
-    linker.elementFactory.setExportsOfLibrary('$uri', exports);
+    element.exportedReferences = exportScope.map.values.toList();
 
     var definedNames = <String, Element>{};
     for (var entry in exportScope.map.entries) {
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index b76283b..d4b9866 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -241,10 +241,7 @@
     );
 
     for (var builder in builders.values) {
-      bundleWriter.writeLibraryElement(
-        builder.element,
-        builder.exports,
-      );
+      bundleWriter.writeLibraryElement(builder.element);
     }
 
     var writeWriterResult = bundleWriter.finish();
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 01ddaa6..64cb301 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -16,7 +16,6 @@
   AnalysisSessionImpl analysisSession;
   final Reference rootReference;
   final Map<String, LibraryReader> _libraryReaders = {};
-  final Map<String, List<Reference>> _exportsOfLibrary = {};
 
   bool isApplyingInformativeData = false;
 
@@ -41,10 +40,9 @@
     _libraryReaders.addAll(libraries);
   }
 
-  Namespace buildExportNamespace(Uri uri) {
+  Namespace buildExportNamespace(Uri uri, List<Reference> exportedReferences) {
     var exportedNames = <String, Element>{};
 
-    var exportedReferences = exportsOfLibrary('$uri');
     for (var exportedReference in exportedReferences) {
       var element = elementOfReference(exportedReference);
       // TODO(scheglov) Remove after https://github.com/dart-lang/sdk/issues/41212
@@ -146,17 +144,6 @@
     return element;
   }
 
-  List<Reference> exportsOfLibrary(String uriStr) {
-    var exports = _exportsOfLibrary[uriStr];
-    if (exports != null) return exports;
-
-    // TODO(scheglov) Use [setExportsOfLibrary] instead
-    var library = _libraryReaders[uriStr];
-    if (library == null) return const [];
-
-    return library.exports;
-  }
-
   bool hasLibrary(String uriStr) {
     // We already have the element, linked or read.
     if (rootReference[uriStr]?.element is LibraryElementImpl) {
@@ -196,7 +183,6 @@
   /// any session level caches.
   void removeLibraries(Set<String> uriStrSet) {
     for (var uriStr in uriStrSet) {
-      _exportsOfLibrary.remove(uriStr);
       _libraryReaders.remove(uriStr);
       rootReference.removeChild(uriStr);
     }
@@ -233,12 +219,6 @@
     }
   }
 
-  /// Set exports of the library with [uriStr], after building exports during
-  /// linking, or after reading a linked bundle.
-  void setExportsOfLibrary(String uriStr, List<Reference> exports) {
-    _exportsOfLibrary[uriStr] = exports;
-  }
-
   void setLibraryTypeSystem(LibraryElementImpl libraryElement) {
     // During linking we create libraries when typeProvider is not ready.
     // And if we link dart:core and dart:async, we cannot create it.
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 e64b61a..930ee37 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -188,6 +190,56 @@
     _assertNoLinkedCycles();
   }
 
+  test_getLibraryByUri_invalidated_exportNamespace() async {
+    useEmptyByteStore();
+
+    var a = newFile2('$testPackageLibPath/a.dart', 'const a1 = 0;');
+    newFile2('$testPackageLibPath/b.dart', r'''
+import 'a.dart';
+''');
+
+    var driver = driverFor(testFilePath);
+
+    // Link both libraries, keep them.
+    await driver.getLibraryByUri('package:test/a.dart');
+    await driver.getLibraryByUri('package:test/b.dart');
+
+    // Discard both libraries.
+    driver.changeFile(a.path);
+
+    // Read `package:test/a.dart` from bytes.
+    // Don't ask for `exportNamespace`, this used to keep it in the state
+    // "should be asked from LinkedElementLibrary", which will ask it
+    // from the `LibraryReader` current at the moment of `exportNamespace`
+    // access, not necessary the same that created this instance.
+    final aResult = await driver.getLibraryByUri('package:test/a.dart');
+    final aElement = (aResult as LibraryElementResult).element;
+
+    // The element is valid at this point.
+    expect(driver.isValidLibraryElement(aElement), isTrue);
+
+    // Discard both libraries.
+    driver.changeFile(a.path);
+
+    // Read `package:test/b.dart`, actually create `LibraryElement` for it.
+    // We used to create only `LibraryReader` for `package:test/a.dart`.
+    await driver.getLibraryByUri('package:test/b.dart');
+
+    // The element is not valid anymore.
+    expect(driver.isValidLibraryElement(aElement), isFalse);
+
+    // But its `exportNamespace` can be accessed.
+    expect(aElement.exportNamespace.definedNames, isNotEmpty);
+
+    // TODO(scheglov) This is not quite right.
+    // When we return `LibraryElement` that is not fully read, and read
+    // anything lazily, we can be in a situation when there was a change,
+    // and an imported library does not define a referenced element anymore.
+    // But there is still a client that holds this `LibraryElement`, and
+    // its summary information says "get element X from `package:Y"; and when
+    // we attempt to get it, the might be no `X` in `Y`.
+  }
+
   test_lint_dependOnReferencedPackage_update_pubspec_addDependency() async {
     useEmptyByteStore();
 
@@ -323,3 +375,9 @@
     return errorsResult.errors;
   }
 }
+
+extension on AnalysisDriver {
+  bool isValidLibraryElement(LibraryElement element) {
+    return identical(element.session, currentSession);
+  }
+}
diff --git a/tools/VERSION b/tools/VERSION
index a959df0..fd2f0a9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 5
+PRERELEASE 6
 PRERELEASE_PATCH 0
\ No newline at end of file