Use ImportDirectiveState and others in LibraryAnalyzer.

Change-Id: I9cdeedcb8f3e9b35814bb457547bb52ac85f7f4c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250263
Reviewed-by: Brian Wilkerson <brianwilkerson@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 bd9d063..cb70639 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1330,7 +1330,6 @@
         var results = LibraryAnalyzer(
           analysisOptions as AnalysisOptionsImpl,
           declaredVariables,
-          sourceFactory,
           libraryContext.elementFactory.libraryOfUri2(library.file.uri),
           libraryContext.elementFactory.analysisSession.inheritanceManager,
           library,
@@ -1397,7 +1396,6 @@
       var unitResults = LibraryAnalyzer(
               analysisOptions as AnalysisOptionsImpl,
               declaredVariables,
-              sourceFactory,
               libraryContext.elementFactory.libraryOfUri2(library.file.uri),
               libraryContext.elementFactory.analysisSession.inheritanceManager,
               library,
@@ -1771,7 +1769,6 @@
     var analysisResult = LibraryAnalyzer(
       analysisOptions as AnalysisOptionsImpl,
       declaredVariables,
-      sourceFactory,
       libraryContext.elementFactory.libraryOfUri2(library.file.uri),
       libraryContext.elementFactory.analysisSession.inheritanceManager,
       library,
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 9fd787f..65fc403 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -131,12 +131,82 @@
   void dispose() {}
 }
 
-/// Information about a single `import` directive.
-class ExportDirectiveState extends DirectiveState {
+/// Meaning of a URI referenced in a directive.
+class DirectiveUri {
+  Source? get source => null;
+}
+
+/// [DirectiveUriWithUri] with URI that resolves to a [FileState].
+class DirectiveUriWithFile extends DirectiveUriWithUri {
+  final FileState file;
+
+  DirectiveUriWithFile({
+    required super.relativeUriStr,
+    required super.relativeUri,
+    required this.file,
+  });
+
+  @override
+  Source? get source => file.source;
+
+  @override
+  String toString() => '$file';
+}
+
+/// [DirectiveUriWithUri] with URI that resolves to a [InSummarySource].
+class DirectiveUriWithInSummarySource extends DirectiveUriWithUri {
+  @override
+  final InSummarySource source;
+
+  DirectiveUriWithInSummarySource({
+    required super.relativeUriStr,
+    required super.relativeUri,
+    required this.source,
+  });
+
+  @override
+  String toString() => '$source';
+}
+
+/// [DirectiveUri] for which we can get its relative URI string.
+class DirectiveUriWithString extends DirectiveUri {
+  final String relativeUriStr;
+
+  DirectiveUriWithString({
+    required this.relativeUriStr,
+  });
+
+  @override
+  String toString() => relativeUriStr;
+}
+
+/// [DirectiveUriWithString] that can be parsed into a relative URI.
+class DirectiveUriWithUri extends DirectiveUriWithString {
+  final Uri relativeUri;
+
+  DirectiveUriWithUri({
+    required super.relativeUriStr,
+    required this.relativeUri,
+  });
+
+  bool get isValid {
+    return relativeUri.path.isNotEmpty;
+  }
+
+  @override
+  String toString() => '$relativeUri';
+}
+
+/// Information about a single `export` directive.
+class ExportDirectiveState<U extends DirectiveUri> extends DirectiveState {
   final UnlinkedNamespaceDirective directive;
+  final U selectedUri;
+  final NamespaceDirectiveUris uris;
 
   ExportDirectiveState({
     required this.directive,
+    required this.selectedUri,
+    required this.uris,
   });
 
   /// If [exportedSource] corresponds to a library, returns it.
@@ -151,19 +221,21 @@
 }
 
 /// [ExportDirectiveWithUri] that has a valid URI that references a file.
-class ExportDirectiveWithFile extends ExportDirectiveWithUri {
+class ExportDirectiveWithFile
+    extends ExportDirectiveWithUri<DirectiveUriWithFile> {
   final LibraryOrAugmentationFileKind container;
-  final FileState exportedFile;
 
   ExportDirectiveWithFile({
     required this.container,
     required super.directive,
-    required this.exportedFile,
-    required super.selectedUriStr,
+    required super.selectedUri,
+    required super.uris,
   }) {
     exportedFile.referencingFiles.add(container.file);
   }
 
+  FileState get exportedFile => selectedUri.file;
+
   /// Returns [exportedFile] if it is a library.
   LibraryFileStateKind? get exportedLibrary {
     final kind = exportedFile.kind;
@@ -191,14 +263,12 @@
 }
 
 /// [ExportDirectiveWithUri] with a URI that resolves to [InSummarySource].
-class ExportDirectiveWithInSummarySource extends ExportDirectiveWithUri {
-  @override
-  final InSummarySource exportedSource;
-
+class ExportDirectiveWithInSummarySource
+    extends ExportDirectiveWithUri<DirectiveUriWithInSummarySource> {
   ExportDirectiveWithInSummarySource({
     required super.directive,
-    required this.exportedSource,
-    required super.selectedUriStr,
+    required super.selectedUri,
+    required super.uris,
   });
 
   @override
@@ -209,15 +279,18 @@
       return null;
     }
   }
+
+  @override
+  InSummarySource get exportedSource => selectedUri.source;
 }
 
-/// [ExportDirectiveState] that has a valid URI string.
-class ExportDirectiveWithUri extends ExportDirectiveState {
-  final String selectedUriStr;
-
+/// [ExportDirectiveState] that has a valid URI.
+class ExportDirectiveWithUri<U extends DirectiveUriWithUri>
+    extends ExportDirectiveState<U> {
   ExportDirectiveWithUri({
     required super.directive,
-    required this.selectedUriStr,
+    required super.selectedUri,
+    required super.uris,
   });
 }
 
@@ -593,6 +666,70 @@
     return '$uri = $path';
   }
 
+  DirectiveUri _buildDirectiveUri(String? relativeUriStr) {
+    if (relativeUriStr == null) {
+      return DirectiveUri();
+    }
+
+    final relativeUri = Uri.tryParse(relativeUriStr);
+    if (relativeUri == null) {
+      return DirectiveUriWithString(
+        relativeUriStr: relativeUriStr,
+      );
+    }
+
+    final absoluteUri = resolveRelativeUri(uri, relativeUri);
+    return _fsState.getFileForUri(absoluteUri).map(
+      (file) {
+        if (file != null) {
+          return DirectiveUriWithFile(
+            relativeUriStr: relativeUriStr,
+            relativeUri: relativeUri,
+            file: file,
+          );
+        } else {
+          return DirectiveUriWithUri(
+            relativeUriStr: relativeUriStr,
+            relativeUri: relativeUri,
+          );
+        }
+      },
+      (externalLibrary) {
+        return DirectiveUriWithInSummarySource(
+          relativeUriStr: relativeUriStr,
+          relativeUri: relativeUri,
+          source: externalLibrary.source,
+        );
+      },
+    );
+  }
+
+  /// TODO(scheglov) move to _fsState?
+  NamespaceDirectiveUris _buildNamespaceDirectiveUris(
+    UnlinkedNamespaceDirective directive,
+  ) {
+    final primaryUri = _buildDirectiveUri(directive.uri);
+
+    final configurationUris = <DirectiveUri>[];
+    DirectiveUri? selectedConfigurationUri;
+    for (final configuration in directive.configurations) {
+      final configurationUri = _buildDirectiveUri(configuration.uri);
+      configurationUris.add(configurationUri);
+      // Maybe select this URI.
+      final name = configuration.name;
+      final value = configuration.valueOrTrue;
+      if (_fsState._declaredVariables.get(name) == value) {
+        selectedConfigurationUri ??= configurationUri;
+      }
+    }
+
+    return NamespaceDirectiveUris(
+      primary: primaryUri,
+      configurations: configurationUris,
+      selected: selectedConfigurationUri ?? primaryUri,
+    );
+  }
+
   /// Return the [FileState] for the given [relativeUri], or `null` if the
   /// URI cannot be parsed, cannot correspond any file, etc.
   Either2<FileState?, ExternalLibrary> _fileForRelativeUri(
@@ -1092,17 +1229,13 @@
 
     _uriToFile.remove(file.uri);
 
-    // The removed file does not reference other file anymore.
-    for (var referencedFile in file.directReferencedFiles) {
-      referencedFile.referencingFiles.remove(file);
-    }
+    // The removed file does not reference other files anymore.
+    file._kind?.dispose();
 
     // Recursively remove files that reference the removed file.
     for (var reference in file.referencingFiles.toList()) {
       changeFile(reference.path, removedFiles);
     }
-
-    file._kind?.dispose();
   }
 
   /// Collected files that transitively reference a file with the [path].
@@ -1454,11 +1587,14 @@
 }
 
 /// Information about a single `import augment` directive.
-class ImportAugmentationDirectiveState extends DirectiveState {
+class ImportAugmentationDirectiveState<U extends DirectiveUri>
+    extends DirectiveState {
   final UnlinkedImportAugmentationDirective directive;
+  final U uri;
 
   ImportAugmentationDirectiveState({
     required this.directive,
+    required this.uri,
   });
 
   /// Returns a [Source] that is referenced by this directive.
@@ -1469,14 +1605,13 @@
 
 /// [ImportAugmentationWithUri] that has a valid URI that references a file.
 class ImportAugmentationDirectiveWithFile
-    extends ImportAugmentationDirectiveState {
+    extends ImportAugmentationWithUri<DirectiveUriWithFile> {
   final LibraryOrAugmentationFileKind container;
-  final FileState importedFile;
 
   ImportAugmentationDirectiveWithFile({
     required this.container,
     required super.directive,
-    required this.importedFile,
+    required super.uri,
   }) {
     importedFile.referencingFiles.add(container.file);
   }
@@ -1491,6 +1626,8 @@
     return null;
   }
 
+  FileState get importedFile => uri.file;
+
   @override
   Source? get importedSource => importedFile.source;
 
@@ -1501,21 +1638,24 @@
 }
 
 /// [ImportAugmentationDirectiveState] that has a valid URI.
-class ImportAugmentationWithUri extends ImportAugmentationDirectiveState {
-  final String uriStr;
-
+class ImportAugmentationWithUri<U extends DirectiveUriWithUri>
+    extends ImportAugmentationDirectiveState<U> {
   ImportAugmentationWithUri({
     required super.directive,
-    required this.uriStr,
+    required super.uri,
   });
 }
 
 /// Information about a single `import` directive.
-class ImportDirectiveState extends DirectiveState {
+class ImportDirectiveState<U extends DirectiveUri> extends DirectiveState {
   final UnlinkedNamespaceDirective directive;
+  final U selectedUri;
+  final NamespaceDirectiveUris uris;
 
   ImportDirectiveState({
     required this.directive,
+    required this.selectedUri,
+    required this.uris,
   });
 
   /// If [importedSource] corresponds to a library, returns it.
@@ -1532,19 +1672,21 @@
 }
 
 /// [ImportDirectiveWithUri] that has a valid URI that references a file.
-class ImportDirectiveWithFile extends ImportDirectiveWithUri {
+class ImportDirectiveWithFile
+    extends ImportDirectiveWithUri<DirectiveUriWithFile> {
   final LibraryOrAugmentationFileKind container;
-  final FileState importedFile;
 
   ImportDirectiveWithFile({
     required this.container,
     required super.directive,
-    required this.importedFile,
-    required super.selectedUriStr,
+    required super.selectedUri,
+    required super.uris,
   }) {
     importedFile.referencingFiles.add(container.file);
   }
 
+  FileState get importedFile => selectedUri.file;
+
   /// Returns [importedFile] if it is a library.
   LibraryFileStateKind? get importedLibrary {
     final kind = importedFile.kind;
@@ -1572,14 +1714,12 @@
 }
 
 /// [ImportDirectiveWithUri] with a URI that resolves to [InSummarySource].
-class ImportDirectiveWithInSummarySource extends ImportDirectiveWithUri {
-  @override
-  final InSummarySource importedSource;
-
+class ImportDirectiveWithInSummarySource
+    extends ImportDirectiveWithUri<DirectiveUriWithInSummarySource> {
   ImportDirectiveWithInSummarySource({
     required super.directive,
-    required this.importedSource,
-    required super.selectedUriStr,
+    required super.selectedUri,
+    required super.uris,
   });
 
   @override
@@ -1590,15 +1730,18 @@
       return null;
     }
   }
+
+  @override
+  InSummarySource get importedSource => selectedUri.source;
 }
 
 /// [ImportDirectiveState] that has a valid URI.
-class ImportDirectiveWithUri extends ImportDirectiveState {
-  final String selectedUriStr;
-
+class ImportDirectiveWithUri<U extends DirectiveUriWithUri>
+    extends ImportDirectiveState<U> {
   ImportDirectiveWithUri({
     required super.directive,
-    required this.selectedUriStr,
+    required super.selectedUri,
+    required super.uris,
   });
 }
 
@@ -1658,37 +1801,24 @@
 
   List<PartDirectiveState> get parts {
     return _parts ??= file.unlinked2.parts.map((directive) {
-      final uriStr = directive.uri;
-      if (uriStr != null) {
-        return file._fileForRelativeUri(uriStr).map(
-          (refFile) {
-            if (refFile != null) {
-              return PartDirectiveWithFile(
-                library: this,
-                directive: directive,
-                includedFile: refFile,
-                uriStr: uriStr,
-              );
-            } else {
-              return PartDirectiveWithUri(
-                library: this,
-                directive: directive,
-                uriStr: uriStr,
-              );
-            }
-          },
-          (externalLibrary) {
-            return PartDirectiveWithUri(
-              library: this,
-              directive: directive,
-              uriStr: uriStr,
-            );
-          },
+      final uri = file._buildDirectiveUri(directive.uri);
+      if (uri is DirectiveUriWithFile) {
+        return PartDirectiveWithFile(
+          library: this,
+          directive: directive,
+          uri: uri,
+        );
+      } else if (uri is DirectiveUriWithUri) {
+        return PartDirectiveWithUri(
+          library: this,
+          directive: directive,
+          uri: uri,
         );
       } else {
         return PartDirectiveState(
           library: this,
           directive: directive,
+          uri: uri,
         );
       }
     }).toList();
@@ -1750,105 +1880,90 @@
 
   List<ImportAugmentationDirectiveState> get augmentations {
     return _augmentations ??= file.unlinked2.augmentations.map((directive) {
-      final uriStr = directive.uri;
-      if (uriStr != null) {
-        return file._fileForRelativeUri(uriStr).map(
-          (refFile) {
-            if (refFile != null) {
-              return ImportAugmentationDirectiveWithFile(
-                container: this,
-                directive: directive,
-                importedFile: refFile,
-              );
-            } else {
-              return ImportAugmentationWithUri(
-                directive: directive,
-                uriStr: uriStr,
-              );
-            }
-          },
-          (externalLibrary) {
-            return ImportAugmentationWithUri(
-              directive: directive,
-              uriStr: uriStr,
-            );
-          },
+      final uri = file._buildDirectiveUri(directive.uri);
+      if (uri is DirectiveUriWithFile) {
+        return ImportAugmentationDirectiveWithFile(
+          container: this,
+          directive: directive,
+          uri: uri,
+        );
+      } else if (uri is DirectiveUriWithUri) {
+        return ImportAugmentationWithUri(
+          directive: directive,
+          uri: uri,
         );
       } else {
         return ImportAugmentationDirectiveState(
           directive: directive,
+          uri: uri,
         );
       }
     }).toList();
   }
 
   List<ExportDirectiveState> get exports {
-    return _exports ??= file.unlinked2.exports.map((directive) {
-      final uriStr = file._selectRelativeUri(directive);
-      if (uriStr != null) {
-        return file._fileForRelativeUri(uriStr).map(
-          (refFile) {
-            if (refFile != null) {
-              return ExportDirectiveWithFile(
-                container: this,
-                directive: directive,
-                exportedFile: refFile,
-                selectedUriStr: uriStr,
-              );
-            } else {
-              return ExportDirectiveWithUri(
-                directive: directive,
-                selectedUriStr: uriStr,
-              );
-            }
-          },
-          (externalLibrary) {
-            return ExportDirectiveWithInSummarySource(
-              directive: directive,
-              exportedSource: externalLibrary.source,
-              selectedUriStr: uriStr,
-            );
-          },
+    return _exports ??=
+        file.unlinked2.exports.map<ExportDirectiveState>((directive) {
+      final uris = file._buildNamespaceDirectiveUris(directive);
+      final selectedUri = uris.selected;
+      if (selectedUri is DirectiveUriWithFile) {
+        return ExportDirectiveWithFile(
+          container: this,
+          directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
+        );
+      } else if (selectedUri is DirectiveUriWithInSummarySource) {
+        return ExportDirectiveWithInSummarySource(
+          directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
+        );
+      } else if (selectedUri is DirectiveUriWithUri) {
+        return ExportDirectiveWithUri(
+          directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
         );
       } else {
         return ExportDirectiveState(
           directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
         );
       }
     }).toList();
   }
 
   List<ImportDirectiveState> get imports {
-    return _imports ??= file.unlinked2.imports.map((directive) {
-      final uriStr = file._selectRelativeUri(directive);
-      if (uriStr != null) {
-        return file._fileForRelativeUri(uriStr).map(
-          (refFile) {
-            if (refFile != null) {
-              return ImportDirectiveWithFile(
-                container: this,
-                directive: directive,
-                importedFile: refFile,
-                selectedUriStr: uriStr,
-              );
-            } else {
-              return ImportDirectiveWithUri(
-                directive: directive,
-                selectedUriStr: uriStr,
-              );
-            }
-          },
-          (externalLibrary) {
-            return ImportDirectiveWithInSummarySource(
-              directive: directive,
-              importedSource: externalLibrary.source,
-              selectedUriStr: uriStr,
-            );
-          },
+    return _imports ??=
+        file.unlinked2.imports.map<ImportDirectiveState>((directive) {
+      final uris = file._buildNamespaceDirectiveUris(directive);
+      final selectedUri = uris.selected;
+      if (selectedUri is DirectiveUriWithFile) {
+        return ImportDirectiveWithFile(
+          container: this,
+          directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
+        );
+      } else if (selectedUri is DirectiveUriWithInSummarySource) {
+        return ImportDirectiveWithInSummarySource(
+          directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
+        );
+      } else if (selectedUri is DirectiveUriWithUri) {
+        return ImportDirectiveWithUri(
+          directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
         );
       } else {
         return ImportDirectiveState(
           directive: directive,
+          selectedUri: selectedUri,
+          uris: uris,
         );
       }
     }).toList();
@@ -1912,14 +2027,28 @@
   }
 }
 
+class NamespaceDirectiveUris {
+  final DirectiveUri primary;
+  final List<DirectiveUri> configurations;
+  final DirectiveUri selected;
+
+  NamespaceDirectiveUris({
+    required this.primary,
+    required this.configurations,
+    required this.selected,
+  });
+}
+
 /// Information about a single `part` directive.
-class PartDirectiveState extends DirectiveState {
+class PartDirectiveState<U extends DirectiveUri> extends DirectiveState {
   final LibraryFileStateKind library;
   final UnlinkedPartDirective directive;
+  final U uri;
 
   PartDirectiveState({
     required this.library,
     required this.directive,
+    required this.uri,
   });
 
   /// Returns a [Source] that is referenced by this directive.
@@ -1929,18 +2058,17 @@
 }
 
 /// [PartDirectiveWithUri] that has a valid URI that references a file.
-class PartDirectiveWithFile extends PartDirectiveWithUri {
-  final FileState includedFile;
-
+class PartDirectiveWithFile extends PartDirectiveWithUri<DirectiveUriWithFile> {
   PartDirectiveWithFile({
     required super.library,
     required super.directive,
-    required super.uriStr,
-    required this.includedFile,
+    required super.uri,
   }) {
     includedFile.referencingFiles.add(library.file);
   }
 
+  FileState get includedFile => uri.file;
+
   /// If [includedFile] is a [PartFileStateKind], and it confirms that it
   /// is a part of the [library], returns the [includedFile].
   PartFileStateKind? get includedPart {
@@ -1961,13 +2089,12 @@
 }
 
 /// [PartDirectiveState] that has a valid URI.
-class PartDirectiveWithUri extends PartDirectiveState {
-  final String uriStr;
-
+class PartDirectiveWithUri<U extends DirectiveUriWithUri>
+    extends PartDirectiveState<U> {
   PartDirectiveWithUri({
     required super.library,
     required super.directive,
-    required this.uriStr,
+    required super.uri,
   });
 }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index a584d14..998b077 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -41,16 +41,13 @@
 import 'package:analyzer/src/generated/ffi_verifier.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/hint/sdk_constraint_verifier.dart';
 import 'package:analyzer/src/ignore_comments/ignore_info.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/linter_visitor.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:analyzer/src/util/performance/operation_performance.dart';
-import 'package:analyzer/src/util/uri.dart';
 
 class AnalysisForCompletionResult {
   final CompilationUnit parsedUnit;
@@ -66,7 +63,6 @@
 class LibraryAnalyzer {
   final AnalysisOptionsImpl _analysisOptions;
   final DeclaredVariables _declaredVariables;
-  final SourceFactory _sourceFactory;
   final LibraryFileStateKind _library;
   final InheritanceManager3 _inheritance;
 
@@ -79,13 +75,8 @@
   final Map<FileState, ErrorReporter> _errorReporters = {};
   final TestingData? _testingData;
 
-  LibraryAnalyzer(
-      this._analysisOptions,
-      this._declaredVariables,
-      this._sourceFactory,
-      this._libraryElement,
-      this._inheritance,
-      this._library,
+  LibraryAnalyzer(this._analysisOptions, this._declaredVariables,
+      this._libraryElement, this._inheritance, this._library,
       {TestingData? testingData})
       : _testingData = testingData;
 
@@ -296,13 +287,17 @@
     // This must happen after all other diagnostics have been computed but
     // before the list of diagnostics has been filtered.
     for (var file in _library.files) {
-      IgnoreValidator(
-        _getErrorReporter(file),
-        _getErrorListener(file).errors,
-        _fileToIgnoreInfo[file]!,
-        _fileToLineInfo[file]!,
-        _analysisOptions.unignorableNames,
-      ).reportErrors();
+      final ignoreInfo = _fileToIgnoreInfo[file];
+      // TODO(scheglov) make it safer
+      if (ignoreInfo != null) {
+        IgnoreValidator(
+          _getErrorReporter(file),
+          _getErrorListener(file).errors,
+          ignoreInfo,
+          _fileToLineInfo[file]!,
+          _analysisOptions.unignorableNames,
+        ).reportErrors();
+      }
     }
   }
 
@@ -440,11 +435,6 @@
     }
 
     //
-    // Validate the directives.
-    //
-    _validateUriBasedDirectives(file, unit);
-
-    //
     // Use the ConstantVerifier to compute errors.
     //
     _computeConstantErrors(errorReporter, unit);
@@ -515,42 +505,6 @@
     });
   }
 
-  /// Return the name of the library that the given part is declared to be a
-  /// part of, or `null` if the part does not contain a part-of directive.
-  _NameOrSource? _getPartLibraryNameOrUri(Source partSource,
-      CompilationUnit partUnit, List<Directive> directivesToResolve) {
-    for (Directive directive in partUnit.directives) {
-      if (directive is PartOfDirective) {
-        directivesToResolve.add(directive);
-        LibraryIdentifier? libraryName = directive.libraryName;
-        if (libraryName != null) {
-          return _NameOrSource(libraryName.name, null);
-        }
-        String? uri = directive.uri?.stringValue;
-        if (uri != null) {
-          Source? librarySource = _sourceFactory.resolveUri(partSource, uri);
-          if (librarySource != null) {
-            return _NameOrSource(null, librarySource);
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  bool _isExistingSource(Source source) {
-    if (source is InSummarySource) {
-      return true;
-    }
-    for (var file in _library.file.directReferencedFiles) {
-      if (file.uri == source.uri) {
-        return file.exists;
-      }
-    }
-    // A library can refer to itself with an empty URI.
-    return source == _library.file.source;
-  }
-
   /// Return a new parsed unresolved [CompilationUnit].
   CompilationUnitImpl _parse(FileState file) {
     AnalysisErrorListener errorListener = _getErrorListener(file);
@@ -565,21 +519,28 @@
 
   /// Parse and resolve all files in [_library].
   Map<FileState, CompilationUnitImpl> _parseAndResolve() {
-    var units = <FileState, CompilationUnitImpl>{};
-
     // Parse all files.
-    for (FileState file in _library.files) {
-      units[file] = _parse(file);
+    final libraryFile = _library.file;
+    final libraryUnit = _parse(libraryFile);
+    final units = <FileState, CompilationUnitImpl>{
+      libraryFile: libraryUnit,
+    };
+    for (final part in _library.parts) {
+      if (part is PartDirectiveWithFile) {
+        final partFile = part.includedPart?.file;
+        if (partFile != null) {
+          units[partFile] = _parse(partFile);
+        }
+      }
     }
 
     // Resolve URIs in directives to corresponding sources.
-    FeatureSet featureSet = units[_library.file]!.featureSet;
+    final featureSet = _libraryElement.featureSet;
     units.forEach((file, unit) {
       _validateFeatureSet(unit, featureSet);
-      _resolveUriBasedDirectives(file, unit);
     });
 
-    _resolveDirectives(units);
+    _resolveDirectives(units, libraryUnit);
 
     units.forEach((file, unit) {
       _resolveFile(file, unit);
@@ -590,136 +551,56 @@
     return units;
   }
 
-  void _resolveDirectives(Map<FileState, CompilationUnitImpl> units) {
-    var definingCompilationUnit = units[_library.file]!;
-    definingCompilationUnit.element = _libraryElement.definingCompilationUnit;
-
-    bool matchNodeElement(Directive node, Element element) {
-      return node.keyword.offset == element.nameOffset;
-    }
+  void _resolveDirectives(
+    Map<FileState, CompilationUnitImpl> units,
+    CompilationUnitImpl libraryUnit,
+  ) {
+    libraryUnit.element = _libraryElement.definingCompilationUnit;
 
     ErrorReporter libraryErrorReporter = _getErrorReporter(_library.file);
 
+    var importIndex = 0;
+    var exportIndex = 0;
+
     LibraryIdentifier? libraryNameNode;
     var seenPartSources = <Source>{};
     var directivesToResolve = <DirectiveImpl>[];
-    int partDirectiveIndex = 0;
-    int partElementIndex = 0;
-    for (Directive directive in definingCompilationUnit.directives) {
+    final partIndexes = _PartDirectiveIndexes();
+    for (Directive directive in libraryUnit.directives) {
       if (directive is LibraryDirectiveImpl) {
         libraryNameNode = directive.name;
         directivesToResolve.add(directive);
       } else if (directive is ImportDirectiveImpl) {
-        // TODO(scheglov) Rewrite to iterating `ImportDirectiveState`.
-        for (var index = 0; index < _libraryElement.imports.length; index++) {
-          final importElement = _libraryElement.imports[index];
-          if (matchNodeElement(directive, importElement)) {
-            directive.element = importElement;
-            directive.prefix?.staticElement = importElement.prefix;
-            final importDirectiveState = _library.imports[index];
-            // TODO(scheglov) rewrite
-            if (importDirectiveState is ImportDirectiveWithUri) {
-              if (importDirectiveState.importedSource != null) {
-                if (importDirectiveState.importedLibrarySource == null) {
-                  libraryErrorReporter.reportErrorForNode(
-                    CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
-                    directive.uri,
-                    [importDirectiveState.selectedUriStr],
-                  );
-                }
-              }
-            }
-          }
+        if (directive.augmentKeyword != null) {
+          // TODO(scheglov) implement
+          throw UnimplementedError();
+        } else {
+          _resolveImportDirective(
+            directive: directive,
+            importElement: _libraryElement.imports[importIndex],
+            importState: _library.imports[importIndex],
+            libraryErrorReporter: libraryErrorReporter,
+          );
+          importIndex++;
         }
       } else if (directive is ExportDirectiveImpl) {
-        // TODO(scheglov) Rewrite to iterating `ExportDirectiveState`.
-        for (var index = 0; index < _libraryElement.exports.length; index++) {
-          final exportElement = _libraryElement.exports[index];
-          if (matchNodeElement(directive, exportElement)) {
-            directive.element = exportElement;
-            final exportDirectiveState = _library.exports[index];
-            // TODO(scheglov) rewrite
-            if (exportDirectiveState is ExportDirectiveWithUri) {
-              if (exportDirectiveState.exportedSource != null) {
-                if (exportDirectiveState.exportedLibrarySource == null) {
-                  libraryErrorReporter.reportErrorForNode(
-                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-                    directive.uri,
-                    [exportDirectiveState.selectedUriStr],
-                  );
-                }
-              }
-            }
-          }
-        }
+        _resolveExportDirective(
+          directive: directive,
+          exportElement: _libraryElement.exports[exportIndex],
+          exportState: _library.exports[exportIndex],
+          libraryErrorReporter: libraryErrorReporter,
+        );
+        exportIndex++;
       } else if (directive is PartDirectiveImpl) {
-        StringLiteral partUri = directive.uri;
-
-        if (partElementIndex >= _libraryElement.parts.length) {
-          continue;
-        }
-
-        final partState = _library.parts[partDirectiveIndex++];
-        if (partState is! PartDirectiveWithFile) {
-          continue;
-        }
-        final partFile = partState.includedFile;
-
-        var partUnit = units[partFile]!;
-        var partElement = _libraryElement.parts[partElementIndex++];
-        partUnit.element = partElement;
-        directive.element = partElement;
-
-        Source? partSource = directive.uriSource;
-        if (partSource == null) {
-          continue;
-        }
-
-        //
-        // Validate that the part source is unique in the library.
-        //
-        if (!seenPartSources.add(partSource)) {
-          libraryErrorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DUPLICATE_PART, partUri, [partSource.uri]);
-        }
-
-        //
-        // Validate that the part contains a part-of directive with the same
-        // name or uri as the library.
-        //
-        if (_isExistingSource(partSource)) {
-          _NameOrSource? nameOrSource = _getPartLibraryNameOrUri(
-              partSource, partUnit, directivesToResolve);
-          if (nameOrSource == null) {
-            libraryErrorReporter.reportErrorForNode(
-                CompileTimeErrorCode.PART_OF_NON_PART,
-                partUri,
-                [partUri.toSource()]);
-          } else {
-            String? name = nameOrSource.name;
-            if (name != null) {
-              if (libraryNameNode == null) {
-                libraryErrorReporter.reportErrorForNode(
-                    CompileTimeErrorCode.PART_OF_UNNAMED_LIBRARY,
-                    partUri,
-                    [name]);
-              } else if (libraryNameNode.name != name) {
-                libraryErrorReporter.reportErrorForNode(
-                    CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
-                    partUri,
-                    [libraryNameNode.name, name]);
-              }
-            } else {
-              Source source = nameOrSource.source!;
-              if (source != _library.file.source) {
-                libraryErrorReporter.reportErrorForNode(
-                    CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
-                    partUri,
-                    [_library.file.uriStr, source.uri]);
-              }
-            }
-          }
-        }
+        _resolvePartDirective(
+          directive: directive,
+          partIndexes: partIndexes,
+          libraryErrorReporter: libraryErrorReporter,
+          libraryNameNode: libraryNameNode,
+          units: units,
+          directivesToResolve: directivesToResolve,
+          seenPartSources: seenPartSources,
+        );
       }
     }
 
@@ -734,6 +615,62 @@
     }
   }
 
+  void _resolveExportDirective({
+    required ExportDirectiveImpl directive,
+    required ExportElement exportElement,
+    required ExportDirectiveState exportState,
+    required ErrorReporter libraryErrorReporter,
+  }) {
+    directive.element = exportElement;
+    _resolveNamespaceDirective(
+      directive: directive,
+      primaryUriNode: directive.uri,
+      primaryUriState: exportState.uris.primary,
+      configurationNodes: directive.configurations,
+      configurationUris: exportState.uris.configurations,
+      selectedUriState: exportState.selectedUri,
+    );
+    if (exportState is ExportDirectiveWithUri) {
+      final selectedUriStr = exportState.selectedUri.relativeUriStr;
+      if (selectedUriStr.startsWith('dart-ext:')) {
+        libraryErrorReporter.reportErrorForNode(
+          CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
+          directive.uri,
+        );
+      } else if (exportState.exportedSource == null) {
+        final errorCode = exportState.selectedUri.isValid
+            ? CompileTimeErrorCode.URI_DOES_NOT_EXIST
+            : CompileTimeErrorCode.INVALID_URI;
+        libraryErrorReporter.reportErrorForNode(
+          errorCode,
+          directive.uri,
+          [selectedUriStr],
+        );
+      } else if (exportState is ExportDirectiveWithFile &&
+          !exportState.exportedFile.exists) {
+        final errorCode = isGeneratedSource(exportState.exportedSource)
+            ? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
+            : CompileTimeErrorCode.URI_DOES_NOT_EXIST;
+        libraryErrorReporter.reportErrorForNode(
+          errorCode,
+          directive.uri,
+          [selectedUriStr],
+        );
+      } else if (exportState.exportedLibrarySource == null) {
+        libraryErrorReporter.reportErrorForNode(
+          CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+          directive.uri,
+          [selectedUriStr],
+        );
+      }
+    } else {
+      libraryErrorReporter.reportErrorForNode(
+        CompileTimeErrorCode.URI_WITH_INTERPOLATION,
+        directive.uri,
+      );
+    }
+  }
+
   void _resolveFile(FileState file, CompilationUnit unit) {
     var source = file.source;
     RecordingErrorListener errorListener = _getErrorListener(file);
@@ -772,86 +709,202 @@
         featureSet: unit.featureSet, flowAnalysisHelper: flowAnalysisHelper));
   }
 
-  Uri? _resolveRelativeUri(String relativeUriStr) {
-    Uri relativeUri;
-    try {
-      relativeUri = Uri.parse(relativeUriStr);
-    } on FormatException {
-      return null;
+  void _resolveImportDirective({
+    required ImportDirectiveImpl directive,
+    required ImportElement importElement,
+    required ImportDirectiveState importState,
+    required ErrorReporter libraryErrorReporter,
+  }) {
+    directive.element = importElement;
+    directive.prefix?.staticElement = importElement.prefix;
+    _resolveNamespaceDirective(
+      directive: directive,
+      primaryUriNode: directive.uri,
+      primaryUriState: importState.uris.primary,
+      configurationNodes: directive.configurations,
+      configurationUris: importState.uris.configurations,
+      selectedUriState: importState.selectedUri,
+    );
+    if (importState is ImportDirectiveWithUri) {
+      final selectedUriStr = importState.selectedUri.relativeUriStr;
+      if (selectedUriStr.startsWith('dart-ext:')) {
+        libraryErrorReporter.reportErrorForNode(
+          CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
+          directive.uri,
+        );
+      } else if (importState.importedSource == null) {
+        final errorCode = importState.selectedUri.isValid
+            ? CompileTimeErrorCode.URI_DOES_NOT_EXIST
+            : CompileTimeErrorCode.INVALID_URI;
+        libraryErrorReporter.reportErrorForNode(
+          errorCode,
+          directive.uri,
+          [selectedUriStr],
+        );
+      } else if (importState is ImportDirectiveWithFile &&
+          !importState.importedFile.exists) {
+        final errorCode = isGeneratedSource(importState.importedSource)
+            ? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
+            : CompileTimeErrorCode.URI_DOES_NOT_EXIST;
+        libraryErrorReporter.reportErrorForNode(
+          errorCode,
+          directive.uri,
+          [selectedUriStr],
+        );
+      } else if (importState.importedLibrarySource == null) {
+        libraryErrorReporter.reportErrorForNode(
+          CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
+          directive.uri,
+          [selectedUriStr],
+        );
+      }
+    } else {
+      libraryErrorReporter.reportErrorForNode(
+        CompileTimeErrorCode.URI_WITH_INTERPOLATION,
+        directive.uri,
+      );
     }
-
-    var absoluteUri = resolveRelativeUri(_library.file.uri, relativeUri);
-    return rewriteToCanonicalUri(_sourceFactory, absoluteUri);
   }
 
-  /// Return the result of resolve the given [uriContent], reporting errors
-  /// against the [uriLiteral].
-  Source? _resolveUri(FileState file, bool isImport, StringLiteral uriLiteral,
-      String? uriContent) {
-    UriValidationCode? code =
-        UriBasedDirectiveImpl.validateUri(isImport, uriLiteral, uriContent);
-    if (code == null) {
-      try {
-        Uri.parse(uriContent!);
-      } on FormatException {
-        return null;
-      }
-      return _sourceFactory.resolveUri(file.source, uriContent);
-    } else if (code == UriValidationCode.URI_WITH_INTERPOLATION) {
-      _getErrorReporter(file).reportErrorForNode(
-          CompileTimeErrorCode.URI_WITH_INTERPOLATION, uriLiteral);
-      return null;
-    } else if (code == UriValidationCode.INVALID_URI) {
-      // It is safe to assume [uriContent] is non-null because the only way for
-      // it to be null is if the string literal contained an interpolation, and
-      // in that case the validation code would have been
-      // UriValidationCode.URI_WITH_INTERPOLATION.
-      assert(uriContent != null);
-      _getErrorReporter(file).reportErrorForNode(
-          CompileTimeErrorCode.INVALID_URI, uriLiteral, [uriContent!]);
-      return null;
+  void _resolveNamespaceDirective({
+    required NamespaceDirectiveImpl directive,
+    required StringLiteralImpl primaryUriNode,
+    required DirectiveUri primaryUriState,
+    required DirectiveUri selectedUriState,
+    required List<Configuration> configurationNodes,
+    required List<DirectiveUri> configurationUris,
+  }) {
+    for (var i = 0; i < configurationNodes.length; i++) {
+      final configurationNode = configurationNodes[i];
+      configurationNode as ConfigurationImpl;
+      configurationNode.uriSource = configurationUris[i].source;
     }
-    return null;
+
+    if (primaryUriState is DirectiveUriWithString) {
+      directive.uriContent = primaryUriState.relativeUriStr;
+      directive.uriSource = primaryUriState.source;
+    }
+
+    if (selectedUriState is DirectiveUriWithString) {
+      directive.selectedUriContent = selectedUriState.relativeUriStr;
+      directive.selectedSource = selectedUriState.source;
+    }
   }
 
-  void _resolveUriBasedDirectives(FileState file, CompilationUnit unit) {
-    for (var directive in unit.directives) {
-      if (directive is UriBasedDirectiveImpl) {
-        StringLiteral uriLiteral = directive.uri;
-        String? uriContent = uriLiteral.stringValue?.trim();
-        directive.uriContent = uriContent;
-        Source? defaultSource = _resolveUri(
-            file, directive is ImportDirective, uriLiteral, uriContent);
-        directive.uriSource = defaultSource;
+  void _resolvePartDirective({
+    required PartDirectiveImpl directive,
+    required _PartDirectiveIndexes partIndexes,
+    required ErrorReporter libraryErrorReporter,
+    required LibraryIdentifier? libraryNameNode,
+    required Map<FileState, CompilationUnitImpl> units,
+    required List<DirectiveImpl> directivesToResolve,
+    required Set<Source> seenPartSources,
+  }) {
+    StringLiteral partUri = directive.uri;
+
+    final partState = _library.parts[partIndexes.directive++];
+    directive.uriSource = partState.includedSource;
+    if (partState is! PartDirectiveWithUri) {
+      libraryErrorReporter.reportErrorForNode(
+        CompileTimeErrorCode.URI_WITH_INTERPOLATION,
+        directive.uri,
+      );
+      return;
+    }
+
+    // TODO(scheglov) This should not be necessary if we build `PartElement`
+    // for every `part` directive.
+    if (partIndexes.element >= _libraryElement.parts.length) {
+      final errorCode = partState.uri.isValid
+          ? CompileTimeErrorCode.URI_DOES_NOT_EXIST
+          : CompileTimeErrorCode.INVALID_URI;
+      libraryErrorReporter.reportErrorForNode(
+        errorCode,
+        directive.uri,
+        [partState.uri.relativeUriStr],
+      );
+      return;
+    }
+
+    if (partState is! PartDirectiveWithFile) {
+      libraryErrorReporter.reportErrorForNode(
+        CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+        directive.uri,
+        [partState.uri.relativeUriStr],
+      );
+      return;
+    }
+    final includedFile = partState.includedFile;
+    final includedKind = includedFile.kind;
+
+    if (includedKind is! PartFileStateKind) {
+      if (includedFile.exists) {
+        libraryErrorReporter.reportErrorForNode(
+          CompileTimeErrorCode.PART_OF_NON_PART,
+          partUri,
+          [partUri.toSource()],
+        );
+      } else {
+        final errorCode = isGeneratedSource(includedFile.source)
+            ? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
+            : CompileTimeErrorCode.URI_DOES_NOT_EXIST;
+        libraryErrorReporter.reportErrorForNode(
+          errorCode,
+          directive.uri,
+          [partUri.toSource()],
+        );
       }
-      if (directive is NamespaceDirectiveImpl) {
-        var relativeUriStr = _selectRelativeUri(directive);
-        directive.selectedUriContent = relativeUriStr;
-        var absoluteUri = _resolveRelativeUri(relativeUriStr);
-        if (absoluteUri != null) {
-          directive.selectedSource = _sourceFactory.forUri2(absoluteUri);
+      return;
+    }
+
+    if (includedKind is PartOfNameFileStateKind) {
+      if (!includedKind.libraries.contains(_library)) {
+        final name = includedKind.directive.name;
+        if (libraryNameNode == null) {
+          libraryErrorReporter.reportErrorForNode(
+            CompileTimeErrorCode.PART_OF_UNNAMED_LIBRARY,
+            partUri,
+            [name],
+          );
+        } else {
+          libraryErrorReporter.reportErrorForNode(
+            CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
+            partUri,
+            [libraryNameNode.name, name],
+          );
         }
-        for (var configuration in directive.configurations) {
-          configuration as ConfigurationImpl;
-          var uriLiteral = configuration.uri;
-          String? uriContent = uriLiteral.stringValue?.trim();
-          Source? defaultSource = _resolveUri(
-              file, directive is ImportDirective, uriLiteral, uriContent);
-          configuration.uriSource = defaultSource;
-        }
+        return;
       }
+    } else if (includedKind.library != _library) {
+      libraryErrorReporter.reportErrorForNode(
+        CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
+        partUri,
+        [_library.file.uriStr, includedFile.uriStr],
+      );
+      return;
     }
-  }
 
-  String _selectRelativeUri(NamespaceDirective directive) {
-    for (var configuration in directive.configurations) {
-      var name = configuration.name.components.join('.');
-      var value = configuration.value?.stringValue ?? 'true';
-      if (_declaredVariables.get(name) == value) {
-        return configuration.uri.stringValue ?? '';
+    var partUnit = units[includedFile]!;
+    var partElement = _libraryElement.parts[partIndexes.element++];
+    partUnit.element = partElement;
+    directive.element = partElement;
+
+    final partSource = includedKind.file.source;
+    directive.uriSource = partSource;
+
+    for (final directive in partUnit.directives) {
+      if (directive is PartOfDirectiveImpl) {
+        directivesToResolve.add(directive);
       }
     }
-    return directive.uri.stringValue ?? '';
+
+    //
+    // Validate that the part source is unique in the library.
+    //
+    if (!seenPartSources.add(partSource)) {
+      libraryErrorReporter.reportErrorForNode(
+          CompileTimeErrorCode.DUPLICATE_PART, partUri, [partSource.uri]);
+    }
   }
 
   /// Validate that the feature set associated with the compilation [unit] is
@@ -863,61 +916,6 @@
     }
   }
 
-  /// Check the given [directive] to see if the referenced source exists and
-  /// report an error if it does not.
-  void _validateUriBasedDirective(
-      FileState file, UriBasedDirectiveImpl directive) {
-    String? uriContent;
-    Source? source;
-    if (directive is NamespaceDirectiveImpl) {
-      uriContent = directive.selectedUriContent;
-      source = directive.selectedSource;
-    } else {
-      uriContent = directive.uriContent;
-      source = directive.uriSource;
-    }
-    if (source != null) {
-      if (_isExistingSource(source)) {
-        return;
-      }
-    } else {
-      // Don't report errors already reported by ParseDartTask.resolveDirective
-      // TODO(scheglov) we don't use this task here
-      if (directive.validate() != null) {
-        return;
-      }
-    }
-
-    if (uriContent != null && uriContent.startsWith('dart-ext:')) {
-      _getErrorReporter(file).reportErrorForNode(
-        CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
-        directive.uri,
-      );
-      return;
-    }
-
-    CompileTimeErrorCode errorCode = CompileTimeErrorCode.URI_DOES_NOT_EXIST;
-    if (isGeneratedSource(source)) {
-      errorCode = CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED;
-    }
-    // It is safe to assume that [uriContent] is non-null because the only way
-    // for it to be null is if the string literal contained an interpolation,
-    // and in that case the call to `directive.validate()` above would have
-    // returned a non-null validation code.
-    _getErrorReporter(file)
-        .reportErrorForNode(errorCode, directive.uri, [uriContent!]);
-  }
-
-  /// Check each directive in the given [unit] to see if the referenced source
-  /// exists and report an error if it does not.
-  void _validateUriBasedDirectives(FileState file, CompilationUnit unit) {
-    for (Directive directive in unit.directives) {
-      if (directive is UriBasedDirectiveImpl) {
-        _validateUriBasedDirective(file, directive);
-      }
-    }
-  }
-
   /// Find constants in [unit] to compute.
   static List<ConstantEvaluationTarget> _findConstants(CompilationUnit unit) {
     ConstantFinder constantFinder = ConstantFinder();
@@ -1016,10 +1014,7 @@
   UnitAnalysisResult(this.file, this.unit, this.errors);
 }
 
-/// Either the name or the source associated with a part-of directive.
-class _NameOrSource {
-  final String? name;
-  final Source? source;
-
-  _NameOrSource(this.name, this.source);
+class _PartDirectiveIndexes {
+  int directive = 0;
+  int element = 0;
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
index 0f37cef..116cd36 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
@@ -221,6 +221,14 @@
     );
   }
 
+  String get valueOrTrue {
+    if (value.isEmpty) {
+      return 'true';
+    } else {
+      return value;
+    }
+  }
+
   void write(BufferedSink sink) {
     sink.writeStringUtf8(name);
     sink.writeOptionalStringUtf8(uri);
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 9bac236..055b894 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -581,7 +581,6 @@
         var libraryAnalyzer = LibraryAnalyzer(
           fileContext.analysisOptions,
           contextObjects!.declaredVariables,
-          sourceFactory,
           elementFactory.libraryOfUri2(libraryKind.file.uri),
           analysisSession.inheritanceManager,
           libraryKind,
@@ -647,7 +646,6 @@
         var libraryAnalyzer = LibraryAnalyzer(
           fileContext.analysisOptions,
           contextObjects!.declaredVariables,
-          sourceFactory,
           libraryContext!.elementFactory.libraryOfUri2(libraryKind.file.uri),
           libraryContext!.elementFactory.analysisSession.inheritanceManager,
           libraryKind,
diff --git a/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart b/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart
index 3580fac..f55b678 100644
--- a/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart
+++ b/pkg/analyzer/test/src/dart/analysis/analyzer_state_printer.dart
@@ -111,7 +111,7 @@
           }
           sink.writeln();
         } else if (import is ImportAugmentationWithUri) {
-          final uriStr = _stringOfUriStr(import.uriStr);
+          final uriStr = _stringOfUriStr(import.uri.relativeUriStr);
           _writelnWithIndent('uri: $uriStr');
         } else {
           _writelnWithIndent('noUri');
@@ -204,7 +204,7 @@
           }
           sink.writeln();
         } else if (export is ExportDirectiveWithUri) {
-          final uriStr = _stringOfUriStr(export.selectedUriStr);
+          final uriStr = _stringOfUriStr(export.selectedUri.relativeUriStr);
           _writelnWithIndent('uri: $uriStr');
         } else {
           _writelnWithIndent('noUri');
@@ -255,8 +255,9 @@
           }
           sink.writeln();
         } else if (import is ImportDirectiveWithUri) {
+          final uriStr = _stringOfUriStr(import.selectedUri.relativeUriStr);
           sink.write(_indent);
-          sink.write('uri: ${_stringOfUriStr(import.selectedUriStr)}');
+          sink.write('uri: $uriStr');
           if (import.isSyntheticDartCoreImport) {
             sink.write(' synthetic');
           }
@@ -553,7 +554,7 @@
         }
         sink.writeln();
       } else if (part is PartDirectiveWithUri) {
-        final uriStr = _stringOfUriStr(part.uriStr);
+        final uriStr = _stringOfUriStr(part.uri.relativeUriStr);
         _writelnWithIndent('uri: $uriStr');
       } else {
         _writelnWithIndent('noUri');
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 3c9ebab..40c4384 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -670,19 +670,11 @@
     var session = contextFor(testFilePath).currentSession;
     var resolvedLibrary = await session.getResolvedLibraryValid(test.path);
 
-    expect(resolvedLibrary.units, hasLength(3));
+    expect(resolvedLibrary.units, hasLength(1));
     expect(
       resolvedLibrary.units[0].path,
       convertPath('/home/test/lib/test.dart'),
     );
-    expect(
-      resolvedLibrary.units[1].path,
-      convertPath('/home/test/lib/a.dart'),
-    );
-    expect(
-      resolvedLibrary.units[2].path,
-      convertPath('/home/test/lib/c.dart'),
-    );
   }
 
   test_getResolvedLibrary_invalidPath_notAbsolute() async {
diff --git a/pkg/analyzer/test/src/diagnostics/uri_does_not_exist_test.dart b/pkg/analyzer/test/src/diagnostics/uri_does_not_exist_test.dart
index 8bf563c..0486dd4 100644
--- a/pkg/analyzer/test/src/diagnostics/uri_does_not_exist_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/uri_does_not_exist_test.dart
@@ -34,11 +34,19 @@
     ]);
   }
 
+  test_export_cannotResolve() async {
+    await assertErrorsInCode(r'''
+export 'dart:foo';
+''', [
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 10),
+    ]);
+  }
+
   test_export_dart() async {
     await assertErrorsInCode('''
-export 'dart:foo/bar.dart';
+export 'dart:math/bar.dart';
 ''', [
-      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 19),
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 20),
     ]);
   }
 
@@ -72,11 +80,19 @@
     ]);
   }
 
+  test_import_cannotResolve() async {
+    await assertErrorsInCode(r'''
+import 'dart:foo';
+''', [
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 10),
+    ]);
+  }
+
   test_import_dart() async {
     await assertErrorsInCode('''
-import 'dart:foo/bar.dart';
+import 'dart:math/bar.dart';
 ''', [
-      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 19),
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 20),
     ]);
   }
 
@@ -107,4 +123,12 @@
       error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 18, 14),
     ]);
   }
+
+  test_part_cannotResolve() async {
+    await assertErrorsInCode(r'''
+part 'dart:foo';
+''', [
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 5, 10),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/uri_with_interpolation_test.dart b/pkg/analyzer/test/src/diagnostics/uri_with_interpolation_test.dart
index f637890..a011990 100644
--- a/pkg/analyzer/test/src/diagnostics/uri_with_interpolation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/uri_with_interpolation_test.dart
@@ -15,21 +15,27 @@
 
 @reflectiveTest
 class UriWithInterpolationTest extends PubPackageResolutionTest {
-  test_constant() async {
-    await assertErrorsInCode('''
-import 'stuff_\$platform.dart';
+  test_export() async {
+    await assertErrorsInCode(r'''
+export '${'foo'}.dart';
 ''', [
-      error(CompileTimeErrorCode.URI_WITH_INTERPOLATION, 7, 22),
-      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 15, 8),
+      error(CompileTimeErrorCode.URI_WITH_INTERPOLATION, 7, 15),
     ]);
   }
 
-  test_nonConstant() async {
+  test_import() async {
     await assertErrorsInCode(r'''
-library lib;
-part '${'a'}.dart';
+import '${'foo'}.dart';
 ''', [
-      error(CompileTimeErrorCode.URI_WITH_INTERPOLATION, 18, 13),
+      error(CompileTimeErrorCode.URI_WITH_INTERPOLATION, 7, 15),
+    ]);
+  }
+
+  test_part() async {
+    await assertErrorsInCode(r'''
+part '${'foo'}.dart';
+''', [
+      error(CompileTimeErrorCode.URI_WITH_INTERPOLATION, 5, 15),
     ]);
   }
 }