Version 2.16.0-101.0.dev

Merge commit '5f32f4d7b678dc08d6079664637ad061902c5b69' into 'dev'
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
index 3550b96..444a61b 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
@@ -4,8 +4,8 @@
 
 import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/services/completion/dart/extension_cache.dart';
-import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 
@@ -28,5 +28,7 @@
 
   /// Return top-level declarations with the [name] in libraries that are
   /// available to this context.
-  List<TopLevelDeclaration> getTopLevelDeclarations(String name);
+  Future<Map<LibraryElement, List<Element>>> getTopLevelDeclarations(
+    String name,
+  );
 }
diff --git a/pkg/analysis_server/lib/src/cider/fixes.dart b/pkg/analysis_server/lib/src/cider/fixes.dart
index b3898bd..2ee7754 100644
--- a/pkg/analysis_server/lib/src/cider/fixes.dart
+++ b/pkg/analysis_server/lib/src/cider/fixes.dart
@@ -7,11 +7,11 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
-import 'package:analyzer/src/dart/micro/library_graph.dart' as cider;
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
 
 class CiderErrorFixes {
@@ -68,30 +68,16 @@
     return result;
   }
 
-  List<TopLevelDeclaration> _topLevelDeclarations(String name) {
-    var result = <TopLevelDeclaration>[];
+  Future<Map<LibraryElement, List<Element>>> _topLevelDeclarations(
+      String name) async {
+    var result = <LibraryElement, List<Element>>{};
     var files = _fileResolver.getFilesWithTopLevelDeclarations(name);
-    for (var fileWithKind in files) {
-      void addDeclaration(TopLevelDeclarationKind kind) {
-        var file = fileWithKind.file;
-        result.add(
-          TopLevelDeclaration(file.path, file.uri, kind, name, false),
+    for (var file in files) {
+      if (file.partOfLibrary == null) {
+        var libraryElement = _fileResolver.getLibraryByUri(
+          uriStr: file.uriStr,
         );
-      }
-
-      switch (fileWithKind.kind) {
-        case cider.FileTopLevelDeclarationKind.extension:
-          addDeclaration(TopLevelDeclarationKind.extension);
-          break;
-        case cider.FileTopLevelDeclarationKind.function:
-          addDeclaration(TopLevelDeclarationKind.function);
-          break;
-        case cider.FileTopLevelDeclarationKind.type:
-          addDeclaration(TopLevelDeclarationKind.type);
-          break;
-        case cider.FileTopLevelDeclarationKind.variable:
-          addDeclaration(TopLevelDeclarationKind.variable);
-          break;
+        TopLevelDeclarations.addElement(result, libraryElement, name);
       }
     }
     return result;
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 111aa02..18290c6 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -604,17 +604,9 @@
         if (errorLine == requestLine) {
           var workspace = DartChangeWorkspace(server.currentSessions);
           var context = DartFixContextImpl(
-              server.instrumentationService, workspace, result, error, (name) {
-            var tracker = server.declarationsTracker;
-            if (tracker == null) {
-              return const [];
-            }
-            var provider = TopLevelDeclarationsProvider(tracker);
-            return provider.get(
-              result.session.analysisContext,
-              result.path,
-              name,
-            );
+              server.instrumentationService, workspace, result, error,
+              (name) async {
+            return TopLevelDeclarations(result).withName(name);
           }, extensionCache: server.getExtensionCacheFor(result));
 
           List<Fix> fixes;
diff --git a/pkg/analysis_server/lib/src/g3/fixes.dart b/pkg/analysis_server/lib/src/g3/fixes.dart
index 51c05f4..91b812a 100644
--- a/pkg/analysis_server/lib/src/g3/fixes.dart
+++ b/pkg/analysis_server/lib/src/g3/fixes.dart
@@ -96,7 +96,7 @@
       workspace,
       unitResult,
       error,
-      (name) => const [],
+      (name) async => const {},
     );
 
     List<Fix> fixes;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index ecc14cc..eb8cdc0 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -347,13 +347,9 @@
         }
         var workspace = DartChangeWorkspace(server.currentSessions);
         var context = DartFixContextImpl(
-            server.instrumentationService, workspace, unit, error, (name) {
-          var tracker = server.declarationsTracker!;
-          return TopLevelDeclarationsProvider(tracker).get(
-            unit.session.analysisContext,
-            unit.path,
-            name,
-          );
+            server.instrumentationService, workspace, unit, error,
+            (name) async {
+          return TopLevelDeclarations(unit).withName(name);
         }, extensionCache: server.getExtensionCacheFor(unit));
         final fixes = await fixContributor.computeFixes(context);
         if (fixes.isNotEmpty) {
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 53550d8..070294f 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
@@ -11,10 +11,7 @@
 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/element/element.dart';
-import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/lint/pub.dart';
-import 'package:analyzer/src/workspace/pub.dart';
-import 'package:collection/collection.dart';
+import 'package:analyzer/src/dart/analysis/file_state_filter.dart';
 
 /// A contributor of suggestions from not yet imported libraries.
 class NotImportedContributor extends DartCompletionContributor {
@@ -33,7 +30,9 @@
     var analysisDriver = request.analysisContext.driver;
 
     var fsState = analysisDriver.fsState;
-    var filter = _buildFilter(fsState);
+    var filter = FileStateFilter(
+      fsState.getFileForPath(request.path),
+    );
 
     try {
       await analysisDriver.discoverAvailableFiles().timeout(budget.left);
@@ -80,16 +79,6 @@
     builder.suggestionAdded = null;
   }
 
-  _Filter _buildFilter(FileSystemState fsState) {
-    var file = fsState.getFileForPath(request.path);
-    var workspacePackage = file.workspacePackage;
-    if (workspacePackage is PubWorkspacePackage) {
-      return _PubFilter(workspacePackage, file.path);
-    } else {
-      return _AnyFilter();
-    }
-  }
-
   void _buildSuggestions(List<Element> elements) {
     var visitor = LibraryElementSuggestionBuilder(request, builder);
     for (var element in elements) {
@@ -97,96 +86,3 @@
     }
   }
 }
-
-class _AnyFilter implements _Filter {
-  @override
-  bool shouldInclude(FileState file) => true;
-}
-
-abstract class _Filter {
-  bool shouldInclude(FileState file);
-}
-
-class _PubFilter implements _Filter {
-  final PubWorkspacePackage targetPackage;
-  final String? targetPackageName;
-  final bool targetInLib;
-  final Set<String> dependencies;
-
-  factory _PubFilter(PubWorkspacePackage package, String path) {
-    var inLib = package.workspace.provider
-        .getFolder(package.root)
-        .getChildAssumingFolder('lib')
-        .contains(path);
-
-    var dependencies = <String>{};
-    var pubspec = package.pubspec;
-    if (pubspec != null) {
-      dependencies.addAll(pubspec.dependencies.names);
-      if (!inLib) {
-        dependencies.addAll(pubspec.devDependencies.names);
-      }
-    }
-
-    return _PubFilter._(
-      targetPackage: package,
-      targetPackageName: pubspec?.name?.value.text,
-      targetInLib: inLib,
-      dependencies: dependencies,
-    );
-  }
-
-  _PubFilter._({
-    required this.targetPackage,
-    required this.targetPackageName,
-    required this.targetInLib,
-    required this.dependencies,
-  });
-
-  @override
-  bool shouldInclude(FileState file) {
-    var uri = file.uriProperties;
-    if (uri.isDart) {
-      return true;
-    }
-
-    // Normally only package URIs are available.
-    // But outside of lib/ we allow any files of this package.
-    var packageName = uri.packageName;
-    if (packageName == null) {
-      if (targetInLib) {
-        return false;
-      } else {
-        var filePackage = file.workspacePackage;
-        return filePackage is PubWorkspacePackage &&
-            filePackage.root == targetPackage.root;
-      }
-    }
-
-    // Any `package:` library from the same package.
-    if (packageName == targetPackageName) {
-      return true;
-    }
-
-    // If not the same package, must be public.
-    if (uri.isSrc) {
-      return false;
-    }
-
-    return dependencies.contains(packageName);
-  }
-}
-
-extension on PSDependencyList? {
-  List<String> get names {
-    final self = this;
-    if (self == null) {
-      return const [];
-    } else {
-      return self
-          .map((dependency) => dependency.name?.text)
-          .whereNotNull()
-          .toList();
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 4303a94..35764c0 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -220,7 +220,7 @@
           workspace,
           unit,
           error,
-          (name) => [],
+          (name) async => {},
         );
         await _fixSingleError(fixContext, unit, error, overrideSet);
       }
@@ -266,7 +266,7 @@
         workspace,
         result,
         diagnostic,
-        (name) => [],
+        (name) async => {},
       );
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 03e3a19..16f03aa 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -7,7 +7,6 @@
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/extension_cache.dart';
-import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/utilities/flutter.dart';
@@ -493,8 +492,11 @@
 
   /// Return the top-level declarations with the [name] in libraries that are
   /// available to this context.
-  List<TopLevelDeclaration> getTopLevelDeclarations(String name) =>
-      _context.dartFixContext!.getTopLevelDeclarations(name);
+  Future<Map<LibraryElement, List<Element>>> getTopLevelDeclarations(
+    String name,
+  ) {
+    return _context.dartFixContext!.getTopLevelDeclarations(name);
+  }
 
   /// Return `true` the lint with the given [name] is enabled.
   bool isLintEnabled(String name) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
index d51d0a6..0dd6cca 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
@@ -6,7 +6,6 @@
 
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analysis_server/src/utilities/extensions/element.dart';
@@ -34,10 +33,9 @@
     } else if (_importKind == _ImportKind.forExtension) {
       if (node is SimpleIdentifier) {
         var extensionName = node.name;
-        yield* _importLibraryForElement(
-            extensionName,
-            const [ElementKind.EXTENSION],
-            const [TopLevelDeclarationKind.extension]);
+        yield* _importLibraryForElement(extensionName, const [
+          ElementKind.EXTENSION,
+        ]);
       }
     } else if (_importKind == _ImportKind.forExtensionMember) {
       /// Return producers that will import extensions that apply to the
@@ -83,10 +81,7 @@
         var name = node.name;
         yield* _importLibraryForElement(name, const [
           ElementKind.FUNCTION,
-          ElementKind.TOP_LEVEL_VARIABLE
-        ], const [
-          TopLevelDeclarationKind.function,
-          TopLevelDeclarationKind.variable
+          ElementKind.TOP_LEVEL_VARIABLE,
         ]);
       }
     } else if (_importKind == _ImportKind.forTopLevelVariable) {
@@ -102,10 +97,9 @@
       }
       if (targetNode is SimpleIdentifier) {
         var name = targetNode.name;
-        yield* _importLibraryForElement(
-            name,
-            const [ElementKind.TOP_LEVEL_VARIABLE],
-            const [TopLevelDeclarationKind.variable]);
+        yield* _importLibraryForElement(name, const [
+          ElementKind.TOP_LEVEL_VARIABLE,
+        ]);
       }
     } else if (_importKind == _ImportKind.forType) {
       var targetNode = node;
@@ -124,15 +118,15 @@
             : (targetNode as PrefixedIdentifier).prefix.name;
         yield* _importLibraryForElement(typeName, const [
           ElementKind.CLASS,
+          ElementKind.ENUM,
           ElementKind.FUNCTION_TYPE_ALIAS,
-          ElementKind.TYPE_ALIAS
-        ], const [
-          TopLevelDeclarationKind.type
+          ElementKind.TYPE_ALIAS,
         ]);
       } else if (mightBeImplicitConstructor(targetNode)) {
         var typeName = (targetNode as SimpleIdentifier).name;
-        yield* _importLibraryForElement(typeName, const [ElementKind.CLASS],
-            const [TopLevelDeclarationKind.type]);
+        yield* _importLibraryForElement(typeName, const [
+          ElementKind.CLASS,
+        ]);
       }
     }
   }
@@ -221,16 +215,16 @@
   }
 
   Stream<CorrectionProducer> _importLibraryForElement(
-      String name,
-      List<ElementKind> elementKinds,
-      List<TopLevelDeclarationKind> kinds2) async* {
+    String name,
+    List<ElementKind> kinds,
+  ) async* {
     // ignore if private
     if (name.startsWith('_')) {
       return;
     }
     // may be there is an existing import,
     // but it is with prefix and we don't use this prefix
-    var alreadyImportedWithPrefix = <String>{};
+    var alreadyImportedWithPrefix = <LibraryElement>{};
     for (var imp in libraryElement.imports) {
       // prepare element
       var libraryElement = imp.importedLibrary;
@@ -244,7 +238,7 @@
       if (element is PropertyAccessorElement) {
         element = element.variable;
       }
-      if (!elementKinds.contains(element.kind)) {
+      if (!kinds.contains(element.kind)) {
         continue;
       }
       // may be apply prefix
@@ -268,47 +262,51 @@
             libraryName = libraryElement.source.shortName;
           }
           // don't add this library again
-          alreadyImportedWithPrefix.add(libraryElement.source.fullName);
+          alreadyImportedWithPrefix.add(libraryElement);
           yield _ImportLibraryShow(libraryName, combinator, name);
         }
       }
     }
     // Find new top-level declarations.
-    var declarations = getTopLevelDeclarations(name);
-    for (var declaration in declarations) {
-      // Check the kind.
-      if (!kinds2.contains(declaration.kind)) {
-        continue;
+    var librariesWithElements = await getTopLevelDeclarations(name);
+    for (var libraryEntry in librariesWithElements.entries) {
+      var libraryElement = libraryEntry.key;
+      for (var declaration in libraryEntry.value) {
+        var librarySource = libraryElement.source;
+        // Check the kind.
+        if (!kinds.contains(declaration.kind)) {
+          continue;
+        }
+        // Check the source.
+        if (alreadyImportedWithPrefix.contains(libraryElement)) {
+          continue;
+        }
+        // Check that the import doesn't end with '.template.dart'
+        if (librarySource.uri.path.endsWith('.template.dart')) {
+          continue;
+        }
+        // Compute the fix kind.
+        FixKind fixKind;
+        if (librarySource.uri.isScheme('dart')) {
+          fixKind = DartFixKind.IMPORT_LIBRARY_SDK;
+        } else if (_isLibSrcPath(librarySource.fullName)) {
+          // Bad: non-API.
+          fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT3;
+        } else if (declaration.library != libraryElement) {
+          // Ugly: exports.
+          fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT2;
+        } else {
+          // Good: direct declaration.
+          fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
+        }
+        // If both files are in the same package's lib folder, also include a
+        // relative import.
+        var includeRelativeUri = canBeRelativeImport(
+            librarySource.uri, this.libraryElement.librarySource.uri);
+        // Add the fix(es).
+        yield* _importLibrary(fixKind, librarySource.uri,
+            includeRelativeFix: includeRelativeUri);
       }
-      // Check the source.
-      if (alreadyImportedWithPrefix.contains(declaration.path)) {
-        continue;
-      }
-      // Check that the import doesn't end with '.template.dart'
-      if (declaration.uri.path.endsWith('.template.dart')) {
-        continue;
-      }
-      // Compute the fix kind.
-      FixKind fixKind;
-      if (declaration.uri.isScheme('dart')) {
-        fixKind = DartFixKind.IMPORT_LIBRARY_SDK;
-      } else if (_isLibSrcPath(declaration.path)) {
-        // Bad: non-API.
-        fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT3;
-      } else if (declaration.isExported) {
-        // Ugly: exports.
-        fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT2;
-      } else {
-        // Good: direct declaration.
-        fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
-      }
-      // If both files are in the same package's lib folder, also include a
-      // relative import.
-      var includeRelativeUri = canBeRelativeImport(
-          declaration.uri, libraryElement.librarySource.uri);
-      // Add the fix(es).
-      yield* _importLibrary(fixKind, declaration.uri,
-          includeRelativeFix: includeRelativeUri);
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 84a648c..b764b6f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -4,9 +4,9 @@
 
 import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/extension_cache.dart';
-import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -58,7 +58,7 @@
   @override
   final ExtensionCache extensionCache;
 
-  final List<TopLevelDeclaration> Function(String name)
+  final Future<Map<LibraryElement, List<Element>>> Function(String name)
       getTopLevelDeclarationsFunction;
 
   DartFixContextImpl(this.instrumentationService, this.workspace,
@@ -67,7 +67,8 @@
       : extensionCache = extensionCache ?? ExtensionCache();
 
   @override
-  List<TopLevelDeclaration> getTopLevelDeclarations(String name) {
+  Future<Map<LibraryElement, List<Element>>> getTopLevelDeclarations(
+      String name) {
     return getTopLevelDeclarationsFunction(name);
   }
 }
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 3bc6161..2fab4c2 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
@@ -2,108 +2,63 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/analysis/analysis_context.dart';
-import 'package:analyzer/src/services/available_declarations.dart';
+import 'dart:async';
 
-/// Information about a single top-level declaration.
-class TopLevelDeclaration {
-  /// The path of the library that exports this declaration.
-  final String path;
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/file_state_filter.dart';
 
-  /// The URI of the library that exports this declaration.
-  final Uri uri;
+class TopLevelDeclarations {
+  final ResolvedUnitResult resolvedUnit;
 
-  final TopLevelDeclarationKind kind;
+  TopLevelDeclarations(this.resolvedUnit);
 
-  final String name;
-
-  /// Is `true` if the declaration is exported, not declared in the [path].
-  final bool isExported;
-
-  TopLevelDeclaration(
-    this.path,
-    this.uri,
-    this.kind,
-    this.name,
-    this.isExported,
-  );
-
-  @override
-  String toString() => '($path, $uri, $kind, $name, $isExported)';
-}
-
-/// Kind of a top-level declaration.
-///
-/// We don't need it to be precise, just enough to support quick fixes.
-enum TopLevelDeclarationKind { type, extension, function, variable }
-
-class TopLevelDeclarationsProvider {
-  final DeclarationsTracker tracker;
-
-  TopLevelDeclarationsProvider(this.tracker);
-
-  void doTrackerWork() {
-    while (tracker.hasWork) {
-      tracker.doWork();
-    }
+  DriverBasedAnalysisContext get _analysisContext {
+    var analysisContext = resolvedUnit.session.analysisContext;
+    return analysisContext as DriverBasedAnalysisContext;
   }
 
-  List<TopLevelDeclaration> get(
-    AnalysisContext analysisContext,
-    String path,
+  Future<Map<LibraryElement, List<Element>>> withName(String name) async {
+    var analysisDriver = _analysisContext.driver;
+    await analysisDriver.discoverAvailableFiles();
+
+    var fsState = analysisDriver.fsState;
+    var filter = FileStateFilter(
+      fsState.getFileForPath(resolvedUnit.path),
+    );
+
+    var result = <LibraryElement, List<Element>>{};
+
+    for (var file in fsState.knownFiles.toList()) {
+      if (!filter.shouldInclude(file)) {
+        continue;
+      }
+
+      var libraryElement = analysisDriver.getLibraryByFile(file);
+      if (libraryElement == null) {
+        continue;
+      }
+
+      addElement(result, libraryElement, name);
+    }
+
+    return result;
+  }
+
+  static void addElement(
+    Map<LibraryElement, List<Element>> result,
+    LibraryElement libraryElement,
     String name,
   ) {
-    var declarations = <TopLevelDeclaration>[];
-
-    void addDeclarations(Library library) {
-      for (var declaration in library.declarations) {
-        if (declaration.name != name) continue;
-
-        var kind = _getTopKind(declaration.kind);
-        if (kind == null) continue;
-
-        declarations.add(
-          TopLevelDeclaration(
-            library.path,
-            library.uri,
-            kind,
-            name,
-            declaration.locationLibraryUri != library.uri,
-          ),
-        );
+    var exportNamespace = libraryElement.exportNamespace;
+    var element = exportNamespace.get(name);
+    if (element != null) {
+      // TODO(scheglov) Separate getters and setters.
+      if (element is PropertyAccessorElement) {
+        element = element.variable;
       }
-    }
-
-    var declarationsContext = tracker.getContext(analysisContext);
-    if (declarationsContext == null) return const [];
-
-    var libraries = declarationsContext.getLibraries(path);
-    libraries.context.forEach(addDeclarations);
-    libraries.dependencies.forEach(addDeclarations);
-    libraries.sdk.forEach(addDeclarations);
-
-    return declarations;
-  }
-
-  TopLevelDeclarationKind? _getTopKind(DeclarationKind kind) {
-    switch (kind) {
-      case DeclarationKind.CLASS:
-      case DeclarationKind.CLASS_TYPE_ALIAS:
-      case DeclarationKind.ENUM:
-      case DeclarationKind.FUNCTION_TYPE_ALIAS:
-      case DeclarationKind.TYPE_ALIAS:
-      case DeclarationKind.MIXIN:
-        return TopLevelDeclarationKind.type;
-      case DeclarationKind.EXTENSION:
-        return TopLevelDeclarationKind.extension;
-      case DeclarationKind.FUNCTION:
-        return TopLevelDeclarationKind.function;
-      case DeclarationKind.GETTER:
-      case DeclarationKind.SETTER:
-      case DeclarationKind.VARIABLE:
-        return TopLevelDeclarationKind.variable;
-      default:
-        return null;
+      (result[libraryElement] ??= []).add(element);
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index c6fa293..947f69c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -251,7 +251,7 @@
             workspace,
             resolveResult,
             error,
-            (name) => [],
+            (name) async => {},
             extensionCache: context.extensionCache,
           );
           fixState = await _fixError(fixContext, fixState, generator(), error);
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 09fdeee..432a8b3 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -56,6 +56,9 @@
       '${ExperimentStatus.currentVersion.major}.'
       '${ExperimentStatus.currentVersion.minor}';
 
+  /// The path that is not in [workspaceRootPath], contains external packages.
+  String get packagesRootPath => '/packages';
+
   Folder get sdkRoot => newFolder('/sdk');
 
   AnalysisSession get session => contextFor('/home/test').currentSession;
@@ -66,6 +69,8 @@
 
   String get testPackageRootPath => '$workspaceRootPath/test';
 
+  String get testPackageTestPath => '$testPackageRootPath/test';
+
   /// The file system specific `/home/test/pubspec.yaml` path.
   String get testPubspecPath => convertPath('/home/test/pubspec.yaml');
 
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 67aa683..0c09690 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -64,13 +64,8 @@
     return super.newFile(path, content: content);
   }
 
-  Future<void> resolveTestCode(String code) async {
-    addTestSource(code);
-    await resolveTestFile();
-  }
-
-  Future<void> resolveTestFile() async {
-    var result = await session.getResolvedUnit(testFile) as ResolvedUnitResult;
+  Future<void> resolveFile2(String path) async {
+    var result = await session.getResolvedUnit(path) as ResolvedUnitResult;
     testAnalysisResult = result;
     testCode = result.content;
     testUnit = result.unit;
@@ -91,6 +86,15 @@
     findElement = FindElement(testUnit);
   }
 
+  Future<void> resolveTestCode(String code) async {
+    addTestSource(code);
+    await resolveTestFile();
+  }
+
+  Future<void> resolveTestFile() async {
+    await resolveFile2(testFile);
+  }
+
   @override
   void setUp() {
     super.setUp();
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index 92e87d3..db354c4 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -24,8 +24,6 @@
 
 @reflectiveTest
 class UriContributorTest extends DartCompletionContributorTest {
-  String get testPackageTestPath => '$testPackageRootPath/test';
-
   @override
   DartCompletionContributor createContributor(
     DartCompletionRequest request,
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index a929b5e..a3ab6fc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -197,20 +197,13 @@
 
   /// Computes fixes for the given [error] in [testUnit].
   Future<List<Fix>> _computeFixes(AnalysisError error) async {
-    var analysisContext = contextFor(testFile);
-
-    var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
-    tracker.addContext(analysisContext);
-
     var context = DartFixContextImpl(
       TestInstrumentationService(),
       workspace,
       testAnalysisResult,
       error,
-      (name) {
-        var provider = TopLevelDeclarationsProvider(tracker);
-        provider.doTrackerWork();
-        return provider.get(analysisContext, testFile, name);
+      (name) async {
+        return TopLevelDeclarations(testAnalysisResult).withName(name);
       },
     );
 
@@ -522,10 +515,6 @@
 
   /// Computes fixes for the given [error] in [testUnit].
   Future<List<Fix>> _computeFixes(AnalysisError error) async {
-    var analysisContext = contextFor(testFile);
-
-    var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
-    tracker.addContext(analysisContext);
     extensionCache.cacheFromResult(testAnalysisResult);
 
     var context = DartFixContextImpl(
@@ -533,10 +522,8 @@
       workspace,
       testAnalysisResult,
       error,
-      (name) {
-        var provider = TopLevelDeclarationsProvider(tracker);
-        provider.doTrackerWork();
-        return provider.get(analysisContext, testFile, name);
+      (name) async {
+        return TopLevelDeclarations(testAnalysisResult).withName(name);
       },
       extensionCache: extensionCache,
     );
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index be2de8f..99f9bf1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -714,6 +714,224 @@
 ''');
   }
 
+  Future<void> test_withClass_pub_other_inLib_dependencies() async {
+    var aaaRoot = getFolder('$packagesRootPath/aaa');
+    newFile('${aaaRoot.path}/lib/a.dart', content: '''
+class Test {}
+''');
+
+    updateTestPubspecFile(r'''
+name: test
+dependencies:
+  aaa: any
+''');
+
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'aaa', rootPath: aaaRoot.path),
+    );
+
+    await resolveTestCode('''
+void f(Test t) {}
+''');
+
+    await assertHasFix('''
+import 'package:aaa/a.dart';
+
+void f(Test t) {}
+''');
+  }
+
+  Future<void> test_withClass_pub_other_inLib_devDependencies() async {
+    var aaaRoot = getFolder('$packagesRootPath/aaa');
+    newFile('${aaaRoot.path}/lib/a.dart', content: '''
+class Test {}
+''');
+
+    updateTestPubspecFile(r'''
+name: test
+dev_dependencies:
+  aaa: any
+''');
+
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'aaa', rootPath: aaaRoot.path),
+    );
+
+    await resolveTestCode('''
+void f(Test t) {}
+''');
+
+    await assertNoFix();
+  }
+
+  Future<void> test_withClass_pub_other_inLib_notListed() async {
+    var aaaRoot = getFolder('$packagesRootPath/aaa');
+    newFile('${aaaRoot.path}/lib/a.dart', content: '''
+class Test {}
+''');
+
+    updateTestPubspecFile(r'''
+name: test
+''');
+
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'aaa', rootPath: aaaRoot.path),
+    );
+
+    await resolveTestCode('''
+void f(Test t) {}
+''');
+
+    // If `aaa` is not in `dependencies`, we will not suggest it.
+    await assertNoFix();
+  }
+
+  Future<void> test_withClass_pub_other_inTest_dependencies() async {
+    var aaaRoot = getFolder('$packagesRootPath/aaa');
+    newFile('${aaaRoot.path}/lib/a.dart', content: '''
+class Test {}
+''');
+
+    updateTestPubspecFile(r'''
+name: test
+dependencies:
+  aaa: any
+''');
+
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'aaa', rootPath: aaaRoot.path),
+    );
+
+    var b = newFile('$testPackageTestPath/b.dart', content: r'''
+void f(Test t) {}
+''');
+
+    await resolveFile2(b.path);
+
+    await assertHasFix('''
+import 'package:aaa/a.dart';
+
+void f(Test t) {}
+''', target: b.path);
+  }
+
+  Future<void> test_withClass_pub_other_inTest_devDependencies() async {
+    var aaaRoot = getFolder('$packagesRootPath/aaa');
+    newFile('${aaaRoot.path}/lib/a.dart', content: '''
+class Test {}
+''');
+
+    updateTestPubspecFile(r'''
+name: test
+dev_dependencies:
+  aaa: any
+''');
+
+    writeTestPackageConfig(
+      config: PackageConfigFileBuilder()
+        ..add(name: 'aaa', rootPath: aaaRoot.path),
+    );
+
+    var b = newFile('$testPackageTestPath/b.dart', content: r'''
+void f(Test t) {}
+''');
+
+    await resolveFile2(b.path);
+
+    await assertHasFix('''
+import 'package:aaa/a.dart';
+
+void f(Test t) {}
+''', target: b.path);
+  }
+
+  Future<void> test_withClass_pub_this() async {
+    updateTestPubspecFile(r'''
+name: test
+''');
+
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class Test {}
+''');
+
+    await resolveTestCode('''
+void f(Test t) {}
+''');
+
+    await assertHasFix('''
+import 'package:test/a.dart';
+
+void f(Test t) {}
+''');
+  }
+
+  Future<void> test_withClass_pub_this_inLib_excludesTest() async {
+    updateTestPubspecFile(r'''
+name: test
+''');
+
+    newFile('$testPackageTestPath/a.dart', content: r'''
+class Test {}
+''');
+
+    await resolveTestCode('''
+void f(Test t) {}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_withClass_pub_this_inTest_includesTest() async {
+    updateTestPubspecFile(r'''
+name: test
+''');
+
+    newFile('$testPackageTestPath/a.dart', content: r'''
+class Test {}
+''');
+
+    var b = newFile('$testPackageTestPath/b.dart', content: r'''
+void f(Test t) {}
+''');
+
+    await resolveFile2(b.path);
+
+    await assertHasFix('''
+import 'a.dart';
+
+void f(Test t) {}
+''', target: b.path);
+  }
+
+  Future<void> test_withExtension_pub_this() async {
+    updateTestPubspecFile(r'''
+name: test
+''');
+
+    newFile('$testPackageLibPath/a.dart', content: r'''
+extension IntExtension on int {
+  int get foo => 0;
+}
+''');
+
+    await resolveTestCode('''
+void f() {
+  IntExtension(0).foo;
+}
+''');
+
+    await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+  IntExtension(0).foo;
+}
+''');
+  }
+
   Future<void> test_withFunction() async {
     addSource('$testPackageLibPath/lib.dart', '''
 library lib;
@@ -973,47 +1191,6 @@
   @override
   FixKind get kind => DartFixKind.IMPORT_LIBRARY_PROJECT3;
 
-  Future<void> test_inLibSrc_differentContextRoot() async {
-    newFile('/.pub-cache/bbb/lib/b1.dart', content: r'''
-import 'src/b2.dart';
-class A {}
-''');
-
-    writeTestPackageConfig(
-      config: PackageConfigFileBuilder()
-        ..add(name: 'bbb', rootPath: '/.pub-cache/bbb'),
-    );
-
-    newFile('/.pub-cache/bbb/lib/src/b2.dart', content: 'class Test {}');
-    await resolveTestCode('''
-import 'package:bbb/b1.dart';
-main() {
-  Test t;
-  A? a;
-  print('\$t \$a');
-}
-''');
-    await assertNoFix();
-  }
-
-  Future<void> test_inLibSrc_thisContextRoot() async {
-    addSource('$testPackageLibPath/src/lib.dart', 'class Test {}');
-    await resolveTestCode('''
-main() {
-  Test t;
-  print(t);
-}
-''');
-    await assertHasFix('''
-import 'package:test/src/lib.dart';
-
-main() {
-  Test t;
-  print(t);
-}
-''');
-  }
-
   Future<void> test_inLibSrc_thisContextRoot_extension() async {
     addSource('$testPackageLibPath/src/lib.dart', '''
 extension E on int {
@@ -1033,4 +1210,46 @@
 }
 ''');
   }
+
+  Future<void> test_withClass_pub_this_inLib_includesThisSrc() async {
+    updateTestPubspecFile(r'''
+name: test
+''');
+
+    newFile('$testPackageLibPath/src/a.dart', content: r'''
+class Test {}
+''');
+
+    await resolveTestCode('''
+void f(Test t) {}
+''');
+
+    await assertHasFix('''
+import 'package:test/src/a.dart';
+
+void f(Test t) {}
+''');
+  }
+
+  Future<void> test_withClass_pub_this_inTest_includesThisSrc() async {
+    updateTestPubspecFile(r'''
+name: test
+''');
+
+    newFile('$testPackageLibPath/src/a.dart', content: r'''
+class Test {}
+''');
+
+    var b = newFile('$testPackageTestPath/b.dart', content: r'''
+void f(Test t) {}
+''');
+
+    await resolveFile2(b.path);
+
+    await assertHasFix('''
+import 'package:test/src/a.dart';
+
+void f(Test t) {}
+''', target: b.path);
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state_filter.dart b/pkg/analyzer/lib/src/dart/analysis/file_state_filter.dart
new file mode 100644
index 0000000..828d7ad
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state_filter.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/lint/pub.dart';
+import 'package:analyzer/src/workspace/pub.dart';
+import 'package:collection/collection.dart';
+
+abstract class FileStateFilter {
+  /// Return a filter of files that can be accessed by the [file].
+  factory FileStateFilter(FileState file) {
+    var workspacePackage = file.workspacePackage;
+    if (workspacePackage is PubWorkspacePackage) {
+      return _PubFilter(workspacePackage, file.path);
+    } else {
+      return _AnyFilter();
+    }
+  }
+
+  bool shouldInclude(FileState file);
+}
+
+class _AnyFilter implements FileStateFilter {
+  @override
+  bool shouldInclude(FileState file) => true;
+}
+
+class _PubFilter implements FileStateFilter {
+  final PubWorkspacePackage targetPackage;
+  final String? targetPackageName;
+  final bool targetInLib;
+  final Set<String> dependencies;
+
+  factory _PubFilter(PubWorkspacePackage package, String path) {
+    var inLib = package.workspace.provider
+        .getFolder(package.root)
+        .getChildAssumingFolder('lib')
+        .contains(path);
+
+    var dependencies = <String>{};
+    var pubspec = package.pubspec;
+    if (pubspec != null) {
+      dependencies.addAll(pubspec.dependencies.names);
+      if (!inLib) {
+        dependencies.addAll(pubspec.devDependencies.names);
+      }
+    }
+
+    return _PubFilter._(
+      targetPackage: package,
+      targetPackageName: pubspec?.name?.value.text,
+      targetInLib: inLib,
+      dependencies: dependencies,
+    );
+  }
+
+  _PubFilter._({
+    required this.targetPackage,
+    required this.targetPackageName,
+    required this.targetInLib,
+    required this.dependencies,
+  });
+
+  @override
+  bool shouldInclude(FileState file) {
+    var uri = file.uriProperties;
+    if (uri.isDart) {
+      return true;
+    }
+
+    // Normally only package URIs are available.
+    // But outside of lib/ we allow any files of this package.
+    var packageName = uri.packageName;
+    if (packageName == null) {
+      if (targetInLib) {
+        return false;
+      } else {
+        var filePackage = file.workspacePackage;
+        return filePackage is PubWorkspacePackage &&
+            filePackage.root == targetPackage.root;
+      }
+    }
+
+    // Any `package:` library from the same package.
+    if (packageName == targetPackageName) {
+      return true;
+    }
+
+    // If not the same package, must be public.
+    if (uri.isSrc) {
+      return false;
+    }
+
+    return dependencies.contains(packageName);
+  }
+}
+
+extension on PSDependencyList? {
+  List<String> get names {
+    final self = this;
+    if (self == null) {
+      return const [];
+    } else {
+      return self
+          .map((dependency) => dependency.name?.text)
+          .whereNotNull()
+          .toList();
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 80357fb..6476871 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -43,39 +43,9 @@
   libraryWalker.walk(libraryWalker.getNode(file));
 }
 
-class CiderUnitTopLevelDeclarations {
-  final List<String> extensionNames;
-  final List<String> functionNames;
-  final List<String> typeNames;
-  final List<String> variableNames;
-
-  CiderUnitTopLevelDeclarations({
-    required this.extensionNames,
-    required this.functionNames,
-    required this.typeNames,
-    required this.variableNames,
-  });
-
-  factory CiderUnitTopLevelDeclarations.read(SummaryDataReader reader) {
-    return CiderUnitTopLevelDeclarations(
-      extensionNames: reader.readStringUtf8List(),
-      functionNames: reader.readStringUtf8List(),
-      typeNames: reader.readStringUtf8List(),
-      variableNames: reader.readStringUtf8List(),
-    );
-  }
-
-  void write(BufferedSink sink) {
-    sink.writeStringUtf8Iterable(extensionNames);
-    sink.writeStringUtf8Iterable(functionNames);
-    sink.writeStringUtf8Iterable(typeNames);
-    sink.writeStringUtf8Iterable(variableNames);
-  }
-}
-
 class CiderUnlinkedUnit {
   /// Top-level declarations of the unit.
-  final CiderUnitTopLevelDeclarations topLevelDeclarations;
+  final Set<String> topLevelDeclarations;
 
   /// Unlinked summary of the compilation unit.
   final UnlinkedUnit unit;
@@ -93,7 +63,7 @@
 
   factory CiderUnlinkedUnit.read(SummaryDataReader reader) {
     return CiderUnlinkedUnit(
-      topLevelDeclarations: CiderUnitTopLevelDeclarations.read(reader),
+      topLevelDeclarations: reader.readStringUtf8Set(),
       unit: UnlinkedUnit.read(reader),
     );
   }
@@ -106,7 +76,7 @@
   }
 
   void write(BufferedSink sink) {
-    topLevelDeclarations.write(sink);
+    sink.writeStringUtf8Iterable(topLevelDeclarations);
     unit.write(sink);
   }
 }
@@ -386,40 +356,12 @@
   }
 
   /// Return files that have a top-level declaration with the [name].
-  List<FileWithTopLevelDeclaration> getFilesWithTopLevelDeclarations(
-    String name,
-  ) {
-    var result = <FileWithTopLevelDeclaration>[];
-
+  List<FileState> getFilesWithTopLevelDeclarations(String name) {
+    var result = <FileState>[];
     for (var file in _pathToFile.values) {
-      void addDeclaration(
-        List<String> names,
-        FileTopLevelDeclarationKind kind,
-      ) {
-        if (names.contains(name)) {
-          result.add(
-            FileWithTopLevelDeclaration(file: file, kind: kind),
-          );
-        }
+      if (file._unlinked.unlinked.topLevelDeclarations.contains(name)) {
+        result.add(file);
       }
-
-      var topLevelDeclarations = file._unlinked.unlinked.topLevelDeclarations;
-      addDeclaration(
-        topLevelDeclarations.extensionNames,
-        FileTopLevelDeclarationKind.extension,
-      );
-      addDeclaration(
-        topLevelDeclarations.functionNames,
-        FileTopLevelDeclarationKind.function,
-      );
-      addDeclaration(
-        topLevelDeclarations.typeNames,
-        FileTopLevelDeclarationKind.type,
-      );
-      addDeclaration(
-        topLevelDeclarations.variableNames,
-        FileTopLevelDeclarationKind.variable,
-      );
     }
     return result;
   }
@@ -527,20 +469,6 @@
   }
 }
 
-/// The kind in [FileWithTopLevelDeclaration].
-enum FileTopLevelDeclarationKind { extension, function, type, variable }
-
-/// The data structure for top-level declarations response.
-class FileWithTopLevelDeclaration {
-  final FileState file;
-  final FileTopLevelDeclarationKind kind;
-
-  FileWithTopLevelDeclaration({
-    required this.file,
-    required this.kind,
-  });
-}
-
 /// Information about libraries that reference each other, so form a cycle.
 class LibraryCycle {
   /// The libraries that belong to this cycle.
@@ -1004,27 +932,24 @@
       );
     }
 
-    var declaredExtensions = <String>[];
-    var declaredFunctions = <String>[];
-    var declaredTypes = <String>[];
-    var declaredVariables = <String>[];
+    var topLevelDeclarations = <String>{};
     for (var declaration in unit.declarations) {
       if (declaration is ClassDeclaration) {
-        declaredTypes.add(declaration.name.name);
+        topLevelDeclarations.add(declaration.name.name);
       } else if (declaration is EnumDeclaration) {
-        declaredTypes.add(declaration.name.name);
+        topLevelDeclarations.add(declaration.name.name);
       } else if (declaration is ExtensionDeclaration) {
         var name = declaration.name;
         if (name != null) {
-          declaredExtensions.add(name.name);
+          topLevelDeclarations.add(name.name);
         }
       } else if (declaration is FunctionDeclaration) {
-        declaredFunctions.add(declaration.name.name);
+        topLevelDeclarations.add(declaration.name.name);
       } else if (declaration is MixinDeclaration) {
-        declaredTypes.add(declaration.name.name);
+        topLevelDeclarations.add(declaration.name.name);
       } else if (declaration is TopLevelVariableDeclaration) {
         for (var variable in declaration.variables.variables) {
-          declaredVariables.add(variable.name.name);
+          topLevelDeclarations.add(variable.name.name);
         }
       }
     }
@@ -1044,12 +969,7 @@
 
     return CiderUnlinkedUnit(
       unit: unlinkedUnit,
-      topLevelDeclarations: CiderUnitTopLevelDeclarations(
-        extensionNames: declaredExtensions,
-        functionNames: declaredFunctions,
-        typeNames: declaredTypes,
-        variableNames: declaredVariables,
-      ),
+      topLevelDeclarations: topLevelDeclarations,
     );
   }
 
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 61e6301..ac5a4809 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -310,9 +310,7 @@
   }
 
   /// Return files that have a top-level declaration with the [name].
-  List<FileWithTopLevelDeclaration> getFilesWithTopLevelDeclarations(
-    String name,
-  ) {
+  List<FileState> getFilesWithTopLevelDeclarations(String name) {
     final fsState = this.fsState;
     if (fsState == null) {
       return const [];
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 276bad0..0279e72 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -45,6 +45,7 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/this_access_tracker.dart';
+import 'package:analyzer/src/utilities/extensions/string.dart';
 import 'package:collection/collection.dart';
 
 class EnclosingExecutableContext {
@@ -1501,7 +1502,7 @@
           conflictingMembers.map((e) => _getLibraryName(e)).toList();
       libraryNames.sort();
       errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_IMPORT,
-          node, [name, StringUtilities.printListOfQuotedNames(libraryNames)]);
+          node, [name, libraryNames.quotedAndCommaSeparatedWithAnd]);
     }
   }
 
@@ -4967,7 +4968,7 @@
       buffer.write(" (via ");
       if (indirectCount > 1) {
         indirectSources.sort();
-        buffer.write(StringUtilities.printListOfQuotedNames(indirectSources));
+        buffer.write(indirectSources.quotedAndCommaSeparatedWithAnd);
       } else {
         buffer.write(indirectSources[0]);
       }
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index e880604..c2e9773 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -46,34 +46,4 @@
   }
 
   static String intern(String string) => INTERNER.intern(string);
-
-  /// Produce a string containing all of the names in the given array,
-  /// surrounded by single quotes, and separated by commas.
-  ///
-  /// The list must contain at least two elements.
-  ///
-  /// @param names the names to be printed
-  /// @return the result of printing the names
-  static String printListOfQuotedNames(List<String>? names) {
-    if (names == null) {
-      throw ArgumentError("The list must not be null");
-    }
-    int count = names.length;
-    if (count < 2) {
-      throw ArgumentError("The list must contain at least two names");
-    }
-    StringBuffer buffer = StringBuffer();
-    buffer.write("'");
-    buffer.write(names[0]);
-    buffer.write("'");
-    for (int i = 1; i < count - 1; i++) {
-      buffer.write(", '");
-      buffer.write(names[i]);
-      buffer.write("'");
-    }
-    buffer.write(" and '");
-    buffer.write(names[count - 1]);
-    buffer.write("'");
-    return buffer.toString();
-  }
 }
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 73b4a73..682acc6 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/src/analysis_options/error/option_codes.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/lint/config.dart';
@@ -365,7 +364,7 @@
 
   /// Pretty String listing legal values.
   static final String legalValueString =
-      StringUtilities.printListOfQuotedNames(legalValues);
+      legalValues.quotedAndCommaSeparatedWithAnd;
 
   /// Lazily populated set of error codes.
   static final Set<String> _errorCodes =
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index e307a4f..d13df5d 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -1142,8 +1142,9 @@
       throw 0;
 }
 
-enum ProcessStartMode {
-  normal,
+class ProcessStartMode {
+  static const normal = const ProcessStartMode._internal(0);
+  const ProcessStartMode._internal(int mode);
 }
 
 abstract class Process {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 42f04ed..d3beec6 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2592,39 +2592,4 @@
     expect(StringUtilities.endsWithChar("b", 0x61), isFalse);
     expect(StringUtilities.endsWithChar("", 0x61), isFalse);
   }
-
-  void test_printListOfQuotedNames_empty() {
-    expect(() {
-      StringUtilities.printListOfQuotedNames([]);
-    }, throwsArgumentError);
-  }
-
-  void test_printListOfQuotedNames_five() {
-    expect(
-        StringUtilities.printListOfQuotedNames(
-            <String>["a", "b", "c", "d", "e"]),
-        "'a', 'b', 'c', 'd' and 'e'");
-  }
-
-  void test_printListOfQuotedNames_null() {
-    expect(() {
-      StringUtilities.printListOfQuotedNames(null);
-    }, throwsArgumentError);
-  }
-
-  void test_printListOfQuotedNames_one() {
-    expect(() {
-      StringUtilities.printListOfQuotedNames(<String>["a"]);
-    }, throwsArgumentError);
-  }
-
-  void test_printListOfQuotedNames_three() {
-    expect(StringUtilities.printListOfQuotedNames(<String>["a", "b", "c"]),
-        "'a', 'b' and 'c'");
-  }
-
-  void test_printListOfQuotedNames_two() {
-    expect(StringUtilities.printListOfQuotedNames(<String>["a", "b"]),
-        "'a' and 'b'");
-  }
 }
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 0b35e99..4044e88 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
-import 'package:analyzer/src/dart/micro/library_graph.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
 import 'package:analyzer/src/dart/micro/utils.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -768,8 +767,7 @@
       var files = fileResolver.getFilesWithTopLevelDeclarations('a');
       expect(files, hasLength(1));
       var file = files.single;
-      expect(file.file.path, result.path);
-      expect(file.kind, FileTopLevelDeclarationKind.variable);
+      expect(file.path, result.path);
     }
 
     // Ask to check that it works when parsed.
diff --git a/pkg/front_end/lib/src/fasta/builder/builder.dart b/pkg/front_end/lib/src/fasta/builder/builder.dart
index f933d9f..7b208f1 100644
--- a/pkg/front_end/lib/src/fasta/builder/builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/builder.dart
@@ -200,10 +200,6 @@
   /// Returns the number of patches that was finished.
   int finishPatch();
 
-  /// Resolve constructors (lookup names in scope) recorded in this builder and
-  /// return the number of constructors resolved.
-  int resolveConstructors(covariant Builder? parent);
-
   /// Return `true` if this builder is a duplicate of another with the same
   /// name. This is `false` for the builder first declared amongst duplicates.
   bool get isDuplicate;
@@ -305,8 +301,5 @@
   }
 
   @override
-  int resolveConstructors(covariant Builder parent) => 0;
-
-  @override
   bool get isDuplicate => next != null;
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index b181d62..5c954d0 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -220,18 +220,22 @@
   void buildOutlineExpressions(SourceLibraryBuilder library,
       List<DelayedActionPerformer> delayedActionPerformers) {
     if (initializerToken != null) {
-      // For modular compilation we need to include initializers for optional
-      // and named parameters of const constructors into the outline - to enable
-      // constant evaluation. Similarly we need to include initializers for
-      // optional and named parameters of instance methods because these might
-      // be needed to generated noSuchMethod forwarders.
-      bool isConstConstructorParameter = false;
+      // For modular compilation we need to include default values for optional
+      // and named parameters in several cases:
+      // * for const constructors to enable constant evaluation,
+      // * for instance methods because these might be needed to generated
+      //   noSuchMethod forwarders, and
+      // * for generative constructors to support forwarding constructors
+      //   in mixin applications.
+      bool needsDefaultValues = false;
       if (parent is ConstructorBuilder) {
-        isConstConstructorParameter = parent!.isConst;
+        needsDefaultValues = true;
       } else if (parent is SourceFactoryBuilder) {
-        isConstConstructorParameter = parent!.isFactory && parent!.isConst;
+        needsDefaultValues = parent!.isFactory && parent!.isConst;
+      } else {
+        needsDefaultValues = parent!.isClassInstanceMember;
       }
-      if (isConstConstructorParameter || parent!.isClassInstanceMember) {
+      if (needsDefaultValues) {
         final ClassBuilder classBuilder = parent!.parent as ClassBuilder;
         Scope scope = classBuilder.scope;
         BodyBuilder bodyBuilder = library.loader
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 1672a7d..f2c63b8 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -29,7 +29,6 @@
 
 import 'builder.dart';
 import 'class_builder.dart';
-import 'field_builder.dart';
 import 'member_builder.dart';
 import 'modifier_builder.dart';
 import 'name_iterator.dart';
@@ -101,14 +100,6 @@
       String name, Builder declaration, Builder other, int charOffset,
       {bool isExport: false, bool isImport: false});
 
-  int finishDeferredLoadTearoffs();
-
-  int finishForwarders();
-
-  int finishNativeMethods();
-
-  int finishPatchMethods();
-
   /// Looks up [constructorName] in the class named [className].
   ///
   /// The class is looked up in this library's export scope unless
@@ -124,21 +115,6 @@
   MemberBuilder getConstructor(String className,
       {String constructorName, bool bypassLibraryPrivacy: false});
 
-  int finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType);
-
-  /// Computes variances of type parameters on typedefs.
-  ///
-  /// The variance property of type parameters on typedefs is computed from the
-  /// use of the parameters in the right-hand side of the typedef definition.
-  int computeVariances() => 0;
-
-  /// This method instantiates type parameters to their bounds in some cases
-  /// where they were omitted by the programmer and not provided by the type
-  /// inference.  The method returns the number of distinct type variables
-  /// that were instantiated in this library.
-  int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
-      TypeBuilder bottomType, ClassBuilder objectClass);
-
   void becomeCoreLibrary();
 
   void addSyntheticDeclarationOfDynamic();
@@ -160,10 +136,6 @@
 
   void recordAccess(int charOffset, int length, Uri fileUri);
 
-  void buildOutlineExpressions();
-
-  List<FieldBuilder>? takeImplicitlyTypedFields();
-
   bool get isNonNullableByDefault;
 
   Nullability get nullable;
@@ -286,18 +258,6 @@
   }
 
   @override
-  int finishDeferredLoadTearoffs() => 0;
-
-  @override
-  int finishForwarders() => 0;
-
-  @override
-  int finishNativeMethods() => 0;
-
-  @override
-  int finishPatchMethods() => 0;
-
-  @override
   MemberBuilder getConstructor(String className,
       {String? constructorName, bool bypassLibraryPrivacy: false}) {
     constructorName ??= "";
@@ -340,18 +300,6 @@
   }
 
   @override
-  int finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) => 0;
-
-  @override
-  int computeVariances() => 0;
-
-  @override
-  int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
-      TypeBuilder bottomType, ClassBuilder objectClass) {
-    return 0;
-  }
-
-  @override
   void becomeCoreLibrary() {
     if (scope.lookupLocalMember("dynamic", setter: false) == null) {
       addSyntheticDeclarationOfDynamic();
@@ -392,12 +340,6 @@
   void recordAccess(int charOffset, int length, Uri fileUri) {}
 
   @override
-  void buildOutlineExpressions() {}
-
-  @override
-  List<FieldBuilder>? takeImplicitlyTypedFields() => null;
-
-  @override
   Nullability get nullable {
     return isNonNullableByDefault ? Nullability.nullable : Nullability.legacy;
   }
@@ -438,7 +380,7 @@
 
   @override
   StringBuffer printOn(StringBuffer buffer) {
-    return buffer..write(name ?? importUri);
+    return buffer..write(name ?? (isPart ? fileUri : importUri));
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index c693edd..a95dd25 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -465,24 +465,17 @@
     Set<Library> newDillLibraryBuilders = new Set<Library>();
     _userBuilders ??= <Uri, LibraryBuilder>{};
     Map<LibraryBuilder, List<LibraryBuilder>>? convertedLibraries;
-    for (LibraryBuilder builder
-        in nextGoodKernelTarget.loader.libraryBuilders) {
-      if (builder is SourceLibraryBuilder) {
-        DillLibraryBuilder dillBuilder =
-            _dillLoadedData!.loader.appendLibrary(builder.library);
-        nextGoodKernelTarget.loader.registerLibraryBuilder(
-            // TODO(johnniwinther): Why do we need to create
-            //  [DillLibraryBuilder]s for the patch library file uris?
-            dillBuilder,
-            builder.isPatch ? builder.fileUri : null);
-        _userBuilders![builder.importUri] = dillBuilder;
-        newDillLibraryBuilders.add(builder.library);
-        changed = true;
-        if (experimentalInvalidation != null) {
-          convertedLibraries ??=
-              new Map<LibraryBuilder, List<LibraryBuilder>>();
-          convertedLibraries[builder] = [dillBuilder];
-        }
+    for (SourceLibraryBuilder builder
+        in nextGoodKernelTarget.loader.sourceLibraryBuilders) {
+      DillLibraryBuilder dillBuilder =
+          _dillLoadedData!.loader.appendLibrary(builder.library);
+      nextGoodKernelTarget.loader.registerLibraryBuilder(dillBuilder);
+      _userBuilders![builder.importUri] = dillBuilder;
+      newDillLibraryBuilders.add(builder.library);
+      changed = true;
+      if (experimentalInvalidation != null) {
+        convertedLibraries ??= new Map<LibraryBuilder, List<LibraryBuilder>>();
+        convertedLibraries[builder] = [dillBuilder];
       }
     }
     if (changed) {
@@ -537,6 +530,8 @@
 
   bool _checkEquivalentScopes(
       SourceLoader sourceLoader, DillLoader dillLoader) {
+    // TODO(johnniwinther): Use [SourceLoader.sourceLibraryBuilders] here.
+    // Currently this causes a failure in incremental_dartino_suite.dart.
     for (LibraryBuilder sourceLibraryBuilder in sourceLoader.libraryBuilders) {
       if (sourceLibraryBuilder is SourceLibraryBuilder) {
         Uri uri = sourceLibraryBuilder.importUri;
@@ -1733,12 +1728,11 @@
       }
 
       SourceLibraryBuilder debugLibrary = new SourceLibraryBuilder(
-        libraryUri,
-        debugExprUri,
-        /*packageUri*/ null,
-        new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
-        lastGoodKernelTarget.loader,
-        null,
+        importUri: libraryUri,
+        fileUri: debugExprUri,
+        packageLanguageVersion:
+            new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
+        loader: lastGoodKernelTarget.loader,
         scope: libraryBuilder.scope.createNestedScope("expression"),
         nameOrigin: libraryBuilder,
       );
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 9440adf..031764f0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -361,23 +361,6 @@
     return entryPoint;
   }
 
-  /// Returns classes defined in libraries in [loader].
-  List<SourceClassBuilder> collectMyClasses() {
-    List<SourceClassBuilder> result = <SourceClassBuilder>[];
-    for (LibraryBuilder library in loader.libraryBuilders) {
-      if (library.loader == loader) {
-        Iterator<Builder> iterator = library.iterator;
-        while (iterator.moveNext()) {
-          Builder member = iterator.current;
-          if (member is SourceClassBuilder && !member.isPatch) {
-            result.add(member);
-          }
-        }
-      }
-    }
-    return result;
-  }
-
   /// The class [cls] is involved in a cyclic definition. This method should
   /// ensure that the cycle is broken, for example, by removing superclass and
   /// implemented interfaces.
@@ -460,10 +443,10 @@
       finishSynthesizedParameters();
       loader.finishDeferredLoadTearoffs();
       loader.finishNoSuchMethodForwarders();
-      List<SourceClassBuilder> myClasses = collectMyClasses();
+      List<SourceClassBuilder> sourceClasses = loader.collectSourceClasses();
       loader.finishNativeMethods();
       loader.finishPatchMethods();
-      finishAllConstructors(myClasses);
+      finishAllConstructors(sourceClasses);
       runBuildTransformations();
 
       if (verify) this.verify();
@@ -625,33 +608,8 @@
 
   void installDefaultSupertypes() {
     Class objectClass = this.objectClass;
-    for (LibraryBuilder library in loader.libraryBuilders) {
-      if (library.loader == loader) {
-        Iterator<Builder> iterator = library.iterator;
-        while (iterator.moveNext()) {
-          Builder declaration = iterator.current;
-          if (declaration is SourceClassBuilder) {
-            Class cls = declaration.cls;
-            if (cls != objectClass) {
-              cls.supertype ??= objectClass.asRawSupertype;
-              declaration.supertypeBuilder ??= new NamedTypeBuilder(
-                  "Object",
-                  const NullabilityBuilder.omitted(),
-                  /* arguments = */ null,
-                  /* fileUri = */ null,
-                  /* charOffset = */ null,
-                  instanceTypeVariableAccess:
-                      InstanceTypeVariableAccessState.Unexpected)
-                ..bind(objectClassBuilder);
-            }
-            if (declaration.isMixinApplication) {
-              cls.mixedInType = declaration.mixedInTypeBuilder!
-                  .buildMixedInType(
-                      library, declaration.charOffset, declaration.fileUri);
-            }
-          }
-        }
-      }
+    for (SourceLibraryBuilder library in loader.sourceLibraryBuilders) {
+      library.installDefaultSupertypes(objectClassBuilder, objectClass);
     }
     ticker.logMs("Installed Object as implicit superclass");
   }
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 8873c4e..23ad100 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -913,7 +913,6 @@
         new ConstructorTearOff(constructorBuilder.member)..parent = literal);
   }
 
-  @override
   int resolveConstructors(SourceLibraryBuilder library) {
     if (constructorReferences == null) return 0;
     for (ConstructorReferenceBuilder ref in constructorReferences!) {
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 2666f82..10714d1 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -17,6 +17,7 @@
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
 import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
+import 'package:kernel/core_types.dart';
 
 import 'package:kernel/reference_from_index.dart'
     show IndexedClass, IndexedContainer, IndexedLibrary;
@@ -84,6 +85,7 @@
 import '../kernel/constructor_tearoff_lowering.dart';
 import '../kernel/implicit_field_type.dart';
 import '../kernel/internal_ast.dart';
+import '../kernel/kernel_helper.dart';
 import '../kernel/load_library_builder.dart';
 import '../kernel/type_algorithms.dart'
     show
@@ -122,6 +124,7 @@
 
 import '../type_inference/type_inferrer.dart' show TypeInferrerImpl;
 
+import '../util/helpers.dart';
 import 'name_scheme.dart';
 import 'source_class_builder.dart' show SourceClassBuilder;
 import 'source_extension_builder.dart';
@@ -181,7 +184,7 @@
   @override
   final Library library;
 
-  final SourceLibraryBuilder? actualOrigin;
+  final SourceLibraryBuilder? _origin;
 
   final List<FunctionBuilder> nativeMethods = <FunctionBuilder>[];
 
@@ -256,13 +259,15 @@
   /// [forEachExtensionInScope].
   Set<ExtensionBuilder>? _extensionsInScope;
 
+  List<SourceLibraryBuilder>? _patchLibraries;
+
   SourceLibraryBuilder.internal(
       SourceLoader loader,
       Uri fileUri,
       Uri? packageUri,
       LanguageVersion packageLanguageVersion,
       Scope? scope,
-      SourceLibraryBuilder? actualOrigin,
+      SourceLibraryBuilder? origin,
       Library library,
       LibraryBuilder? nameOrigin,
       Library? referencesFrom,
@@ -274,7 +279,7 @@
             packageLanguageVersion,
             new TypeParameterScopeBuilder.library(),
             scope ?? new Scope.top(),
-            actualOrigin,
+            origin,
             library,
             nameOrigin,
             referencesFrom);
@@ -286,7 +291,7 @@
       this.packageLanguageVersion,
       this._libraryTypeParameterScopeBuilder,
       this.importScope,
-      this.actualOrigin,
+      SourceLibraryBuilder? origin,
       this.library,
       this._nameOrigin,
       this.referencesFrom)
@@ -294,6 +299,7 @@
         currentTypeParameterScopeBuilder = _libraryTypeParameterScopeBuilder,
         referencesFromIndexed =
             referencesFrom == null ? null : new IndexedLibrary(referencesFrom),
+        _origin = origin,
         super(fileUri, _libraryTypeParameterScopeBuilder.toScope(importScope),
             new Scope.top()) {
     assert(
@@ -457,13 +463,13 @@
   }
 
   SourceLibraryBuilder(
-      Uri uri,
-      Uri fileUri,
+      {required Uri importUri,
+      required Uri fileUri,
       Uri? packageUri,
-      LanguageVersion packageLanguageVersion,
-      SourceLoader loader,
-      SourceLibraryBuilder? actualOrigin,
-      {Scope? scope,
+      required LanguageVersion packageLanguageVersion,
+      required SourceLoader loader,
+      SourceLibraryBuilder? origin,
+      Scope? scope,
       Library? target,
       LibraryBuilder? nameOrigin,
       Library? referencesFrom,
@@ -474,10 +480,10 @@
             packageUri,
             packageLanguageVersion,
             scope,
-            actualOrigin,
+            origin,
             target ??
-                (actualOrigin?.library ??
-                    new Library(uri,
+                (origin?.library ??
+                    new Library(importUri,
                         fileUri: fileUri,
                         reference: referenceIsPartOwner == true
                             ? null
@@ -490,6 +496,17 @@
   @override
   bool get isPart => partOfName != null || partOfUri != null;
 
+  // TODO(johnniwinther): Can avoid using this from outside this class?
+  Iterable<SourceLibraryBuilder>? get patchLibraries => _patchLibraries;
+
+  void addPatchLibrary(SourceLibraryBuilder patchLibrary) {
+    assert(patchLibrary.isPatch,
+        "Library ${patchLibrary} must be a patch library.");
+    assert(!patchLibrary.isPart,
+        "Patch library ${patchLibrary} cannot be a part .");
+    (_patchLibraries ??= []).add(patchLibrary);
+  }
+
   List<NamedTypeBuilder> get unresolvedNamedTypes =>
       _libraryTypeParameterScopeBuilder.unresolvedNamedTypes;
 
@@ -1045,6 +1062,19 @@
 
   /// Builds the core AST structure of this library as needed for the outline.
   Library build(LibraryBuilder coreLibrary, {bool modifyTarget: true}) {
+    // TODO(johnniwinther): Avoid the need to process patch libraries before
+    // the origin. Currently, settings performed by the patch are overridden
+    // by the origin. For instance, the `Map` class is abstract in the origin
+    // but (unintentionally) concrete in the patch. By processing the origin
+    // last the `isAbstract` property set by the patch is corrected by the
+    // origin.
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.build(coreLibrary, modifyTarget: modifyTarget);
+      }
+    }
+
     checkMemberConflicts(this, scope,
         checkForInstanceVsStaticConflict: false,
         checkForMethodVsSetterConflict: true);
@@ -1291,9 +1321,9 @@
         (library.problemsAsJson ??= <String>[])
             .addAll(part.library.problemsAsJson!);
       }
-      List<FieldBuilder>? partImplicitlyTypedFields =
-          part.takeImplicitlyTypedFields();
-      if (partImplicitlyTypedFields != null) {
+      List<FieldBuilder> partImplicitlyTypedFields = [];
+      part.collectImplicitlyTypedFields(partImplicitlyTypedFields);
+      if (partImplicitlyTypedFields.isNotEmpty) {
         if (_implicitlyTypedFields == null) {
           _implicitlyTypedFields = partImplicitlyTypedFields;
         } else {
@@ -1324,6 +1354,13 @@
   }
 
   void buildInitialScopes() {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.buildInitialScopes();
+      }
+    }
+
     NameIterator iterator = nameIterator;
     while (iterator.moveNext()) {
       addToExportScope(iterator.name, iterator.current);
@@ -1331,6 +1368,13 @@
   }
 
   void addImportsToScope() {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.addImportsToScope();
+      }
+    }
+
     bool explicitCoreImport = this == loader.coreLibrary;
     for (Import import in imports) {
       if (import.imported?.isPart ?? false) {
@@ -1433,7 +1477,16 @@
   /// Resolves all unresolved types in [unresolvedNamedTypes]. The list of types
   /// is cleared when done.
   int resolveTypes() {
-    int typeCount = unresolvedNamedTypes.length;
+    int typeCount = 0;
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        typeCount += patchLibrary.resolveTypes();
+      }
+    }
+
+    typeCount += unresolvedNamedTypes.length;
     for (NamedTypeBuilder namedType in unresolvedNamedTypes) {
       namedType.resolveIn(
           scope, namedType.charOffset!, namedType.fileUri!, this);
@@ -1443,12 +1496,75 @@
     return typeCount;
   }
 
-  @override
-  int resolveConstructors(_) {
-    int count = 0;
+  void installDefaultSupertypes(
+      ClassBuilder objectClassBuilder, Class objectClass) {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.installDefaultSupertypes(objectClassBuilder, objectClass);
+      }
+    }
+
     Iterator<Builder> iterator = this.iterator;
     while (iterator.moveNext()) {
-      count += iterator.current.resolveConstructors(this);
+      Builder declaration = iterator.current;
+      if (declaration is SourceClassBuilder) {
+        Class cls = declaration.cls;
+        if (cls != objectClass) {
+          cls.supertype ??= objectClass.asRawSupertype;
+          declaration.supertypeBuilder ??= new NamedTypeBuilder(
+              "Object",
+              const NullabilityBuilder.omitted(),
+              /* arguments = */ null,
+              /* fileUri = */ null,
+              /* charOffset = */ null,
+              instanceTypeVariableAccess:
+                  InstanceTypeVariableAccessState.Unexpected)
+            ..bind(objectClassBuilder);
+        }
+        if (declaration.isMixinApplication) {
+          cls.mixedInType = declaration.mixedInTypeBuilder!.buildMixedInType(
+              this, declaration.charOffset, declaration.fileUri);
+        }
+      }
+    }
+  }
+
+  void collectSourceClasses(List<SourceClassBuilder> sourceClasses) {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.collectSourceClasses(sourceClasses);
+      }
+    }
+
+    Iterator<Builder> iterator = this.iterator;
+    while (iterator.moveNext()) {
+      Builder member = iterator.current;
+      if (member is SourceClassBuilder && !member.isPatch) {
+        sourceClasses.add(member);
+      }
+    }
+  }
+
+  /// Resolve constructors (lookup names in scope) recorded in this builder and
+  /// return the number of constructors resolved.
+  int resolveConstructors() {
+    int count = 0;
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        count += patchLibrary.resolveConstructors();
+      }
+    }
+
+    Iterator<Builder> iterator = this.iterator;
+    while (iterator.moveNext()) {
+      Builder builder = iterator.current;
+      if (builder is SourceClassBuilder) {
+        count += builder.resolveConstructors(this);
+      }
     }
     return count;
   }
@@ -1491,7 +1607,7 @@
   }
 
   @override
-  SourceLibraryBuilder get origin => actualOrigin ?? this;
+  SourceLibraryBuilder get origin => _origin ?? this;
 
   @override
   Uri get importUri => library.importUri;
@@ -2800,10 +2916,45 @@
     return builder;
   }
 
-  @override
-  void buildOutlineExpressions() {
+  void buildOutlineExpressions(
+      CoreTypes coreTypes,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes,
+      List<DelayedActionPerformer> delayedActionPerformers) {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.buildOutlineExpressions(
+            coreTypes, synthesizedFunctionNodes, delayedActionPerformers);
+      }
+    }
+
     MetadataBuilder.buildAnnotations(
         library, metadata, this, null, null, fileUri, scope);
+
+    Iterator<Builder> iterator = this.iterator;
+    while (iterator.moveNext()) {
+      Builder declaration = iterator.current;
+      if (declaration is ClassBuilder) {
+        declaration.buildOutlineExpressions(
+            this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+      } else if (declaration is ExtensionBuilder) {
+        declaration.buildOutlineExpressions(
+            this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+      } else if (declaration is MemberBuilder) {
+        declaration.buildOutlineExpressions(
+            this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+      } else if (declaration is SourceTypeAliasBuilder) {
+        declaration.buildOutlineExpressions(
+            this, coreTypes, delayedActionPerformers, synthesizedFunctionNodes);
+      } else {
+        assert(
+            declaration is PrefixBuilder ||
+                declaration is DynamicTypeDeclarationBuilder ||
+                declaration is NeverTypeDeclarationBuilder,
+            "Unexpected builder in library: ${declaration} "
+            "(${declaration.runtimeType}");
+      }
+    }
   }
 
   /// Builds the core AST structures for [declaration] needed for the outline.
@@ -3016,9 +3167,16 @@
         suppressMessage: false);
   }
 
-  @override
   int finishDeferredLoadTearoffs() {
     int total = 0;
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        total += patchLibrary.finishDeferredLoadTearoffs();
+      }
+    }
+
     for (Import import in imports) {
       if (import.deferred) {
         Procedure? tearoff = import.prefixBuilder!.loadLibraryBuilder!.tearoff;
@@ -3028,12 +3186,20 @@
         total++;
       }
     }
+
     return total;
   }
 
-  @override
   int finishForwarders() {
     int count = 0;
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        count += patchLibrary.finishForwarders();
+      }
+    }
+
     CloneVisitorNotMembers cloner = new CloneVisitorNotMembers();
     for (int i = 0; i < forwardersOrigins.length; i += 2) {
       Procedure forwarder = forwardersOrigins[i];
@@ -3086,12 +3252,22 @@
     nativeMethods.add(method);
   }
 
-  @override
   int finishNativeMethods() {
+    int count = 0;
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        count += patchLibrary.finishNativeMethods();
+      }
+    }
+
     for (FunctionBuilder method in nativeMethods) {
       method.becomeNative(loader);
     }
-    return nativeMethods.length;
+    count += nativeMethods.length;
+
+    return count;
   }
 
   /// Creates a copy of [original] into the scope of [declaration].
@@ -3123,9 +3299,18 @@
     return copy;
   }
 
-  @override
   int finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) {
-    int count = unboundTypeVariables.length;
+    int count = 0;
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        count += patchLibrary.finishTypeVariables(object, dynamicType);
+      }
+    }
+
+    count += unboundTypeVariables.length;
+
     // Ensure that type parameters are built after their dependencies by sorting
     // them topologically using references in bounds.
     for (TypeVariableBuilder builder
@@ -3230,9 +3415,20 @@
     _pendingNullabilities.clear();
   }
 
-  @override
+  /// Computes variances of type parameters on typedefs.
+  ///
+  /// The variance property of type parameters on typedefs is computed from the
+  /// use of the parameters in the right-hand side of the typedef definition.
   int computeVariances() {
     int count = 0;
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        count += patchLibrary.computeVariances();
+      }
+    }
+
     for (Builder? declaration
         in _libraryTypeParameterScopeBuilder.members!.values) {
       while (declaration != null) {
@@ -3336,11 +3532,22 @@
     return false;
   }
 
-  @override
+  /// This method instantiates type parameters to their bounds in some cases
+  /// where they were omitted by the programmer and not provided by the type
+  /// inference.  The method returns the number of distinct type variables
+  /// that were instantiated in this library.
   int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
       TypeBuilder bottomType, ClassBuilder objectClass) {
     int count = 0;
 
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        count += patchLibrary.computeDefaultTypes(
+            dynamicType, nullType, bottomType, objectClass);
+      }
+    }
+
     int computeDefaultTypesForVariables(List<TypeVariableBuilder>? variables,
         {required bool inErrorRecovery}) {
       if (variables == null) return 0;
@@ -3560,7 +3767,6 @@
         }
       }
     }
-
     return count;
   }
 
@@ -3628,13 +3834,21 @@
     }
   }
 
-  @override
   int finishPatchMethods() {
-    if (!isPatch) return 0;
     int count = 0;
-    Iterator<Builder> iterator = this.iterator;
-    while (iterator.moveNext()) {
-      count += iterator.current.finishPatch();
+
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        count += patchLibrary.finishPatchMethods();
+      }
+    }
+
+    if (isPatch) {
+      Iterator<Builder> iterator = this.iterator;
+      while (iterator.moveNext()) {
+        count += iterator.current.finishPatch();
+      }
     }
     return count;
   }
@@ -4269,6 +4483,13 @@
   }
 
   void checkTypesInOutline(TypeEnvironment typeEnvironment) {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.checkTypesInOutline(typeEnvironment);
+      }
+    }
+
     Iterator<Builder> iterator = this.iterator;
     while (iterator.moveNext()) {
       Builder declaration = iterator.current;
@@ -4302,6 +4523,13 @@
   }
 
   void computeShowHideElements(ClassMembersBuilder membersBuilder) {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.computeShowHideElements(membersBuilder);
+      }
+    }
+
     assert(currentTypeParameterScopeBuilder.kind ==
         TypeParameterScopeKind.library);
     for (SourceExtensionBuilder extensionBuilder
@@ -4513,11 +4741,19 @@
     (_implicitlyTypedFields ??= <FieldBuilder>[]).add(fieldBuilder);
   }
 
-  @override
-  List<FieldBuilder>? takeImplicitlyTypedFields() {
-    List<FieldBuilder>? result = _implicitlyTypedFields;
-    _implicitlyTypedFields = null;
-    return result;
+  void collectImplicitlyTypedFields(
+      List<FieldBuilder> implicitlyTypedFieldBuilders) {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.collectImplicitlyTypedFields(implicitlyTypedFieldBuilders);
+      }
+    }
+
+    if (_implicitlyTypedFields != null) {
+      implicitlyTypedFieldBuilders.addAll(_implicitlyTypedFields!);
+      _implicitlyTypedFields = null;
+    }
   }
 
   void forEachExtensionInScope(void Function(ExtensionBuilder) f) {
@@ -4583,6 +4819,13 @@
   }
 
   void installTypedefTearOffs() {
+    Iterable<SourceLibraryBuilder>? patches = this.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        patchLibrary.installTypedefTearOffs();
+      }
+    }
+
     Iterator<Builder> iterator = this.iterator;
     while (iterator.moveNext()) {
       Builder? declaration = iterator.current;
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 5568bb4..7bc120f 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -42,7 +42,6 @@
 import '../builder/class_builder.dart';
 import '../builder/constructor_builder.dart';
 import '../builder/declaration_builder.dart';
-import '../builder/dynamic_type_declaration_builder.dart';
 import '../builder/enum_builder.dart';
 import '../builder/extension_builder.dart';
 import '../builder/field_builder.dart';
@@ -51,8 +50,6 @@
 import '../builder/member_builder.dart';
 import '../builder/modifier_builder.dart';
 import '../builder/named_type_builder.dart';
-import '../builder/never_type_declaration_builder.dart';
-import '../builder/prefix_builder.dart';
 import '../builder/procedure_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
@@ -88,11 +85,10 @@
 import 'source_class_builder.dart' show SourceClassBuilder;
 import 'source_library_builder.dart'
     show
-        LanguageVersion,
-        InvalidLanguageVersion,
         ImplicitLanguageVersion,
+        InvalidLanguageVersion,
+        LanguageVersion,
         SourceLibraryBuilder;
-import 'source_type_alias_builder.dart';
 import 'stack_listener_impl.dart' show offsetForToken;
 
 class SourceLoader extends Loader {
@@ -153,6 +149,8 @@
 
   final Map<Uri, LibraryBuilder> _builders = <Uri, LibraryBuilder>{};
 
+  List<SourceLibraryBuilder>? _sourceLibraryBuilders;
+
   final Queue<LibraryBuilder> _unparsedLibraries = new Queue<LibraryBuilder>();
 
   final List<Library> libraries = <Library>[];
@@ -228,12 +226,28 @@
   @override
   LibraryBuilder? lookupLibraryBuilder(Uri importUri) => _builders[importUri];
 
+  /// The [LibraryBuilder]s for libraries built from source or loaded from dill.
+  ///
+  /// Before [resolveParts] have been called, this includes parts and patches.
   Iterable<LibraryBuilder> get libraryBuilders => _builders.values;
 
+  /// The [SourceLibraryBuilder]s for the libraries built from source by this
+  /// source loader.
+  ///
+  /// This is available after [resolveParts] have been called and doesn't
+  /// include parts or patches. Orphaned parts _are_ included.
+  List<SourceLibraryBuilder> get sourceLibraryBuilders {
+    assert(
+        _sourceLibraryBuilders != null,
+        "Source library builder hasn't been computed yet. "
+        "The source libraries are in SourceLoader.resolveParts.");
+    return _sourceLibraryBuilders!;
+  }
+
   Iterable<Uri> get libraryImportUris => _builders.keys;
 
-  void registerLibraryBuilder(LibraryBuilder libraryBuilder, [Uri? uri]) {
-    uri ??= libraryBuilder.importUri;
+  void registerLibraryBuilder(LibraryBuilder libraryBuilder) {
+    Uri uri = libraryBuilder.importUri;
     if (uri.scheme == "dart" && uri.path == "core") {
       _coreLibrary = libraryBuilder;
     }
@@ -253,8 +267,8 @@
 
   Ticker get ticker => target.ticker;
 
-  /// Creates a [SourceLibraryBuilder] corresponding to [uri], if one doesn't
-  /// exist already.
+  /// Creates a [SourceLibraryBuilder] corresponding to [importUri], if one
+  /// doesn't exist already.
   ///
   /// [fileUri] must not be null and is a URI that can be passed to FileSystem
   /// to locate the corresponding file.
@@ -278,15 +292,20 @@
   /// which the library belongs to, or the current sdk version if the library
   /// doesn't belong to a package.
   SourceLibraryBuilder createLibraryBuilder(
-      Uri uri,
-      Uri fileUri,
+      {required Uri importUri,
+      required Uri fileUri,
       Uri? packageUri,
-      LanguageVersion packageLanguageVersion,
+      required LanguageVersion packageLanguageVersion,
       SourceLibraryBuilder? origin,
       Library? referencesFrom,
-      bool? referenceIsPartOwner) {
+      bool? referenceIsPartOwner}) {
     return new SourceLibraryBuilder(
-        uri, fileUri, packageUri, packageLanguageVersion, this, origin,
+        importUri: importUri,
+        fileUri: fileUri,
+        packageUri: packageUri,
+        packageLanguageVersion: packageLanguageVersion,
+        loader: this,
+        origin: origin,
         referencesFrom: referencesFrom,
         referenceIsPartOwner: referenceIsPartOwner);
   }
@@ -370,13 +389,13 @@
         new ImplicitLanguageVersion(target.currentSdkVersion);
 
     SourceLibraryBuilder libraryBuilder = createLibraryBuilder(
-        uri,
-        fileUri,
-        packageUri,
-        packageLanguageVersion,
-        origin,
-        referencesFrom,
-        referenceIsPartOwner);
+        importUri: uri,
+        fileUri: fileUri,
+        packageUri: packageUri,
+        packageLanguageVersion: packageLanguageVersion,
+        origin: origin,
+        referencesFrom: referencesFrom,
+        referenceIsPartOwner: referenceIsPartOwner);
     if (packageLanguageVersionProblem != null) {
       libraryBuilder.addPostponedProblem(
           packageLanguageVersionProblem, 0, noLength, libraryBuilder.fileUri);
@@ -537,11 +556,9 @@
 
   Future<Null> buildBodies() async {
     assert(_coreLibrary != null);
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        currentUriForCrashReporting = library.importUri;
-        await buildBody(library);
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      currentUriForCrashReporting = library.importUri;
+      await buildBody(library);
     }
     currentUriForCrashReporting = null;
     logSummary(templateSourceBodySummary);
@@ -551,7 +568,12 @@
     ticker.log((Duration elapsed, Duration sinceStart) {
       int libraryCount = 0;
       for (LibraryBuilder library in libraryBuilders) {
-        if (library.loader == this) libraryCount++;
+        if (library.loader == this) {
+          libraryCount++;
+          if (library is SourceLibraryBuilder) {
+            libraryCount += library.patchLibraries?.length ?? 0;
+          }
+        }
       }
       double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
       Message message = template.withArguments(
@@ -970,29 +992,34 @@
   }
 
   /// Builds all the method bodies found in the given [library].
-  Future<Null> buildBody(LibraryBuilder library) async {
-    if (library is SourceLibraryBuilder) {
-      // We tokenize source files twice to keep memory usage low. This is the
-      // second time, and the first time was in [buildOutline] above. So this
-      // time we suppress lexical errors.
-      Token tokens = await tokenize(library, suppressLexicalErrors: true);
+  Future<Null> buildBody(SourceLibraryBuilder library) async {
+    Iterable<SourceLibraryBuilder>? patches = library.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        await buildBody(patchLibrary);
+      }
+    }
+
+    // We tokenize source files twice to keep memory usage low. This is the
+    // second time, and the first time was in [buildOutline] above. So this
+    // time we suppress lexical errors.
+    Token tokens = await tokenize(library, suppressLexicalErrors: true);
+    // ignore: unnecessary_null_comparison
+    if (tokens == null) return;
+    DietListener listener = createDietListener(library);
+    DietParser parser = new DietParser(listener);
+    parser.parseUnit(tokens);
+    for (LibraryBuilder part in library.parts) {
+      if (part.partOfLibrary != library) {
+        // Part was included in multiple libraries. Skip it here.
+        continue;
+      }
+      Token tokens = await tokenize(part as SourceLibraryBuilder,
+          suppressLexicalErrors: true);
       // ignore: unnecessary_null_comparison
-      if (tokens == null) return;
-      DietListener listener = createDietListener(library);
-      DietParser parser = new DietParser(listener);
-      parser.parseUnit(tokens);
-      for (LibraryBuilder part in library.parts) {
-        if (part.partOfLibrary != library) {
-          // Part was included in multiple libraries. Skip it here.
-          continue;
-        }
-        Token tokens = await tokenize(part as SourceLibraryBuilder,
-            suppressLexicalErrors: true);
-        // ignore: unnecessary_null_comparison
-        if (tokens != null) {
-          listener.uri = part.fileUri;
-          parser.parseUnit(tokens);
-        }
+      if (tokens != null) {
+        listener.uri = part.fileUri;
+        parser.parseUnit(tokens);
       }
     }
   }
@@ -1068,13 +1095,20 @@
 
   void resolveParts() {
     List<Uri> parts = <Uri>[];
-    List<SourceLibraryBuilder> libraries = <SourceLibraryBuilder>[];
+    List<SourceLibraryBuilder> libraries = [];
+    List<SourceLibraryBuilder> sourceLibraries = [];
+    List<SourceLibraryBuilder> patchLibraries = [];
     _builders.forEach((Uri uri, LibraryBuilder library) {
-      if (library.loader == this) {
+      if (library.loader == this && library is SourceLibraryBuilder) {
         if (library.isPart) {
           parts.add(uri);
         } else {
-          libraries.add(library as SourceLibraryBuilder);
+          if (library.isPatch) {
+            patchLibraries.add(library);
+          } else {
+            sourceLibraries.add(library);
+          }
+          libraries.add(library);
         }
       }
     });
@@ -1093,6 +1127,7 @@
             lookupLibraryBuilder(uri) as SourceLibraryBuilder;
         part.addProblem(messagePartOrphan, 0, 1, part.fileUri);
         part.validatePart(null, null);
+        sourceLibraries.add(part);
       }
     }
     ticker.logMs("Resolved parts");
@@ -1102,6 +1137,25 @@
         library.applyPatches();
       }
     }
+    for (SourceLibraryBuilder patchLibrary in patchLibraries) {
+      _builders.remove(patchLibrary.fileUri);
+      patchLibrary.origin.addPatchLibrary(patchLibrary);
+    }
+    _sourceLibraryBuilders = sourceLibraries;
+    assert(
+        libraryBuilders.every((library) => !library.isPatch),
+        "Patch library found in libraryBuilders: "
+        "${libraryBuilders.where((library) => library.isPatch)}.");
+    assert(
+        sourceLibraries.every((library) => !library.isPatch),
+        "Patch library found in sourceLibraryBuilders: "
+        "${sourceLibraries.where((library) => library.isPatch)}.");
+    assert(
+        libraryBuilders.every((library) =>
+            library.loader != this || sourceLibraries.contains(library)),
+        "Source library not found in sourceLibraryBuilders:"
+        "${libraryBuilders.where((library) => // force line break
+            library.loader == this && !sourceLibraries.contains(library))}");
     ticker.logMs("Applied patches");
   }
 
@@ -1119,6 +1173,19 @@
           exporters.add(exporter.exporter);
         }
       }
+
+      Iterable<SourceLibraryBuilder>? patches =
+          library is SourceLibraryBuilder ? library.patchLibraries : null;
+      if (patches != null) {
+        for (SourceLibraryBuilder patchLibrary in patches) {
+          if (patchLibrary.exporters.isNotEmpty) {
+            exportees.add(patchLibrary);
+            for (Export exporter in patchLibrary.exporters) {
+              exporters.add(exporter.exporter);
+            }
+          }
+        }
+      }
     }
     Set<SourceLibraryBuilder> both = new Set<SourceLibraryBuilder>();
     for (LibraryBuilder exported in exportees) {
@@ -1185,11 +1252,8 @@
 
   void resolveTypes() {
     int typeCount = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
-        typeCount += sourceLibrary.resolveTypes();
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      typeCount += library.resolveTypes();
     }
     ticker.logMs("Resolved $typeCount types");
   }
@@ -1325,8 +1389,8 @@
       return macros.isNotEmpty ? new MacroApplications(macros) : null;
     }
 
-    for (LibraryBuilder libraryBuilder in libraryBuilders) {
-      if (libraryBuilder.loader != this) continue;
+    for (SourceLibraryBuilder libraryBuilder in sourceLibraryBuilders) {
+      // TODO(johnniwinther): Handle patch libraries.
       LibraryMacroApplicationData libraryMacroApplicationData =
           new LibraryMacroApplicationData();
       Library library = libraryBuilder.library;
@@ -1381,60 +1445,48 @@
 
   void finishDeferredLoadTearoffs() {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.finishDeferredLoadTearoffs();
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.finishDeferredLoadTearoffs();
     }
     ticker.logMs("Finished deferred load tearoffs $count");
   }
 
   void finishNoSuchMethodForwarders() {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.finishForwarders();
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.finishForwarders();
     }
     ticker.logMs("Finished forwarders for $count procedures");
   }
 
   void resolveConstructors() {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.resolveConstructors(null);
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.resolveConstructors();
     }
     ticker.logMs("Resolved $count constructors");
   }
 
   void installTypedefTearOffs() {
     if (target.backendTarget.isTypedefTearOffLoweringEnabled) {
-      for (LibraryBuilder library in libraryBuilders) {
-        if (library.loader == this && library is SourceLibraryBuilder) {
-          library.installTypedefTearOffs();
-        }
+      for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+        library.installTypedefTearOffs();
       }
     }
   }
 
   void finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.finishTypeVariables(object, dynamicType);
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.finishTypeVariables(object, dynamicType);
     }
     ticker.logMs("Resolved $count type-variable bounds");
   }
 
   void computeVariances() {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.computeVariances();
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.computeVariances();
     }
     ticker.logMs("Computed variances of $count type variables");
   }
@@ -1442,31 +1494,25 @@
   void computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
       TypeBuilder bottomType, ClassBuilder objectClass) {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.computeDefaultTypes(
-            dynamicType, nullType, bottomType, objectClass);
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.computeDefaultTypes(
+          dynamicType, nullType, bottomType, objectClass);
     }
     ticker.logMs("Computed default types for $count type variables");
   }
 
   void finishNativeMethods() {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.finishNativeMethods();
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.finishNativeMethods();
     }
     ticker.logMs("Finished $count native methods");
   }
 
   void finishPatchMethods() {
     int count = 0;
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        count += library.finishPatchMethods();
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      count += library.finishPatchMethods();
     }
     ticker.logMs("Finished $count patch methods");
   }
@@ -1494,6 +1540,15 @@
     }
   }
 
+  /// Returns classes defined in libraries in this [SourceLoader].
+  List<SourceClassBuilder> collectSourceClasses() {
+    List<SourceClassBuilder> sourceClasses = <SourceClassBuilder>[];
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      library.collectSourceClasses(sourceClasses);
+    }
+    return sourceClasses;
+  }
+
   /// Returns a list of all class builders declared in this loader.  As the
   /// classes are sorted, any cycles in the hierarchy are reported as
   /// errors. Recover by breaking the cycles. This means that the rest of the
@@ -1516,7 +1571,8 @@
     }
 
     // Sort the classes topologically.
-    _SourceClassGraph classGraph = new _SourceClassGraph(this, objectClass);
+    _SourceClassGraph classGraph =
+        new _SourceClassGraph(collectSourceClasses(), objectClass);
     TopologicalSortResult<SourceClassBuilder> result =
         topologicalSort(classGraph);
     List<SourceClassBuilder> classes = result.sortedVertices;
@@ -1661,19 +1717,14 @@
 
   /// Builds the core AST structure needed for the outline of the component.
   void buildComponent() {
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        SourceLibraryBuilder sourceLibrary = library as SourceLibraryBuilder;
-        Library target = sourceLibrary.build(coreLibrary);
-        if (!library.isPatch) {
-          if (sourceLibrary.referencesFrom != null) {
-            referenceFromIndex ??= new ReferenceFromIndex();
-            referenceFromIndex!.addIndexedLibrary(
-                target, sourceLibrary.referencesFromIndexed!);
-          }
-          libraries.add(target);
-        }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      Library target = library.build(coreLibrary);
+      if (library.referencesFrom != null) {
+        referenceFromIndex ??= new ReferenceFromIndex();
+        referenceFromIndex!
+            .addIndexedLibrary(target, library.referencesFromIndexed!);
       }
+      libraries.add(target);
     }
     ticker.logMs("Built component");
   }
@@ -1728,11 +1779,8 @@
   }
 
   void computeShowHideElements() {
-    for (LibraryBuilder libraryBuilder in libraryBuilders) {
-      if (libraryBuilder.loader == this &&
-          libraryBuilder is SourceLibraryBuilder) {
-        libraryBuilder.computeShowHideElements(membersBuilder);
-      }
+    for (SourceLibraryBuilder libraryBuilder in sourceLibraryBuilders) {
+      libraryBuilder.computeShowHideElements(membersBuilder);
     }
     ticker.logMs("Computed show and hide elements");
   }
@@ -1776,13 +1824,8 @@
   }
 
   void checkTypes() {
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library is SourceLibraryBuilder) {
-        if (library.loader == this) {
-          library
-              .checkTypesInOutline(typeInferenceEngine.typeSchemaEnvironment);
-        }
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      library.checkTypesInOutline(typeInferenceEngine.typeSchemaEnvironment);
     }
     ticker.logMs("Checked type arguments of supers against the bounds");
   }
@@ -1857,34 +1900,9 @@
       List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
     List<DelayedActionPerformer> delayedActionPerformers =
         <DelayedActionPerformer>[];
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        (library as SourceLibraryBuilder).buildOutlineExpressions();
-        Iterator<Builder> iterator = library.iterator;
-        while (iterator.moveNext()) {
-          Builder declaration = iterator.current;
-          if (declaration is ClassBuilder) {
-            declaration.buildOutlineExpressions(library, coreTypes,
-                delayedActionPerformers, synthesizedFunctionNodes);
-          } else if (declaration is ExtensionBuilder) {
-            declaration.buildOutlineExpressions(library, coreTypes,
-                delayedActionPerformers, synthesizedFunctionNodes);
-          } else if (declaration is MemberBuilder) {
-            declaration.buildOutlineExpressions(library, coreTypes,
-                delayedActionPerformers, synthesizedFunctionNodes);
-          } else if (declaration is SourceTypeAliasBuilder) {
-            declaration.buildOutlineExpressions(library, coreTypes,
-                delayedActionPerformers, synthesizedFunctionNodes);
-          } else {
-            assert(
-                declaration is PrefixBuilder ||
-                    declaration is DynamicTypeDeclarationBuilder ||
-                    declaration is NeverTypeDeclarationBuilder,
-                "Unexpected builder in library: ${declaration} "
-                "(${declaration.runtimeType}");
-          }
-        }
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      library.buildOutlineExpressions(
+          coreTypes, synthesizedFunctionNodes, delayedActionPerformers);
     }
     for (DelayedActionPerformer delayedActionPerformer
         in delayedActionPerformers) {
@@ -1918,14 +1936,8 @@
     membersBuilder.computeTypes();
 
     List<FieldBuilder> allImplicitlyTypedFields = <FieldBuilder>[];
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        List<FieldBuilder>? implicitlyTypedFields =
-            library.takeImplicitlyTypedFields();
-        if (implicitlyTypedFields != null) {
-          allImplicitlyTypedFields.addAll(implicitlyTypedFields);
-        }
-      }
+    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+      library.collectImplicitlyTypedFields(allImplicitlyTypedFields);
     }
 
     for (int i = 0; i < allImplicitlyTypedFields.length; i++) {
@@ -2011,27 +2023,48 @@
         isTopLevel: isTopLevel);
   }
 
-  void checkMainMethods() {
-    DartType? listOfString;
+  void _checkMainMethods(
+      SourceLibraryBuilder libraryBuilder, DartType listOfString) {
+    Iterable<SourceLibraryBuilder>? patches = libraryBuilder.patchLibraries;
+    if (patches != null) {
+      for (SourceLibraryBuilder patchLibrary in patches) {
+        _checkMainMethods(patchLibrary, listOfString);
+      }
+    }
 
-    for (LibraryBuilder libraryBuilder in libraryBuilders) {
-      if (libraryBuilder.loader == this &&
-          libraryBuilder.isNonNullableByDefault) {
-        Builder? mainBuilder =
-            libraryBuilder.exportScope.lookupLocalMember('main', setter: false);
-        mainBuilder ??=
-            libraryBuilder.exportScope.lookupLocalMember('main', setter: true);
-        if (mainBuilder is MemberBuilder) {
-          if (mainBuilder is InvalidTypeDeclarationBuilder) {
-            // This is an ambiguous export, skip the check.
-            return;
+    if (libraryBuilder.isNonNullableByDefault) {
+      Builder? mainBuilder =
+          libraryBuilder.exportScope.lookupLocalMember('main', setter: false);
+      mainBuilder ??=
+          libraryBuilder.exportScope.lookupLocalMember('main', setter: true);
+      if (mainBuilder is MemberBuilder) {
+        if (mainBuilder is InvalidTypeDeclarationBuilder) {
+          // This is an ambiguous export, skip the check.
+          return;
+        }
+        if (mainBuilder.isField ||
+            mainBuilder.isGetter ||
+            mainBuilder.isSetter) {
+          if (mainBuilder.parent != libraryBuilder) {
+            libraryBuilder.addProblem(messageMainNotFunctionDeclarationExported,
+                libraryBuilder.charOffset, noLength, libraryBuilder.fileUri,
+                context: [
+                  messageExportedMain.withLocation(mainBuilder.fileUri!,
+                      mainBuilder.charOffset, mainBuilder.name.length)
+                ]);
+          } else {
+            libraryBuilder.addProblem(
+                messageMainNotFunctionDeclaration,
+                mainBuilder.charOffset,
+                mainBuilder.name.length,
+                mainBuilder.fileUri);
           }
-          if (mainBuilder.isField ||
-              mainBuilder.isGetter ||
-              mainBuilder.isSetter) {
+        } else {
+          Procedure procedure = mainBuilder.member as Procedure;
+          if (procedure.function.requiredParameterCount > 2) {
             if (mainBuilder.parent != libraryBuilder) {
               libraryBuilder.addProblem(
-                  messageMainNotFunctionDeclarationExported,
+                  messageMainTooManyRequiredParametersExported,
                   libraryBuilder.charOffset,
                   noLength,
                   libraryBuilder.fileUri,
@@ -2041,17 +2074,42 @@
                   ]);
             } else {
               libraryBuilder.addProblem(
-                  messageMainNotFunctionDeclaration,
+                  messageMainTooManyRequiredParameters,
                   mainBuilder.charOffset,
                   mainBuilder.name.length,
                   mainBuilder.fileUri);
             }
-          } else {
-            Procedure procedure = mainBuilder.member as Procedure;
-            if (procedure.function.requiredParameterCount > 2) {
+          } else if (procedure.function.namedParameters
+              .any((parameter) => parameter.isRequired)) {
+            if (mainBuilder.parent != libraryBuilder) {
+              libraryBuilder.addProblem(
+                  messageMainRequiredNamedParametersExported,
+                  libraryBuilder.charOffset,
+                  noLength,
+                  libraryBuilder.fileUri,
+                  context: [
+                    messageExportedMain.withLocation(mainBuilder.fileUri!,
+                        mainBuilder.charOffset, mainBuilder.name.length)
+                  ]);
+            } else {
+              libraryBuilder.addProblem(
+                  messageMainRequiredNamedParameters,
+                  mainBuilder.charOffset,
+                  mainBuilder.name.length,
+                  mainBuilder.fileUri);
+            }
+          } else if (procedure.function.positionalParameters.length > 0) {
+            DartType parameterType =
+                procedure.function.positionalParameters.first.type;
+
+            if (!typeEnvironment.isSubtypeOf(listOfString, parameterType,
+                SubtypeCheckMode.withNullabilities)) {
               if (mainBuilder.parent != libraryBuilder) {
                 libraryBuilder.addProblem(
-                    messageMainTooManyRequiredParametersExported,
+                    templateMainWrongParameterTypeExported.withArguments(
+                        parameterType,
+                        listOfString,
+                        libraryBuilder.isNonNullableByDefault),
                     libraryBuilder.charOffset,
                     noLength,
                     libraryBuilder.fileUri,
@@ -2061,84 +2119,40 @@
                     ]);
               } else {
                 libraryBuilder.addProblem(
-                    messageMainTooManyRequiredParameters,
+                    templateMainWrongParameterType.withArguments(parameterType,
+                        listOfString, libraryBuilder.isNonNullableByDefault),
                     mainBuilder.charOffset,
                     mainBuilder.name.length,
                     mainBuilder.fileUri);
               }
-            } else if (procedure.function.namedParameters
-                .any((parameter) => parameter.isRequired)) {
-              if (mainBuilder.parent != libraryBuilder) {
-                libraryBuilder.addProblem(
-                    messageMainRequiredNamedParametersExported,
-                    libraryBuilder.charOffset,
-                    noLength,
-                    libraryBuilder.fileUri,
-                    context: [
-                      messageExportedMain.withLocation(mainBuilder.fileUri!,
-                          mainBuilder.charOffset, mainBuilder.name.length)
-                    ]);
-              } else {
-                libraryBuilder.addProblem(
-                    messageMainRequiredNamedParameters,
-                    mainBuilder.charOffset,
-                    mainBuilder.name.length,
-                    mainBuilder.fileUri);
-              }
-            } else if (procedure.function.positionalParameters.length > 0) {
-              DartType parameterType =
-                  procedure.function.positionalParameters.first.type;
-
-              listOfString ??= new InterfaceType(
-                  coreTypes.listClass,
-                  Nullability.nonNullable,
-                  [coreTypes.stringNonNullableRawType]);
-
-              if (!typeEnvironment.isSubtypeOf(listOfString, parameterType,
-                  SubtypeCheckMode.withNullabilities)) {
-                if (mainBuilder.parent != libraryBuilder) {
-                  libraryBuilder.addProblem(
-                      templateMainWrongParameterTypeExported.withArguments(
-                          parameterType,
-                          listOfString,
-                          libraryBuilder.isNonNullableByDefault),
-                      libraryBuilder.charOffset,
-                      noLength,
-                      libraryBuilder.fileUri,
-                      context: [
-                        messageExportedMain.withLocation(mainBuilder.fileUri!,
-                            mainBuilder.charOffset, mainBuilder.name.length)
-                      ]);
-                } else {
-                  libraryBuilder.addProblem(
-                      templateMainWrongParameterType.withArguments(
-                          parameterType,
-                          listOfString,
-                          libraryBuilder.isNonNullableByDefault),
-                      mainBuilder.charOffset,
-                      mainBuilder.name.length,
-                      mainBuilder.fileUri);
-                }
-              }
             }
           }
-        } else if (mainBuilder != null) {
-          if (mainBuilder.parent != libraryBuilder) {
-            libraryBuilder.addProblem(messageMainNotFunctionDeclarationExported,
-                libraryBuilder.charOffset, noLength, libraryBuilder.fileUri,
-                context: [
-                  messageExportedMain.withLocation(
-                      mainBuilder.fileUri!, mainBuilder.charOffset, noLength)
-                ]);
-          } else {
-            libraryBuilder.addProblem(messageMainNotFunctionDeclaration,
-                mainBuilder.charOffset, noLength, mainBuilder.fileUri);
-          }
+        }
+      } else if (mainBuilder != null) {
+        if (mainBuilder.parent != libraryBuilder) {
+          libraryBuilder.addProblem(messageMainNotFunctionDeclarationExported,
+              libraryBuilder.charOffset, noLength, libraryBuilder.fileUri,
+              context: [
+                messageExportedMain.withLocation(
+                    mainBuilder.fileUri!, mainBuilder.charOffset, noLength)
+              ]);
+        } else {
+          libraryBuilder.addProblem(messageMainNotFunctionDeclaration,
+              mainBuilder.charOffset, noLength, mainBuilder.fileUri);
         }
       }
     }
   }
 
+  void checkMainMethods() {
+    DartType listOfString = new InterfaceType(coreTypes.listClass,
+        Nullability.nonNullable, [coreTypes.stringNonNullableRawType]);
+
+    for (SourceLibraryBuilder libraryBuilder in sourceLibraryBuilders) {
+      _checkMainMethods(libraryBuilder, listOfString);
+    }
+  }
+
   void releaseAncillaryResources() {
     hierarchy = null;
     _hierarchyBuilder = null;
@@ -2453,26 +2467,13 @@
 
 class _SourceClassGraph implements Graph<SourceClassBuilder> {
   @override
-  final List<SourceClassBuilder> vertices = [];
+  final List<SourceClassBuilder> vertices;
   final ClassBuilder _objectClass;
   final Map<SourceClassBuilder, Map<TypeDeclarationBuilder?, TypeAliasBuilder?>>
       directSupertypeMap = {};
   final Map<SourceClassBuilder, List<SourceClassBuilder>> _supertypeMap = {};
 
-  _SourceClassGraph(SourceLoader loader, this._objectClass) {
-    // Compute the vertices as all classes declared in this loader.
-    for (LibraryBuilder library in loader.libraryBuilders) {
-      if (library.loader == loader) {
-        Iterator<Builder> members = library.iterator;
-        while (members.moveNext()) {
-          Builder member = members.current;
-          if (member is SourceClassBuilder && !member.isPatch) {
-            vertices.add(member);
-          }
-        }
-      }
-    }
-  }
+  _SourceClassGraph(this.vertices, this._objectClass);
 
   List<SourceClassBuilder> computeSuperClasses(SourceClassBuilder cls) {
     Map<TypeDeclarationBuilder?, TypeAliasBuilder?> directSupertypes =
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 5fdfef0..f4790b9 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -84,18 +84,17 @@
     Expression index = new VariableGet(new VariableDeclaration("index"));
     UriTranslator uriTranslator = await c.options.getUriTranslator();
     SourceLibraryBuilder libraryBuilder = new SourceLibraryBuilder(
-        uri,
-        uri,
-        /*packageUri*/ null,
-        new ImplicitLanguageVersion(defaultLanguageVersion),
-        new KernelTarget(
+        importUri: uri,
+        fileUri: uri,
+        packageLanguageVersion:
+            new ImplicitLanguageVersion(defaultLanguageVersion),
+        loader: new KernelTarget(
                 const MockFileSystem(),
                 false,
                 new DillTarget(c.options.ticker, uriTranslator,
                     new NoneTarget(new TargetFlags())),
                 uriTranslator)
-            .loader,
-        null);
+            .loader);
     libraryBuilder.markLanguageVersionFinal();
     LoadLibraryBuilder loadLibraryBuilder =
         new LoadLibraryBuilder(libraryBuilder, dummyLibraryDependency, -1);
diff --git a/pkg/front_end/test/patching/data/abstract_class/libraries.json b/pkg/front_end/test/patching/data/abstract_class/libraries.json
new file mode 100644
index 0000000..a697508
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/libraries.json
@@ -0,0 +1,12 @@
+{
+  "none": {
+    "libraries": {
+      "test": {
+        "patches": [
+          "patch.dart"
+        ],
+        "uri": "origin.dart"
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/test/patching/data/abstract_class/main.dart b/pkg/front_end/test/patching/data/abstract_class/main.dart
new file mode 100644
index 0000000..faf7854
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/main.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*cfe.library: nnbd=false*/
+
+/*cfe:nnbd.library: nnbd=true*/
+
+// ignore: uri_does_not_exist
+import 'dart:test';
+
+void test(Class cls) {}
+
+main() {}
diff --git a/pkg/front_end/test/patching/data/abstract_class/origin.dart b/pkg/front_end/test/patching/data/abstract_class/origin.dart
new file mode 100644
index 0000000..c8359e2
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/origin.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*cfe.library: nnbd=false*/
+
+/*cfe:nnbd.library: nnbd=true*/
+
+/*class: Interface:
+ isAbstract,
+ kernel-members=[
+  Interface.,
+  interfaceMethod],
+ scope=[interfaceMethod]
+*/
+/*member: Interface.:initializers=[SuperInitializer]*/
+abstract class Interface {
+  void interfaceMethod();
+}
+
+/*class: Class:
+ isAbstract,
+ kernel-members=[
+  Class.,
+  classMethod],
+ scope=[classMethod]
+*/
+/*member: Class.:initializers=[SuperInitializer]*/
+abstract class Class implements Interface {
+  external void classMethod();
+}
diff --git a/pkg/front_end/test/patching/data/abstract_class/patch.dart b/pkg/front_end/test/patching/data/abstract_class/patch.dart
new file mode 100644
index 0000000..9d11f24
--- /dev/null
+++ b/pkg/front_end/test/patching/data/abstract_class/patch.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+class Class {
+  @patch
+  /*member: Class.classMethod:patch*/
+  void classMethod() {}
+}
diff --git a/pkg/front_end/test/patching/patching_test.dart b/pkg/front_end/test/patching/patching_test.dart
index 1cd2220..60129e5 100644
--- a/pkg/front_end/test/patching/patching_test.dart
+++ b/pkg/front_end/test/patching/patching_test.dart
@@ -118,6 +118,7 @@
   static const String error = 'message';
   static const String isNonNullableByDefault = 'nnbd';
   static const String patch = 'patch';
+  static const String isAbstract = 'isAbstract';
 }
 
 class PatchingDataExtractor extends CfeDataExtractor<Features> {
@@ -137,6 +138,9 @@
     ClassBuilder clsBuilder = lookupClassBuilder(compilerResult, cls)!;
 
     Features features = new Features();
+    if (cls.isAbstract) {
+      features.add(Tags.isAbstract);
+    }
     clsBuilder.scope.forEach((String name, Builder builder) {
       features.addElement(Tags.scope, name);
     });
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 89cc303..9b57834 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -292,6 +292,7 @@
 dartbug
 dartdoc
 dartfix
+dartino
 dartlang
 dashes
 dc
@@ -1243,6 +1244,7 @@
 substitutes
 substitutor
 suggests
+suite
 sum
 summarizing
 superclasses
@@ -1383,6 +1385,7 @@
 unify
 uninstantiable
 uninstantiated
+unintentionally
 unions
 uniqueness
 unittest
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.expect
index 1b1884e..0e8c87e 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
@@ -10,7 +10,7 @@
 // typedef ImplAlias<T extends num> = _ConstImpl<T>;
 //                   ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.transformed.expect
index 1b1884e..0e8c87e 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
@@ -10,7 +10,7 @@
 // typedef ImplAlias<T extends num> = _ConstImpl<T>;
 //                   ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.expect
index 39fb6b3..f957d96 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
@@ -10,7 +10,7 @@
 // typedef ImplAlias<T extends num> = _ConstImpl<T>;
 //                   ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.modular.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.modular.expect
index 39fb6b3..f957d96 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.modular.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
@@ -10,7 +10,7 @@
 // typedef ImplAlias<T extends num> = _ConstImpl<T>;
 //                   ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.outline.expect
index 50eff12..b497969 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.outline.expect
@@ -2,6 +2,14 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// Try changing type arguments so that they conform to the bounds.
+//         ImplAlias<String>()
+//         ^
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:32:19: Context: This is the type variable whose bound isn't conformed to.
+// typedef ImplAlias<T extends num> = _ConstImpl<T>;
+//                   ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
@@ -17,7 +25,7 @@
 typedef ImplAlias<T extends core::num> = self::_ConstImpl<T>;
 class Class extends core::Object /*hasConstConstructor*/  {
   final field core::List<self::Const> constants;
-  constructor •({core::List<self::Const> constants}) → self::Class
+  constructor •({core::List<self::Const> constants = const <self::Const>[const self::_ConstImpl::•<dynamic>(), const self::_ConstImpl::•<dynamic>(), const self::_ConstImpl::•<core::String>()]}) → self::Class
     ;
   const constructor named({core::List<self::Const> constants = const <self::Const>[const self::_ConstImpl::•<dynamic>(), const self::_ConstImpl::•<dynamic>(), const self::_ConstImpl::•<core::String>()]}) → self::Class
     : self::Class::constants = constants, super core::Object::•()
@@ -48,6 +56,7 @@
 
 
 Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///const_redirect.dart:12:25 -> ListConstant(const <Const*>[const _ConstImpl<dynamic>{}, const _ConstImpl<dynamic>{}, const _ConstImpl<String*>{}])
 Evaluated: ListLiteral @ org-dartlang-testcase:///const_redirect.dart:19:25 -> ListConstant(const <Const*>[const _ConstImpl<dynamic>{}, const _ConstImpl<dynamic>{}, const _ConstImpl<String*>{}])
 Evaluated: ConstructorTearOff @ org-dartlang-testcase:///const_redirect.dart:28:16 -> ConstructorTearOffConstant(Const.impl)
-Extra constant evaluation: evaluated: 12, effectively constant: 2
+Extra constant evaluation: evaluated: 13, effectively constant: 3
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.transformed.expect
index 39fb6b3..f957d96 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
@@ -10,7 +10,7 @@
 // typedef ImplAlias<T extends num> = _ConstImpl<T>;
 //                   ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:15:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
+// pkg/front_end/testcases/constructor_tearoffs/lowering/const_redirect.dart:22:9: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'ImplAlias'.
 // Try changing type arguments so that they conform to the bounds.
 //         ImplAlias<String>()
 //         ^
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.outline.expect
index 128018d..c630d70 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.outline.expect
@@ -4,14 +4,14 @@
 
 class Class1 extends core::Object {
   final field core::int field;
-  constructor •([core::int field]) → self::Class1
+  constructor •([core::int field = 42]) → self::Class1
     ;
   static method _#new#tearOff([core::int field]) → self::Class1
     return new self::Class1::•(field);
 }
 class Class2 extends core::Object {
   final field core::int field;
-  constructor •({core::int field}) → self::Class2
+  constructor •({core::int field = 42}) → self::Class2
     ;
   static method _#new#tearOff({core::int field}) → self::Class2
     return new self::Class2::•(field: field);
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/named_mixin_application.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/named_mixin_application.dart.weak.outline.expect
index 6aab2c5..37b4b1f 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/named_mixin_application.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/named_mixin_application.dart.weak.outline.expect
@@ -10,7 +10,7 @@
 class Class<T extends core::Object? = dynamic> extends core::Object implements self::Interface {
   field core::int field;
   static final field dynamic _redirecting# = <dynamic>[self::Class::redirectingFactory]/*isLegacy*/;
-  constructor •([core::int field]) → self::Class<self::Class::T%>
+  constructor •([core::int field = 0]) → self::Class<self::Class::T%>
     ;
   constructor named(core::int field) → self::Class<self::Class::T%>
     ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values.dart.weak.outline.expect
index 20f744e..a220416 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values.dart.weak.outline.expect
@@ -5,7 +5,7 @@
 class Class1 extends core::Object {
   final field core::int field;
   static final field dynamic _redirecting# = <dynamic>[self::Class1::•]/*isLegacy*/;
-  constructor _([core::int field]) → self::Class1
+  constructor _([core::int field = 42]) → self::Class1
     ;
   static method _#_#tearOff([core::int field]) → self::Class1
     return new self::Class1::_(field);
@@ -17,7 +17,7 @@
 class Class2 extends core::Object {
   final field core::int field;
   static final field dynamic _redirecting# = <dynamic>[self::Class2::•]/*isLegacy*/;
-  constructor _({core::int field}) → self::Class2
+  constructor _({core::int field = 42}) → self::Class2
     ;
   static method _#_#tearOff({core::int field}) → self::Class2
     return new self::Class2::_(field: field);
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values_complex.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values_complex.dart.weak.outline.expect
index 7cf24c4..d465217 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values_complex.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/redirecting_factory_tear_off_default_values_complex.dart.weak.outline.expect
@@ -6,9 +6,9 @@
   final field core::int field1;
   final field core::int field2;
   static final field dynamic _redirecting# = <dynamic>[self::Class1::redirectPositionalSame, self::Class1::redirectPositionalFewer1, self::Class1::redirectPositionalFewer2, self::Class1::redirectNamedSame, self::Class1::redirectNamedReorder, self::Class1::redirectNamedFewer1, self::Class1::redirectNamedFewer2, self::Class1::redirectNamedFewer3]/*isLegacy*/;
-  constructor positional([core::int field1, core::int field2]) → self::Class1
+  constructor positional([core::int field1 = 1, core::int field2 = 2]) → self::Class1
     ;
-  constructor named({core::int field1, core::int field2}) → self::Class1
+  constructor named({core::int field1 = 1, core::int field2 = 2}) → self::Class1
     ;
   static method _#positional#tearOff([core::int field1, core::int field2]) → self::Class1
     return new self::Class1::positional(field1, field2);
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_from.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_from.dart.weak.outline.expect
index 9f1b30a..757a1e2 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_from.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_from.dart.weak.outline.expect
@@ -10,7 +10,7 @@
   static final field dynamic _redirecting# = <dynamic>[self::Class::redirect]/*isLegacy*/;
   constructor •(self::Class::S% a, self::Class::T% b) → self::Class<self::Class::S%, self::Class::T%>
     ;
-  constructor named(self::Class::S% a, [self::Class::T? b, core::int c]) → self::Class<self::Class::S%, self::Class::T%>
+  constructor named(self::Class::S% a, [self::Class::T? b, core::int c = 42]) → self::Class<self::Class::S%, self::Class::T%>
     ;
   static method _#new#tearOff<S extends core::Object? = dynamic, T extends core::Object? = dynamic>(self::Class::_#new#tearOff::S% a, self::Class::_#new#tearOff::T% b) → self::Class<self::Class::_#new#tearOff::S%, self::Class::_#new#tearOff::T%>
     return new self::Class::•<self::Class::_#new#tearOff::S%, self::Class::_#new#tearOff::T%>(a, b);
diff --git a/pkg/front_end/testcases/constructor_tearoffs/named_mixin_application.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/named_mixin_application.dart.weak.outline.expect
index 99e5f30..c282d10 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/named_mixin_application.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/named_mixin_application.dart.weak.outline.expect
@@ -10,7 +10,7 @@
 class Class<T extends core::Object? = dynamic> extends core::Object implements self::Interface {
   field core::int field;
   static final field dynamic _redirecting# = <dynamic>[self::Class::redirectingFactory]/*isLegacy*/;
-  constructor •([core::int field]) → self::Class<self::Class::T%>
+  constructor •([core::int field = 0]) → self::Class<self::Class::T%>
     ;
   constructor named(core::int field) → self::Class<self::Class::T%>
     ;
diff --git a/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.modular.expect b/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.modular.expect
index 1c7ef8f..573e273 100644
--- a/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.modular.expect
@@ -26,20 +26,20 @@
 import "org-dartlang-testcase:///m_lib.dart";
 
 abstract class _B&A&M = a_l::A with m_l::M /*isAnonymousMixin*/  {
-  synthetic constructor •({core::double d, (core::String) → core::String s}) → b_l::_B&A&M
+  synthetic constructor •({core::double d = #C1, (core::String) → core::String s = #C2}) → b_l::_B&A&M
     : super a_l::A::•(d: d, s: s)
     ;
-  synthetic constructor factoryConstructor({core::double d, (core::String) → core::String s}) → b_l::_B&A&M
+  synthetic constructor factoryConstructor({core::double d = #C1, (core::String) → core::String s = #C2}) → b_l::_B&A&M
     : super a_l::A::factoryConstructor(d: d, s: s)
     ;
   mixin-super-stub method m1() → dynamic
     return super.{m_l::M::m1}();
 }
 class B extends b_l::_B&A&M {
-  constructor •({core::double d = #C1}) → b_l::B
+  constructor •({core::double d = #C3}) → b_l::B
     : super b_l::_B&A&M::•(d: d)
     ;
-  static method _#new#tearOff({core::double d = #C1}) → b_l::B
+  static method _#new#tearOff({core::double d = #C3}) → b_l::B
     return new b_l::B::•(d: d);
 }
 
@@ -54,5 +54,7 @@
 }
 
 constants  {
-  #C1 = 2.71
+  #C1 = 3.14
+  #C2 = static-tearoff a_l::_defaultStringy
+  #C3 = 2.71
 }
diff --git a/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.outline.expect
index 1aa4284..2950126 100644
--- a/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/dart2js/mixin_default_values/main.dart.weak.outline.expect
@@ -28,7 +28,7 @@
     return super.{m_l::M::m1}();
 }
 class B extends self2::_B&A&M {
-  constructor •({core::double d}) → self2::B
+  constructor •({core::double d = 2.71}) → self2::B
     ;
   static method _#new#tearOff({core::double d}) → self2::B
     return new self2::B::•(d: d);
@@ -54,9 +54,9 @@
 class A extends core::Object {
   final field core::double d;
   final field (core::String) → core::String _s;
-  constructor •({core::double d, (core::String) → core::String s}) → a_l::A
+  constructor •({core::double d = #C1, (core::String) → core::String s = #C2}) → a_l::A
     ;
-  constructor factoryConstructor({core::double d, (core::String) → core::String s}) → a_l::A
+  constructor factoryConstructor({core::double d = #C1, (core::String) → core::String s = #C2}) → a_l::A
     ;
   static method _#new#tearOff({core::double d, (core::String) → core::String s}) → a_l::A
     return new a_l::A::•(d: d, s: s);
@@ -73,3 +73,8 @@
 import "dart:core" as core;
 
 typedef StringyFunction<contravariant T extends core::Object? = dynamic> = (T%) → core::String;
+
+constants  {
+  #C1 = 3.14
+  #C2 = static-tearoff a_l::_defaultStringy
+}
diff --git a/pkg/front_end/testcases/general/constructor_patch/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/constructor_patch/main.dart.weak.outline.expect
index d5e5658..ef6d09e 100644
--- a/pkg/front_end/testcases/general/constructor_patch/main.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/constructor_patch/main.dart.weak.outline.expect
@@ -17,7 +17,7 @@
 class Class extends core::Object /*hasConstConstructor*/  {
   final field core::bool defaultValue /* from org-dartlang-testcase:///patch_lib.dart */;
   @_in::patch
-  external constructor generative({core::bool defaultValue}) → self2::Class
+  external constructor generative({core::bool defaultValue = true}) → self2::Class
     ;
   @_in::patch
   const constructor constGenerative({core::bool defaultValue = true}) → self2::Class
diff --git a/pkg/front_end/testcases/general/issue31767.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue31767.dart.weak.outline.expect
index 43bfbd8..d4d8c65 100644
--- a/pkg/front_end/testcases/general/issue31767.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/issue31767.dart.weak.outline.expect
@@ -7,7 +7,7 @@
 
 class C extends core::Object {
   final field core::int* w;
-  constructor foo(core::int* x, [core::int* y, core::int* z]) → self::C*
+  constructor foo(core::int* x, [core::int* y = 0, core::int* z = 0]) → self::C*
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -59,7 +59,7 @@
 class A extends core::Object {
   final field core::int* w;
   final field iss::_A* a;
-  constructor foo(core::int* x, [core::int* y, core::int* z, iss::_A* a]) → iss::A*
+  constructor foo(core::int* x, [core::int* y = iss::_private, core::int* z = iss::_private, iss::_A* a = const iss::_A::•(5)]) → iss::A*
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -89,3 +89,10 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static const field core::int* _private = 3;
+
+
+Extra constant evaluation status:
+Evaluated: StaticGet @ org-dartlang-testcase:///issue31767_lib.dart:14:25 -> IntConstant(3)
+Evaluated: StaticGet @ org-dartlang-testcase:///issue31767_lib.dart:14:43 -> IntConstant(3)
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue31767_lib.dart:14:68 -> InstanceConstant(const _A{_A.field: 5})
+Extra constant evaluation: evaluated: 13, effectively constant: 3
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.expect
index eba1d44..813bde3 100644
--- a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.expect
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart:9:15: Error: Type variables can't be used as constants.
+// pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart:9:15: Error: Type variables can't be used in static members.
 //   C({a: 0, b: T}) : trace = "a: $a, b: $b";
 //               ^
 //
@@ -14,7 +14,7 @@
 
 class C<T extends core::Object* = dynamic> extends core::Object {
   field core::String* trace;
-  constructor •({dynamic a = #C1, dynamic b = invalid-expression "Type variables can't be used as constants."}) → self::C<self::C::T*>*
+  constructor •({dynamic a = #C1, dynamic b = #C2}) → self::C<self::C::T*>*
     : self::C::trace = "a: ${a}, b: ${b}", super core::Object::•()
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
@@ -54,7 +54,7 @@
     ;
 }
 abstract class _F&C&M = self::C<core::int*> with self::M /*isAnonymousMixin*/  {
-  synthetic constructor •({dynamic a = #C1, dynamic b = #C3}) → self::_F&C&M*
+  synthetic constructor •({dynamic a = #C1, dynamic b = #C2}) → self::_F&C&M*
     : super self::C::•(a: a, b: b)
     ;
 }
@@ -73,6 +73,5 @@
 
 constants  {
   #C1 = 0
-  #C2 = TypeLiteralConstant(core::String*)
-  #C3 = TypeLiteralConstant(core::int*)
+  #C2 = TypeLiteralConstant(invalid-type)
 }
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.modular.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.modular.expect
index eba1d44..813bde3 100644
--- a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.modular.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart:9:15: Error: Type variables can't be used as constants.
+// pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart:9:15: Error: Type variables can't be used in static members.
 //   C({a: 0, b: T}) : trace = "a: $a, b: $b";
 //               ^
 //
@@ -14,7 +14,7 @@
 
 class C<T extends core::Object* = dynamic> extends core::Object {
   field core::String* trace;
-  constructor •({dynamic a = #C1, dynamic b = invalid-expression "Type variables can't be used as constants."}) → self::C<self::C::T*>*
+  constructor •({dynamic a = #C1, dynamic b = #C2}) → self::C<self::C::T*>*
     : self::C::trace = "a: ${a}, b: ${b}", super core::Object::•()
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
@@ -54,7 +54,7 @@
     ;
 }
 abstract class _F&C&M = self::C<core::int*> with self::M /*isAnonymousMixin*/  {
-  synthetic constructor •({dynamic a = #C1, dynamic b = #C3}) → self::_F&C&M*
+  synthetic constructor •({dynamic a = #C1, dynamic b = #C2}) → self::_F&C&M*
     : super self::C::•(a: a, b: b)
     ;
 }
@@ -73,6 +73,5 @@
 
 constants  {
   #C1 = 0
-  #C2 = TypeLiteralConstant(core::String*)
-  #C3 = TypeLiteralConstant(core::int*)
+  #C2 = TypeLiteralConstant(invalid-type)
 }
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.outline.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.outline.expect
index 1b5d000..b84923c 100644
--- a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.outline.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart:9:15: Error: Type variables can't be used in static members.
+//   C({a: 0, b: T}) : trace = "a: $a, b: $b";
+//               ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -6,7 +13,7 @@
 
 class C<T extends core::Object* = dynamic> extends core::Object {
   field core::String* trace;
-  constructor •({dynamic a, dynamic b}) → self::C<self::C::T*>*
+  constructor •({dynamic a = 0, dynamic b = invalid-type}) → self::C<self::C::T*>*
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -53,3 +60,8 @@
 }
 static method main() → dynamic
   ;
+
+
+Extra constant evaluation status:
+Evaluated: TypeLiteral @ org-dartlang-testcase:///mixin_constructors_with_default_values.dart:9:15 -> TypeLiteralConstant(<invalid>)
+Extra constant evaluation: evaluated: 5, effectively constant: 1
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.transformed.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.transformed.expect
index 7780786..ee8735c 100644
--- a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart:9:15: Error: Type variables can't be used as constants.
+// pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart:9:15: Error: Type variables can't be used in static members.
 //   C({a: 0, b: T}) : trace = "a: $a, b: $b";
 //               ^
 //
@@ -14,7 +14,7 @@
 
 class C<T extends core::Object* = dynamic> extends core::Object {
   field core::String* trace;
-  constructor •({dynamic a = #C1, dynamic b = invalid-expression "Type variables can't be used as constants."}) → self::C<self::C::T*>*
+  constructor •({dynamic a = #C1, dynamic b = #C2}) → self::C<self::C::T*>*
     : self::C::trace = "a: ${a}, b: ${b}", super core::Object::•()
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
@@ -54,7 +54,7 @@
     ;
 }
 abstract class _F&C&M extends self::C<core::int*> implements self::M /*isAnonymousMixin,isEliminatedMixin*/  {
-  synthetic constructor •({dynamic a = #C1, dynamic b = #C3}) → self::_F&C&M*
+  synthetic constructor •({dynamic a = #C1, dynamic b = #C2}) → self::_F&C&M*
     : super self::C::•(a: a, b: b)
     ;
 }
@@ -73,6 +73,5 @@
 
 constants  {
   #C1 = 0
-  #C2 = TypeLiteralConstant(core::String*)
-  #C3 = TypeLiteralConstant(core::int*)
+  #C2 = TypeLiteralConstant(invalid-type)
 }
diff --git a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.outline.expect
index 03b90d2..46d5dff 100644
--- a/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/mixin_from_patch/main.dart.weak.outline.expect
@@ -15,7 +15,7 @@
 
 @_in::patch
 class Class extends core::Object {
-  constructor _internal({core::bool* value}) → self2::Class*
+  constructor _internal({core::bool* value = false}) → self2::Class*
     ;
   @_in::patch
   external constructor patched() → self2::Class*
diff --git a/pkg/front_end/testcases/general/redirecting_factory_default_value.dart.weak.outline.expect b/pkg/front_end/testcases/general/redirecting_factory_default_value.dart.weak.outline.expect
index 7669a3f..05e4ae1 100644
--- a/pkg/front_end/testcases/general/redirecting_factory_default_value.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/redirecting_factory_default_value.dart.weak.outline.expect
@@ -5,7 +5,7 @@
 class A extends core::Object {
   final field core::int field;
   static final field dynamic _redirecting# = <dynamic>[self::A::redirect]/*isLegacy*/;
-  constructor •([core::int field]) → self::A
+  constructor •([core::int field = 42]) → self::A
     ;
   static factory redirect([core::int field]) → self::A
     return new self::A::•(field);
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.weak.outline.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.weak.outline.expect
index 2f2896d..91466e9 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.weak.outline.expect
@@ -5,9 +5,9 @@
 typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = ([S*]) →* T*;
 class Foo extends core::Object {
   field core::List<core::int*>* x;
-  constructor •([core::List<core::int*>* x]) → self::Foo*
+  constructor •([core::List<core::int*>* x = const <core::int*>[1]]) → self::Foo*
     ;
-  constructor named([core::List<core::int*>* x]) → self::Foo*
+  constructor named([core::List<core::int*>* x = const <core::int*>[1]]) → self::Foo*
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -25,3 +25,9 @@
   ;
 static method main() → dynamic
   ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///downwards_inference_initializing_formal_default_formal.dart:12:38 -> ListConstant(const <int*>[1])
+Evaluated: ListLiteral @ org-dartlang-testcase:///downwards_inference_initializing_formal_default_formal.dart:13:49 -> ListConstant(const <int*>[1])
+Extra constant evaluation: evaluated: 2, effectively constant: 2
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.weak.outline.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.weak.outline.expect
index 0bc9761..c617c3d 100644
--- a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.weak.outline.expect
@@ -1,10 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+//   Foo([this.x = /*error:INVALID_ASSIGNMENT*/ "1"]);
+//                                              ^
+//
 import self as self;
 import "dart:core" as core;
 
 class Foo extends core::Object {
   field core::int* x;
-  constructor •([core::int* x]) → self::Foo*
+  constructor •([core::int* x = invalid-expression "pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+  Foo([this.x = /*error:INVALID_ASSIGNMENT*/ \"1\"]);
+                                             ^" in "1" as{TypeError} core::int*]) → self::Foo*
     ;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.weak.outline.expect
index fa7bd6a..6ae21b7 100644
--- a/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.weak.outline.expect
@@ -11,7 +11,7 @@
     ;
   constructor constructor3(core::int value) → self::Class
     ;
-  constructor constructor4([core::int field]) → self::Class
+  constructor constructor4([core::int field = 42]) → self::Class
     ;
   get field() → core::int;
   set field(core::int #t1) → void;
@@ -23,7 +23,7 @@
     ;
   constructor constructor3(core::int value) → self::Subclass
     ;
-  constructor constructor4([core::int value]) → self::Subclass
+  constructor constructor4([core::int value = 87]) → self::Subclass
     ;
 }
 static method test1() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.weak.outline.expect
index f83a9eb..b454862 100644
--- a/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.weak.outline.expect
@@ -11,7 +11,7 @@
     ;
   constructor constructor3(core::int value) → self::Class
     ;
-  constructor constructor4([core::int field]) → self::Class
+  constructor constructor4([core::int field = 42]) → self::Class
     ;
   get field() → core::int;
   set field(core::int #t1) → void;
@@ -23,7 +23,7 @@
     ;
   constructor constructor3(core::int value) → self::Subclass
     ;
-  constructor constructor4([core::int value]) → self::Subclass
+  constructor constructor4([core::int value = 87]) → self::Subclass
     ;
 }
 static method test1() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.weak.outline.expect
index f83a9eb..b454862 100644
--- a/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.weak.outline.expect
@@ -11,7 +11,7 @@
     ;
   constructor constructor3(core::int value) → self::Class
     ;
-  constructor constructor4([core::int field]) → self::Class
+  constructor constructor4([core::int field = 42]) → self::Class
     ;
   get field() → core::int;
   set field(core::int #t1) → void;
@@ -23,7 +23,7 @@
     ;
   constructor constructor3(core::int value) → self::Subclass
     ;
-  constructor constructor4([core::int value]) → self::Subclass
+  constructor constructor4([core::int value = 87]) → self::Subclass
     ;
 }
 static method test1() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.outline.expect
index 511d101..dfec80d 100644
--- a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.outline.expect
@@ -11,7 +11,7 @@
     ;
   constructor constructor3(core::int value) → self::Class
     ;
-  constructor constructor4([core::int? field]) → self::Class
+  constructor constructor4([core::int? field = 42]) → self::Class
     ;
   get field() → core::int?;
   set field(core::int? #t1) → void;
@@ -23,7 +23,7 @@
     ;
   constructor constructor3(core::int value) → self::Subclass
     ;
-  constructor constructor4([core::int value]) → self::Subclass
+  constructor constructor4([core::int value = 87]) → self::Subclass
     ;
 }
 static method initField() → core::int?
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.weak.outline.expect
index 2ed3a81..4c71a87 100644
--- a/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.weak.outline.expect
@@ -11,7 +11,7 @@
     ;
   constructor constructor3(core::int value) → self::Class
     ;
-  constructor constructor4([core::int? field]) → self::Class
+  constructor constructor4([core::int? field = 42]) → self::Class
     ;
   get field() → core::int?;
   set field(core::int? #t1) → void;
@@ -23,7 +23,7 @@
     ;
   constructor constructor3(core::int value) → self::Subclass
     ;
-  constructor constructor4([core::int value]) → self::Subclass
+  constructor constructor4([core::int value = 87]) → self::Subclass
     ;
 }
 static method test1() → dynamic
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.weak.outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.weak.outline.expect
index 2ed3a81..4c71a87 100644
--- a/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.weak.outline.expect
@@ -11,7 +11,7 @@
     ;
   constructor constructor3(core::int value) → self::Class
     ;
-  constructor constructor4([core::int? field]) → self::Class
+  constructor constructor4([core::int? field = 42]) → self::Class
     ;
   get field() → core::int?;
   set field(core::int? #t1) → void;
@@ -23,7 +23,7 @@
     ;
   constructor constructor3(core::int value) → self::Subclass
     ;
-  constructor constructor4([core::int value]) → self::Subclass
+  constructor constructor4([core::int value = 87]) → self::Subclass
     ;
 }
 static method test1() → dynamic
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 64d0aa7..9be9af8 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -826,12 +826,11 @@
   SourceLibraryBuilder createDartDocTestLibrary(
       SourceLoader loader, LibraryBuilder libraryBuilder) {
     SourceLibraryBuilder dartDocTestLibrary = new SourceLibraryBuilder(
-      dartDocTestUri,
-      dartDocTestUri,
-      /*packageUri*/ null,
-      new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
-      loader,
-      null,
+      importUri: dartDocTestUri,
+      fileUri: dartDocTestUri,
+      packageLanguageVersion:
+          new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
+      loader: loader,
       scope: libraryBuilder.scope.createNestedScope("dartdoctest"),
       nameOrigin: libraryBuilder,
     );
@@ -899,14 +898,14 @@
 
   @override
   SourceLibraryBuilder createLibraryBuilder(
-      Uri uri,
-      Uri fileUri,
+      {required Uri importUri,
+      required Uri fileUri,
       Uri? packageUri,
-      LanguageVersion packageLanguageVersion,
+      required LanguageVersion packageLanguageVersion,
       SourceLibraryBuilder? origin,
       kernel.Library? referencesFrom,
-      bool? referenceIsPartOwner) {
-    if (uri == DocTestIncrementalCompiler.dartDocTestUri) {
+      bool? referenceIsPartOwner}) {
+    if (importUri == DocTestIncrementalCompiler.dartDocTestUri) {
       HybridFileSystem hfs = target.fileSystem as HybridFileSystem;
       MemoryFileSystem fs = hfs.memory;
       fs
@@ -915,7 +914,13 @@
       return compiler.createDartDocTestLibrary(
           this, compiler._dartDocTestLibraryBuilder!);
     }
-    return super.createLibraryBuilder(uri, fileUri, packageUri,
-        packageLanguageVersion, origin, referencesFrom, referenceIsPartOwner);
+    return super.createLibraryBuilder(
+        importUri: importUri,
+        fileUri: fileUri,
+        packageUri: packageUri,
+        packageLanguageVersion: packageLanguageVersion,
+        origin: origin,
+        referencesFrom: referencesFrom,
+        referenceIsPartOwner: referenceIsPartOwner);
   }
 }
diff --git a/tools/VERSION b/tools/VERSION
index 4958d12..406d617 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 100
+PRERELEASE 101
 PRERELEASE_PATCH 0
\ No newline at end of file