Version 2.15.0-178.0.dev

Merge commit 'e2a689bafd30c6bc59b81db1d48bea5d02628ed9' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 105f851..f09e2dd 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-10-01T13:54:59.751334",
+  "generated": "2021-10-03T09:32:39.517171",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -94,7 +94,7 @@
       "name": "analyzer_plugin",
       "rootUri": "../pkg/analyzer_plugin",
       "packageUri": "lib/",
-      "languageVersion": "2.12"
+      "languageVersion": "2.14"
     },
     {
       "name": "analyzer_utilities",
diff --git a/pkg/analyzer_plugin/CHANGELOG.md b/pkg/analyzer_plugin/CHANGELOG.md
index 3ee89a3..04ab329 100644
--- a/pkg/analyzer_plugin/CHANGELOG.md
+++ b/pkg/analyzer_plugin/CHANGELOG.md
@@ -1,6 +1,9 @@
-## 0.7.0
+## 0.8.0
+- Require SDK `2.14` to use `Object.hash()`.
+- Require `yaml 3.1.0` to use `recover`.
 
-- Support verison `2.x` of the `analyzer` package
+## 0.7.0
+- Support version `2.x` of the `analyzer` package
 
 ## 0.6.0
 - Bug fixes to the protocol.
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index 7b0003e..41b859d 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -1,17 +1,17 @@
 name: analyzer_plugin
 description: A framework and support code for building plugins for the analysis server.
-version: 0.7.0
+version: 0.8.0
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_plugin
 
 environment:
-  sdk: '>=2.12.0 <3.0.0'
+  sdk: '>=2.14.0 <3.0.0'
 
 dependencies:
-  analyzer: ^2.0.0
+  analyzer: ^2.4.0
   collection: ^1.15.0
   dart_style: ^2.0.0
   pub_semver: ^2.0.0
-  yaml: ^3.0.0
+  yaml: ^3.1.0
 
 dev_dependencies:
   analyzer_utilities:
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
index 31ac71e..cf6125b 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
@@ -22,7 +22,7 @@
     show isRedirectingGenerativeConstructorImplementation;
 import '../kernel/kernel_helper.dart' show SynthesizedFunctionNode;
 
-import '../loader.dart' show Loader;
+import '../source/source_loader.dart' show SourceLoader;
 
 import '../messages.dart'
     show
@@ -90,7 +90,7 @@
   Set<FieldBuilder>? takeInitializedFields();
 }
 
-class ConstructorBuilderImpl extends FunctionBuilderImpl
+class SourceConstructorBuilder extends FunctionBuilderImpl
     implements ConstructorBuilder {
   final Constructor _constructor;
   final Procedure? _constructorTearOff;
@@ -114,7 +114,7 @@
   @override
   Constructor get actualConstructor => _constructor;
 
-  ConstructorBuilderImpl(
+  SourceConstructorBuilder(
       List<MetadataBuilder>? metadata,
       int modifiers,
       TypeBuilder? returnType,
@@ -147,6 +147,10 @@
   SourceLibraryBuilder get library => super.library as SourceLibraryBuilder;
 
   @override
+  SourceClassBuilder get classBuilder =>
+      super.classBuilder as SourceClassBuilder;
+
+  @override
   Member? get readTarget => _constructorTearOff ?? _constructor;
 
   @override
@@ -213,7 +217,7 @@
 
       if (_constructorTearOff != null) {
         buildConstructorTearOffProcedure(_constructorTearOff!, _constructor,
-            classBuilder!.cls, libraryBuilder);
+            classBuilder.cls, libraryBuilder);
       }
 
       _hasBeenBuilt = true;
@@ -243,7 +247,7 @@
     if (formals != null) {
       for (FormalParameterBuilder formal in formals!) {
         if (formal.type == null && formal.isInitializingFormal) {
-          formal.finalizeInitializingFormal(classBuilder!);
+          formal.finalizeInitializingFormal(classBuilder);
         }
       }
     }
@@ -270,7 +274,7 @@
     if (isConst && beginInitializers != null) {
       BodyBuilder bodyBuilder = library.loader
           .createBodyBuilderForOutlineExpression(
-              library, classBuilder!, this, classBuilder!.scope, fileUri);
+              library, classBuilder, this, classBuilder.scope, fileUri);
       bodyBuilder.constantContext = ConstantContext.required;
       bodyBuilder.parseInitializers(beginInitializers!);
       bodyBuilder.performBacklogComputations(delayedActionPerformers);
@@ -287,7 +291,7 @@
     // According to the specification §9.3 the return type of a constructor
     // function is its enclosing class.
     super.buildFunction(library);
-    Class enclosingClass = classBuilder!.cls;
+    Class enclosingClass = classBuilder.cls;
     List<DartType> typeParameterTypes = <DartType>[];
     for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
       TypeParameter typeParameter = enclosingClass.typeParameters[i];
@@ -426,14 +430,14 @@
   }
 
   @override
-  void becomeNative(Loader loader) {
+  void becomeNative(SourceLoader loader) {
     _constructor.isExternal = true;
     super.becomeNative(loader);
   }
 
   @override
   void applyPatch(Builder patch) {
-    if (patch is ConstructorBuilderImpl) {
+    if (patch is SourceConstructorBuilder) {
       if (checkPatch(patch)) {
         patch.actualOrigin = this;
         dataForTesting?.patchForTesting = patch;
diff --git a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
index 5fff739..6f9fcec 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
@@ -217,7 +217,7 @@
           referencesFromIndexed.lookupSetterReference(valuesName);
     }
 
-    ConstructorBuilder constructorBuilder = new ConstructorBuilderImpl(
+    ConstructorBuilder constructorBuilder = new SourceConstructorBuilder(
         /* metadata = */ null,
         constMask,
         /* returnType = */ null,
@@ -410,8 +410,8 @@
     SourceFieldBuilder valuesBuilder =
         firstMemberNamed("values") as SourceFieldBuilder;
     valuesBuilder.build(libraryBuilder);
-    ConstructorBuilderImpl constructorBuilder =
-        constructorScopeBuilder[""] as ConstructorBuilderImpl;
+    SourceConstructorBuilder constructorBuilder =
+        constructorScopeBuilder[""] as SourceConstructorBuilder;
     Constructor constructor = constructorBuilder.build(libraryBuilder);
     ClassBuilder objectClass = objectType.declaration as ClassBuilder;
     ClassBuilder enumClass = supertypeBuilder.declaration as ClassBuilder;
@@ -459,8 +459,8 @@
         coreTypes,
         new ListLiteral(values,
             typeArgument: rawType(library.nonNullable), isConst: true));
-    ConstructorBuilderImpl constructorBuilder =
-        constructorScopeBuilder[""] as ConstructorBuilderImpl;
+    SourceConstructorBuilder constructorBuilder =
+        constructorScopeBuilder[""] as SourceConstructorBuilder;
     Constructor constructor = constructorBuilder.constructor;
     int index = 0;
     if (enumConstantInfos != null) {
diff --git a/pkg/front_end/lib/src/fasta/builder/factory_builder.dart b/pkg/front_end/lib/src/fasta/builder/factory_builder.dart
index 090b24b..d19bcde 100644
--- a/pkg/front_end/lib/src/fasta/builder/factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/factory_builder.dart
@@ -16,7 +16,7 @@
 import '../kernel/redirecting_factory_body.dart'
     show getRedirectingFactoryBody, RedirectingFactoryBody;
 
-import '../loader.dart' show Loader;
+import '../source/source_loader.dart' show SourceLoader;
 
 import '../messages.dart'
     show messageConstFactoryRedirectionToNonConst, noLength;
@@ -199,7 +199,7 @@
       throw new UnsupportedError('${runtimeType}.localSetters');
 
   @override
-  void becomeNative(Loader loader) {
+  void becomeNative(SourceLoader loader) {
     _procedureInternal.isExternal = true;
     super.becomeNative(loader);
   }
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index 0f1cb27..8c525b7 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -15,7 +15,7 @@
 import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
 import '../kernel/kernel_helper.dart';
 
-import '../loader.dart' show Loader;
+import '../source/source_loader.dart' show SourceLoader;
 
 import '../messages.dart'
     show
@@ -129,7 +129,7 @@
   /// members.
   List<TypeParameter>? get extensionTypeParameters;
 
-  void becomeNative(Loader loader);
+  void becomeNative(SourceLoader loader);
 
   bool checkPatch(FunctionBuilder patch);
 
@@ -526,7 +526,7 @@
   Member build(SourceLibraryBuilder library);
 
   @override
-  void becomeNative(Loader loader) {
+  void becomeNative(SourceLoader loader) {
     MemberBuilder constructor = loader.getNativeAnnotation();
     Arguments arguments =
         new Arguments(<Expression>[new StringLiteral(nativeMethodName!)]);
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index 7f0a2a7..a1118c6 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -8,9 +8,8 @@
 import '../kernel/class_hierarchy_builder.dart';
 import '../kernel/member_covariance.dart';
 
-import '../loader.dart' show Loader;
-
 import '../source/name_scheme.dart';
+import '../source/source_loader.dart' show SourceLoader;
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 
 import 'builder.dart';
@@ -477,7 +476,7 @@
           : const <ClassMember>[];
 
   @override
-  void becomeNative(Loader loader) {
+  void becomeNative(SourceLoader loader) {
     _procedure.isExternal = true;
     super.becomeNative(loader);
   }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 242c2cb..3598ae5 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -4,35 +4,251 @@
 
 library fasta.dill_loader;
 
+import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
+
 import 'package:kernel/ast.dart' show Class, Component, DartType, Library;
 
 import '../builder/class_builder.dart';
 import '../builder/library_builder.dart';
 import '../builder/type_builder.dart';
 
+import '../crash.dart' show firstSourceUri;
+
 import '../fasta_codes.dart'
     show SummaryTemplate, Template, templateDillOutlineSummary;
 
 import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
 
-import '../loader.dart' show Loader;
+import '../loader.dart';
 
-import '../problems.dart' show unhandled;
+import '../messages.dart'
+    show
+        FormattedMessage,
+        LocatedMessage,
+        Message,
+        noLength,
+        SummaryTemplate,
+        Template,
+        messagePlatformPrivateLibraryAccess,
+        templateInternalProblemContextSeverity;
+
+import '../problems.dart' show internalProblem, unhandled;
 
 import '../source/source_loader.dart' show SourceLoader;
 
-import '../target_implementation.dart' show TargetImplementation;
+import '../ticker.dart' show Ticker;
 
 import 'dill_library_builder.dart' show DillLibraryBuilder;
 
 import 'dill_target.dart' show DillTarget;
 
+import 'dart:collection' show Queue;
+
 class DillLoader extends Loader {
   SourceLoader? currentSourceLoader;
 
-  DillLoader(TargetImplementation target) : super(target);
+  @override
+  final Map<Uri, DillLibraryBuilder> builders = <Uri, DillLibraryBuilder>{};
+
+  final Queue<DillLibraryBuilder> _unparsedLibraries =
+      new Queue<DillLibraryBuilder>();
+
+  final List<Library> libraries = <Library>[];
 
   @override
+  final DillTarget target;
+
+  /// List of all handled compile-time errors seen so far by libraries loaded
+  /// by this loader.
+  ///
+  /// A handled error is an error that has been added to the generated AST
+  /// already, for example, as a throw expression.
+  final List<LocatedMessage> handledErrors = <LocatedMessage>[];
+
+  /// List of all unhandled compile-time errors seen so far by libraries loaded
+  /// by this loader.
+  ///
+  /// An unhandled error is an error that hasn't been handled, see
+  /// [handledErrors].
+  final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];
+
+  final Set<String> seenMessages = new Set<String>();
+
+  LibraryBuilder? _coreLibrary;
+
+  /// The first library loaded by this [DillLoader].
+  // TODO(johnniwinther): Do we need this?
+  LibraryBuilder? first;
+
+  int byteCount = 0;
+
+  DillLoader(this.target);
+
+  @override
+  LibraryBuilder get coreLibrary => _coreLibrary!;
+
+  void set coreLibrary(LibraryBuilder value) {
+    _coreLibrary = value;
+  }
+
+  Ticker get ticker => target.ticker;
+
+  /// Look up a library builder by the [uri], or if such doesn't exist, create
+  /// one. The canonical URI of the library is [uri], and its actual location is
+  /// [fileUri].
+  ///
+  /// Canonical URIs have schemes like "dart", or "package", and the actual
+  /// location is often a file URI.
+  ///
+  /// The [accessor] is the library that's trying to import, export, or include
+  /// as part [uri], and [charOffset] is the location of the corresponding
+  /// directive. If [accessor] isn't allowed to access [uri], it's a
+  /// compile-time error.
+  DillLibraryBuilder read(Uri uri, int charOffset, {LibraryBuilder? accessor}) {
+    DillLibraryBuilder builder = builders.putIfAbsent(uri, () {
+      DillLibraryBuilder library = target.createLibraryBuilder(uri);
+      assert(library.loader == this);
+      if (uri.scheme == "dart") {
+        if (uri.path == "core") {
+          _coreLibrary = library;
+        }
+      }
+      {
+        // Add any additional logic after this block. Setting the
+        // firstSourceUri and first library should be done as early as
+        // possible.
+        firstSourceUri ??= uri;
+        first ??= library;
+      }
+      if (_coreLibrary == library) {
+        target.loadExtraRequiredLibraries(this);
+      }
+      if (target.backendTarget.mayDefineRestrictedType(uri)) {
+        library.mayImplementRestrictedTypes = true;
+      }
+      _unparsedLibraries.addLast(library);
+      return library;
+    });
+    if (accessor != null) {
+      builder.recordAccess(charOffset, noLength, accessor.fileUri);
+      if (!accessor.isPatch &&
+          !accessor.isPart &&
+          !target.backendTarget
+              .allowPlatformPrivateLibraryAccess(accessor.importUri, uri)) {
+        accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
+            noLength, accessor.fileUri);
+      }
+    }
+    return builder;
+  }
+
+  void _ensureCoreLibrary() {
+    if (_coreLibrary == null) {
+      read(Uri.parse("dart:core"), 0, accessor: first);
+      // TODO(askesc): When all backends support set literals, we no longer
+      // need to index dart:collection, as it is only needed for desugaring of
+      // const sets. We can remove it from this list at that time.
+      read(Uri.parse("dart:collection"), 0, accessor: first);
+      assert(_coreLibrary != null);
+    }
+  }
+
+  void buildOutlines() {
+    _ensureCoreLibrary();
+    while (_unparsedLibraries.isNotEmpty) {
+      DillLibraryBuilder library = _unparsedLibraries.removeFirst();
+      buildOutline(library);
+    }
+    _logSummary(outlineSummaryTemplate);
+  }
+
+  void _logSummary(Template<SummaryTemplate> template) {
+    ticker.log((Duration elapsed, Duration sinceStart) {
+      int libraryCount = 0;
+      for (DillLibraryBuilder library in builders.values) {
+        assert(library.loader == this);
+        libraryCount++;
+      }
+      double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
+      Message message = template.withArguments(
+          libraryCount, byteCount, ms, byteCount / ms, ms / libraryCount);
+      print("$sinceStart: ${message.message}");
+    });
+  }
+
+  /// Register [message] as a problem with a severity determined by the
+  /// intrinsic severity of the message.
+  // TODO(johnniwinther): Avoid the need for this. If this is ever used, it is
+  // inconsistent with messages reported through the [SourceLoader] since they
+  // each have their own list of unhandled/unhandled errors and seen messages,
+  // and only those of the [SourceLoader] are used elsewhere. Use
+  // [currentSourceLoader] to forward messages to the [SourceLoader] instead.
+  @override
+  FormattedMessage? addProblem(
+      Message message, int charOffset, int length, Uri? fileUri,
+      {bool wasHandled: false,
+      List<LocatedMessage>? context,
+      Severity? severity,
+      bool problemOnLibrary: false,
+      List<Uri>? involvedFiles}) {
+    return _addMessage(message, charOffset, length, fileUri, severity,
+        wasHandled: wasHandled,
+        context: context,
+        problemOnLibrary: problemOnLibrary,
+        involvedFiles: involvedFiles);
+  }
+
+  /// All messages reported by the compiler (errors, warnings, etc.) are routed
+  /// through this method.
+  ///
+  /// Returns a FormattedMessage if the message is new, that is, not previously
+  /// reported. This is important as some parser errors may be reported up to
+  /// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
+  /// If the message is not new, [null] is reported.
+  ///
+  /// If [severity] is `Severity.error`, the message is added to
+  /// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
+  /// [wasHandled] is false.
+  FormattedMessage? _addMessage(Message message, int charOffset, int length,
+      Uri? fileUri, Severity? severity,
+      {bool wasHandled: false,
+      List<LocatedMessage>? context,
+      bool problemOnLibrary: false,
+      List<Uri>? involvedFiles}) {
+    severity ??= message.code.severity;
+    if (severity == Severity.ignored) return null;
+    String trace = """
+message: ${message.message}
+charOffset: $charOffset
+fileUri: $fileUri
+severity: $severity
+""";
+    if (!seenMessages.add(trace)) return null;
+    if (message.code.severity == Severity.context) {
+      internalProblem(
+          templateInternalProblemContextSeverity
+              .withArguments(message.code.name),
+          charOffset,
+          fileUri);
+    }
+    target.context.report(
+        fileUri != null
+            ? message.withLocation(fileUri, charOffset, length)
+            : message.withoutLocation(),
+        severity,
+        context: context,
+        involvedFiles: involvedFiles);
+    if (severity == Severity.error) {
+      (wasHandled ? handledErrors : unhandledErrors).add(fileUri != null
+          ? message.withLocation(fileUri, charOffset, length)
+          : message.withoutLocation());
+    }
+    FormattedMessage formattedMessage = target.createFormattedMessage(
+        message, charOffset, length, fileUri, context, severity,
+        involvedFiles: involvedFiles);
+    return formattedMessage;
+  }
+
   Template<SummaryTemplate> get outlineSummaryTemplate =>
       templateDillOutlineSummary;
 
@@ -43,22 +259,19 @@
     List<Library> componentLibraries = component.libraries;
     List<Uri> requestedLibraries = <Uri>[];
     List<Uri> requestedLibrariesFileUri = <Uri>[];
-    DillTarget target = this.target as DillTarget;
     for (int i = 0; i < componentLibraries.length; i++) {
       Library library = componentLibraries[i];
       Uri uri = library.importUri;
       if (filter == null || filter(library.importUri)) {
         libraries.add(library);
-        target.addLibrary(library);
+        target.registerLibrary(library);
         requestedLibraries.add(uri);
         requestedLibrariesFileUri.add(library.fileUri);
       }
     }
     List<DillLibraryBuilder> result = <DillLibraryBuilder>[];
     for (int i = 0; i < requestedLibraries.length; i++) {
-      result.add(
-          read(requestedLibraries[i], -1, fileUri: requestedLibrariesFileUri[i])
-              as DillLibraryBuilder);
+      result.add(read(requestedLibraries[i], -1));
     }
     target.uriToSource.addAll(component.uriToSource);
     this.byteCount += byteCount;
@@ -74,29 +287,21 @@
     libraries.add(library);
 
     // Weird interaction begins.
-    DillTarget target = this.target as DillTarget;
+    //
     // Create dill library builder (adds it to a map where it's fetched
     // again momentarily).
-    target.addLibrary(library);
+    target.registerLibrary(library);
     // Set up the dill library builder (fetch it from the map again, add it to
     // another map and setup some auxiliary things).
-    return read(library.importUri, -1, fileUri: library.fileUri)
-        as DillLibraryBuilder;
+    return read(library.importUri, -1);
   }
 
-  @override
-  Future<Null> buildOutline(DillLibraryBuilder builder) {
+  void buildOutline(DillLibraryBuilder builder) {
     // ignore: unnecessary_null_comparison
     if (builder.library == null) {
       unhandled("null", "builder.library", 0, builder.fileUri);
     }
     builder.markAsReadyToBuild();
-    return new Future.value(null);
-  }
-
-  @override
-  Future<Null> buildBody(DillLibraryBuilder builder) {
-    return buildOutline(builder);
   }
 
   void finalizeExports({bool suppressFinalizationErrors: false}) {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_target.dart b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
index f9c24fd..28ccfbc 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -2,92 +2,114 @@
 // 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.
 
-library fasta.dill_target;
+import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
-import 'package:kernel/ast.dart' show Library;
+import 'package:kernel/ast.dart' show Library, Source;
 
 import 'package:kernel/target/targets.dart' show Target;
 
-import '../builder/class_builder.dart';
+import '../../base/processed_options.dart' show ProcessedOptions;
 
-import '../builder/library_builder.dart' show LibraryBuilder;
+import '../compiler_context.dart' show CompilerContext;
 
-import '../problems.dart' show unsupported;
-
-import '../source/source_library_builder.dart' show LanguageVersion;
-
-import '../target_implementation.dart' show TargetImplementation;
+import '../messages.dart' show FormattedMessage, LocatedMessage, Message;
 
 import '../ticker.dart' show Ticker;
 
 import '../uri_translator.dart' show UriTranslator;
 
+import '../target_implementation.dart' show TargetImplementation;
+
 import 'dill_library_builder.dart' show DillLibraryBuilder;
 
 import 'dill_loader.dart' show DillLoader;
 
 class DillTarget extends TargetImplementation {
-  final Map<Uri, DillLibraryBuilder> libraryBuilders =
+  final Ticker ticker;
+
+  final Map<Uri, DillLibraryBuilder> _knownLibraryBuilders =
       <Uri, DillLibraryBuilder>{};
 
   bool isLoaded = false;
 
   late final DillLoader loader;
 
-  DillTarget(Ticker ticker, UriTranslator uriTranslator, Target backendTarget)
-      : super(ticker, uriTranslator, backendTarget) {
+  final UriTranslator uriTranslator;
+
+  @override
+  final Target backendTarget;
+
+  @override
+  final CompilerContext context = CompilerContext.current;
+
+  /// Shared with [CompilerContext].
+  final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
+
+  DillTarget(this.ticker, this.uriTranslator, this.backendTarget)
+      // ignore: unnecessary_null_comparison
+      : assert(ticker != null),
+        // ignore: unnecessary_null_comparison
+        assert(uriTranslator != null),
+        // ignore: unnecessary_null_comparison
+        assert(backendTarget != null) {
     loader = new DillLoader(this);
   }
 
-  @override
-  void addSourceInformation(
-      Uri importUri, Uri fileUri, List<int> lineStarts, List<int> sourceCode) {
-    unsupported("addSourceInformation", -1, null);
+  void loadExtraRequiredLibraries(DillLoader loader) {
+    for (String uri in backendTarget.extraRequiredLibraries) {
+      loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
+    }
+    if (context.compilingPlatform) {
+      for (String uri in backendTarget.extraRequiredLibrariesPlatform) {
+        loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
+      }
+    }
   }
 
-  @override
-  Future<Null> buildComponent() {
-    return new Future<Null>.sync(() => unsupported("buildComponent", -1, null));
+  FormattedMessage createFormattedMessage(
+      Message message,
+      int charOffset,
+      int length,
+      Uri? fileUri,
+      List<LocatedMessage>? messageContext,
+      Severity severity,
+      {List<Uri>? involvedFiles}) {
+    ProcessedOptions processedOptions = context.options;
+    return processedOptions.format(
+        fileUri != null
+            ? message.withLocation(fileUri, charOffset, length)
+            : message.withoutLocation(),
+        severity,
+        messageContext,
+        involvedFiles: involvedFiles);
   }
 
-  @override
-  Future<Null> buildOutlines({bool suppressFinalizationErrors: false}) async {
+  void buildOutlines({bool suppressFinalizationErrors: false}) {
     if (loader.libraries.isNotEmpty) {
-      await loader.buildOutlines();
+      loader.buildOutlines();
       loader.finalizeExports(
           suppressFinalizationErrors: suppressFinalizationErrors);
     }
     isLoaded = true;
   }
 
-  @override
-  DillLibraryBuilder createLibraryBuilder(
-      Uri uri,
-      Uri fileUri,
-      Uri? packageUri,
-      LanguageVersion packageLanguageVersion,
-      LibraryBuilder? origin,
-      Library? referencesFrom,
-      bool? referenceIsPartOwner) {
-    assert(origin == null);
-    assert(referencesFrom == null);
+  /// Returns the [DillLibraryBuilder] corresponding to [uri].
+  ///
+  /// The [DillLibraryBuilder] is pulled from [_knownLibraryBuilders].
+  DillLibraryBuilder createLibraryBuilder(Uri uri) {
     DillLibraryBuilder libraryBuilder =
-        libraryBuilders.remove(uri) as DillLibraryBuilder;
+        _knownLibraryBuilders.remove(uri) as DillLibraryBuilder;
     // ignore: unnecessary_null_comparison
     assert(libraryBuilder != null, "No library found for $uri.");
     return libraryBuilder;
   }
 
-  @override
-  void breakCycle(ClassBuilder cls) {}
-
-  void addLibrary(Library library) {
-    libraryBuilders[library.importUri] =
+  void registerLibrary(Library library) {
+    _knownLibraryBuilders[library.importUri] =
         new DillLibraryBuilder(library, loader);
   }
 
-  @override
   void releaseAncillaryResources() {
-    libraryBuilders.clear();
+    _knownLibraryBuilders.clear();
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/get_dependencies.dart b/pkg/front_end/lib/src/fasta/get_dependencies.dart
index 78504b7..1db1afa 100644
--- a/pkg/front_end/lib/src/fasta/get_dependencies.dart
+++ b/pkg/front_end/lib/src/fasta/get_dependencies.dart
@@ -52,7 +52,7 @@
         new KernelTarget(fileSystem, false, dillTarget, uriTranslator);
 
     kernelTarget.setEntryPoints(<Uri>[script]);
-    await dillTarget.buildOutlines();
+    dillTarget.buildOutlines();
     await kernelTarget.loader.buildOutlines();
     return new List<Uri>.from(c.dependencies);
   });
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 159cbab..a188b12 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -288,7 +288,7 @@
 
       // For modular compilation we can be asked to load components and track
       // which libraries we actually use for the compilation. Set that up now.
-      await loadEnsureLoadedComponents(reusedLibraries);
+      loadEnsureLoadedComponents(reusedLibraries);
       resetTrackingOfUsedLibraries(hierarchy);
 
       // For each computeDelta call we create a new userCode object which needs
@@ -373,7 +373,7 @@
         dillLoadedData!.loader.currentSourceLoader = userCode!.loader;
       } else {
         previousSourceBuilders =
-            await convertSourceLibraryBuildersToDill(experimentalInvalidation);
+            convertSourceLibraryBuildersToDill(experimentalInvalidation);
       }
 
       experimentalInvalidation = null;
@@ -409,8 +409,8 @@
   /// source builders and they will thus be patched up here too.
   ///
   /// Returns the set of Libraries that now has new (dill) builders.
-  Future<Set<Library>> convertSourceLibraryBuildersToDill(
-      ExperimentalInvalidation? experimentalInvalidation) async {
+  Set<Library> convertSourceLibraryBuildersToDill(
+      ExperimentalInvalidation? experimentalInvalidation) {
     bool changed = false;
     Set<Library> newDillLibraryBuilders = new Set<Library>();
     userBuilders ??= <Uri, LibraryBuilder>{};
@@ -438,7 +438,7 @@
     if (changed) {
       // We suppress finalization errors because they have already been
       // reported.
-      await dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
+      dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
       assert(_checkEquivalentScopes(
           userCode!.loader.builders, dillLoadedData!.loader.builders));
 
@@ -1284,7 +1284,7 @@
 
       // We suppress finalization errors because they will reported via
       // problemsAsJson fields (with better precision).
-      await dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
+      dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
       userBuilders = <Uri, LibraryBuilder>{};
       platformBuilders = <LibraryBuilder>[];
       dillLoadedData!.loader.builders.forEach((uri, builder) {
@@ -1420,8 +1420,7 @@
   }
 
   /// Internal method.
-  Future<void> loadEnsureLoadedComponents(
-      List<LibraryBuilder> reusedLibraries) async {
+  void loadEnsureLoadedComponents(List<LibraryBuilder> reusedLibraries) {
     if (modulesToLoad != null) {
       bool loadedAnything = false;
       for (Component module in modulesToLoad!) {
@@ -1429,7 +1428,7 @@
         for (Library lib in module.libraries) {
           if (!dillLoadedData!.loader.builders.containsKey(lib.importUri)) {
             dillLoadedData!.loader.libraries.add(lib);
-            dillLoadedData!.addLibrary(lib);
+            dillLoadedData!.registerLibrary(lib);
             reusedLibraries.add(dillLoadedData!.loader.read(lib.importUri, -1));
             usedComponent = true;
           }
@@ -1442,7 +1441,7 @@
       if (loadedAnything) {
         // We suppress finalization errors because they will reported via
         // problemsAsJson fields (with better precision).
-        await dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
+        dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
         userBuilders = <Uri, LibraryBuilder>{};
         platformBuilders = <LibraryBuilder>[];
         dillLoadedData!.loader.builders.forEach((uri, builder) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
index a7da5cc..67be0a6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
@@ -8,12 +8,12 @@
 
 import '../fasta_codes.dart' show LocatedMessage;
 
-import '../loader.dart' show Loader;
+import '../source/source_loader.dart' show SourceLoader;
 
 import 'constant_evaluator.dart' show ErrorReporter;
 
 class KernelConstantErrorReporter extends ErrorReporter {
-  final Loader loader;
+  final SourceLoader loader;
 
   KernelConstantErrorReporter(this.loader);
 
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 e2be4ca..296cbc5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -4,21 +4,23 @@
 
 library fasta.kernel_target;
 
+import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/core_types.dart';
 import 'package:kernel/reference_from_index.dart' show IndexedClass;
 import 'package:kernel/target/changed_structure_notifier.dart'
     show ChangedStructureNotifier;
-import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+import 'package:kernel/target/targets.dart' show DiagnosticReporter, Target;
 import 'package:kernel/transformations/value_class.dart' as valueClass;
 import 'package:kernel/type_algebra.dart' show substitute;
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
 import 'package:package_config/package_config.dart' hide LanguageVersion;
 
+import '../../api_prototype/experimental_flags.dart' show ExperimentalFlag;
 import '../../api_prototype/file_system.dart' show FileSystem;
-import '../../api_prototype/experimental_flags.dart';
 import '../../base/nnbd_mode.dart';
+import '../../base/processed_options.dart' show ProcessedOptions;
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/constructor_builder.dart';
@@ -38,15 +40,16 @@
 import '../builder/void_type_declaration_builder.dart';
 import '../compiler_context.dart' show CompilerContext;
 import '../crash.dart' show withCrashReporting;
-import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
+import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 import '../dill/dill_target.dart' show DillTarget;
-import '../fasta_codes.dart' show LocatedMessage, Message;
 import '../kernel/constructor_tearoff_lowering.dart';
 import '../loader.dart' show Loader;
 import '../messages.dart'
     show
         FormattedMessage,
+        LocatedMessage,
+        Message,
         messageAgnosticWithStrongDillLibrary,
         messageAgnosticWithWeakDillLibrary,
         messageConstConstructorLateFinalFieldCause,
@@ -73,6 +76,7 @@
     show LanguageVersion, SourceLibraryBuilder;
 import '../source/source_loader.dart' show SourceLoader;
 import '../target_implementation.dart' show TargetImplementation;
+import '../ticker.dart' show Ticker;
 import '../type_inference/type_schema.dart';
 import '../uri_translator.dart' show UriTranslator;
 import 'constant_evaluator.dart' as constants
@@ -87,6 +91,8 @@
 import 'verifier.dart' show verifyComponent, verifyGetStaticType;
 
 class KernelTarget extends TargetImplementation {
+  final Ticker ticker;
+
   /// The [FileSystem] which should be used to access files.
   final FileSystem fileSystem;
 
@@ -144,17 +150,161 @@
   final List<SynthesizedFunctionNode> synthesizedFunctionNodes =
       <SynthesizedFunctionNode>[];
 
+  final UriTranslator uriTranslator;
+
+  @override
+  final Target backendTarget;
+
+  @override
+  final CompilerContext context = CompilerContext.current;
+
+  /// Shared with [CompilerContext].
+  final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
+
+  MemberBuilder? _cachedAbstractClassInstantiationError;
+  MemberBuilder? _cachedCompileTimeError;
+  MemberBuilder? _cachedDuplicatedFieldInitializerError;
+  MemberBuilder? _cachedNativeAnnotation;
+
+  final ProcessedOptions _options;
+
   KernelTarget(this.fileSystem, this.includeComments, DillTarget dillTarget,
-      UriTranslator uriTranslator)
+      this.uriTranslator)
       : dillTarget = dillTarget,
-        super(dillTarget.ticker, uriTranslator, dillTarget.backendTarget) {
+        backendTarget = dillTarget.backendTarget,
+        _options = CompilerContext.current.options,
+        ticker = dillTarget.ticker {
     loader = createLoader();
   }
 
+  bool isExperimentEnabledInLibrary(ExperimentalFlag flag, Uri importUri) {
+    return _options.isExperimentEnabledInLibrary(flag, importUri);
+  }
+
+  Version getExperimentEnabledVersionInLibrary(
+      ExperimentalFlag flag, Uri importUri) {
+    return _options.getExperimentEnabledVersionInLibrary(flag, importUri);
+  }
+
+  bool isExperimentEnabledInLibraryByVersion(
+      ExperimentalFlag flag, Uri importUri, Version version) {
+    return _options.isExperimentEnabledInLibraryByVersion(
+        flag, importUri, version);
+  }
+
+  /// Returns `true` if the [flag] is enabled by default.
+  bool isExperimentEnabledByDefault(ExperimentalFlag flag) {
+    return _options.isExperimentEnabledByDefault(flag);
+  }
+
+  /// Returns `true` if the [flag] is enabled globally.
+  ///
+  /// This is `true` either if the [flag] is passed through an explicit
+  /// `--enable-experiment` option or if the [flag] is expired and on by
+  /// default.
+  bool isExperimentEnabledGlobally(ExperimentalFlag flag) {
+    return _options.isExperimentEnabledGlobally(flag);
+  }
+
+  Uri? translateUri(Uri uri) => uriTranslator.translate(uri);
+
+  /// Returns a reference to the constructor of
+  /// [AbstractClassInstantiationError] error.  The constructor is expected to
+  /// accept a single argument of type String, which is the name of the
+  /// abstract class.
+  MemberBuilder getAbstractClassInstantiationError(Loader loader) {
+    return _cachedAbstractClassInstantiationError ??=
+        loader.coreLibrary.getConstructor("AbstractClassInstantiationError");
+  }
+
+  /// Returns a reference to the constructor used for creating a compile-time
+  /// error. The constructor is expected to accept a single argument of type
+  /// String, which is the compile-time error message.
+  MemberBuilder getCompileTimeError(Loader loader) {
+    return _cachedCompileTimeError ??= loader.coreLibrary
+        .getConstructor("_CompileTimeError", bypassLibraryPrivacy: true);
+  }
+
+  /// Returns a reference to the constructor used for creating a runtime error
+  /// when a final field is initialized twice. The constructor is expected to
+  /// accept a single argument which is the name of the field.
+  MemberBuilder getDuplicatedFieldInitializerError(Loader loader) {
+    return _cachedDuplicatedFieldInitializerError ??= loader.coreLibrary
+        .getConstructor("_DuplicatedFieldInitializerError",
+            bypassLibraryPrivacy: true);
+  }
+
+  /// Returns a reference to the constructor used for creating `native`
+  /// annotations. The constructor is expected to accept a single argument of
+  /// type String, which is the name of the native method.
+  MemberBuilder getNativeAnnotation(SourceLoader loader) {
+    if (_cachedNativeAnnotation != null) return _cachedNativeAnnotation!;
+    LibraryBuilder internal = loader.read(Uri.parse("dart:_internal"), -1,
+        accessor: loader.coreLibrary);
+    return _cachedNativeAnnotation = internal.getConstructor("ExternalName");
+  }
+
+  void loadExtraRequiredLibraries(SourceLoader loader) {
+    for (String uri in backendTarget.extraRequiredLibraries) {
+      loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
+    }
+    if (context.compilingPlatform) {
+      for (String uri in backendTarget.extraRequiredLibrariesPlatform) {
+        loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
+      }
+    }
+  }
+
+  FormattedMessage createFormattedMessage(
+      Message message,
+      int charOffset,
+      int length,
+      Uri? fileUri,
+      List<LocatedMessage>? messageContext,
+      Severity severity,
+      {List<Uri>? involvedFiles}) {
+    ProcessedOptions processedOptions = context.options;
+    return processedOptions.format(
+        fileUri != null
+            ? message.withLocation(fileUri, charOffset, length)
+            : message.withoutLocation(),
+        severity,
+        messageContext,
+        involvedFiles: involvedFiles);
+  }
+
+  String get currentSdkVersionString {
+    return CompilerContext.current.options.currentSdkVersion;
+  }
+
+  Version? _currentSdkVersion;
+  Version get currentSdkVersion {
+    if (_currentSdkVersion == null) {
+      _parseCurrentSdkVersion();
+    }
+    return _currentSdkVersion!;
+  }
+
+  void _parseCurrentSdkVersion() {
+    bool good = false;
+    // ignore: unnecessary_null_comparison
+    if (currentSdkVersionString != null) {
+      List<String> dotSeparatedParts = currentSdkVersionString.split(".");
+      if (dotSeparatedParts.length >= 2) {
+        _currentSdkVersion = new Version(int.tryParse(dotSeparatedParts[0])!,
+            int.tryParse(dotSeparatedParts[1])!);
+        good = true;
+      }
+    }
+    if (!good) {
+      throw new StateError(
+          "Unparsable sdk version given: $currentSdkVersionString");
+    }
+  }
+
   SourceLoader createLoader() =>
       new SourceLoader(fileSystem, includeComments, this);
 
-  @override
   void addSourceInformation(
       Uri importUri, Uri fileUri, List<int> lineStarts, List<int> sourceCode) {
     uriToSource[fileUri] =
@@ -214,7 +364,30 @@
     return entryPoint;
   }
 
-  @override
+  /// Creates a [LibraryBuilder] corresponding to [uri], 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.
+  ///
+  /// [origin] is non-null if the created library is a patch to [origin].
+  ///
+  /// [packageUri] is the base uri for the package which the library belongs to.
+  /// For instance 'package:foo'.
+  ///
+  /// This is used to associate libraries in for instance the 'bin' and 'test'
+  /// folders of a package source with the package uri of the 'lib' folder.
+  ///
+  /// If the [packageUri] is `null` the package association of this library is
+  /// based on its [importUri].
+  ///
+  /// For libraries with a 'package:' [importUri], the package path must match
+  /// the path in the [importUri]. For libraries with a 'dart:' [importUri] the
+  /// [packageUri] must be `null`.
+  ///
+  /// [packageLanguageVersion] is the language version defined by the package
+  /// which the library belongs to, or the current sdk version if the library
+  /// doesn't belong to a package.
   LibraryBuilder createLibraryBuilder(
       Uri uri,
       Uri fileUri,
@@ -224,13 +397,13 @@
       Library? referencesFrom,
       bool? referenceIsPartOwner) {
     if (dillTarget.isLoaded) {
-      LibraryBuilder? builder = dillTarget.loader.builders[uri];
+      DillLibraryBuilder? builder = dillTarget.loader.builders[uri];
       if (builder != null) {
         if (!builder.isNonNullableByDefault &&
             (loader.nnbdMode == NnbdMode.Strong ||
                 loader.nnbdMode == NnbdMode.Agnostic)) {
           loader.registerStrongOptOutLibrary(builder);
-        } else if (builder is DillLibraryBuilder) {
+        } else {
           NonNullableByDefaultCompiledMode libraryMode =
               builder.library.nonNullableByDefaultCompiledMode;
           if (libraryMode == NonNullableByDefaultCompiledMode.Invalid) {
@@ -292,7 +465,9 @@
     return result;
   }
 
-  @override
+  /// 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.
   void breakCycle(ClassBuilder builder) {
     Class cls = builder.cls;
     cls.implementedTypes.clear();
@@ -309,7 +484,6 @@
     builder.mixedInTypeBuilder = null;
   }
 
-  @override
   Future<Component?> buildOutlines({CanonicalName? nameRoot}) async {
     if (loader.first == null) return null;
     return withCrashReporting<Component?>(() async {
@@ -363,7 +537,6 @@
   ///
   /// If [verify], run the default kernel verification on the resulting
   /// component.
-  @override
   Future<Component?> buildComponent({bool verify: false}) async {
     if (loader.first == null) return null;
     return withCrashReporting<Component?>(() async {
@@ -1362,7 +1535,6 @@
     return loader.libraries.contains(library);
   }
 
-  @override
   void readPatchFiles(SourceLibraryBuilder library) {
     assert(library.importUri.scheme == "dart");
     List<Uri>? patches = uriTranslator.getDartPatches(library.importUri.path);
@@ -1389,7 +1561,6 @@
     }
   }
 
-  @override
   void releaseAncillaryResources() {
     component = null;
   }
@@ -1418,7 +1589,7 @@
 
 class KernelDiagnosticReporter
     extends DiagnosticReporter<Message, LocatedMessage> {
-  final Loader loader;
+  final SourceLoader loader;
 
   KernelDiagnosticReporter(this.loader);
 
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index 7dedab8..5b07db1 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -4,330 +4,24 @@
 
 library fasta.loader;
 
-import 'dart:collection' show Queue;
-
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
-import 'package:kernel/ast.dart' show Class, DartType, Library, Version;
-import 'package:package_config/package_config.dart';
-
-import 'scope.dart';
+import 'package:kernel/ast.dart' show Class, DartType;
 
 import 'builder/class_builder.dart';
-import 'builder/declaration_builder.dart';
 import 'builder/library_builder.dart';
-import 'builder/member_builder.dart';
-import 'builder/modifier_builder.dart';
 import 'builder/type_builder.dart';
 
-import 'crash.dart' show firstSourceUri;
-
-import 'kernel/body_builder.dart' show BodyBuilder;
-
-import 'messages.dart'
-    show
-        FormattedMessage,
-        LocatedMessage,
-        Message,
-        noLength,
-        SummaryTemplate,
-        Template,
-        messageLanguageVersionInvalidInDotPackages,
-        messagePlatformPrivateLibraryAccess,
-        templateInternalProblemContextSeverity,
-        templateLanguageVersionTooHigh,
-        templateSourceBodySummary;
-
-import 'problems.dart' show internalProblem, unhandled;
-
-import 'source/source_library_builder.dart' as src
-    show
-        LanguageVersion,
-        InvalidLanguageVersion,
-        ImplicitLanguageVersion,
-        SourceLibraryBuilder;
+import 'messages.dart' show FormattedMessage, LocatedMessage, Message;
 
 import 'target_implementation.dart' show TargetImplementation;
 
-import 'ticker.dart' show Ticker;
-
 const String untranslatableUriScheme = "org-dartlang-untranslatable-uri";
 
 abstract class Loader {
-  final Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
+  TargetImplementation get target;
 
-  final Queue<LibraryBuilder> unparsedLibraries = new Queue<LibraryBuilder>();
-
-  final List<Library> libraries = <Library>[];
-
-  final TargetImplementation target;
-
-  /// List of all handled compile-time errors seen so far by libraries loaded
-  /// by this loader.
-  ///
-  /// A handled error is an error that has been added to the generated AST
-  /// already, for example, as a throw expression.
-  final List<LocatedMessage> handledErrors = <LocatedMessage>[];
-
-  /// List of all unhandled compile-time errors seen so far by libraries loaded
-  /// by this loader.
-  ///
-  /// An unhandled error is an error that hasn't been handled, see
-  /// [handledErrors].
-  final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];
-
-  /// List of all problems seen so far by libraries loaded by this loader that
-  /// does not belong directly to a library.
-  final List<FormattedMessage> allComponentProblems = <FormattedMessage>[];
-
-  final Set<String> seenMessages = new Set<String>();
-  bool _hasSeenError = false;
-
-  void resetSeenMessages() {
-    seenMessages.clear();
-    _hasSeenError = false;
-  }
-
-  /// Returns `true` if a compile time error has been reported.
-  bool get hasSeenError => _hasSeenError;
-
-  LibraryBuilder? _coreLibrary;
-  LibraryBuilder? typedDataLibrary;
-
-  /// The first library that we've been asked to compile. When compiling a
-  /// program (aka script), this is the library that should have a main method.
-  LibraryBuilder? first;
-
-  int byteCount = 0;
-
-  Uri? currentUriForCrashReporting;
-
-  Loader(this.target);
-
-  LibraryBuilder get coreLibrary => _coreLibrary!;
-
-  void set coreLibrary(LibraryBuilder value) {
-    _coreLibrary = value;
-  }
-
-  Ticker get ticker => target.ticker;
-
-  Template<SummaryTemplate> get outlineSummaryTemplate;
-
-  bool get isSourceLoader => false;
-
-  /// Look up a library builder by the name [uri], or if such doesn't
-  /// exist, create one. The canonical URI of the library is [uri], and its
-  /// actual location is [fileUri].
-  ///
-  /// Canonical URIs have schemes like "dart", or "package", and the actual
-  /// location is often a file URI.
-  ///
-  /// The [accessor] is the library that's trying to import, export, or include
-  /// as part [uri], and [charOffset] is the location of the corresponding
-  /// directive. If [accessor] isn't allowed to access [uri], it's a
-  /// compile-time error.
-  LibraryBuilder read(Uri uri, int charOffset,
-      {Uri? fileUri,
-      LibraryBuilder? accessor,
-      LibraryBuilder? origin,
-      Library? referencesFrom,
-      bool? referenceIsPartOwner}) {
-    LibraryBuilder builder = builders.putIfAbsent(uri, () {
-      if (fileUri != null &&
-          (fileUri!.scheme == "dart" ||
-              fileUri!.scheme == "package" ||
-              fileUri!.scheme == "dart-ext")) {
-        fileUri = null;
-      }
-      Package? packageForLanguageVersion;
-      if (fileUri == null) {
-        switch (uri.scheme) {
-          case "package":
-          case "dart":
-            fileUri = target.translateUri(uri) ??
-                new Uri(
-                    scheme: untranslatableUriScheme,
-                    path: Uri.encodeComponent("$uri"));
-            if (uri.scheme == "package") {
-              packageForLanguageVersion = target.uriTranslator.getPackage(uri);
-            } else {
-              packageForLanguageVersion =
-                  target.uriTranslator.packages.packageOf(fileUri!);
-            }
-            break;
-
-          default:
-            fileUri = uri;
-            packageForLanguageVersion =
-                target.uriTranslator.packages.packageOf(fileUri!);
-            break;
-        }
-      } else {
-        packageForLanguageVersion =
-            target.uriTranslator.packages.packageOf(fileUri!);
-      }
-      src.LanguageVersion? packageLanguageVersion;
-      Uri? packageUri;
-      Message? packageLanguageVersionProblem;
-      if (packageForLanguageVersion != null) {
-        Uri importUri = origin?.importUri ?? uri;
-        if (importUri.scheme != 'dart' &&
-            importUri.scheme != 'package' &&
-            // ignore: unnecessary_null_comparison
-            packageForLanguageVersion.name != null) {
-          packageUri =
-              new Uri(scheme: 'package', path: packageForLanguageVersion.name);
-        }
-        if (packageForLanguageVersion.languageVersion != null) {
-          if (packageForLanguageVersion.languageVersion
-              is InvalidLanguageVersion) {
-            packageLanguageVersionProblem =
-                messageLanguageVersionInvalidInDotPackages;
-            packageLanguageVersion = new src.InvalidLanguageVersion(
-                fileUri!, 0, noLength, target.currentSdkVersion, false);
-          } else {
-            Version version = new Version(
-                packageForLanguageVersion.languageVersion!.major,
-                packageForLanguageVersion.languageVersion!.minor);
-            if (version > target.currentSdkVersion) {
-              packageLanguageVersionProblem =
-                  templateLanguageVersionTooHigh.withArguments(
-                      target.currentSdkVersion.major,
-                      target.currentSdkVersion.minor);
-              packageLanguageVersion = new src.InvalidLanguageVersion(
-                  fileUri!, 0, noLength, target.currentSdkVersion, false);
-            } else {
-              packageLanguageVersion = new src.ImplicitLanguageVersion(version);
-            }
-          }
-        }
-      }
-      packageLanguageVersion ??=
-          new src.ImplicitLanguageVersion(target.currentSdkVersion);
-
-      LibraryBuilder? library = target.createLibraryBuilder(
-          uri,
-          fileUri!,
-          packageUri,
-          packageLanguageVersion,
-          origin,
-          referencesFrom,
-          referenceIsPartOwner);
-      if (library == null) {
-        throw new StateError("createLibraryBuilder for uri $uri, "
-            "fileUri $fileUri returned null.");
-      }
-      if (packageLanguageVersionProblem != null &&
-          library is src.SourceLibraryBuilder) {
-        library.addPostponedProblem(
-            packageLanguageVersionProblem, 0, noLength, library.fileUri);
-      }
-
-      if (uri.scheme == "dart") {
-        if (uri.path == "core") {
-          _coreLibrary = library;
-        } else if (uri.path == "typed_data") {
-          typedDataLibrary = library;
-        }
-      }
-      if (library.loader != this) {
-        if (_coreLibrary == library) {
-          target.loadExtraRequiredLibraries(this);
-        }
-        // This library isn't owned by this loader, so no further processing
-        // should be attempted.
-        return library;
-      }
-
-      {
-        // Add any additional logic after this block. Setting the
-        // firstSourceUri and first library should be done as early as
-        // possible.
-        firstSourceUri ??= uri;
-        first ??= library;
-      }
-      if (_coreLibrary == library) {
-        target.loadExtraRequiredLibraries(this);
-      }
-      Uri libraryUri = origin?.importUri ?? uri;
-      if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
-        library.mayImplementRestrictedTypes = true;
-      }
-      if (uri.scheme == "dart") {
-        target.readPatchFiles(library);
-      }
-      unparsedLibraries.addLast(library);
-      return library;
-    });
-    if (accessor == null) {
-      if (builder.loader == this && first != builder && isSourceLoader) {
-        unhandled("null", "accessor", charOffset, uri);
-      }
-    } else {
-      builder.recordAccess(charOffset, noLength, accessor.fileUri);
-      if (!accessor.isPatch &&
-          !accessor.isPart &&
-          !target.backendTarget
-              .allowPlatformPrivateLibraryAccess(accessor.importUri, uri)) {
-        accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
-            noLength, accessor.fileUri);
-      }
-    }
-    return builder;
-  }
-
-  void ensureCoreLibrary() {
-    if (_coreLibrary == null) {
-      read(Uri.parse("dart:core"), 0, accessor: first);
-      // TODO(askesc): When all backends support set literals, we no longer
-      // need to index dart:collection, as it is only needed for desugaring of
-      // const sets. We can remove it from this list at that time.
-      read(Uri.parse("dart:collection"), 0, accessor: first);
-      assert(_coreLibrary != null);
-    }
-  }
-
-  Future<Null> buildBodies() async {
-    assert(_coreLibrary != null);
-    for (LibraryBuilder library in builders.values) {
-      if (library.loader == this) {
-        currentUriForCrashReporting = library.importUri;
-        await buildBody(library);
-      }
-    }
-    currentUriForCrashReporting = null;
-    logSummary(templateSourceBodySummary);
-  }
-
-  Future<Null> buildOutlines() async {
-    ensureCoreLibrary();
-    while (unparsedLibraries.isNotEmpty) {
-      LibraryBuilder library = unparsedLibraries.removeFirst();
-      currentUriForCrashReporting = library.importUri;
-      await buildOutline(library);
-    }
-    currentUriForCrashReporting = null;
-    logSummary(outlineSummaryTemplate);
-  }
-
-  void logSummary(Template<SummaryTemplate> template) {
-    ticker.log((Duration elapsed, Duration sinceStart) {
-      int libraryCount = 0;
-      for (LibraryBuilder library in builders.values) {
-        if (library.loader == this) libraryCount++;
-      }
-      double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
-      Message message = template.withArguments(
-          libraryCount, byteCount, ms, byteCount / ms, ms / libraryCount);
-      print("$sinceStart: ${message.message}");
-    });
-  }
-
-  Future<Null> buildOutline(covariant LibraryBuilder library);
-
-  /// Builds all the method bodies found in the given [library].
-  Future<Null> buildBody(covariant LibraryBuilder library);
+  Map<Uri, LibraryBuilder> get builders;
 
   /// Register [message] as a problem with a severity determined by the
   /// intrinsic severity of the message.
@@ -337,94 +31,11 @@
       List<LocatedMessage>? context,
       Severity? severity,
       bool problemOnLibrary: false,
-      List<Uri>? involvedFiles}) {
-    return addMessage(message, charOffset, length, fileUri, severity,
-        wasHandled: wasHandled,
-        context: context,
-        problemOnLibrary: problemOnLibrary,
-        involvedFiles: involvedFiles);
-  }
-
-  /// All messages reported by the compiler (errors, warnings, etc.) are routed
-  /// through this method.
-  ///
-  /// Returns a FormattedMessage if the message is new, that is, not previously
-  /// reported. This is important as some parser errors may be reported up to
-  /// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
-  /// If the message is not new, [null] is reported.
-  ///
-  /// If [severity] is `Severity.error`, the message is added to
-  /// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
-  /// [wasHandled] is false.
-  FormattedMessage? addMessage(Message message, int charOffset, int length,
-      Uri? fileUri, Severity? severity,
-      {bool wasHandled: false,
-      List<LocatedMessage>? context,
-      bool problemOnLibrary: false,
-      List<Uri>? involvedFiles}) {
-    severity ??= message.code.severity;
-    if (severity == Severity.ignored) return null;
-    String trace = """
-message: ${message.message}
-charOffset: $charOffset
-fileUri: $fileUri
-severity: $severity
-""";
-    if (!seenMessages.add(trace)) return null;
-    if (message.code.severity == Severity.error) {
-      _hasSeenError = true;
-    }
-    if (message.code.severity == Severity.context) {
-      internalProblem(
-          templateInternalProblemContextSeverity
-              .withArguments(message.code.name),
-          charOffset,
-          fileUri);
-    }
-    target.context.report(
-        fileUri != null
-            ? message.withLocation(fileUri, charOffset, length)
-            : message.withoutLocation(),
-        severity,
-        context: context,
-        involvedFiles: involvedFiles);
-    if (severity == Severity.error) {
-      (wasHandled ? handledErrors : unhandledErrors).add(fileUri != null
-          ? message.withLocation(fileUri, charOffset, length)
-          : message.withoutLocation());
-    }
-    FormattedMessage formattedMessage = target.createFormattedMessage(
-        message, charOffset, length, fileUri, context, severity,
-        involvedFiles: involvedFiles);
-    if (!problemOnLibrary) {
-      allComponentProblems.add(formattedMessage);
-    }
-    return formattedMessage;
-  }
-
-  MemberBuilder getAbstractClassInstantiationError() {
-    return target.getAbstractClassInstantiationError(this);
-  }
-
-  MemberBuilder getCompileTimeError() => target.getCompileTimeError(this);
-
-  MemberBuilder getDuplicatedFieldInitializerError() {
-    return target.getDuplicatedFieldInitializerError(this);
-  }
-
-  MemberBuilder getNativeAnnotation() => target.getNativeAnnotation(this);
+      List<Uri>? involvedFiles});
 
   ClassBuilder computeClassBuilderFromTargetClass(Class cls);
 
   TypeBuilder computeTypeBuilder(DartType type);
 
-  BodyBuilder createBodyBuilderForOutlineExpression(
-      src.SourceLibraryBuilder library,
-      DeclarationBuilder? declarationBuilder,
-      ModifierBuilder member,
-      Scope scope,
-      Uri fileUri) {
-    return new BodyBuilder.forOutlineExpression(
-        library, declarationBuilder, member, scope, fileUri);
-  }
+  LibraryBuilder get coreLibrary;
 }
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 480fb3a..dbecaaa 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
@@ -2353,7 +2353,7 @@
           new Name(
               constructorName, _currentClassReferencesFromIndexed!.library));
     }
-    ConstructorBuilder constructorBuilder = new ConstructorBuilderImpl(
+    ConstructorBuilder constructorBuilder = new SourceConstructorBuilder(
         metadata,
         modifiers & ~abstractMask,
         returnType,
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 bd7fb08..9e34d6d 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -4,16 +4,14 @@
 
 library fasta.source_loader;
 
+import 'dart:collection' show Queue;
 import 'dart:convert' show utf8;
-
 import 'dart:typed_data' show Uint8List;
 
 import 'package:_fe_analyzer_shared/src/parser/class_member_parser.dart'
     show ClassMemberParser;
-
 import 'package:_fe_analyzer_shared/src/parser/parser.dart'
     show Parser, lengthForToken;
-
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
     show
         ErrorToken,
@@ -23,57 +21,23 @@
         ScannerResult,
         Token,
         scan;
-
-import 'package:kernel/ast.dart'
-    show
-        Arguments,
-        AsyncMarker,
-        Class,
-        Component,
-        Constructor,
-        DartType,
-        Expression,
-        FunctionNode,
-        InterfaceType,
-        Library,
-        LibraryDependency,
-        Member,
-        NeverType,
-        Nullability,
-        Procedure,
-        ProcedureKind,
-        Reference,
-        Supertype,
-        TreeNode,
-        VariableDeclaration,
-        Version;
-
+import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart'
     show ClassHierarchy, HandleAmbiguousSupertypes;
-
 import 'package:kernel/core_types.dart' show CoreTypes;
-
 import 'package:kernel/reference_from_index.dart' show ReferenceFromIndex;
-
 import 'package:kernel/type_environment.dart';
-
-import 'package:package_config/package_config.dart';
+import 'package:package_config/package_config.dart' as package_config;
 
 import '../../api_prototype/experimental_flags.dart';
 import '../../api_prototype/file_system.dart';
-
 import '../../base/common.dart';
-
 import '../../base/instrumentation.dart' show Instrumentation;
-
 import '../../base/nnbd_mode.dart';
-
-import '../denylisted_classes.dart'
-    show denylistedCoreClasses, denylistedTypedDataClasses;
-
 import '../builder/builder.dart';
 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';
@@ -81,6 +45,7 @@
 import '../builder/invalid_type_declaration_builder.dart';
 import '../builder/library_builder.dart';
 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';
@@ -88,11 +53,11 @@
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_declaration_builder.dart';
-
+import '../crash.dart' show firstSourceUri;
+import '../denylisted_classes.dart'
+    show denylistedCoreClasses, denylistedTypedDataClasses;
 import '../export.dart' show Export;
-
 import '../fasta_codes.dart';
-
 import '../kernel/body_builder.dart' show BodyBuilder;
 import '../kernel/class_hierarchy_builder.dart';
 import '../kernel/kernel_helper.dart'
@@ -101,22 +66,24 @@
 import '../kernel/transform_collections.dart' show CollectionTransformer;
 import '../kernel/transform_set_literals.dart' show SetLiteralTransformer;
 import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
-
 import '../loader.dart' show Loader, untranslatableUriScheme;
-
-import '../problems.dart' show internalProblem;
-
+import '../problems.dart' show internalProblem, unhandled;
+import '../scope.dart';
+import '../ticker.dart' show Ticker;
 import '../type_inference/type_inference_engine.dart';
 import '../type_inference/type_inferrer.dart';
-
 import '../util/helpers.dart';
-
 import 'diet_listener.dart' show DietListener;
 import 'diet_parser.dart' show DietParser, useImplicitCreationExpressionInCfe;
 import 'name_scheme.dart';
 import 'outline_builder.dart' show OutlineBuilder;
 import 'source_class_builder.dart' show SourceClassBuilder;
-import 'source_library_builder.dart' show SourceLibraryBuilder;
+import 'source_library_builder.dart'
+    show
+        LanguageVersion,
+        InvalidLanguageVersion,
+        ImplicitLanguageVersion,
+        SourceLibraryBuilder;
 import 'source_type_alias_builder.dart';
 import 'stack_listener_impl.dart' show offsetForToken;
 
@@ -174,10 +141,365 @@
 
   final SourceLoaderDataForTesting? dataForTesting;
 
-  SourceLoader(this.fileSystem, this.includeComments, KernelTarget target)
+  @override
+  final Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
+
+  final Queue<LibraryBuilder> _unparsedLibraries = new Queue<LibraryBuilder>();
+
+  final List<Library> libraries = <Library>[];
+
+  @override
+  final KernelTarget target;
+
+  /// List of all handled compile-time errors seen so far by libraries loaded
+  /// by this loader.
+  ///
+  /// A handled error is an error that has been added to the generated AST
+  /// already, for example, as a throw expression.
+  final List<LocatedMessage> handledErrors = <LocatedMessage>[];
+
+  /// List of all unhandled compile-time errors seen so far by libraries loaded
+  /// by this loader.
+  ///
+  /// An unhandled error is an error that hasn't been handled, see
+  /// [handledErrors].
+  final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];
+
+  /// List of all problems seen so far by libraries loaded by this loader that
+  /// does not belong directly to a library.
+  final List<FormattedMessage> allComponentProblems = <FormattedMessage>[];
+
+  /// The text of the messages that have been reported.
+  ///
+  /// This is used filter messages so that we don't report the same error twice.
+  final Set<String> seenMessages = new Set<String>();
+
+  /// Set to `true` if one of the reported errors had severity `Severity.error`.
+  ///
+  /// This is used for [hasSeenError].
+  bool _hasSeenError = false;
+
+  /// Clears the [seenMessages] and [hasSeenError] state.
+  void resetSeenMessages() {
+    seenMessages.clear();
+    _hasSeenError = false;
+  }
+
+  /// Returns `true` if a compile time error has been reported.
+  bool get hasSeenError => _hasSeenError;
+
+  LibraryBuilder? _coreLibrary;
+  LibraryBuilder? typedDataLibrary;
+
+  /// The first library that we've been asked to compile. When compiling a
+  /// program (aka script), this is the library that should have a main method.
+  LibraryBuilder? first;
+
+  int byteCount = 0;
+
+  Uri? currentUriForCrashReporting;
+
+  SourceLoader(this.fileSystem, this.includeComments, this.target)
       : dataForTesting =
-            retainDataForTesting ? new SourceLoaderDataForTesting() : null,
-        super(target);
+            retainDataForTesting ? new SourceLoaderDataForTesting() : null;
+
+  @override
+  LibraryBuilder get coreLibrary => _coreLibrary!;
+
+  void set coreLibrary(LibraryBuilder value) {
+    _coreLibrary = value;
+  }
+
+  Ticker get ticker => target.ticker;
+
+  /// Look up a library builder by the [uri], or if such doesn't exist, create
+  /// one. The canonical URI of the library is [uri], and its actual location is
+  /// [fileUri].
+  ///
+  /// Canonical URIs have schemes like "dart", or "package", and the actual
+  /// location is often a file URI.
+  ///
+  /// The [accessor] is the library that's trying to import, export, or include
+  /// as part [uri], and [charOffset] is the location of the corresponding
+  /// directive. If [accessor] isn't allowed to access [uri], it's a
+  /// compile-time error.
+  LibraryBuilder read(Uri uri, int charOffset,
+      {Uri? fileUri,
+      LibraryBuilder? accessor,
+      LibraryBuilder? origin,
+      Library? referencesFrom,
+      bool? referenceIsPartOwner}) {
+    LibraryBuilder builder = builders.putIfAbsent(uri, () {
+      if (fileUri != null &&
+          (fileUri!.scheme == "dart" ||
+              fileUri!.scheme == "package" ||
+              fileUri!.scheme == "dart-ext")) {
+        fileUri = null;
+      }
+      package_config.Package? packageForLanguageVersion;
+      if (fileUri == null) {
+        switch (uri.scheme) {
+          case "package":
+          case "dart":
+            fileUri = target.translateUri(uri) ??
+                new Uri(
+                    scheme: untranslatableUriScheme,
+                    path: Uri.encodeComponent("$uri"));
+            if (uri.scheme == "package") {
+              packageForLanguageVersion = target.uriTranslator.getPackage(uri);
+            } else {
+              packageForLanguageVersion =
+                  target.uriTranslator.packages.packageOf(fileUri!);
+            }
+            break;
+
+          default:
+            fileUri = uri;
+            packageForLanguageVersion =
+                target.uriTranslator.packages.packageOf(fileUri!);
+            break;
+        }
+      } else {
+        packageForLanguageVersion =
+            target.uriTranslator.packages.packageOf(fileUri!);
+      }
+      LanguageVersion? packageLanguageVersion;
+      Uri? packageUri;
+      Message? packageLanguageVersionProblem;
+      if (packageForLanguageVersion != null) {
+        Uri importUri = origin?.importUri ?? uri;
+        if (importUri.scheme != 'dart' &&
+            importUri.scheme != 'package' &&
+            // ignore: unnecessary_null_comparison
+            packageForLanguageVersion.name != null) {
+          packageUri =
+              new Uri(scheme: 'package', path: packageForLanguageVersion.name);
+        }
+        if (packageForLanguageVersion.languageVersion != null) {
+          if (packageForLanguageVersion.languageVersion
+              is package_config.InvalidLanguageVersion) {
+            packageLanguageVersionProblem =
+                messageLanguageVersionInvalidInDotPackages;
+            packageLanguageVersion = new InvalidLanguageVersion(
+                fileUri!, 0, noLength, target.currentSdkVersion, false);
+          } else {
+            Version version = new Version(
+                packageForLanguageVersion.languageVersion!.major,
+                packageForLanguageVersion.languageVersion!.minor);
+            if (version > target.currentSdkVersion) {
+              packageLanguageVersionProblem =
+                  templateLanguageVersionTooHigh.withArguments(
+                      target.currentSdkVersion.major,
+                      target.currentSdkVersion.minor);
+              packageLanguageVersion = new InvalidLanguageVersion(
+                  fileUri!, 0, noLength, target.currentSdkVersion, false);
+            } else {
+              packageLanguageVersion = new ImplicitLanguageVersion(version);
+            }
+          }
+        }
+      }
+      packageLanguageVersion ??=
+          new ImplicitLanguageVersion(target.currentSdkVersion);
+
+      LibraryBuilder library = target.createLibraryBuilder(
+          uri,
+          fileUri!,
+          packageUri,
+          packageLanguageVersion,
+          origin as SourceLibraryBuilder?,
+          referencesFrom,
+          referenceIsPartOwner);
+      if (packageLanguageVersionProblem != null &&
+          library is SourceLibraryBuilder) {
+        library.addPostponedProblem(
+            packageLanguageVersionProblem, 0, noLength, library.fileUri);
+      }
+
+      if (uri.scheme == "dart") {
+        if (uri.path == "core") {
+          _coreLibrary = library;
+        } else if (uri.path == "typed_data") {
+          typedDataLibrary = library;
+        }
+      }
+      if (library.loader != this) {
+        if (_coreLibrary == library) {
+          target.loadExtraRequiredLibraries(this);
+        }
+        // This library isn't owned by this loader, so no further processing
+        // should be attempted.
+        return library;
+      }
+
+      {
+        // Add any additional logic after this block. Setting the
+        // firstSourceUri and first library should be done as early as
+        // possible.
+        firstSourceUri ??= uri;
+        first ??= library;
+      }
+      if (_coreLibrary == library) {
+        target.loadExtraRequiredLibraries(this);
+      }
+      Uri libraryUri = origin?.importUri ?? uri;
+      if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
+        library.mayImplementRestrictedTypes = true;
+      }
+      if (uri.scheme == "dart") {
+        target.readPatchFiles(library as SourceLibraryBuilder);
+      }
+      _unparsedLibraries.addLast(library);
+      return library;
+    });
+    if (accessor == null) {
+      if (builder.loader == this && first != builder) {
+        unhandled("null", "accessor", charOffset, uri);
+      }
+    } else {
+      builder.recordAccess(charOffset, noLength, accessor.fileUri);
+      if (!accessor.isPatch &&
+          !accessor.isPart &&
+          !target.backendTarget
+              .allowPlatformPrivateLibraryAccess(accessor.importUri, uri)) {
+        accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
+            noLength, accessor.fileUri);
+      }
+    }
+    return builder;
+  }
+
+  void _ensureCoreLibrary() {
+    if (_coreLibrary == null) {
+      read(Uri.parse("dart:core"), 0, accessor: first);
+      // TODO(askesc): When all backends support set literals, we no longer
+      // need to index dart:collection, as it is only needed for desugaring of
+      // const sets. We can remove it from this list at that time.
+      read(Uri.parse("dart:collection"), 0, accessor: first);
+      assert(_coreLibrary != null);
+    }
+  }
+
+  Future<Null> buildBodies() async {
+    assert(_coreLibrary != null);
+    for (LibraryBuilder library in builders.values) {
+      if (library.loader == this) {
+        currentUriForCrashReporting = library.importUri;
+        await buildBody(library);
+      }
+    }
+    currentUriForCrashReporting = null;
+    logSummary(templateSourceBodySummary);
+  }
+
+  void logSummary(Template<SummaryTemplate> template) {
+    ticker.log((Duration elapsed, Duration sinceStart) {
+      int libraryCount = 0;
+      for (LibraryBuilder library in builders.values) {
+        if (library.loader == this) libraryCount++;
+      }
+      double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
+      Message message = template.withArguments(
+          libraryCount, byteCount, ms, byteCount / ms, ms / libraryCount);
+      print("$sinceStart: ${message.message}");
+    });
+  }
+
+  /// Register [message] as a problem with a severity determined by the
+  /// intrinsic severity of the message.
+  @override
+  FormattedMessage? addProblem(
+      Message message, int charOffset, int length, Uri? fileUri,
+      {bool wasHandled: false,
+      List<LocatedMessage>? context,
+      Severity? severity,
+      bool problemOnLibrary: false,
+      List<Uri>? involvedFiles}) {
+    return addMessage(message, charOffset, length, fileUri, severity,
+        wasHandled: wasHandled,
+        context: context,
+        problemOnLibrary: problemOnLibrary,
+        involvedFiles: involvedFiles);
+  }
+
+  /// All messages reported by the compiler (errors, warnings, etc.) are routed
+  /// through this method.
+  ///
+  /// Returns a FormattedMessage if the message is new, that is, not previously
+  /// reported. This is important as some parser errors may be reported up to
+  /// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
+  /// If the message is not new, [null] is reported.
+  ///
+  /// If [severity] is `Severity.error`, the message is added to
+  /// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
+  /// [wasHandled] is false.
+  FormattedMessage? addMessage(Message message, int charOffset, int length,
+      Uri? fileUri, Severity? severity,
+      {bool wasHandled: false,
+      List<LocatedMessage>? context,
+      bool problemOnLibrary: false,
+      List<Uri>? involvedFiles}) {
+    severity ??= message.code.severity;
+    if (severity == Severity.ignored) return null;
+    String trace = """
+message: ${message.message}
+charOffset: $charOffset
+fileUri: $fileUri
+severity: $severity
+""";
+    if (!seenMessages.add(trace)) return null;
+    if (message.code.severity == Severity.error) {
+      _hasSeenError = true;
+    }
+    if (message.code.severity == Severity.context) {
+      internalProblem(
+          templateInternalProblemContextSeverity
+              .withArguments(message.code.name),
+          charOffset,
+          fileUri);
+    }
+    target.context.report(
+        fileUri != null
+            ? message.withLocation(fileUri, charOffset, length)
+            : message.withoutLocation(),
+        severity,
+        context: context,
+        involvedFiles: involvedFiles);
+    if (severity == Severity.error) {
+      (wasHandled ? handledErrors : unhandledErrors).add(fileUri != null
+          ? message.withLocation(fileUri, charOffset, length)
+          : message.withoutLocation());
+    }
+    FormattedMessage formattedMessage = target.createFormattedMessage(
+        message, charOffset, length, fileUri, context, severity,
+        involvedFiles: involvedFiles);
+    if (!problemOnLibrary) {
+      allComponentProblems.add(formattedMessage);
+    }
+    return formattedMessage;
+  }
+
+  MemberBuilder getAbstractClassInstantiationError() {
+    return target.getAbstractClassInstantiationError(this);
+  }
+
+  MemberBuilder getCompileTimeError() => target.getCompileTimeError(this);
+
+  MemberBuilder getDuplicatedFieldInitializerError() {
+    return target.getDuplicatedFieldInitializerError(this);
+  }
+
+  MemberBuilder getNativeAnnotation() => target.getNativeAnnotation(this);
+
+  BodyBuilder createBodyBuilderForOutlineExpression(
+      SourceLibraryBuilder library,
+      DeclarationBuilder? declarationBuilder,
+      ModifierBuilder member,
+      Scope scope,
+      Uri fileUri) {
+    return new BodyBuilder.forOutlineExpression(
+        library, declarationBuilder, member, scope, fileUri);
+  }
 
   NnbdMode get nnbdMode => target.context.options.nnbdMode;
 
@@ -203,13 +525,9 @@
 
   ClassHierarchyBuilder get builderHierarchy => _builderHierarchy!;
 
-  @override
   Template<SummaryTemplate> get outlineSummaryTemplate =>
       templateSourceOutlineSummary;
 
-  @override
-  bool get isSourceLoader => true;
-
   Future<Token> tokenize(SourceLibraryBuilder library,
       {bool suppressLexicalErrors: false}) async {
     Uri fileUri = library.fileUri;
@@ -372,9 +690,15 @@
     _typeInferenceEngine!.typeDependencies[member] = typeDependency;
   }
 
-  @override
   Future<Null> buildOutlines() async {
-    await super.buildOutlines();
+    _ensureCoreLibrary();
+    while (_unparsedLibraries.isNotEmpty) {
+      LibraryBuilder library = _unparsedLibraries.removeFirst();
+      currentUriForCrashReporting = library.importUri;
+      await buildOutline(library as SourceLibraryBuilder);
+    }
+    currentUriForCrashReporting = null;
+    logSummary(outlineSummaryTemplate);
 
     if (_strongOptOutLibraries != null) {
       // We have libraries that are opted out in strong mode "non-explicitly",
@@ -409,9 +733,9 @@
       Set<LibraryBuilder> libraries,
       {required bool emitNonPackageErrors}) {
     Map<String?, List<LibraryBuilder>> libraryByPackage = {};
-    Map<Package, Version> enableNonNullableVersionByPackage = {};
+    Map<package_config.Package, Version> enableNonNullableVersionByPackage = {};
     for (LibraryBuilder libraryBuilder in libraries) {
-      final Package? package =
+      final package_config.Package? package =
           target.uriTranslator.getPackage(libraryBuilder.importUri);
 
       if (package != null &&
@@ -476,7 +800,6 @@
     return bytes.sublist(0, bytes.length - 1);
   }
 
-  @override
   Future<Null> buildOutline(SourceLibraryBuilder library) async {
     Token tokens = await tokenize(library);
     // ignore: unnecessary_null_comparison
@@ -485,7 +808,7 @@
     new ClassMemberParser(listener).parseUnit(tokens);
   }
 
-  @override
+  /// 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
@@ -578,9 +901,6 @@
         parameters);
   }
 
-  @override
-  KernelTarget get target => super.target as KernelTarget;
-
   DietListener createDietListener(SourceLibraryBuilder library) {
     return new DietListener(library, hierarchy, coreTypes, typeInferenceEngine);
   }
diff --git a/pkg/front_end/lib/src/fasta/target.dart b/pkg/front_end/lib/src/fasta/target.dart
deleted file mode 100644
index 4c9944a..0000000
--- a/pkg/front_end/lib/src/fasta/target.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2016, 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.
-
-library fasta.target;
-
-import 'package:kernel/ast.dart' show Component;
-
-import 'ticker.dart' show Ticker;
-
-/// A compilation target.
-///
-/// A target reads source files with [read], builds outlines when
-/// [buildOutlines] is called and builds the full component when
-/// [buildComponent] is called.
-abstract class Target {
-  final Ticker ticker;
-
-  Target(this.ticker);
-
-  /// Build and return outlines for all libraries.
-  Future<Component?> buildOutlines();
-
-  /// Build and return the full component for all libraries.
-  Future<Component?> buildComponent();
-}
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index d179dbd..14f9c7a 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -2,230 +2,13 @@
 // 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.
 
-library fasta.target_implementation;
-
-import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
-import 'package:kernel/ast.dart' show Library, Source, Version;
-
-import 'package:kernel/target/targets.dart' as backend show Target;
-
-import '../base/processed_options.dart' show ProcessedOptions;
-
-import 'builder/class_builder.dart';
-import 'builder/library_builder.dart';
-import 'builder/member_builder.dart';
-import 'source/source_library_builder.dart' show LanguageVersion;
+import 'package:kernel/target/targets.dart' show Target;
 
 import 'compiler_context.dart' show CompilerContext;
 
-import 'loader.dart' show Loader;
-
-import 'messages.dart' show FormattedMessage, LocatedMessage, Message;
-
-import 'target.dart' show Target;
-
-import 'ticker.dart' show Ticker;
-
-import 'uri_translator.dart' show UriTranslator;
-
-import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
-
 /// Provides the implementation details used by a loader for a target.
-abstract class TargetImplementation extends Target {
-  final UriTranslator uriTranslator;
+abstract class TargetImplementation {
+  CompilerContext get context;
 
-  final backend.Target backendTarget;
-
-  final CompilerContext context = CompilerContext.current;
-
-  /// Shared with [CompilerContext].
-  final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
-
-  MemberBuilder? cachedAbstractClassInstantiationError;
-  MemberBuilder? cachedCompileTimeError;
-  MemberBuilder? cachedDuplicatedFieldInitializerError;
-  MemberBuilder? cachedNativeAnnotation;
-
-  final ProcessedOptions _options;
-
-  TargetImplementation(Ticker ticker, this.uriTranslator, this.backendTarget)
-      // ignore: unnecessary_null_comparison
-      : assert(ticker != null),
-        // ignore: unnecessary_null_comparison
-        assert(uriTranslator != null),
-        // ignore: unnecessary_null_comparison
-        assert(backendTarget != null),
-        _options = CompilerContext.current.options,
-        super(ticker);
-
-  bool isExperimentEnabledInLibrary(ExperimentalFlag flag, Uri importUri) {
-    return _options.isExperimentEnabledInLibrary(flag, importUri);
-  }
-
-  Version getExperimentEnabledVersionInLibrary(
-      ExperimentalFlag flag, Uri importUri) {
-    return _options.getExperimentEnabledVersionInLibrary(flag, importUri);
-  }
-
-  bool isExperimentEnabledInLibraryByVersion(
-      ExperimentalFlag flag, Uri importUri, Version version) {
-    return _options.isExperimentEnabledInLibraryByVersion(
-        flag, importUri, version);
-  }
-
-  /// Returns `true` if the [flag] is enabled by default.
-  bool isExperimentEnabledByDefault(ExperimentalFlag flag) {
-    return _options.isExperimentEnabledByDefault(flag);
-  }
-
-  /// Returns `true` if the [flag] is enabled globally.
-  ///
-  /// This is `true` either if the [flag] is passed through an explicit
-  /// `--enable-experiment` option or if the [flag] is expired and on by
-  /// default.
-  bool isExperimentEnabledGlobally(ExperimentalFlag flag) {
-    return _options.isExperimentEnabledGlobally(flag);
-  }
-
-  /// Creates a [LibraryBuilder] corresponding to [uri], 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.
-  ///
-  /// [origin] is non-null if the created library is a patch to [origin].
-  ///
-  /// [packageUri] is the base uri for the package which the library belongs to.
-  /// For instance 'package:foo'.
-  ///
-  /// This is used to associate libraries in for instance the 'bin' and 'test'
-  /// folders of a package source with the package uri of the 'lib' folder.
-  ///
-  /// If the [packageUri] is `null` the package association of this library is
-  /// based on its [importUri].
-  ///
-  /// For libraries with a 'package:' [importUri], the package path must match
-  /// the path in the [importUri]. For libraries with a 'dart:' [importUri] the
-  /// [packageUri] must be `null`.
-  ///
-  /// [packageLanguageVersion] is the language version defined by the package
-  /// which the library belongs to, or the current sdk version if the library
-  /// doesn't belong to a package.
-  LibraryBuilder? createLibraryBuilder(
-      Uri uri,
-      Uri fileUri,
-      Uri? packageUri,
-      LanguageVersion packageLanguageVersion,
-      covariant LibraryBuilder? origin,
-      Library? referencesFrom,
-      bool? referenceIsPartOwner);
-
-  /// 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.
-  void breakCycle(ClassBuilder cls);
-
-  Uri? translateUri(Uri uri) => uriTranslator.translate(uri);
-
-  /// Returns a reference to the constructor of
-  /// [AbstractClassInstantiationError] error.  The constructor is expected to
-  /// accept a single argument of type String, which is the name of the
-  /// abstract class.
-  MemberBuilder getAbstractClassInstantiationError(Loader loader) {
-    return cachedAbstractClassInstantiationError ??=
-        loader.coreLibrary.getConstructor("AbstractClassInstantiationError");
-  }
-
-  /// Returns a reference to the constructor used for creating a compile-time
-  /// error. The constructor is expected to accept a single argument of type
-  /// String, which is the compile-time error message.
-  MemberBuilder getCompileTimeError(Loader loader) {
-    return cachedCompileTimeError ??= loader.coreLibrary
-        .getConstructor("_CompileTimeError", bypassLibraryPrivacy: true);
-  }
-
-  /// Returns a reference to the constructor used for creating a runtime error
-  /// when a final field is initialized twice. The constructor is expected to
-  /// accept a single argument which is the name of the field.
-  MemberBuilder getDuplicatedFieldInitializerError(Loader loader) {
-    return cachedDuplicatedFieldInitializerError ??= loader.coreLibrary
-        .getConstructor("_DuplicatedFieldInitializerError",
-            bypassLibraryPrivacy: true);
-  }
-
-  /// Returns a reference to the constructor used for creating `native`
-  /// annotations. The constructor is expected to accept a single argument of
-  /// type String, which is the name of the native method.
-  MemberBuilder getNativeAnnotation(Loader loader) {
-    if (cachedNativeAnnotation != null) return cachedNativeAnnotation!;
-    LibraryBuilder internal = loader.read(Uri.parse("dart:_internal"), -1,
-        accessor: loader.coreLibrary);
-    return cachedNativeAnnotation = internal.getConstructor("ExternalName");
-  }
-
-  void loadExtraRequiredLibraries(Loader loader) {
-    for (String uri in backendTarget.extraRequiredLibraries) {
-      loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
-    }
-    if (context.compilingPlatform) {
-      for (String uri in backendTarget.extraRequiredLibrariesPlatform) {
-        loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
-      }
-    }
-  }
-
-  void addSourceInformation(
-      Uri importUri, Uri fileUri, List<int> lineStarts, List<int> sourceCode);
-
-  void readPatchFiles(covariant LibraryBuilder library) {}
-
-  FormattedMessage createFormattedMessage(
-      Message message,
-      int charOffset,
-      int length,
-      Uri? fileUri,
-      List<LocatedMessage>? messageContext,
-      Severity severity,
-      {List<Uri>? involvedFiles}) {
-    ProcessedOptions processedOptions = context.options;
-    return processedOptions.format(
-        fileUri != null
-            ? message.withLocation(fileUri, charOffset, length)
-            : message.withoutLocation(),
-        severity,
-        messageContext,
-        involvedFiles: involvedFiles);
-  }
-
-  String get currentSdkVersionString {
-    return CompilerContext.current.options.currentSdkVersion;
-  }
-
-  Version? _currentSdkVersion;
-  Version get currentSdkVersion {
-    if (_currentSdkVersion == null) {
-      _parseCurrentSdkVersion();
-    }
-    return _currentSdkVersion!;
-  }
-
-  void _parseCurrentSdkVersion() {
-    bool good = false;
-    // ignore: unnecessary_null_comparison
-    if (currentSdkVersionString != null) {
-      List<String> dotSeparatedParts = currentSdkVersionString.split(".");
-      if (dotSeparatedParts.length >= 2) {
-        _currentSdkVersion = new Version(int.tryParse(dotSeparatedParts[0])!,
-            int.tryParse(dotSeparatedParts[1])!);
-        good = true;
-      }
-    }
-    if (!good) {
-      throw new StateError(
-          "Unparsable sdk version given: $currentSdkVersionString");
-    }
-  }
-
-  void releaseAncillaryResources();
+  Target get backendTarget;
 }
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index aa99dc8..9ae38bb 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -29,7 +29,7 @@
 
 import 'fasta/kernel/verifier.dart' show verifyComponent;
 
-import 'fasta/loader.dart' show Loader;
+import 'fasta/source/source_loader.dart' show SourceLoader;
 
 import 'fasta/uri_translator.dart' show UriTranslator;
 
@@ -67,7 +67,7 @@
   options.reportNullSafetyCompilationModeInfo();
   FileSystem fs = options.fileSystem;
 
-  Loader? sourceLoader;
+  SourceLoader? sourceLoader;
   return withCrashReporting<CompilerResult>(() async {
     UriTranslator uriTranslator = await options.getUriTranslator();
 
@@ -90,7 +90,7 @@
       dillTarget.loader.appendLibraries(additionalDill);
     }
 
-    await dillTarget.buildOutlines();
+    dillTarget.buildOutlines();
 
     KernelTarget kernelTarget =
         new KernelTarget(fs, false, dillTarget, uriTranslator);
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 0140af0..387f68f 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -1895,7 +1895,7 @@
         StandardFileSystem.instance, false, dillTarget, uriTranslator);
 
     sourceTarget.setEntryPoints(entryPoints);
-    await dillTarget.buildOutlines();
+    dillTarget.buildOutlines();
     return sourceTarget;
   }
 }
diff --git a/pkg/front_end/test/incremental_compiler_leak_test.dart b/pkg/front_end/test/incremental_compiler_leak_tester.dart
similarity index 100%
rename from pkg/front_end/test/incremental_compiler_leak_test.dart
rename to pkg/front_end/test/incremental_compiler_leak_tester.dart
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 6d05e95..2aa92c9 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -289,7 +289,7 @@
       CompilerContext.recordDependency(platform);
     }
     kernelTarget.setEntryPoints(c.options.inputs);
-    await dillTarget.buildOutlines();
+    dillTarget.buildOutlines();
     await kernelTarget.loader.buildOutlines();
 
     Uri? dFile;
@@ -328,7 +328,7 @@
     }
 
     kernelTarget.setEntryPoints(c.options.inputs);
-    await dillTarget.buildOutlines();
+    dillTarget.buildOutlines();
     var outline = await kernelTarget.buildOutlines();
     if (c.options.debugDump && output != null) {
       printComponentText(outline,
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 520a92b..37f4d7a 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -883,7 +883,7 @@
       Uri fileUri,
       Uri? packageUri,
       LanguageVersion packageLanguageVersion,
-      SourceLibraryBuilder origin,
+      SourceLibraryBuilder? origin,
       kernel.Library? referencesFrom,
       bool? referenceIsPartOwner) {
     if (uri == DocTestIncrementalCompiler.dartDocTestUri) {
diff --git a/tools/VERSION b/tools/VERSION
index c36ef67..b303eca 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 177
+PRERELEASE 178
 PRERELEASE_PATCH 0
\ No newline at end of file