Version 2.15.0-225.0.dev

Merge commit 'edf9fa73ec0eb8e86425d472fefa96c6cb29a649' into 'dev'
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 86a4c3b..9524f5b 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -47,6 +47,9 @@
 class DillLoader extends Loader {
   SourceLoader? currentSourceLoader;
 
+  final Map<Uri, DillLibraryBuilder> _knownLibraryBuilders =
+      <Uri, DillLibraryBuilder>{};
+
   final Map<Uri, DillLibraryBuilder> _builders = <Uri, DillLibraryBuilder>{};
 
   final Queue<DillLibraryBuilder> _unparsedLibraries =
@@ -88,6 +91,16 @@
 
   Ticker get ticker => target.ticker;
 
+  void registerKnownLibrary(Library library) {
+    _knownLibraryBuilders[library.importUri] =
+        new DillLibraryBuilder(library, this);
+  }
+
+  // TODO(johnniwinther): This is never called!?!
+  void releaseAncillaryResources() {
+    _knownLibraryBuilders.clear();
+  }
+
   /// 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].
@@ -100,12 +113,16 @@
   /// 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);
+    DillLibraryBuilder? libraryBuilder = _builders[uri];
+    if (libraryBuilder == null) {
+      libraryBuilder = _knownLibraryBuilders.remove(uri);
+      // ignore: unnecessary_null_comparison
+      assert(libraryBuilder != null, "No library found for $uri.");
+      _builders[uri] = libraryBuilder!;
+      assert(libraryBuilder.loader == this);
       if (uri.scheme == "dart") {
         if (uri.path == "core") {
-          _coreLibrary = library;
+          _coreLibrary = libraryBuilder;
         }
       }
       {
@@ -113,19 +130,18 @@
         // firstSourceUri and first library should be done as early as
         // possible.
         firstSourceUri ??= uri;
-        first ??= library;
+        first ??= libraryBuilder;
       }
-      if (_coreLibrary == library) {
+      if (_coreLibrary == libraryBuilder) {
         target.loadExtraRequiredLibraries(this);
       }
       if (target.backendTarget.mayDefineRestrictedType(uri)) {
-        library.mayImplementRestrictedTypes = true;
+        libraryBuilder.mayImplementRestrictedTypes = true;
       }
-      _unparsedLibraries.addLast(library);
-      return library;
-    });
+      _unparsedLibraries.addLast(libraryBuilder);
+    }
     if (accessor != null) {
-      builder.recordAccess(charOffset, noLength, accessor.fileUri);
+      libraryBuilder.recordAccess(charOffset, noLength, accessor.fileUri);
       if (!accessor.isPatch &&
           !accessor.isPart &&
           !target.backendTarget
@@ -134,7 +150,7 @@
             noLength, accessor.fileUri);
       }
     }
-    return builder;
+    return libraryBuilder;
   }
 
   void _ensureCoreLibrary() {
@@ -259,7 +275,7 @@
       Uri uri = library.importUri;
       if (filter == null || filter(library.importUri)) {
         libraries.add(library);
-        target.registerLibrary(library);
+        registerKnownLibrary(library);
         requestedLibraries.add(uri);
         requestedLibrariesFileUri.add(library.fileUri);
       }
@@ -285,7 +301,7 @@
     //
     // Create dill library builder (adds it to a map where it's fetched
     // again momentarily).
-    target.registerLibrary(library);
+    registerKnownLibrary(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);
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 459831a..b5b737e 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -4,7 +4,7 @@
 
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
-import 'package:kernel/ast.dart' show Library, Source;
+import 'package:kernel/ast.dart' show Source;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -20,16 +20,11 @@
 
 import '../target_implementation.dart' show TargetImplementation;
 
-import 'dill_library_builder.dart' show DillLibraryBuilder;
-
 import 'dill_loader.dart' show DillLoader;
 
 class DillTarget extends TargetImplementation {
   final Ticker ticker;
 
-  final Map<Uri, DillLibraryBuilder> _knownLibraryBuilders =
-      <Uri, DillLibraryBuilder>{};
-
   bool isLoaded = false;
 
   late final DillLoader loader;
@@ -92,23 +87,4 @@
     }
     isLoaded = true;
   }
-
-  /// Returns the [DillLibraryBuilder] corresponding to [uri].
-  ///
-  /// The [DillLibraryBuilder] is pulled from [_knownLibraryBuilders].
-  DillLibraryBuilder createLibraryBuilder(Uri uri) {
-    DillLibraryBuilder libraryBuilder = _knownLibraryBuilders.remove(uri)!;
-    // ignore: unnecessary_null_comparison
-    assert(libraryBuilder != null, "No library found for $uri.");
-    return libraryBuilder;
-  }
-
-  void registerLibrary(Library library) {
-    _knownLibraryBuilders[library.importUri] =
-        new DillLibraryBuilder(library, loader);
-  }
-
-  void releaseAncillaryResources() {
-    _knownLibraryBuilders.clear();
-  }
 }
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index febaaf8..61bdb2e 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -1426,7 +1426,7 @@
         for (Library lib in module.libraries) {
           if (!dillLoadedData!.loader.containsLibraryBuilder(lib.importUri)) {
             dillLoadedData!.loader.libraries.add(lib);
-            dillLoadedData!.registerLibrary(lib);
+            dillLoadedData!.loader.registerKnownLibrary(lib);
             reusedLibraries.add(dillLoadedData!.loader.read(lib.importUri, -1));
             usedComponent = true;
           }
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 a98493d..890bf9d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -40,7 +40,6 @@
 import '../builder/void_type_declaration_builder.dart';
 import '../compiler_context.dart' show CompilerContext;
 import '../crash.dart' show withCrashReporting;
-import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 import '../dill/dill_target.dart' show DillTarget;
 import '../kernel/constructor_tearoff_lowering.dart';
@@ -50,16 +49,11 @@
         FormattedMessage,
         LocatedMessage,
         Message,
-        messageAgnosticWithStrongDillLibrary,
-        messageAgnosticWithWeakDillLibrary,
         messageConstConstructorLateFinalFieldCause,
         messageConstConstructorLateFinalFieldError,
         messageConstConstructorNonFinalField,
         messageConstConstructorNonFinalFieldCause,
         messageConstConstructorRedirectionToNonConst,
-        messageInvalidNnbdDillLibrary,
-        messageStrongWithWeakDillLibrary,
-        messageWeakWithStrongDillLibrary,
         noLength,
         templateFieldNonNullableNotInitializedByConstructorError,
         templateFieldNonNullableWithoutInitializerError,
@@ -72,8 +66,7 @@
 import '../scope.dart' show AmbiguousBuilder;
 import '../source/name_scheme.dart';
 import '../source/source_class_builder.dart' show SourceClassBuilder;
-import '../source/source_library_builder.dart'
-    show LanguageVersion, SourceLibraryBuilder;
+import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 import '../source/source_loader.dart' show SourceLoader;
 import '../target_implementation.dart' show TargetImplementation;
 import '../ticker.dart' show Ticker;
@@ -368,90 +361,6 @@
     return entryPoint;
   }
 
-  /// 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,
-      SourceLibraryBuilder? origin,
-      Library? referencesFrom,
-      bool? referenceIsPartOwner) {
-    if (dillTarget.isLoaded) {
-      DillLibraryBuilder? builder = dillTarget.loader.lookupLibraryBuilder(uri);
-      if (builder != null) {
-        if (!builder.isNonNullableByDefault &&
-            (loader.nnbdMode == NnbdMode.Strong ||
-                loader.nnbdMode == NnbdMode.Agnostic)) {
-          loader.registerStrongOptOutLibrary(builder);
-        } else {
-          NonNullableByDefaultCompiledMode libraryMode =
-              builder.library.nonNullableByDefaultCompiledMode;
-          if (libraryMode == NonNullableByDefaultCompiledMode.Invalid) {
-            loader.registerNnbdMismatchLibrary(
-                builder, messageInvalidNnbdDillLibrary);
-          } else {
-            switch (loader.nnbdMode) {
-              case NnbdMode.Weak:
-                if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
-                    libraryMode != NonNullableByDefaultCompiledMode.Weak) {
-                  loader.registerNnbdMismatchLibrary(
-                      builder, messageWeakWithStrongDillLibrary);
-                }
-                break;
-              case NnbdMode.Strong:
-                if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
-                    libraryMode != NonNullableByDefaultCompiledMode.Strong) {
-                  loader.registerNnbdMismatchLibrary(
-                      builder, messageStrongWithWeakDillLibrary);
-                }
-                break;
-              case NnbdMode.Agnostic:
-                if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic) {
-                  if (libraryMode == NonNullableByDefaultCompiledMode.Strong) {
-                    loader.registerNnbdMismatchLibrary(
-                        builder, messageAgnosticWithStrongDillLibrary);
-                  } else {
-                    loader.registerNnbdMismatchLibrary(
-                        builder, messageAgnosticWithWeakDillLibrary);
-                  }
-                }
-                break;
-            }
-          }
-        }
-        return builder;
-      }
-    }
-    return new SourceLibraryBuilder(
-        uri, fileUri, packageUri, packageLanguageVersion, loader, origin,
-        referencesFrom: referencesFrom,
-        referenceIsPartOwner: referenceIsPartOwner);
-  }
-
   /// Returns classes defined in libraries in [loader].
   List<SourceClassBuilder> collectMyClasses() {
     List<SourceClassBuilder> result = <SourceClassBuilder>[];
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 696a640..29c7861 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -34,6 +34,7 @@
 import '../../base/common.dart';
 import '../../base/instrumentation.dart' show Instrumentation;
 import '../../base/nnbd_mode.dart';
+import '../dill/dill_library_builder.dart';
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/constructor_builder.dart';
@@ -215,7 +216,7 @@
   void registerLibraryBuilder(LibraryBuilder libraryBuilder, [Uri? uri]) {
     uri ??= libraryBuilder.importUri;
     if (uri.scheme == "dart" && uri.path == "core") {
-      coreLibrary = libraryBuilder;
+      _coreLibrary = libraryBuilder;
     }
     _builders[uri] = libraryBuilder;
   }
@@ -231,11 +232,226 @@
   @override
   LibraryBuilder get coreLibrary => _coreLibrary!;
 
-  void set coreLibrary(LibraryBuilder value) {
-    _coreLibrary = value;
+  Ticker get ticker => target.ticker;
+
+  /// Creates a [SourceLibraryBuilder] 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.
+  SourceLibraryBuilder createLibraryBuilder(
+      Uri uri,
+      Uri fileUri,
+      Uri? packageUri,
+      LanguageVersion packageLanguageVersion,
+      SourceLibraryBuilder? origin,
+      Library? referencesFrom,
+      bool? referenceIsPartOwner) {
+    return new SourceLibraryBuilder(
+        uri, fileUri, packageUri, packageLanguageVersion, this, origin,
+        referencesFrom: referencesFrom,
+        referenceIsPartOwner: referenceIsPartOwner);
   }
 
-  Ticker get ticker => target.ticker;
+  SourceLibraryBuilder _createSourceLibraryBuilder(
+      Uri uri,
+      Uri? fileUri,
+      SourceLibraryBuilder? origin,
+      Library? referencesFrom,
+      bool? referenceIsPartOwner) {
+    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);
+
+    SourceLibraryBuilder libraryBuilder = createLibraryBuilder(
+        uri,
+        fileUri,
+        packageUri,
+        packageLanguageVersion,
+        origin,
+        referencesFrom,
+        referenceIsPartOwner);
+    if (packageLanguageVersionProblem != null) {
+      libraryBuilder.addPostponedProblem(
+          packageLanguageVersionProblem, 0, noLength, libraryBuilder.fileUri);
+    }
+
+    // Add any additional logic after this block. Setting the
+    // firstSourceUri and first library should be done as early as
+    // possible.
+    firstSourceUri ??= uri;
+    first ??= libraryBuilder;
+
+    _checkForDartCore(uri, libraryBuilder);
+
+    Uri libraryUri = origin?.importUri ?? uri;
+    if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
+      libraryBuilder.mayImplementRestrictedTypes = true;
+    }
+    if (uri.scheme == "dart") {
+      target.readPatchFiles(libraryBuilder);
+    }
+    _unparsedLibraries.addLast(libraryBuilder);
+
+    return libraryBuilder;
+  }
+
+  DillLibraryBuilder? _lookupDillLibraryBuilder(Uri uri) {
+    DillLibraryBuilder? libraryBuilder =
+        target.dillTarget.loader.lookupLibraryBuilder(uri);
+    if (libraryBuilder != null) {
+      _checkDillLibraryBuilderNnbdMode(libraryBuilder);
+      _checkForDartCore(uri, libraryBuilder);
+    }
+    return libraryBuilder;
+  }
+
+  void _checkDillLibraryBuilderNnbdMode(DillLibraryBuilder libraryBuilder) {
+    if (!libraryBuilder.isNonNullableByDefault &&
+        (nnbdMode == NnbdMode.Strong || nnbdMode == NnbdMode.Agnostic)) {
+      registerStrongOptOutLibrary(libraryBuilder);
+    } else {
+      NonNullableByDefaultCompiledMode libraryMode =
+          libraryBuilder.library.nonNullableByDefaultCompiledMode;
+      if (libraryMode == NonNullableByDefaultCompiledMode.Invalid) {
+        registerNnbdMismatchLibrary(
+            libraryBuilder, messageInvalidNnbdDillLibrary);
+      } else {
+        switch (nnbdMode) {
+          case NnbdMode.Weak:
+            if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
+                libraryMode != NonNullableByDefaultCompiledMode.Weak) {
+              registerNnbdMismatchLibrary(
+                  libraryBuilder, messageWeakWithStrongDillLibrary);
+            }
+            break;
+          case NnbdMode.Strong:
+            if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
+                libraryMode != NonNullableByDefaultCompiledMode.Strong) {
+              registerNnbdMismatchLibrary(
+                  libraryBuilder, messageStrongWithWeakDillLibrary);
+            }
+            break;
+          case NnbdMode.Agnostic:
+            if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic) {
+              if (libraryMode == NonNullableByDefaultCompiledMode.Strong) {
+                registerNnbdMismatchLibrary(
+                    libraryBuilder, messageAgnosticWithStrongDillLibrary);
+              } else {
+                registerNnbdMismatchLibrary(
+                    libraryBuilder, messageAgnosticWithWeakDillLibrary);
+              }
+            }
+            break;
+        }
+      }
+    }
+  }
+
+  void _checkForDartCore(Uri uri, LibraryBuilder libraryBuilder) {
+    if (uri.scheme == "dart") {
+      if (uri.path == "core") {
+        _coreLibrary = libraryBuilder;
+      } else if (uri.path == "typed_data") {
+        typedDataLibrary = libraryBuilder;
+      }
+    }
+    // TODO(johnniwinther): If we save the created library in [_builders]
+    // here, i.e. before calling `target.loadExtraRequiredLibraries` below,
+    // the order of the libraries change, making `dart:core` come before the
+    // required arguments. Currently [DillLoader.appendLibrary] one works
+    // when this is not the case.
+    if (_coreLibrary == libraryBuilder) {
+      target.loadExtraRequiredLibraries(this);
+    }
+  }
 
   /// 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
@@ -254,135 +470,28 @@
       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;
+    LibraryBuilder? libraryBuilder = _builders[uri];
+    if (libraryBuilder == null) {
+      if (target.dillTarget.isLoaded) {
+        libraryBuilder = _lookupDillLibraryBuilder(uri);
       }
-      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 (libraryBuilder == null) {
+        libraryBuilder = _createSourceLibraryBuilder(
+            uri,
+            fileUri,
+            origin as SourceLibraryBuilder?,
+            referencesFrom,
+            referenceIsPartOwner);
       }
 
-      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;
-    });
+      _builders[uri] = libraryBuilder;
+    }
     if (accessor == null) {
-      if (builder.loader == this && first != builder) {
+      if (libraryBuilder.loader == this && first != libraryBuilder) {
         unhandled("null", "accessor", charOffset, uri);
       }
     } else {
-      builder.recordAccess(charOffset, noLength, accessor.fileUri);
+      libraryBuilder.recordAccess(charOffset, noLength, accessor.fileUri);
       if (!accessor.isPatch &&
           !accessor.isPart &&
           !target.backendTarget
@@ -391,7 +500,7 @@
             noLength, accessor.fileUri);
       }
     }
-    return builder;
+    return libraryBuilder;
   }
 
   void _ensureCoreLibrary() {
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 63cd5db..d2a057e 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -248,7 +248,7 @@
       "pattern": [
         "pkg/front_end/.*\\.dart$",
         "pkg/front_end/.*\\.crash_dart$",
-        "tests/.*\\.dart$"
+        "/tests/.*\\.dart$"
       ],
       "exclude": []
     },
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 3ef774c..1e51b84 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -51,6 +51,7 @@
     show useImplicitCreationExpressionInCfe;
 // ignore: import_of_legacy_library_into_null_safe
 import 'package:front_end/src/fasta/source/source_library_builder.dart';
+import 'package:front_end/src/fasta/source/source_loader.dart';
 import 'package:front_end/src/fasta/uri_translator.dart';
 import 'package:kernel/kernel.dart' as kernel
     show Combinator, Component, LibraryDependency, Library, Location, Source;
@@ -878,7 +879,20 @@
       : super(fileSystem, includeComments, dillTarget, uriTranslator);
 
   @override
-  LibraryBuilder createLibraryBuilder(
+  SourceLoader createLoader() {
+    return new DocTestSourceLoader(compiler, fileSystem, includeComments, this);
+  }
+}
+
+class DocTestSourceLoader extends SourceLoader {
+  final DocTestIncrementalCompiler compiler;
+
+  DocTestSourceLoader(this.compiler, FileSystem fileSystem,
+      bool includeComments, DocTestIncrementalKernelTarget target)
+      : super(fileSystem, includeComments, target);
+
+  @override
+  SourceLibraryBuilder createLibraryBuilder(
       Uri uri,
       Uri fileUri,
       Uri? packageUri,
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index 3cc94ca..a27d27c 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -6842,13 +6842,13 @@
   const intptr_t version_len = strlen(expected_version);
   WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
 
-  const char* expected_features =
+  char* expected_features =
       Dart::FeaturesString(IsolateGroup::Current(), is_vm_snapshot, kind_);
   ASSERT(expected_features != NULL);
   const intptr_t features_len = strlen(expected_features);
   WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
              features_len + 1);
-  free(const_cast<char*>(expected_features));
+  free(expected_features);
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index b041eb8..ced30ca 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -1064,9 +1064,9 @@
   return Error::null();
 }
 
-const char* Dart::FeaturesString(IsolateGroup* isolate_group,
-                                 bool is_vm_isolate,
-                                 Snapshot::Kind kind) {
+char* Dart::FeaturesString(IsolateGroup* isolate_group,
+                           bool is_vm_isolate,
+                           Snapshot::Kind kind) {
   TextBuffer buffer(64);
 
 // Different fields are included for DEBUG/RELEASE/PRODUCT.
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index c22f1f0..9d0cdf1 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -111,9 +111,10 @@
   static uword AllocateReadOnlyHandle();
   static bool IsReadOnlyHandle(uword address);
 
-  static const char* FeaturesString(IsolateGroup* isolate_group,
-                                    bool is_vm_snapshot,
-                                    Snapshot::Kind kind);
+  // The returned string has to be free()ed.
+  static char* FeaturesString(IsolateGroup* isolate_group,
+                              bool is_vm_snapshot,
+                              Snapshot::Kind kind);
   static Snapshot::Kind vm_snapshot_kind() { return vm_snapshot_kind_; }
 
   static Dart_ThreadExitCallback thread_exit_callback() {
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index fd3b9ee..a0a5b9c 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -4889,7 +4889,9 @@
 #else
   Snapshot::Kind kind = Snapshot::kFullJIT;
 #endif
-  jsobj.AddProperty("_features", Dart::FeaturesString(nullptr, true, kind));
+  char* features_string = Dart::FeaturesString(nullptr, true, kind);
+  jsobj.AddProperty("_features", features_string);
+  free(features_string);
   jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart");
   jsobj.AddProperty64("pid", OS::ProcessId());
   jsobj.AddPropertyTimeMillis(
diff --git a/tools/VERSION b/tools/VERSION
index a34cafe..6ccaf6a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 224
+PRERELEASE 225
 PRERELEASE_PATCH 0
\ No newline at end of file