Version 2.16.0-80.1.beta

Merge '2.16.0-80.0.dev' into beta
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 981de4b..d50d6f5 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-26T10:20:01.277340",
+  "generated": "2021-11-15T17:34:02.415038",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -88,7 +88,7 @@
       "name": "analyzer_cli",
       "rootUri": "../pkg/analyzer_cli",
       "packageUri": "lib/",
-      "languageVersion": "2.7"
+      "languageVersion": "2.14"
     },
     {
       "name": "analyzer_plugin",
@@ -124,7 +124,7 @@
       "name": "bazel_worker",
       "rootUri": "../third_party/pkg/bazel_worker",
       "packageUri": "lib/",
-      "languageVersion": "2.12"
+      "languageVersion": "2.14"
     },
     {
       "name": "benchmark_harness",
@@ -659,7 +659,7 @@
       "name": "stream_channel",
       "rootUri": "../third_party/pkg/stream_channel",
       "packageUri": "lib/",
-      "languageVersion": "2.10"
+      "languageVersion": "2.14"
     },
     {
       "name": "string_scanner",
@@ -710,6 +710,11 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "test_package",
+      "rootUri": "../pkg/vm_service/test/test_package",
+      "languageVersion": "2.12"
+    },
+    {
       "name": "test_process",
       "rootUri": "../third_party/pkg/test_process",
       "packageUri": "lib/",
diff --git a/.packages b/.packages
index 568fa66..f5ea5bc 100644
--- a/.packages
+++ b/.packages
@@ -105,6 +105,7 @@
 test_api:third_party/pkg/test/pkgs/test_api/lib
 test_core:third_party/pkg/test/pkgs/test_core/lib
 test_descriptor:third_party/pkg/test_descriptor/lib
+test_package:pkg/vm_service/test/test_package
 test_process:third_party/pkg/test_process/lib
 test_reflective_loader:third_party/pkg/test_reflective_loader/lib
 test_runner:pkg/test_runner/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68af803..2c48329 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,41 @@
+## 2.16.0
+
+### Core libraries
+
+#### `dart:core`
+
+- **Breaking Change** [#47653](https://github.com/dart-lang/sdk/issues/47653):
+  On Windows, `Directory.rename` will no longer delete a directory if
+  `newPath` specifies one. Instead, a `FileSystemException` will be thrown.
+
+- Add `Error.throwWithStackTrace` which can `throw` an
+  error with an existing stack trace, instead of creating
+  a new stack trace.
+
+### Tools
+
+#### Dart command line
+
+- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+  The standalone `dartanalyzer` tool has been
+  marked deprecated as previously announced.
+  Its replacement is the `dart analyze` command.
+  Should you find any issues, or missing features, in the replacement
+  command, kindly file [an issue][].
+
+[an issue]: https://github.com/dart-lang/sdk/issues/new
+
+#### Linter
+
+Updated the Linter to `1.15.0`, which includes changes that
+- adds new lint: `use_decorated_box`.
+- adds new lint: `no_leading_underscores_for_library_prefixes`.
+- adds new lint: `no_leading_underscores_for_local_identifiers`.
+- adds new lint: `secure_pubspec_urls`.
+- adds new lint: `sized_box_shrink_expand`.
+- adds new lint: `avoid_final_parameters`.
+- improves docs for `omit_local_variable_types`.
+
 ## 2.15.0
 
 ### Language
diff --git a/DEPS b/DEPS
index cb395cc..cec2977 100644
--- a/DEPS
+++ b/DEPS
@@ -39,21 +39,22 @@
 
   # Checked-in SDK version. The checked-in SDK is a Dart SDK distribution in a
   # cipd package used to run Dart scripts in the build and test infrastructure.
-  "sdk_tag": "version:2.15.0-82.0.dev",
+  "sdk_tag": "version:2.15.0-268.8.beta",
 
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
   # has.
-  "co19_rev": "73545b2bf6c7f8e4eb931bb04d86e38d6485deee",
+  "co19_rev": "4ef349830b971c22d8ddb2970c4ba9002806fd85",
   # This line prevents conflicts when both packages are rolled simultaneously.
-  "co19_2_rev": "52d3d2a6d2550ccd69c8facf8a36099be66f1493",
+  "co19_2_rev": "995745937abffe9fc3a6441f9f0db27b2d706e4c",
 
   # The internal benchmarks to use. See go/dart-benchmarks-internal
   "benchmarks_internal_rev": "076df10d9b77af337f2d8029725787155eb1cd52",
   "checkout_benchmarks_internal": False,
 
   # Checkout Android dependencies only on Mac and Linux.
-  "download_android_deps": 'host_os == "mac" or host_os == "linux"',
+  "download_android_deps":
+    "(host_os == mac or host_os == linux) and host_cpu == x64",
 
   # Checkout extra javascript engines for testing or benchmarking.
   # d8, the V8 shell, is always checked out.
@@ -64,8 +65,8 @@
   # The list of revisions for these tools comes from Fuchsia, here:
   # https://fuchsia.googlesource.com/integration/+/HEAD/prebuilts
   # If there are problems with the toolchain, contact fuchsia-toolchain@.
-  "clang_revision": "f37e8b0b831e61d3b6033829fff05d6d193ab735",
-  "gn_revision": "693f9fb87e4febdd4299db9f73d8d2c958e63148",
+  "clang_revision": "e3a7f0e2f9ab566bd9b71fb54fe77e947b061a12",
+  "gn_revision": "b79031308cc878488202beb99883ec1f2efd9a6d",
 
   # Scripts that make 'git cl format' work.
   "clang_format_scripts_rev": "c09c8deeac31f05bd801995c475e7c8070f9ecda",
@@ -75,11 +76,11 @@
   # Revisions of /third_party/* dependencies.
   "args_rev": "3b3f55766af13d895d2020ec001a28e8dc147f91",
   "async_rev": "80886150a5e6c58006c8ae5a6c2aa7108638e2a9",
-  "bazel_worker_rev": "0885637b037979afbf5bcd05fd748b309fd669c0",
+  "bazel_worker_rev": "ceeba0982d4ff40d32371c9d35f3d2dc1868de20",
   "benchmark_harness_rev": "c546dbd9f639f75cd2f75de8df2eb9f8ea15e8e7",
   "boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
-  "boringssl_gen_rev": "7322fc15cc065d8d2957fccce6b62a509dc4d641",
-  "boringssl_rev" : "1607f54fed72c6589d560254626909a64124f091",
+  "boringssl_gen_rev": "ced85ef0a00bbca77ce5a91261a5f2ae61b1e62f",
+  "boringssl_rev" : "87f316d7748268eb56f2dc147bd593254ae93198",
   "browser-compat-data_tag": "v1.0.22",
   "browser_launcher_rev": "c6cc1025d6901926cf022e144ba109677e3548f1",
   "characters_rev": "6ec389c4dfa8fce14820dc5cbf6e693202e7e052",
@@ -90,7 +91,7 @@
   "collection_rev": "a4c941ab94044d118b2086a3f261c30377604127",
   "convert_rev": "e063fdca4bebffecbb5e6aa5525995120982d9ce",
   "crypto_rev": "b5024e4de2b1c474dd558bef593ddbf0bfade152",
-  "csslib_rev": "6f35da3d93eb56eb25925779d235858d4090ce6f",
+  "csslib_rev": "02abc1ddf93092efef2be365300f15504d23cd23",
 
   # Note: Updates to dart_style have to be coordinated with the infrastructure
   # team so that the internal formatter `tools/sdks/dart-sdk/bin/dart format`
@@ -106,8 +107,8 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_rev": "08b0294d0a500d5c02168ef57dcb8868d0c3cb48",
 
-  "dartdoc_rev" : "520e64977de7a87b2fd5be56e5c2e1a58d55bdad",
-  "devtools_rev" : "3a2f570813200e6dee141f3e7a9edcae5f31c2e8",
+  "dartdoc_rev" : "ff0d94bdb87f11c04a7e0ddab811bf94211b08a4",
+  "devtools_rev" : "f2ede24a4ea666d4832d78b813c7d4e376aa77d0",
   "jsshell_tag": "version:88.0",
   "ffi_rev": "4dd32429880a57b64edaf54c9d5af8a9fa9a4ffb",
   "fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",
@@ -122,11 +123,11 @@
   "intl_tag": "0.17.0-nullsafety",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
-  "linter_tag": "1.14.0",
+  "linter_tag": "1.15.0",
   "lints_tag": "f9670df2a66e0ec12eb51554e70c1cbf56c8f5d0",
   "logging_rev": "575781ef196e4fed4fb737e38fb4b73d62727187",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
-  "markdown_rev": "9c4beaac96d8f008078e00b027915f81b665d2de",
+  "markdown_rev": "7479783f0493f6717e1d7ae31cb37d39a91026b2",
   "matcher_rev": "6ba4a6d68bdfacff3d572c9ea98333dfc66fd6bf",
   "mime_rev": "c931f4bed87221beaece356494b43731445ce7b8",
   "mockito_rev": "d39ac507483b9891165e422ec98d9fb480037c8b",
@@ -139,7 +140,7 @@
   "pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
   "process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
   "protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
-  "pub_rev": "96404e0749864c9fbf8b12e1d424e8078809e00a",
+  "pub_rev": "dcb6abac2d7d43258c03b348be42bf4aab9529b1",
   "pub_semver_rev": "a43ad72fb6b7869607581b5fedcb186d1e74276a",
   "root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
@@ -153,8 +154,8 @@
   "source_maps_rev": "6499ee3adac8d469e2953e2e8ba4bdb4c2fbef90",
   "source_span_rev": "1be3c44045a06dff840d2ed3a13e6082d7a03a23",
   "sse_rev": "9084339389eb441d0c0518cddac211a097e78657",
-  "stack_trace_rev": "6788afc61875079b71b3d1c3e65aeaa6a25cbc2f",
-  "stream_channel_rev": "d7251e61253ec389ee6e045ee1042311bced8f1d",
+  "stack_trace_rev": "5220580872625ddee41e9ca9a5f3364789b2f0f6",
+  "stream_channel_rev": "3fa3e40c75c210d617b8b943b9b8f580e9866a89",
   "string_scanner_rev": "1b63e6e5db5933d7be0a45da6e1129fe00262734",
   "sync_http_rev": "b59c134f2e34d12acac110d4f17f83e5a7db4330",
   "test_descriptor_rev": "ead23c1e7df079ac0f6457a35f7a71432892e527",
@@ -655,6 +656,15 @@
       ],
           "dep_type": "cipd",
   },
+  Var("dart_root") + "/benchmarks/NativeCall/native/out/": {
+      "packages": [
+          {
+              "package": "dart/benchmarks/nativecall",
+              "version": "w1JKzCIHSfDNIjqnioMUPq0moCXKwX67aUfhyrvw4E0C",
+          },
+      ],
+          "dep_type": "cipd",
+  },
   Var("dart_root") + "/third_party/browsers/chrome": {
       "packages": [
           {
diff --git a/benchmarks/FfiAsTypedList/dart/FfiAsTypedList.dart b/benchmarks/FfiAsTypedList/dart/FfiAsTypedList.dart
new file mode 100644
index 0000000..f32f5d0
--- /dev/null
+++ b/benchmarks/FfiAsTypedList/dart/FfiAsTypedList.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Micro-benchmark for creating TypeData lists from Pointers.
+//
+// The FfiMemory benchmark tests accessing memory through TypedData.
+
+import 'dart:ffi';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+import 'package:ffi/ffi.dart';
+
+//
+// Benchmark fixture.
+//
+
+// Number of repeats: 1000
+const N = 1000;
+
+class FromPointerInt8 extends BenchmarkBase {
+  Pointer<Int8> pointer = nullptr;
+  FromPointerInt8() : super('FfiAsTypedList.FromPointerInt8');
+
+  @override
+  void setup() => pointer = calloc(1);
+  @override
+  void teardown() => calloc.free(pointer);
+
+  @override
+  void run() {
+    for (var i = 0; i < N; i++) {
+      pointer.asTypedList(1);
+    }
+  }
+}
+
+//
+// Main driver.
+//
+
+void main() {
+  final benchmarks = [
+    () => FromPointerInt8(),
+  ];
+  for (final benchmark in benchmarks) {
+    benchmark().report();
+  }
+}
diff --git a/benchmarks/FfiAsTypedList/dart2/FfiAsTypedList.dart b/benchmarks/FfiAsTypedList/dart2/FfiAsTypedList.dart
new file mode 100644
index 0000000..bab621d
--- /dev/null
+++ b/benchmarks/FfiAsTypedList/dart2/FfiAsTypedList.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Micro-benchmark for creating TypeData lists from Pointers.
+//
+// The FfiMemory benchmark tests accessing memory through TypedData.
+
+// @dart=2.9
+
+import 'dart:ffi';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+import 'package:ffi/ffi.dart';
+
+//
+// Benchmark fixture.
+//
+
+// Number of repeats: 1000
+const N = 1000;
+
+class FromPointerInt8 extends BenchmarkBase {
+  Pointer<Int8> pointer = nullptr;
+  FromPointerInt8() : super('FfiAsTypedList.FromPointerInt8');
+
+  @override
+  void setup() => pointer = calloc(1);
+  @override
+  void teardown() => calloc.free(pointer);
+
+  @override
+  void run() {
+    for (var i = 0; i < N; i++) {
+      pointer.asTypedList(1);
+    }
+  }
+}
+
+//
+// Main driver.
+//
+
+void main() {
+  final benchmarks = [
+    () => FromPointerInt8(),
+  ];
+  for (final benchmark in benchmarks) {
+    benchmark().report();
+  }
+}
diff --git a/benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart b/benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart
index 84b7572..4af3028 100644
--- a/benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart
+++ b/benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart
@@ -34,8 +34,7 @@
   final rpRun = ReceivePort();
   final int nWarmup = 17; // enough runs to trigger optimized compilation
   final int nWarmupFactorial = 2584;
-  // With --enable-isolate-groups runs for about 8 seconds.
-  // Should not be run witout --enable-isolate-groups as it would be too slow.
+  // Runs for about 8 seconds.
   final int n = 21;
   final int nFactorial = 17711;
   final beforeRss = ProcessInfo.currentRss;
@@ -48,8 +47,7 @@
   final watch = Stopwatch();
   watch.start();
 
-  // For the benefit of enable-isolate-groups configuration, warm up target
-  // isolate code by running couple iterations in the main isolate.
+  // Warm up code by running a couple iterations in the main isolate.
   await Isolate.spawn(fibonacciRecursive, [rpWarmup.sendPort, nWarmup]);
   Expect.equals(nWarmupFactorial, await rpWarmup.first);
 
@@ -60,7 +58,7 @@
 
   final done = watch.elapsedMicroseconds;
 
-  print('IsolateFibonacci_$n.Calculation(RunTimeRaw): ${done-warmup} us.');
-  print('IsolateFibonacci_$n.DeltaPeak(MemoryUse): ${maxRss-beforeRss}');
+  print('IsolateFibonacci_$n.Calculation(RunTimeRaw): ${done - warmup} us.');
+  print('IsolateFibonacci_$n.DeltaPeak(MemoryUse): ${maxRss - beforeRss}');
   rssTimer.cancel();
 }
diff --git a/benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart b/benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart
index 84b7572..4af3028 100644
--- a/benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart
+++ b/benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart
@@ -34,8 +34,7 @@
   final rpRun = ReceivePort();
   final int nWarmup = 17; // enough runs to trigger optimized compilation
   final int nWarmupFactorial = 2584;
-  // With --enable-isolate-groups runs for about 8 seconds.
-  // Should not be run witout --enable-isolate-groups as it would be too slow.
+  // Runs for about 8 seconds.
   final int n = 21;
   final int nFactorial = 17711;
   final beforeRss = ProcessInfo.currentRss;
@@ -48,8 +47,7 @@
   final watch = Stopwatch();
   watch.start();
 
-  // For the benefit of enable-isolate-groups configuration, warm up target
-  // isolate code by running couple iterations in the main isolate.
+  // Warm up code by running a couple iterations in the main isolate.
   await Isolate.spawn(fibonacciRecursive, [rpWarmup.sendPort, nWarmup]);
   Expect.equals(nWarmupFactorial, await rpWarmup.first);
 
@@ -60,7 +58,7 @@
 
   final done = watch.elapsedMicroseconds;
 
-  print('IsolateFibonacci_$n.Calculation(RunTimeRaw): ${done-warmup} us.');
-  print('IsolateFibonacci_$n.DeltaPeak(MemoryUse): ${maxRss-beforeRss}');
+  print('IsolateFibonacci_$n.Calculation(RunTimeRaw): ${done - warmup} us.');
+  print('IsolateFibonacci_$n.DeltaPeak(MemoryUse): ${maxRss - beforeRss}');
   rssTimer.cancel();
 }
diff --git a/benchmarks/IsolateSpawnMemory/dart/IsolateSpawnMemory.dart b/benchmarks/IsolateSpawnMemory/dart/IsolateSpawnMemory.dart
index 1f7b009..0160c03 100644
--- a/benchmarks/IsolateSpawnMemory/dart/IsolateSpawnMemory.dart
+++ b/benchmarks/IsolateSpawnMemory/dart/IsolateSpawnMemory.dart
@@ -158,16 +158,6 @@
 }
 
 // Returns the set of isolate groups for which we should count the heap usage.
-//
-// We have two cases
-//
-//   a) --enable-isolate-groups: All isolates will be within the same isolate
-//   group.
-//
-//   b) --no-enable-isolate-groups: All isolates will be within their own,
-//   separate isolate group.
-//
-// In both cases we want to sum up the heap sizes of all isolate groups.
 Future<List<String>> getGroupIds(vm_service.VmService vmService) async {
   final groupIds = <String>{};
   final vm = await vmService.getVM();
diff --git a/benchmarks/IsolateSpawnMemory/dart2/IsolateSpawnMemory.dart b/benchmarks/IsolateSpawnMemory/dart2/IsolateSpawnMemory.dart
index 115e705..28fee38 100644
--- a/benchmarks/IsolateSpawnMemory/dart2/IsolateSpawnMemory.dart
+++ b/benchmarks/IsolateSpawnMemory/dart2/IsolateSpawnMemory.dart
@@ -160,16 +160,6 @@
 }
 
 // Returns the set of isolate groups for which we should count the heap usage.
-//
-// We have two cases
-//
-//   a) --enable-isolate-groups: All isolates will be within the same isolate
-//   group.
-//
-//   b) --no-enable-isolate-groups: All isolates will be within their own,
-//   separate isolate group.
-//
-// In both cases we want to sum up the heap sizes of all isolate groups.
 Future<List<String>> getGroupIds(vm_service.VmService vmService) async {
   final groupIds = <String>{};
   final vm = await vmService.getVM();
diff --git a/benchmarks/NativeCall/dart/NativeCall.dart b/benchmarks/NativeCall/dart/NativeCall.dart
new file mode 100644
index 0000000..c453038
--- /dev/null
+++ b/benchmarks/NativeCall/dart/NativeCall.dart
@@ -0,0 +1,277 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// These micro benchmarks track the speed of native calls.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+import 'dlopen_helper.dart';
+
+// Number of benchmark iterations per function.
+const N = 1000;
+
+// The native library that holds all the native functions being called.
+final nativeFunctionsLib = dlopenPlatformSpecific('native_functions',
+    path: Platform.script.resolve('../native/out/').path);
+
+final getRootLibraryUrl = nativeFunctionsLib
+    .lookupFunction<Handle Function(), Object Function()>('GetRootLibraryUrl');
+
+final setNativeResolverForTest = nativeFunctionsLib.lookupFunction<
+    Void Function(Handle), void Function(Object)>('SetNativeResolverForTest');
+
+//
+// Benchmark fixtures.
+//
+
+abstract class NativeCallBenchmarkBase extends BenchmarkBase {
+  NativeCallBenchmarkBase(String name) : super(name);
+
+  void expectEquals(actual, expected) {
+    if (actual != expected) {
+      throw Exception('$name: Unexpected result: $actual, expected $expected');
+    }
+  }
+
+  void expectApprox(actual, expected) {
+    if (0.999 * expected > actual || actual > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $actual, expected $expected');
+    }
+  }
+
+  void expectIdentical(actual, expected) {
+    if (!identical(actual, expected)) {
+      throw Exception('$name: Unexpected result: $actual, expected $expected');
+    }
+  }
+}
+
+class Uint8x01 extends NativeCallBenchmarkBase {
+  Uint8x01() : super('NativeCall.Uint8x01');
+
+  @pragma('vm:external-name', 'Function1Uint8')
+  external static int f(int a);
+
+  @override
+  void run() {
+    int x = 0;
+    for (int i = 0; i < N; i++) {
+      x += f(17);
+    }
+    expectEquals(x, N * 17 + N * 42);
+  }
+}
+
+class Int64x20 extends NativeCallBenchmarkBase {
+  Int64x20() : super('NativeCall.Int64x20');
+
+  @pragma('vm:external-name', 'Function20Int64')
+  external static int f(
+      int a,
+      int b,
+      int c,
+      int d,
+      int e,
+      int f,
+      int g,
+      int h,
+      int i,
+      int j,
+      int k,
+      int l,
+      int m,
+      int n,
+      int o,
+      int p,
+      int q,
+      int r,
+      int s,
+      int t);
+
+  @override
+  void run() {
+    int x = 0;
+    for (int i = 0; i < N; i++) {
+      x += f(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i);
+    }
+    expectEquals(x, N * (N - 1) * 20 / 2);
+  }
+}
+
+class Doublex01 extends NativeCallBenchmarkBase {
+  Doublex01() : super('NativeCall.Doublex01');
+
+  @pragma('vm:external-name', 'Function1Double')
+  external static double f(double a);
+
+  @override
+  void run() {
+    double x = 0.0;
+    for (int i = 0; i < N; i++) {
+      x += f(17.0);
+    }
+    final double expected = N * (17.0 + 42.0);
+    expectApprox(x, expected);
+  }
+}
+
+class Doublex20 extends NativeCallBenchmarkBase {
+  Doublex20() : super('NativeCall.Doublex20');
+
+  @pragma('vm:external-name', 'Function20Double')
+  external static double f(
+      double a,
+      double b,
+      double c,
+      double d,
+      double e,
+      double f,
+      double g,
+      double h,
+      double i,
+      double j,
+      double k,
+      double l,
+      double m,
+      double n,
+      double o,
+      double p,
+      double q,
+      double r,
+      double s,
+      double t);
+
+  @override
+  void run() {
+    double x = 0;
+    for (int i = 0; i < N; i++) {
+      x += f(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
+          13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0);
+    }
+    final double expected = N *
+        (1.0 +
+            2.0 +
+            3.0 +
+            4.0 +
+            5.0 +
+            6.0 +
+            7.0 +
+            8.0 +
+            9.0 +
+            10.0 +
+            11.0 +
+            12.0 +
+            13.0 +
+            14.0 +
+            15.0 +
+            16.0 +
+            17.0 +
+            18.0 +
+            19.0 +
+            20.0);
+    expectApprox(x, expected);
+  }
+}
+
+class MyClass {
+  int a;
+  MyClass(this.a);
+}
+
+class Handlex01 extends NativeCallBenchmarkBase {
+  Handlex01() : super('NativeCall.Handlex01');
+
+  @pragma('vm:external-name', 'Function1Handle')
+  external static Object f(Object a);
+
+  @override
+  void run() {
+    final p1 = MyClass(123);
+    Object x = p1;
+    for (int i = 0; i < N; i++) {
+      x = f(x);
+    }
+    expectIdentical(x, p1);
+  }
+}
+
+class Handlex20 extends NativeCallBenchmarkBase {
+  Handlex20() : super('NativeCall.Handlex20');
+
+  @pragma('vm:external-name', 'Function20Handle')
+  external static Object f(
+      Object a,
+      Object b,
+      Object c,
+      Object d,
+      Object e,
+      Object f,
+      Object g,
+      Object h,
+      Object i,
+      Object j,
+      Object k,
+      Object l,
+      Object m,
+      Object n,
+      Object o,
+      Object p,
+      Object q,
+      Object r,
+      Object s,
+      Object t);
+
+  @override
+  void run() {
+    final p1 = MyClass(123);
+    final p2 = MyClass(2);
+    final p3 = MyClass(3);
+    final p4 = MyClass(4);
+    final p5 = MyClass(5);
+    final p6 = MyClass(6);
+    final p7 = MyClass(7);
+    final p8 = MyClass(8);
+    final p9 = MyClass(9);
+    final p10 = MyClass(10);
+    final p11 = MyClass(11);
+    final p12 = MyClass(12);
+    final p13 = MyClass(13);
+    final p14 = MyClass(14);
+    final p15 = MyClass(15);
+    final p16 = MyClass(16);
+    final p17 = MyClass(17);
+    final p18 = MyClass(18);
+    final p19 = MyClass(19);
+    final p20 = MyClass(20);
+    Object x = p1;
+    for (int i = 0; i < N; i++) {
+      x = f(x, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15,
+          p16, p17, p18, p19, p20);
+    }
+    expectIdentical(x, p1);
+  }
+}
+
+//
+// Main driver.
+//
+
+void main() {
+  setNativeResolverForTest(getRootLibraryUrl());
+
+  final benchmarks = [
+    () => Uint8x01(),
+    () => Int64x20(),
+    () => Doublex01(),
+    () => Doublex20(),
+    () => Handlex01(),
+    () => Handlex20(),
+  ];
+  for (final benchmark in benchmarks) {
+    benchmark().report();
+  }
+}
diff --git a/benchmarks/NativeCall/dart/dlopen_helper.dart b/benchmarks/NativeCall/dart/dlopen_helper.dart
new file mode 100644
index 0000000..7e6129e
--- /dev/null
+++ b/benchmarks/NativeCall/dart/dlopen_helper.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'dart:io';
+
+const arm = 'arm';
+const arm64 = 'arm64';
+const ia32 = 'ia32';
+const x64 = 'x64';
+
+// https://stackoverflow.com/questions/45125516/possible-values-for-uname-m
+final _unames = {
+  'arm': arm,
+  'aarch64_be': arm64,
+  'aarch64': arm64,
+  'armv8b': arm64,
+  'armv8l': arm64,
+  'i386': ia32,
+  'i686': ia32,
+  'x86_64': x64,
+};
+
+String _checkRunningMode(String architecture) {
+  // Check if we're running in 32bit mode.
+  final int pointerSize = sizeOf<IntPtr>();
+  if (pointerSize == 4 && architecture == x64) return ia32;
+  if (pointerSize == 4 && architecture == arm64) return arm;
+
+  return architecture;
+}
+
+String _architecture() {
+  final String uname = Process.runSync('uname', ['-m']).stdout.trim();
+  final String? architecture = _unames[uname];
+  if (architecture == null) {
+    throw Exception('Unrecognized architecture: "$uname"');
+  }
+
+  // Check if we're running in 32bit mode.
+  return _checkRunningMode(architecture);
+}
+
+String _platformPath(String name, String path) {
+  if (Platform.isMacOS || Platform.isIOS) {
+    return '${path}mac/${_architecture()}/lib$name.dylib';
+  }
+
+  if (Platform.isWindows) {
+    return '${path}win/${_checkRunningMode(x64)}/$name.dll';
+  }
+
+  // Unknown platforms default to Unix implementation.
+  return '${path}linux/${_architecture()}/lib$name.so';
+}
+
+DynamicLibrary dlopenPlatformSpecific(String name, {String path = ''}) {
+  final String fullPath = _platformPath(name, path);
+  return DynamicLibrary.open(fullPath);
+}
diff --git a/benchmarks/NativeCall/dart2/NativeCall.dart b/benchmarks/NativeCall/dart2/NativeCall.dart
new file mode 100644
index 0000000..c2dbf13
--- /dev/null
+++ b/benchmarks/NativeCall/dart2/NativeCall.dart
@@ -0,0 +1,279 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// These micro benchmarks track the speed of native calls.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+import 'dlopen_helper.dart';
+
+// Number of benchmark iterations per function.
+const N = 1000;
+
+// The native library that holds all the native functions being called.
+final nativeFunctionsLib = dlopenPlatformSpecific('native_functions',
+    path: Platform.script.resolve('../native/out/').path);
+
+final getRootLibraryUrl = nativeFunctionsLib
+    .lookupFunction<Handle Function(), Object Function()>('GetRootLibraryUrl');
+
+final setNativeResolverForTest = nativeFunctionsLib.lookupFunction<
+    Void Function(Handle), void Function(Object)>('SetNativeResolverForTest');
+
+//
+// Benchmark fixtures.
+//
+
+abstract class NativeCallBenchmarkBase extends BenchmarkBase {
+  NativeCallBenchmarkBase(String name) : super(name);
+
+  void expectEquals(actual, expected) {
+    if (actual != expected) {
+      throw Exception('$name: Unexpected result: $actual, expected $expected');
+    }
+  }
+
+  void expectApprox(actual, expected) {
+    if (0.999 * expected > actual || actual > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $actual, expected $expected');
+    }
+  }
+
+  void expectIdentical(actual, expected) {
+    if (!identical(actual, expected)) {
+      throw Exception('$name: Unexpected result: $actual, expected $expected');
+    }
+  }
+}
+
+class Uint8x01 extends NativeCallBenchmarkBase {
+  Uint8x01() : super('NativeCall.Uint8x01');
+
+  @pragma('vm:external-name', 'Function1Uint8')
+  external static int f(int a);
+
+  @override
+  void run() {
+    int x = 0;
+    for (int i = 0; i < N; i++) {
+      x += f(17);
+    }
+    expectEquals(x, N * 17 + N * 42);
+  }
+}
+
+class Int64x20 extends NativeCallBenchmarkBase {
+  Int64x20() : super('NativeCall.Int64x20');
+
+  @pragma('vm:external-name', 'Function20Int64')
+  external static int f(
+      int a,
+      int b,
+      int c,
+      int d,
+      int e,
+      int f,
+      int g,
+      int h,
+      int i,
+      int j,
+      int k,
+      int l,
+      int m,
+      int n,
+      int o,
+      int p,
+      int q,
+      int r,
+      int s,
+      int t);
+
+  @override
+  void run() {
+    int x = 0;
+    for (int i = 0; i < N; i++) {
+      x += f(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i);
+    }
+    expectEquals(x, N * (N - 1) * 20 / 2);
+  }
+}
+
+class Doublex01 extends NativeCallBenchmarkBase {
+  Doublex01() : super('NativeCall.Doublex01');
+
+  @pragma('vm:external-name', 'Function1Double')
+  external static double f(double a);
+
+  @override
+  void run() {
+    double x = 0.0;
+    for (int i = 0; i < N; i++) {
+      x += f(17.0);
+    }
+    final double expected = N * (17.0 + 42.0);
+    expectApprox(x, expected);
+  }
+}
+
+class Doublex20 extends NativeCallBenchmarkBase {
+  Doublex20() : super('NativeCall.Doublex20');
+
+  @pragma('vm:external-name', 'Function20Double')
+  external static double f(
+      double a,
+      double b,
+      double c,
+      double d,
+      double e,
+      double f,
+      double g,
+      double h,
+      double i,
+      double j,
+      double k,
+      double l,
+      double m,
+      double n,
+      double o,
+      double p,
+      double q,
+      double r,
+      double s,
+      double t);
+
+  @override
+  void run() {
+    double x = 0;
+    for (int i = 0; i < N; i++) {
+      x += f(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
+          13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0);
+    }
+    final double expected = N *
+        (1.0 +
+            2.0 +
+            3.0 +
+            4.0 +
+            5.0 +
+            6.0 +
+            7.0 +
+            8.0 +
+            9.0 +
+            10.0 +
+            11.0 +
+            12.0 +
+            13.0 +
+            14.0 +
+            15.0 +
+            16.0 +
+            17.0 +
+            18.0 +
+            19.0 +
+            20.0);
+    expectApprox(x, expected);
+  }
+}
+
+class MyClass {
+  int a;
+  MyClass(this.a);
+}
+
+class Handlex01 extends NativeCallBenchmarkBase {
+  Handlex01() : super('NativeCall.Handlex01');
+
+  @pragma('vm:external-name', 'Function1Handle')
+  external static Object f(Object a);
+
+  @override
+  void run() {
+    final p1 = MyClass(123);
+    Object x = p1;
+    for (int i = 0; i < N; i++) {
+      x = f(x);
+    }
+    expectIdentical(x, p1);
+  }
+}
+
+class Handlex20 extends NativeCallBenchmarkBase {
+  Handlex20() : super('NativeCall.Handlex20');
+
+  @pragma('vm:external-name', 'Function20Handle')
+  external static Object f(
+      Object a,
+      Object b,
+      Object c,
+      Object d,
+      Object e,
+      Object f,
+      Object g,
+      Object h,
+      Object i,
+      Object j,
+      Object k,
+      Object l,
+      Object m,
+      Object n,
+      Object o,
+      Object p,
+      Object q,
+      Object r,
+      Object s,
+      Object t);
+
+  @override
+  void run() {
+    final p1 = MyClass(123);
+    final p2 = MyClass(2);
+    final p3 = MyClass(3);
+    final p4 = MyClass(4);
+    final p5 = MyClass(5);
+    final p6 = MyClass(6);
+    final p7 = MyClass(7);
+    final p8 = MyClass(8);
+    final p9 = MyClass(9);
+    final p10 = MyClass(10);
+    final p11 = MyClass(11);
+    final p12 = MyClass(12);
+    final p13 = MyClass(13);
+    final p14 = MyClass(14);
+    final p15 = MyClass(15);
+    final p16 = MyClass(16);
+    final p17 = MyClass(17);
+    final p18 = MyClass(18);
+    final p19 = MyClass(19);
+    final p20 = MyClass(20);
+    Object x = p1;
+    for (int i = 0; i < N; i++) {
+      x = f(x, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15,
+          p16, p17, p18, p19, p20);
+    }
+    expectIdentical(x, p1);
+  }
+}
+
+//
+// Main driver.
+//
+
+void main() {
+  setNativeResolverForTest(getRootLibraryUrl());
+
+  final benchmarks = [
+    () => Uint8x01(),
+    () => Int64x20(),
+    () => Doublex01(),
+    () => Doublex20(),
+    () => Handlex01(),
+    () => Handlex20(),
+  ];
+  for (final benchmark in benchmarks) {
+    benchmark().report();
+  }
+}
diff --git a/benchmarks/NativeCall/dart2/dlopen_helper.dart b/benchmarks/NativeCall/dart2/dlopen_helper.dart
new file mode 100644
index 0000000..e6e3bfa
--- /dev/null
+++ b/benchmarks/NativeCall/dart2/dlopen_helper.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+import 'dart:ffi';
+import 'dart:io';
+
+const arm = 'arm';
+const arm64 = 'arm64';
+const ia32 = 'ia32';
+const x64 = 'x64';
+
+// https://stackoverflow.com/questions/45125516/possible-values-for-uname-m
+final _unames = {
+  'arm': arm,
+  'aarch64_be': arm64,
+  'aarch64': arm64,
+  'armv8b': arm64,
+  'armv8l': arm64,
+  'i386': ia32,
+  'i686': ia32,
+  'x86_64': x64,
+};
+
+String _checkRunningMode(String architecture) {
+  // Check if we're running in 32bit mode.
+  final int pointerSize = sizeOf<IntPtr>();
+  if (pointerSize == 4 && architecture == x64) return ia32;
+  if (pointerSize == 4 && architecture == arm64) return arm;
+
+  return architecture;
+}
+
+String _architecture() {
+  final String uname = Process.runSync('uname', ['-m']).stdout.trim();
+  final String architecture = _unames[uname];
+  if (architecture == null) {
+    throw Exception('Unrecognized architecture: "$uname"');
+  }
+
+  // Check if we're running in 32bit mode.
+  return _checkRunningMode(architecture);
+}
+
+String _platformPath(String name, {String path = ''}) {
+  if (Platform.isMacOS || Platform.isIOS) {
+    return '${path}mac/${_architecture()}/lib$name.dylib';
+  }
+
+  if (Platform.isWindows) {
+    return '${path}win/${_checkRunningMode(x64)}/$name.dll';
+  }
+
+  // Unknown platforms default to Unix implementation.
+  return '${path}linux/${_architecture()}/lib$name.so';
+}
+
+DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
+  final String fullPath = _platformPath(name, path: path);
+  return DynamicLibrary.open(fullPath);
+}
diff --git a/benchmarks/NativeCall/native/.gitignore b/benchmarks/NativeCall/native/.gitignore
new file mode 100644
index 0000000..e778c6f
--- /dev/null
+++ b/benchmarks/NativeCall/native/.gitignore
@@ -0,0 +1,5 @@
+# Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+out/
diff --git a/benchmarks/NativeCall/native/Makefile b/benchmarks/NativeCall/native/Makefile
new file mode 100644
index 0000000..9a2eb44
--- /dev/null
+++ b/benchmarks/NativeCall/native/Makefile
@@ -0,0 +1,57 @@
+# Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# TODO(37531): Remove this makefile and build with sdk instead when
+# benchmark runner gets support for that.
+
+CC=gcc
+CCARM=arm-linux-gnueabihf-gcc
+CCARM64=aarch64-linux-gnu-gcc
+CFLAGS=-Wall -g -O -fPIC -I../../../runtime/
+
+.PHONY: all clean
+
+all: out/linux/x64/libnative_functions.so out/linux/ia32/libnative_functions.so out/linux/arm64/libnative_functions.so out/linux/arm/libnative_functions.so
+
+cipd:
+	cipd create -name dart/benchmarks/nativecall -in out -install-mode copy
+
+clean:
+	rm -rf *.o *.so out
+
+out/linux/x64:
+	mkdir -p out/linux/x64
+
+out/linux/x64/native_functions.o: native_functions.c | out/linux/x64
+	$(CC) $(CFLAGS) -c -o $@ native_functions.c
+
+out/linux/x64/libnative_functions.so: out/linux/x64/native_functions.o
+	$(CC) $(CFLAGS) -s -shared -o $@ out/linux/x64/native_functions.o
+
+out/linux/ia32:
+	mkdir -p out/linux/ia32
+
+out/linux/ia32/native_functions.o: native_functions.c | out/linux/ia32
+	$(CC) $(CFLAGS) -m32 -c -o $@ native_functions.c
+
+out/linux/ia32/libnative_functions.so: out/linux/ia32/native_functions.o
+	$(CC) $(CFLAGS) -m32 -s -shared -o $@ out/linux/ia32/native_functions.o
+
+out/linux/arm64:
+	mkdir -p out/linux/arm64
+
+out/linux/arm64/native_functions.o: native_functions.c | out/linux/arm64
+	$(CCARM64) $(CFLAGS) -c -o $@ native_functions.c
+
+out/linux/arm64/libnative_functions.so: out/linux/arm64/native_functions.o
+	$(CCARM64) $(CFLAGS) -s -shared -o $@ out/linux/arm64/native_functions.o
+
+out/linux/arm:
+	mkdir -p out/linux/arm
+
+out/linux/arm/native_functions.o: native_functions.c | out/linux/arm
+	$(CCARM) $(CFLAGS) -c -o $@ native_functions.c
+
+out/linux/arm/libnative_functions.so: out/linux/arm/native_functions.o
+	$(CCARM) $(CFLAGS) -s -shared -o $@ out/linux/arm/native_functions.o
diff --git a/benchmarks/NativeCall/native/native_functions.c b/benchmarks/NativeCall/native/native_functions.c
new file mode 100644
index 0000000..c19251d
--- /dev/null
+++ b/benchmarks/NativeCall/native/native_functions.c
@@ -0,0 +1,119 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// TODO(dartbug.com/40579): This requires static linking to either link
+// dart.exe or dart_precompiled_runtime.exe on Windows.
+// The sample currently fails on Windows in AOT mode.
+#include "include/dart_api.h"
+
+#define ENSURE(X)                                                              \
+  if (!(X)) {                                                                  \
+    fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, "Check failed: " #X);   \
+    exit(1);                                                                   \
+  }
+
+#define ENSURE_VALID(X) ENSURE(!Dart_IsError(X))
+
+//
+// Functions under test.
+//
+
+void Function1Uint8(Dart_NativeArguments args) {
+  int64_t arg = 0;
+  Dart_GetNativeIntegerArgument(args, /*index=*/0, &arg);
+  Dart_SetIntegerReturnValue(args, arg + 42);
+}
+
+void Function20Int64(Dart_NativeArguments args) {
+  int64_t arg = 0;
+  int64_t result = 0;
+  for (int i = 0; i < 20; i++) {
+    Dart_GetNativeIntegerArgument(args, /*index=*/i, &arg);
+    result += arg;
+  }
+  Dart_SetIntegerReturnValue(args, result);
+}
+
+void Function1Double(Dart_NativeArguments args) {
+  double arg = 0.0;
+  Dart_GetNativeDoubleArgument(args, /*index=*/0, &arg);
+  Dart_SetDoubleReturnValue(args, arg + 42.0);
+}
+
+void Function20Double(Dart_NativeArguments args) {
+  double arg = 0;
+  double result = 0;
+  for (int i = 0; i < 20; i++) {
+    Dart_GetNativeDoubleArgument(args, /*index=*/i, &arg);
+    result += arg;
+  }
+  Dart_SetDoubleReturnValue(args, result);
+}
+
+void Function1Handle(Dart_NativeArguments args) {
+  Dart_Handle arg = Dart_GetNativeArgument(args, /*index=*/0);
+  Dart_SetReturnValue(args, arg);
+}
+
+void Function20Handle(Dart_NativeArguments args) {
+  Dart_Handle arg = Dart_GetNativeArgument(args, /*index=*/0);
+  Dart_SetReturnValue(args, arg);
+}
+
+//
+// Test helpers.
+//
+
+DART_EXPORT Dart_Handle GetRootLibraryUrl() {
+  Dart_Handle root_lib = Dart_RootLibrary();
+  Dart_Handle lib_url = Dart_LibraryUrl(root_lib);
+  ENSURE_VALID(lib_url);
+  return lib_url;
+}
+
+Dart_NativeFunction NativeEntryResolver(Dart_Handle name,
+                                        int num_of_arguments,
+                                        bool* auto_setup_scope) {
+  ENSURE(Dart_IsString(name));
+
+  ENSURE(auto_setup_scope != NULL);
+  *auto_setup_scope = true;
+
+  const char* name_str = NULL;
+  ENSURE_VALID(Dart_StringToCString(name, &name_str));
+
+  if (strcmp(name_str, "Function1Uint8") == 0 && num_of_arguments == 1) {
+    return &Function1Uint8;
+  } else if (strcmp(name_str, "Function20Int64") == 0 &&
+             num_of_arguments == 20) {
+    return &Function20Int64;
+  } else if (strcmp(name_str, "Function1Double") == 0 &&
+             num_of_arguments == 1) {
+    return &Function1Double;
+  } else if (strcmp(name_str, "Function20Double") == 0 &&
+             num_of_arguments == 20) {
+    return &Function20Double;
+  } else if (strcmp(name_str, "Function1Handle") == 0 &&
+             num_of_arguments == 1) {
+    return &Function1Handle;
+  } else if (strcmp(name_str, "Function20Handle") == 0 &&
+             num_of_arguments == 20) {
+    return &Function20Handle;
+  }
+
+  // Unreachable in benchmark.
+  ENSURE(false);
+}
+
+DART_EXPORT void SetNativeResolverForTest(Dart_Handle url) {
+  Dart_Handle library = Dart_LookupLibrary(url);
+  ENSURE_VALID(library);
+  Dart_Handle result =
+      Dart_SetNativeResolver(library, &NativeEntryResolver, NULL);
+  ENSURE_VALID(result);
+}
diff --git a/build/mac/find_sdk.py b/build/mac/find_sdk.py
index d2bf424..e28244a 100755
--- a/build/mac/find_sdk.py
+++ b/build/mac/find_sdk.py
@@ -96,19 +96,16 @@
     if job.returncode != 0:
         print(out, file=sys.stderr)
         print(err, file=sys.stderr)
-        raise Exception((
-            'Error %d running xcode-select, you might have to run '
-            '|sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer| '
-            'if you are using Xcode 4.') % job.returncode)
-    # The Developer folder moved in Xcode 4.3.
-    xcode43_sdk_path = os.path.join(out.rstrip(),
-                                    'Platforms/MacOSX.platform/Developer/SDKs')
-    if os.path.isdir(xcode43_sdk_path):
-        sdk_dir = xcode43_sdk_path
-    else:
-        sdk_dir = os.path.join(out.rstrip(), 'SDKs')
+        raise Exception('Error %d running xcode-select' % job.returncode)
+    sdk_dir = os.path.join(out.rstrip(),
+                           'Platforms/MacOSX.platform/Developer/SDKs')
+    if not os.path.isdir(sdk_dir):
+        raise Exception(
+            'Install Xcode, launch it, accept the license ' +
+            'agreement, and run `sudo xcode-select -s /path/to/Xcode.app` ' +
+            'to continue.')
     sdks = [
-        re.findall('^MacOSX(1[01]\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)
+        re.findall('^MacOSX(\d+\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)
     ]
     sdks = [s[0] for s in sdks if s]  # [['10.5'], ['10.6']] => ['10.5', '10.6']
     sdks = [
diff --git a/docs/process/breaking-changes.md b/docs/process/breaking-changes.md
index 64a0df4..4ea8bda 100644
--- a/docs/process/breaking-changes.md
+++ b/docs/process/breaking-changes.md
@@ -53,7 +53,8 @@
 
 ### Step 1: Announcement
 
-* Create an issue in the Dart SDK issue tracker labelled
+* Create an issue in the
+  [Dart SDK issue tracker](https://github.com/dart-lang/sdk/issues) labelled
   `breaking-change-request` containing the following:
 
   * The intended change in behavior.
@@ -64,8 +65,6 @@
 
   * Clear steps for mitigating the change.
 
-[TODO: Link to an issue template for this]
-
 * Email Dart Announce (`announce@dartlang.org`):
 
   * Subject: 'Breaking change [bug ID]: [short summary]'
@@ -77,7 +76,7 @@
   * A request that developers may leave comments in the linked issue, if this
     breaking change poses a severe problem.
 
-Once you have sent the announce email, please let @devoncarew know in order
+Once you have sent the announce email, please let devoncarew@ know in order
 to start the review and approval process.
 
 ### Step 2: Approval
@@ -119,7 +118,7 @@
   * The impact of the change was significantly larger than described in the
     breaking change announcement
 
-, then they may file a 'request for roll-back' using the following steps:
+Then they may file a 'request for roll-back' using the following steps:
 
 * Create an issue in the Dart SDK issue tracker labelled
   `roll-back-request` containing the following:
@@ -132,8 +131,6 @@
   * A link to the program that was affected, or another program that illustrated
     the same effect.
 
-[TODO: Link to an issue template for this]
-
 Upon receiving such an issue the Dart SDK team will either:
 
   * Roll-back the change, or
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 5e5e650..7cfb915 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -2768,6 +2768,16 @@
     problemMessage: r"""An enum declaration can't be empty.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeEnumDeclaresFactory = messageEnumDeclaresFactory;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageEnumDeclaresFactory = const MessageCode(
+    "EnumDeclaresFactory",
+    problemMessage: r"""Enums can't declare factory constructors.""",
+    correctionMessage:
+        r"""Try removing the factory constructor declaration.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeEnumInClass = messageEnumInClass;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -5661,6 +5671,17 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeInternalProblemOmittedTypeNameInConstructorReference =
+    messageInternalProblemOmittedTypeNameInConstructorReference;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageInternalProblemOmittedTypeNameInConstructorReference =
+    const MessageCode("InternalProblemOmittedTypeNameInConstructorReference",
+        severity: Severity.internalProblem,
+        problemMessage:
+            r"""Unsupported omission of the type name in a constructor reference outside of an enum element declaration.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeInternalProblemPreviousTokenNotFound =
     messageInternalProblemPreviousTokenNotFound;
 
@@ -9387,7 +9408,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageSuperInitializerNotLast = const MessageCode(
     "SuperInitializerNotLast",
-    analyzerCodes: <String>["INVALID_SUPER_INVOCATION"],
+    analyzerCodes: <String>["SUPER_INVOCATION_NOT_LAST"],
     problemMessage: r"""Can't have initializers after 'super'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/declaration_kind.dart b/pkg/_fe_analyzer_shared/lib/src/parser/declaration_kind.dart
index 7037020..1efc9da 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/declaration_kind.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/declaration_kind.dart
@@ -14,4 +14,7 @@
 
   /// An extension declaration.
   Extension,
+
+  /// An enum.
+  Enum,
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index 042507d..c60aa80 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -636,8 +636,66 @@
   }
 
   @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
-    listener?.endEnum(enumKeyword, leftBrace, count);
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
+    listener?.endEnum(enumKeyword, leftBrace, memberCount);
+  }
+
+  @override
+  void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    listener?.endEnumConstructor(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
+  }
+
+  @override
+  void handleEnumElement(Token beginToken) {
+    listener?.handleEnumElement(beginToken);
+  }
+
+  @override
+  void handleEnumElements(Token elementsEndToken, int elementsCount) {
+    listener?.handleEnumElements(elementsEndToken, elementsCount);
+  }
+
+  @override
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    listener?.handleEnumHeader(enumKeyword, leftBrace);
+  }
+
+  @override
+  void endEnumFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    listener?.endEnumFactoryMethod(beginToken, factoryKeyword, endToken);
+  }
+
+  @override
+  void endEnumFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    listener?.endClassFields(
+        abstractToken,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        count,
+        beginToken,
+        endToken);
+  }
+
+  @override
+  void endEnumMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    listener?.endEnumMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
   }
 
   @override
@@ -728,14 +786,22 @@
   @override
   void endFormalParameter(
       Token? thisKeyword,
-      Token? periodAfterThis,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
       Token nameToken,
       Token? initializerStart,
       Token? initializerEnd,
       FormalParameterKind kind,
       MemberKind memberKind) {
-    listener?.endFormalParameter(thisKeyword, periodAfterThis, nameToken,
-        initializerStart, initializerEnd, kind, memberKind);
+    listener?.endFormalParameter(
+        thisKeyword,
+        superKeyword,
+        periodAfterThisOrSuper,
+        nameToken,
+        initializerStart,
+        initializerEnd,
+        kind,
+        memberKind);
   }
 
   @override
@@ -1165,9 +1231,13 @@
   }
 
   @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
-    listener?.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
+  void handleEnumNoWithClause() {
+    listener?.handleEnumNoWithClause();
+  }
+
+  @override
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
+    listener?.handleImplements(implementsKeyword, interfacesCount);
   }
 
   @override
@@ -1183,6 +1253,11 @@
   }
 
   @override
+  void handleEnumWithClause(Token withKeyword) {
+    listener?.handleEnumWithClause(withKeyword);
+  }
+
+  @override
   void handleCommentReference(
       Token? newKeyword, Token? prefix, Token? period, Token token) {
     listener?.handleCommentReference(newKeyword, prefix, period, token);
@@ -1540,6 +1615,11 @@
   }
 
   @override
+  void handleNoTypeNameInConstructorReference(Token token) {
+    listener?.handleNoTypeNameInConstructorReference(token);
+  }
+
+  @override
   void handleNoTypeVariables(Token token) {
     listener?.handleNoTypeVariables(token);
   }
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 63a247f..332225f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -137,12 +137,11 @@
     logEvent("ClassExtends");
   }
 
-  /// Handle an implements clause in a class or mixin declaration.
+  /// Handle an implements clause in a class, mixin or enum declaration.
   /// Substructures:
   /// - implemented types
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
-    logEvent("ClassImplements");
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
+    logEvent("Implements");
   }
 
   /// Handle a show clause in an extension declaration.
@@ -306,12 +305,55 @@
   void beginEnum(Token enumKeyword) {}
 
   /// Handle the end of an enum declaration.  Substructures:
+  /// - [memberCount] times:
+  ///   - Enum member
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
+    logEvent("Enum");
+  }
+
+  /// Handle the end of an enum constructor declaration.  Substructures:
+  /// - metadata
+  /// - return type
+  /// - method name (identifier, possibly qualified)
+  /// - type variables
+  /// - formal parameters
+  /// - initializers
+  /// - async marker
+  /// - body
+  void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    // TODO(danrubel): push implementation into subclasses
+    endClassMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
+  }
+
+  /// Handle the enum elements. Substructures:
+  /// - [elementsCount] times:
+  ///   - Enum element
+  void handleEnumElements(Token elementsEndToken, int elementsCount) {
+    logEvent("EnumElements");
+  }
+
+  /// Handle the header of an enum declaration.  Substructures:
   /// - Metadata
   /// - Enum name (identifier)
-  /// - [count] times:
-  ///   - Enum value (identifier)
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
-    logEvent("Enum");
+  /// - type variables
+  /// - with clause
+  /// - implemented types
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    logEvent("EnumHeader");
+  }
+
+  /// Handle the enum element. Substructures:
+  /// - Metadata
+  /// - Enum value (identifier)
+  void handleEnumElement(Token beginToken) {
+    logEvent("EnumElement");
+  }
+
+  void endEnumFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    endClassFactoryMethod(beginToken, factoryKeyword, endToken);
   }
 
   void beginExport(Token token) {}
@@ -363,7 +405,8 @@
 
   void endFormalParameter(
       Token? thisKeyword,
-      Token? periodAfterThis,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
       Token nameToken,
       Token? initializerStart,
       Token? initializerEnd,
@@ -447,6 +490,42 @@
         lateToken, varFinalOrConst, count, beginToken, endToken);
   }
 
+  /// Handle the end of an enum field declaration.  Substructures:
+  /// - Metadata
+  /// - Modifiers
+  /// - Type
+  /// - Variable declarations (count times)
+  ///
+  /// Started by [beginFields].
+  void endEnumFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    endClassFields(abstractToken, externalToken, staticToken, covariantToken,
+        lateToken, varFinalOrConst, count, beginToken, endToken);
+  }
+
+  /// Handle the end of an enum method declaration.  Substructures:
+  /// - metadata
+  /// - return type
+  /// - method name (identifier, possibly qualified)
+  /// - type variables
+  /// - formal parameters
+  /// - initializers
+  /// - async marker
+  /// - body
+  void endEnumMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    endClassMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
+  }
+
   /// Marks that the grammar term `forInitializerStatement` has been parsed and
   /// it was an empty statement.
   void handleForInitializerEmptyStatement(Token token) {
@@ -608,18 +687,33 @@
     logEvent("FunctionTypeAlias");
   }
 
-  /// Handle the end of a with clause (e.g. "with B, C").
+  /// Handle the end of a class with clause (e.g. "with B, C").
   /// Substructures:
   /// - mixin types (TypeList)
   void handleClassWithClause(Token withKeyword) {
     logEvent("ClassWithClause");
   }
 
-  /// Handle the absence of a with clause.
+  /// Handle the absence of a class with clause.
   void handleClassNoWithClause() {
     logEvent("ClassNoWithClause");
   }
 
+  /// Handle the end of an enum with clause (e.g. "with B, C").
+  /// Substructures:
+  /// - mixin types (TypeList)
+  ///
+  /// This method is separated from [handleClassWithClause] to simplify
+  /// handling the different objects in the context.
+  void handleEnumWithClause(Token withKeyword) {
+    logEvent("EnumWithClause");
+  }
+
+  /// Handle the absence of an enum with clause.
+  void handleEnumNoWithClause() {
+    logEvent("EnumNoWithClause");
+  }
+
   /// Handle the beginning of a named mixin application.
   /// [beginToken] may be the same as [name], or may point to modifiers
   /// (or extraneous modifiers in the case of recovery) preceding [name].
@@ -1566,6 +1660,10 @@
     logEvent("NoConstructorReferenceContinuationAfterTypeArguments");
   }
 
+  void handleNoTypeNameInConstructorReference(Token token) {
+    logEvent("NoTypeNameInConstructorReference");
+  }
+
   void handleNoType(Token lastConsumed) {
     logEvent("NoType");
   }
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index cb1ef21..fac9391 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -1286,7 +1286,7 @@
     return token;
   }
 
-  Token parseWithClauseOpt(Token token) {
+  Token parseClassWithClauseOpt(Token token) {
     // <mixins> ::= with <typeNotVoidList>
     Token withKeyword = token.next!;
     if (optional('with', withKeyword)) {
@@ -1298,6 +1298,18 @@
     return token;
   }
 
+  Token parseEnumWithClauseOpt(Token token) {
+    // <mixins> ::= with <typeNotVoidList>
+    Token withKeyword = token.next!;
+    if (optional('with', withKeyword)) {
+      token = parseTypeList(withKeyword);
+      listener.handleEnumWithClause(withKeyword);
+    } else {
+      listener.handleEnumNoWithClause();
+    }
+    return token;
+  }
+
   /// Parse the formal parameters of a getter (which shouldn't have parameters)
   /// or function or method.
   Token parseGetterOrFormalParameters(
@@ -1612,13 +1624,19 @@
         parameterKind == FormalParameterKind.optionalNamed;
 
     Token? thisKeyword;
-    Token? periodAfterThis;
+    Token? superKeyword;
+    Token? periodAfterThisOrSuper;
     IdentifierContext nameContext =
         IdentifierContext.formalParameterDeclaration;
 
-    if (!inFunctionType && optional('this', next)) {
+    if (!inFunctionType &&
+        (optional('this', next) || optional('super', next))) {
       Token originalToken = token;
-      thisKeyword = token = next;
+      if (optional('this', next)) {
+        thisKeyword = token = next;
+      } else {
+        superKeyword = token = next;
+      }
       next = token.next!;
       if (!optional('.', next)) {
         if (isOneOf(next, okNextValueInFormalParameter)) {
@@ -1626,7 +1644,7 @@
           // later that it's not an allowed identifier.
           token = originalToken;
           next = token.next!;
-          thisKeyword = null;
+          thisKeyword = superKeyword = null;
         } else {
           // Recover from a missing period by inserting one.
           next = rewriteAndRecover(
@@ -1634,13 +1652,13 @@
               codes.templateExpectedButGot.withArguments('.'),
               new SyntheticToken(TokenType.PERIOD, next.charOffset));
           // These 3 lines are duplicated here and below.
-          periodAfterThis = token = next;
+          periodAfterThisOrSuper = token = next;
           next = token.next!;
           nameContext = IdentifierContext.fieldInitializer;
         }
       } else {
         // These 3 lines are duplicated here and above.
-        periodAfterThis = token = next;
+        periodAfterThisOrSuper = token = next;
         next = token.next!;
         nameContext = IdentifierContext.fieldInitializer;
       }
@@ -1711,8 +1729,8 @@
     }
 
     Token nameToken;
-    if (periodAfterThis != null) {
-      token = periodAfterThis;
+    if (periodAfterThisOrSuper != null) {
+      token = periodAfterThisOrSuper;
     }
     next = token.next!;
     if (inFunctionType &&
@@ -1759,8 +1777,15 @@
     } else {
       listener.handleFormalParameterWithoutValue(next);
     }
-    listener.endFormalParameter(thisKeyword, periodAfterThis, nameToken,
-        initializerStart, initializerEnd, parameterKind, memberKind);
+    listener.endFormalParameter(
+        thisKeyword,
+        superKeyword,
+        periodAfterThisOrSuper,
+        nameToken,
+        initializerStart,
+        initializerEnd,
+        parameterKind,
+        memberKind);
     return token;
   }
 
@@ -1917,35 +1942,45 @@
 
   /// ```
   /// enumType:
-  ///   metadata 'enum' id '{' metadata id [',' metadata id]* [','] '}'
-  /// ;
+  ///   metadata 'enum' id typeParameters? mixins? interfaces? '{'
+  ///      enumEntry (',' enumEntry)* (',')? (';'
+  ///      (metadata classMemberDefinition)*
+  ///      )?
+  ///   '}'
+  ///
+  /// enumEntry:
+  ///     metadata id argumentPart?
+  ///   | metadata id typeArguments? '.' id arguments
   /// ```
   Token parseEnum(Token enumKeyword) {
     assert(optional('enum', enumKeyword));
     listener.beginUncategorizedTopLevelDeclaration(enumKeyword);
-    listener.beginEnum(enumKeyword);
     Token token =
         ensureIdentifier(enumKeyword, IdentifierContext.enumDeclaration);
+    String name = token.lexeme;
+    listener.beginEnum(enumKeyword);
+    token = parseEnumHeaderOpt(token, enumKeyword);
     Token leftBrace = token.next!;
-    int count = 0;
+    int elementCount = 0;
+    int memberCount = 0;
     if (optional('{', leftBrace)) {
+      listener.handleEnumHeader(enumKeyword, leftBrace);
       token = leftBrace;
       while (true) {
         Token next = token.next!;
-        if (optional('}', next)) {
+        if (optional('}', next) || optional(';', next)) {
           token = next;
-          if (count == 0) {
+          if (elementCount == 0) {
             reportRecoverableError(token, codes.messageEnumDeclarationEmpty);
           }
           break;
         }
-        token = parseMetadataStar(token);
-        token = ensureIdentifier(token, IdentifierContext.enumValueDeclaration);
+        token = parseEnumElement(token);
         next = token.next!;
-        count++;
+        elementCount++;
         if (optional(',', next)) {
           token = next;
-        } else if (optional('}', next)) {
+        } else if (optional('}', next) || optional(';', next)) {
           token = next;
           break;
         } else {
@@ -1971,14 +2006,51 @@
           }
         }
       }
+      listener.handleEnumElements(token, elementCount);
+      if (optional(';', token)) {
+        while (notEofOrValue('}', token.next!)) {
+          token = parseClassOrMixinOrExtensionOrEnumMemberImpl(
+              token, DeclarationKind.Enum, name);
+          ++memberCount;
+        }
+        token = token.next!;
+        assert(token.isEof || optional('}', token));
+      }
     } else {
       // TODO(danrubel): merge this error message with missing class/mixin body
       leftBrace = ensureBlock(
           token, codes.templateExpectedEnumBody, /* missingBlockName = */ null);
+      listener.handleEnumHeader(enumKeyword, leftBrace);
+      listener.handleEnumElements(token, elementCount);
       token = leftBrace.endGroup!;
     }
     assert(optional('}', token));
-    listener.endEnum(enumKeyword, leftBrace, count);
+    listener.endEnum(enumKeyword, leftBrace, memberCount);
+    return token;
+  }
+
+  Token parseEnumHeaderOpt(Token token, Token enumKeyword) {
+    token = computeTypeParamOrArg(
+            token, /* inDeclaration = */ true, /* allowsVariance = */ true)
+        .parseVariables(token, this);
+    token = parseEnumWithClauseOpt(token);
+    token = parseClassOrMixinOrEnumImplementsOpt(token);
+    return token;
+  }
+
+  Token parseEnumElement(Token token) {
+    Token beginToken = token;
+    token = parseMetadataStar(token);
+    token = ensureIdentifier(token, IdentifierContext.enumValueDeclaration);
+    token = parseConstructorReference(token, ConstructorReferenceContext.Const,
+        /* typeArg = */ null, /* isImplicitTypeName = */ true);
+    Token next = token.next!;
+    if (optional('(', next) || optional('<', next)) {
+      token = parseConstructorInvocationArguments(token);
+    } else {
+      listener.handleNoArguments(token);
+    }
+    listener.handleEnumElement(beginToken);
     return token;
   }
 
@@ -2047,8 +2119,8 @@
 
   Token parseClassHeaderOpt(Token token, Token begin, Token classKeyword) {
     token = parseClassExtendsOpt(token);
-    token = parseWithClauseOpt(token);
-    token = parseClassOrMixinImplementsOpt(token);
+    token = parseClassWithClauseOpt(token);
+    token = parseClassOrMixinOrEnumImplementsOpt(token);
     Token? nativeToken;
     if (optional('native', token.next!)) {
       nativeToken = token.next!;
@@ -2114,7 +2186,7 @@
         }
       }
 
-      token = parseWithClauseOpt(token);
+      token = parseClassWithClauseOpt(token);
 
       if (recoveryListener.withKeyword != null) {
         if (hasWith) {
@@ -2129,7 +2201,7 @@
         }
       }
 
-      token = parseClassOrMixinImplementsOpt(token);
+      token = parseClassOrMixinOrEnumImplementsOpt(token);
 
       if (recoveryListener.implementsKeyword != null) {
         if (hasImplements) {
@@ -2191,7 +2263,7 @@
   ///   'implements' typeName (',' typeName)*
   /// ;
   /// ```
-  Token parseClassOrMixinImplementsOpt(Token token) {
+  Token parseClassOrMixinOrEnumImplementsOpt(Token token) {
     Token? implementsKeyword;
     int interfacesCount = 0;
     if (optional('implements', token.next!)) {
@@ -2202,7 +2274,7 @@
         ++interfacesCount;
       } while (optional(',', token.next!));
     }
-    listener.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
+    listener.handleImplements(implementsKeyword, interfacesCount);
     return token;
   }
 
@@ -2237,7 +2309,7 @@
 
   Token parseMixinHeaderOpt(Token token, Token mixinKeyword) {
     token = parseMixinOnOpt(token);
-    token = parseClassOrMixinImplementsOpt(token);
+    token = parseClassOrMixinOrEnumImplementsOpt(token);
     listener.handleMixinHeader(mixinKeyword);
     return token;
   }
@@ -2294,7 +2366,7 @@
         }
       }
 
-      token = parseClassOrMixinImplementsOpt(token);
+      token = parseClassOrMixinOrEnumImplementsOpt(token);
 
       if (recoveryListener.implementsKeyword != null) {
         if (hasImplements) {
@@ -2993,6 +3065,18 @@
             beforeStart.next!,
             token);
         break;
+      case DeclarationKind.Enum:
+        listener.endEnumFields(
+            abstractToken,
+            externalToken,
+            staticToken,
+            covariantToken,
+            lateToken,
+            varFinalOrConst,
+            fieldCount,
+            beforeStart.next!,
+            token);
+        break;
     }
     return token;
   }
@@ -3537,7 +3621,7 @@
     listener.beginClassOrMixinOrExtensionBody(kind, token);
     int count = 0;
     while (notEofOrValue('}', token.next!)) {
-      token = parseClassOrMixinOrExtensionMemberImpl(
+      token = parseClassOrMixinOrExtensionOrEnumMemberImpl(
           token, kind, enclosingDeclarationName);
       ++count;
     }
@@ -3559,7 +3643,7 @@
   /// token and returns the token after the last consumed token rather than the
   /// last consumed token.
   Token parseClassMember(Token token, String? className) {
-    return parseClassOrMixinOrExtensionMemberImpl(
+    return parseClassOrMixinOrExtensionOrEnumMemberImpl(
             syntheticPreviousToken(token), DeclarationKind.Class, className)
         .next!;
   }
@@ -3571,7 +3655,7 @@
   /// token and returns the token after the last consumed token rather than the
   /// last consumed token.
   Token parseMixinMember(Token token, String mixinName) {
-    return parseClassOrMixinOrExtensionMemberImpl(
+    return parseClassOrMixinOrExtensionOrEnumMemberImpl(
             syntheticPreviousToken(token), DeclarationKind.Mixin, mixinName)
         .next!;
   }
@@ -3583,8 +3667,10 @@
   /// token and returns the token after the last consumed token rather than the
   /// last consumed token.
   Token parseExtensionMember(Token token, String extensionName) {
-    return parseClassOrMixinOrExtensionMemberImpl(syntheticPreviousToken(token),
-            DeclarationKind.Extension, extensionName)
+    return parseClassOrMixinOrExtensionOrEnumMemberImpl(
+            syntheticPreviousToken(token),
+            DeclarationKind.Extension,
+            extensionName)
         .next!;
   }
 
@@ -3623,7 +3709,7 @@
   ///   methodDeclaration
   /// ;
   /// ```
-  Token parseClassOrMixinOrExtensionMemberImpl(
+  Token parseClassOrMixinOrExtensionOrEnumMemberImpl(
       Token token, DeclarationKind kind, String? enclosingDeclarationName) {
     Token beforeStart = token = parseMetadataStar(token);
 
@@ -4147,6 +4233,10 @@
           break;
         case DeclarationKind.TopLevel:
           throw "Internal error: TopLevel constructor.";
+        case DeclarationKind.Enum:
+          listener.endEnumConstructor(getOrSet, beforeStart.next!,
+              beforeParam.next!, beforeInitializers?.next, token);
+          break;
       }
     } else {
       //
@@ -4176,6 +4266,10 @@
           break;
         case DeclarationKind.TopLevel:
           throw "Internal error: TopLevel method.";
+        case DeclarationKind.Enum:
+          listener.endEnumMethod(getOrSet, beforeStart.next!, beforeParam.next!,
+              beforeInitializers?.next, token);
+          break;
       }
     }
     return token;
@@ -4268,6 +4362,11 @@
         break;
       case DeclarationKind.TopLevel:
         throw "Internal error: TopLevel factory.";
+      case DeclarationKind.Enum:
+        reportRecoverableError(
+            factoryKeyword, codes.messageEnumDeclaresFactory);
+        listener.endEnumFactoryMethod(beforeStart.next!, factoryKeyword, token);
+        break;
     }
     return token;
   }
@@ -4391,12 +4490,19 @@
 
   Token parseConstructorReference(
       Token token, ConstructorReferenceContext constructorReferenceContext,
-      [TypeParamOrArgInfo? typeArg]) {
-    Token start =
-        ensureIdentifier(token, IdentifierContext.constructorReference);
+      [TypeParamOrArgInfo? typeArg, bool isImplicitTypeName = false]) {
+    Token start;
+    if (isImplicitTypeName) {
+      listener.handleNoTypeNameInConstructorReference(token.next!);
+      start = token;
+    } else {
+      start = ensureIdentifier(token, IdentifierContext.constructorReference);
+    }
     listener.beginConstructorReference(start);
-    token = parseQualifiedRestOpt(
-        start, IdentifierContext.constructorReferenceContinuation);
+    if (!isImplicitTypeName) {
+      token = parseQualifiedRestOpt(
+          start, IdentifierContext.constructorReferenceContinuation);
+    }
     typeArg ??= computeTypeParamOrArg(token);
     token = typeArg.parseArguments(token, this);
     Token? period = null;
@@ -6050,8 +6156,8 @@
     }
 
     listener.beginNewExpression(newKeyword);
-    token = parseConstructorReference(
-        newKeyword, ConstructorReferenceContext.New, potentialTypeArg);
+    token = parseConstructorReference(newKeyword,
+        ConstructorReferenceContext.New, /* typeArg = */ potentialTypeArg);
     token = parseConstructorInvocationArguments(token);
     listener.endNewExpression(newKeyword);
     return token;
@@ -6062,7 +6168,7 @@
     Token begin = token.next!; // This is the class name.
     listener.beginImplicitCreationExpression(begin);
     token = parseConstructorReference(
-        token, ConstructorReferenceContext.Implicit, typeArg);
+        token, ConstructorReferenceContext.Implicit, /* typeArg = */ typeArg);
     token = parseConstructorInvocationArguments(token);
     listener.endImplicitCreationExpression(begin, openAngleBracket);
     return token;
@@ -6178,8 +6284,8 @@
       }
     }
     listener.beginConstExpression(constKeyword);
-    token = parseConstructorReference(
-        token, ConstructorReferenceContext.Const, potentialTypeArg);
+    token = parseConstructorReference(token, ConstructorReferenceContext.Const,
+        /* typeArg = */ potentialTypeArg);
     token = parseConstructorInvocationArguments(token);
     listener.endConstExpression(constKeyword);
     return token;
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart b/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart
index 5c24c53..7936de0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/recovery_listeners.dart
@@ -24,10 +24,9 @@
   }
 
   @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
     this.implementsKeyword = implementsKeyword;
-    super.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
+    super.handleImplements(implementsKeyword, interfacesCount);
   }
 
   @override
@@ -82,10 +81,9 @@
   }
 
   @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
     this.implementsKeyword = implementsKeyword;
-    super.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
+    super.handleImplements(implementsKeyword, interfacesCount);
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
index 245bef3..fbc3ab3 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart
@@ -37,6 +37,7 @@
   ConditionallySelectedImport,
   ConstructorInitializerSeparator,
   ConstructorInitializers,
+  ConstructorReference,
   ConstructorReferenceContinuationAfterTypeArguments,
   ContinueTarget,
   Deferred,
@@ -346,9 +347,8 @@
   }
 
   @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
-    debugEvent("ClassImplements");
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
+    debugEvent("Implements");
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 41a87a0..445f314 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _fe_analyzer_shared
-version: 30.0.0
+version: 31.0.0
 description: Logic that is shared between the front_end and analyzer packages.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
 
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
index 2e4f847..4a20a40 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
@@ -139,11 +139,10 @@
           VariableGet(function.positionalParameters.first),
           StringLiteral(_getExtensionMemberName(node))
         ], types: [
-          DynamicType()
+          function.returnType
         ]))
       ..fileOffset = node.fileOffset;
-    return ReturnStatement(
-        AsExpression(getPropertyInvocation, function.returnType));
+    return ReturnStatement(getPropertyInvocation);
   }
 
   /// Returns a new function body for the given [node] external setter.
@@ -153,18 +152,18 @@
   ReturnStatement _getExternalSetterBody(Procedure node) {
     var function = node.function;
     assert(function.positionalParameters.length == 2);
+    var value = function.positionalParameters.last;
     var setPropertyInvocation = StaticInvocation(
         _setPropertyTarget,
         Arguments([
           VariableGet(function.positionalParameters.first),
           StringLiteral(_getExtensionMemberName(node)),
-          VariableGet(function.positionalParameters.last)
+          VariableGet(value)
         ], types: [
-          DynamicType()
+          value.type
         ]))
       ..fileOffset = node.fileOffset;
-    return ReturnStatement(AsExpression(
-        _lowerSetProperty(setPropertyInvocation), function.returnType));
+    return ReturnStatement(_lowerSetProperty(setPropertyInvocation));
   }
 
   /// Returns a new function body for the given [node] external method.
@@ -183,11 +182,10 @@
               .map((argument) => VariableGet(argument))
               .toList())
         ], types: [
-          DynamicType()
+          function.returnType
         ]))
       ..fileOffset = node.fileOffset;
-    return ReturnStatement(AsExpression(
-        _lowerCallMethod(callMethodInvocation), function.returnType));
+    return ReturnStatement(_lowerCallMethod(callMethodInvocation));
   }
 
   /// Returns the extension member name.
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index 90f1d22..e737f27 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -2,6 +2,7 @@
 
 analyzer:
   # This currently finds ~1,200 implicit-casts issues when enabled.
+  # TODO(srawlins): Switch to strict-casts
   # strong-mode:
   #   implicit-casts: false
   exclude:
diff --git a/pkg/analysis_server/benchmark/benchmarks.dart b/pkg/analysis_server/benchmark/benchmarks.dart
index c6b391f..78a1b36 100644
--- a/pkg/analysis_server/benchmark/benchmarks.dart
+++ b/pkg/analysis_server/benchmark/benchmarks.dart
@@ -222,16 +222,20 @@
 
   @override
   Future run() async {
-    if (argResults!.rest.isEmpty) {
+    var args = argResults;
+    if (args == null) {
+      throw StateError('argResults have not been set');
+    }
+    if (args.rest.isEmpty) {
       printUsage();
       exit(1);
     }
 
-    var benchmarkId = argResults!.rest.first;
-    var repeatCount = int.parse(argResults!['repeat'] as String);
-    var flutterRepository = argResults!['flutter-repository'] as String?;
-    var quick = argResults!['quick'];
-    var verbose = argResults!['verbose'];
+    var benchmarkId = args.rest.first;
+    var repeatCount = int.parse(args['repeat'] as String);
+    var flutterRepository = args['flutter-repository'] as String?;
+    var quick = args['quick'] as bool;
+    var verbose = args['verbose'] as bool;
 
     var benchmark =
         benchmarks.firstWhere((b) => b.id == benchmarkId, orElse: () {
@@ -241,8 +245,14 @@
 
     if (benchmark is FlutterBenchmark) {
       if (flutterRepository != null) {
-        (benchmark as FlutterBenchmark).flutterRepositoryPath =
-            flutterRepository;
+        if (path.isAbsolute(flutterRepository) &&
+            path.normalize(flutterRepository) == flutterRepository) {
+          (benchmark as FlutterBenchmark).flutterRepositoryPath =
+              flutterRepository;
+        } else {
+          print('The path must be absolute and normalized: $flutterRepository');
+          exit(1);
+        }
       } else {
         print('The option --flutter-repository is required to '
             "run '$benchmarkId'.");
diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart
index da47e28..aec8d14 100644
--- a/pkg/analysis_server/benchmark/integration/input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/input_converter.dart
@@ -62,7 +62,7 @@
 
   /// Return an operation for the notification or `null` if none.
   Operation? convertNotification(Map<String, dynamic> json) {
-    String event = json['event'];
+    var event = json['event'] as String;
     if (event == SERVER_NOTIFICATION_STATUS) {
       // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
       var params = asMap2(json['params']);
@@ -214,21 +214,21 @@
   /// Recursively translate source paths in the specified JSON to reference
   /// the temporary source used during performance measurement rather than
   /// the original source when the instrumentation or log file was generated.
-  dynamic translateSrcPaths(json) {
+  Object? translateSrcPaths(Object? json) {
     if (json is String) {
       return srcPathMap.translate(json);
     }
     if (json is List) {
-      var result = [];
+      var result = <Object?>[];
       for (var i = 0; i < json.length; ++i) {
-        result.add(translateSrcPaths(json[i]));
+        result.add(translateSrcPaths(json[i] as Object?));
       }
       return result;
     }
     if (json is Map) {
       var result = <String, Object?>{};
       json.forEach((origKey, value) {
-        result[translateSrcPaths(origKey)] = translateSrcPaths(value);
+        result[translateSrcPaths(origKey) as String] = translateSrcPaths(value);
       });
       return result;
     }
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index b63675e..07ce8bb 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -130,8 +130,8 @@
     printHelp();
     exit(1);
   }
-
-  var showHelp = args[HELP_CMDLINE_OPTION] || args.rest.isNotEmpty;
+  var helpArg = args[HELP_CMDLINE_OPTION] as bool;
+  var showHelp = helpArg || args.rest.isNotEmpty;
 
   var inputArg = args[INPUT_CMDLINE_OPTION];
   if (inputArg is! String || inputArg.isEmpty) {
@@ -141,7 +141,8 @@
     perfArgs.inputPath = inputArg;
   }
 
-  for (var pair in args[MAP_OPTION]) {
+  var mapArg = args[MAP_OPTION] as List<Object?>;
+  for (var pair in mapArg) {
     if (pair is String) {
       var index = pair.indexOf(',');
       if (index != -1 && !pair.contains(',', index + 1)) {
@@ -175,9 +176,10 @@
     }
   }
 
-  if (args[VERY_VERBOSE_CMDLINE_OPTION] || rawArgs.contains('-vv')) {
+  var verboseArg = args[VERY_VERBOSE_CMDLINE_OPTION] as bool;
+  if (verboseArg || rawArgs.contains('-vv')) {
     Logger.root.level = Level.FINE;
-  } else if (args[VERBOSE_CMDLINE_OPTION]) {
+  } else if (verboseArg) {
     Logger.root.level = Level.INFO;
   } else {
     Logger.root.level = Level.WARNING;
diff --git a/pkg/analysis_server/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart
index 311e979..db0bfcf 100644
--- a/pkg/analysis_server/benchmark/integration/operation.dart
+++ b/pkg/analysis_server/benchmark/integration/operation.dart
@@ -70,8 +70,8 @@
   @override
   Future<void>? perform(Driver driver) {
     var stopwatch = Stopwatch();
-    String originalId = json['id'];
-    String method = json['method'];
+    var originalId = json['id'] as String;
+    var method = json['method'] as String;
     json['clientRequestTime'] = DateTime.now().millisecondsSinceEpoch;
     driver.logger.log(Level.FINE, 'Sending request: $method\n  $json');
     stopwatch.start();
diff --git a/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart b/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart
index e2bac08..78497cb 100644
--- a/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart
+++ b/pkg/analysis_server/benchmark/perf/flutter_completion_benchmark.dart
@@ -77,8 +77,10 @@
     // time analyzing, and do apply the filter.
     // Total number of suggestions: 2322.
     // Filtered to: 82.
+    // Long name: completion-smallFile-body
+    var name = 'completion-1';
     result.add(
-      'completion-smallFile-body',
+      name,
       BenchMarkResult(
         'micros',
         await _completionTiming(
@@ -86,7 +88,7 @@
           filePath: '$flutterPkgPath/lib/src/material/flutter_logo.dart',
           uniquePrefix: 'Widget build(BuildContext context) {',
           insertStringGenerator: () => 'M',
-          name: 'completion-smallFile-body',
+          name: name,
         ),
       ),
     );
@@ -98,8 +100,10 @@
       // JSON in the server, and deserializing on the client.
       // Total number of suggestions: 2322.
       // Filtered to: 2322.
+      // Long name: completion-smallFile-body-withoutPrefix
+      name = 'completion-2';
       result.add(
-        'completion-smallFile-body-withoutPrefix',
+        name,
         BenchMarkResult(
           'micros',
           await _completionTiming(
@@ -107,7 +111,7 @@
             filePath: '$flutterPkgPath/lib/src/material/flutter_logo.dart',
             uniquePrefix: 'Widget build(BuildContext context) {',
             insertStringGenerator: null,
-            name: 'completion-smallFile-body-withoutPrefix',
+            name: name,
           ),
         ),
       );
@@ -118,8 +122,10 @@
       // The target method body is small, so something could be optimized.
       // Total number of suggestions: 4654.
       // Filtered to: 182.
+      // Long name: completion-smallLibraryCycle-largeFile-smallBody
+      name = 'completion-3';
       result.add(
-        'completion-smallLibraryCycle-largeFile-smallBody',
+        name,
         BenchMarkResult(
           'micros',
           await _completionTiming(
@@ -127,7 +133,7 @@
             filePath: '$flutterPkgPath/test/material/text_field_test.dart',
             uniquePrefix: 'getOpacity(WidgetTester tester, Finder finder) {',
             insertStringGenerator: () => 'M',
-            name: 'completion-smallLibraryCycle-largeFile-smallBody',
+            name: name,
           ),
         ),
       );
@@ -143,8 +149,10 @@
       // TODO(scheglov) Remove the previous sentence when improved.
       // Total number of suggestions: 3429.
       // Filtered to: 133.
+      // Long name: completion-mediumLibraryCycle-mediumFile-smallBody
+      name = 'completion-4';
       result.add(
-        'completion-mediumLibraryCycle-mediumFile-smallBody',
+        name,
         BenchMarkResult(
           'micros',
           await _completionTiming(
@@ -152,7 +160,7 @@
             filePath: '$flutterPkgPath/lib/src/material/app_bar.dart',
             uniquePrefix: 'computeDryLayout(BoxConstraints constraints) {',
             insertStringGenerator: () => 'M',
-            name: 'completion-mediumLibraryCycle-mediumFile-smallBody',
+            name: name,
           ),
         ),
       );
@@ -163,8 +171,10 @@
       // cycle. This is expensive.
       // Total number of suggestions: 1510.
       // Filtered to: 0.
+      // Long name: completion-mediumLibraryCycle-mediumFile-api-parameterType
+      name = 'completion-5';
       result.add(
-        'completion-mediumLibraryCycle-mediumFile-api-parameterType',
+        name,
         BenchMarkResult(
           'micros',
           await _completionTiming(
@@ -172,7 +182,7 @@
             filePath: '$flutterPkgPath/lib/src/material/app_bar.dart',
             uniquePrefix: 'computeDryLayout(BoxConstraints',
             insertStringGenerator: _IncrementingStringGenerator(),
-            name: 'completion-mediumLibraryCycle-mediumFile-api-parameterType',
+            name: name,
           ),
         ),
       );
diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart
index 528f672..1837834 100644
--- a/pkg/analysis_server/benchmark/perf/memory_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/memory_tests.dart
@@ -230,7 +230,7 @@
   Map<String, List<Diagnostic>> currentAnalysisErrors = {};
 
   @override
-  void expect(actual, matcher, {String? reason}) =>
+  void expect(Object? actual, Matcher matcher, {String? reason}) =>
       outOfTestExpect(actual, matcher, reason: reason);
 
   /// The server is automatically started before every test.
@@ -265,8 +265,8 @@
 
     var total = 0;
 
-    List isolateGroupsRefs = vm['isolateGroups'];
-    for (Map isolateGroupRef in isolateGroupsRefs) {
+    var isolateGroupsRefs = vm['isolateGroups'] as List<Object?>;
+    for (var isolateGroupRef in isolateGroupsRefs.cast<Map>()) {
       final heapUsage = await service.call('getIsolateGroupMemoryUsage',
           {'isolateGroupId': isolateGroupRef['id']});
       total += heapUsage['heapUsage'] + heapUsage['externalUsage'] as int;
@@ -312,10 +312,10 @@
     }
 
     try {
-      dynamic json = jsonDecode(message);
+      var json = jsonDecode(message) as Map<Object?, Object?>;
       if (json.containsKey('id')) {
-        dynamic id = json['id'];
-        _completers[id]?.complete(json['result']);
+        var id = json['id'];
+        _completers[id]?.complete(json['result'] as Map<Object?, Object?>);
         _completers.remove(id);
       }
     } catch (e) {
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
index c4469ea..c56e634 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
@@ -15,7 +15,9 @@
   /// Assists with the same relevance are sorted alphabetically.
   static final Comparator<Assist> SORT_BY_RELEVANCE = (Assist a, Assist b) {
     if (a.kind.priority != b.kind.priority) {
-      return a.kind.priority - b.kind.priority;
+      // A higher priority indicates a higher relevance
+      // and should be sorted before a lower priority.
+      return b.kind.priority - a.kind.priority;
     }
     return a.change.message.compareTo(b.change.message);
   };
diff --git a/pkg/analysis_server/lib/protocol/protocol.dart b/pkg/analysis_server/lib/protocol/protocol.dart
index 9d15dac..263083a 100644
--- a/pkg/analysis_server/lib/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/protocol/protocol.dart
@@ -37,7 +37,7 @@
 
   /// Initialize a newly created instance based on the given JSON data.
   factory Notification.fromJson(Map json) {
-    return Notification(json[Notification.EVENT],
+    return Notification(json[Notification.EVENT] as String,
         json[Notification.PARAMS] as Map<String, Object>?);
   }
 
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 2689506..85a4474 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -141,6 +141,7 @@
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_MAX_RESULTS = 'maxResults';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_OFFSET = 'offset';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_TIMEOUT = 'timeout';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_FILE = 'file';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset';
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS =
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 8cd904d..bfdf408 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -4698,7 +4698,14 @@
   /// to true.
   int maxResults;
 
-  CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults);
+  /// The approximate time in milliseconds that the server should spend. The
+  /// server will perform some steps anyway, even if it takes longer than the
+  /// specified timeout. This field is intended to be used for benchmarking,
+  /// and usually should not be provided, so that the default timeout is used.
+  int? timeout;
+
+  CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
+      {this.timeout});
 
   factory CompletionGetSuggestions2Params.fromJson(
       JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4723,7 +4730,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'maxResults');
       }
-      return CompletionGetSuggestions2Params(file, offset, maxResults);
+      int? timeout;
+      if (json.containsKey('timeout')) {
+        timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
+      }
+      return CompletionGetSuggestions2Params(file, offset, maxResults,
+          timeout: timeout);
     } else {
       throw jsonDecoder.mismatch(
           jsonPath, 'completion.getSuggestions2 params', json);
@@ -4741,6 +4753,10 @@
     result['file'] = file;
     result['offset'] = offset;
     result['maxResults'] = maxResults;
+    var timeout = this.timeout;
+    if (timeout != null) {
+      result['timeout'] = timeout;
+    }
     return result;
   }
 
@@ -4757,7 +4773,8 @@
     if (other is CompletionGetSuggestions2Params) {
       return file == other.file &&
           offset == other.offset &&
-          maxResults == other.maxResults;
+          maxResults == other.maxResults &&
+          timeout == other.timeout;
     }
     return false;
   }
@@ -4767,6 +4784,7 @@
         file,
         offset,
         maxResults,
+        timeout,
       );
 }
 
@@ -11547,7 +11565,7 @@
       double? doubleValue;
       if (json.containsKey('doubleValue')) {
         doubleValue = jsonDecoder.decodeDouble(
-            jsonPath + '.doubleValue', json['doubleValue']);
+            jsonPath + '.doubleValue', json['doubleValue'] as Object);
       }
       int? intValue;
       if (json.containsKey('intValue')) {
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index fd9daec..bbe634a 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -33,6 +33,7 @@
 import 'package:analysis_server/src/protocol_server.dart' as server;
 import 'package:analysis_server/src/search/search_domain.dart';
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
+import 'package:analysis_server/src/server/debounce_requests.dart';
 import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
 import 'package:analysis_server/src/server/diagnostic_server.dart';
 import 'package:analysis_server/src/server/error_notifier.dart';
@@ -55,6 +56,7 @@
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
 import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 import 'package:http/http.dart' as http;
+import 'package:meta/meta.dart';
 import 'package:telemetry/crash_reporting.dart';
 import 'package:telemetry/telemetry.dart' as telemetry;
 import 'package:watcher/watcher.dart';
@@ -115,6 +117,12 @@
 
   final DetachableFileSystemManager? detachableFileSystemManager;
 
+  /// The broadcast stream of requests that were discarded because there
+  /// was another request that made this one irrelevant.
+  @visibleForTesting
+  final StreamController<Request> discardedRequests =
+      StreamController.broadcast(sync: true);
+
   /// Initialize a newly created server to receive requests from and send
   /// responses to the given [channel].
   ///
@@ -161,10 +169,14 @@
         performance = performanceAfterStartup = ServerPerformance();
       });
     });
-    var notification =
-        ServerConnectedParams(PROTOCOL_VERSION, io.pid).toNotification();
-    channel.sendNotification(notification);
-    channel.listen(handleRequest, onDone: done, onError: error);
+    channel.sendNotification(
+      ServerConnectedParams(
+        options.reportProtocolVersion ?? PROTOCOL_VERSION,
+        io.pid,
+      ).toNotification(),
+    );
+    debounceRequests(channel, discardedRequests)
+        .listen(handleRequest, onDone: done, onError: error);
     handlers = <server.RequestHandler>[
       ServerDomainHandler(this),
       AnalysisDomainHandler(this),
@@ -635,6 +647,9 @@
 
   /// The set of enabled features.
   FeatureSet featureSet = FeatureSet();
+
+  /// If set, this string will be reported as the protocol version.
+  String? reportProtocolVersion;
 }
 
 class ServerContextManagerCallbacks extends ContextManagerCallbacks {
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 9e758b6..7724107 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -44,12 +44,14 @@
     show EvictingFileByteStore;
 import 'package:analyzer/src/dart/analysis/file_content_cache.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/analysis/results.dart';
 import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:collection/collection.dart';
 import 'package:http/http.dart' as http;
 import 'package:meta/meta.dart';
@@ -302,8 +304,14 @@
   }
 
   DartdocDirectiveInfo getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
+    return getDartdocDirectiveInfoForSession(result.session);
+  }
+
+  DartdocDirectiveInfo getDartdocDirectiveInfoForSession(
+    AnalysisSession session,
+  ) {
     return declarationsTracker
-            ?.getContext(result.session.analysisContext)
+            ?.getContext(session.analysisContext)
             ?.dartdocDirectiveInfo ??
         DartdocDirectiveInfo();
   }
@@ -312,7 +320,14 @@
   /// context that produced the [result], or `null` if there is no cache for the
   /// context.
   DocumentationCache? getDocumentationCacheFor(ResolvedUnitResult result) {
-    var context = result.session.analysisContext;
+    return getDocumentationCacheForSession(result.session);
+  }
+
+  /// Return the object used to cache the documentation for elements in the
+  /// context that produced the [session], or `null` if there is no cache for
+  /// the context.
+  DocumentationCache? getDocumentationCacheForSession(AnalysisSession session) {
+    var context = session.analysisContext;
     var tracker = declarationsTracker?.getContext(context);
     if (tracker == null) {
       return null;
@@ -416,7 +431,7 @@
     return driver
         .getResult(path, sendCachedToStream: sendCachedToStream)
         .then((value) => value is ResolvedUnitResult ? value : null)
-        .catchError((e, st) {
+        .catchError((Object e, StackTrace st) {
       instrumentationService.logException(e, st);
       return null;
     });
@@ -462,11 +477,36 @@
     contextManager.refresh();
   }
 
+  ResolvedForCompletionResultImpl? resolveForCompletion({
+    required String path,
+    required int offset,
+    required OperationPerformanceImpl performance,
+  }) {
+    if (!file_paths.isDart(resourceProvider.pathContext, path)) {
+      return null;
+    }
+
+    var driver = getAnalysisDriver(path);
+    if (driver == null) {
+      return null;
+    }
+
+    try {
+      return driver.resolveForCompletion(
+        path: path,
+        offset: offset,
+        performance: performance,
+      );
+    } catch (e, st) {
+      instrumentationService.logException(e, st);
+    }
+  }
+
   /// Sends an error notification to the user.
   void sendServerErrorNotification(
     String message,
-    dynamic exception,
-    /*StackTrace*/ stackTrace, {
+    Object exception,
+    StackTrace? stackTrace, {
     bool fatal = false,
   });
 
diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
index bfbc6ba..955e547 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
@@ -73,7 +73,6 @@
 /// standard input and standard output) to communicate with clients.
 class ByteStreamServerChannel implements ServerCommunicationChannel {
   final Stream _input;
-
   final IOSink _output;
 
   /// The instrumentation service that is to be used by this analysis server.
@@ -88,6 +87,20 @@
   /// True if [close] has been called.
   bool _closeRequested = false;
 
+  @override
+  late final Stream<Request> requests = _input
+      .transform(const Utf8Decoder())
+      .transform(const LineSplitter())
+      .transform(
+        StreamTransformer.fromHandlers(
+          handleData: _readRequest,
+          handleDone: (sink) {
+            close();
+            sink.close();
+          },
+        ),
+      );
+
   ByteStreamServerChannel(
       this._input, this._output, this._instrumentationService,
       {RequestStatisticsHelper? requestStatistics})
@@ -110,17 +123,6 @@
   }
 
   @override
-  void listen(void Function(Request request) onRequest,
-      {Function? onError, void Function()? onDone}) {
-    _input.transform(const Utf8Decoder()).transform(LineSplitter()).listen(
-        (String data) => _readRequest(data, onRequest),
-        onError: onError, onDone: () {
-      close();
-      onDone?.call();
-    });
-  }
-
-  @override
   void sendNotification(Notification notification) {
     // Don't send any further notifications after the communication channel is
     // closed.
@@ -159,7 +161,7 @@
 
   /// Read a request from the given [data] and use the given function to handle
   /// the request.
-  void _readRequest(String data, void Function(Request request) onRequest) {
+  void _readRequest(String data, Sink<Request> sink) {
     // Ignore any further requests after the communication channel is closed.
     if (_closed.isCompleted) {
       return;
@@ -173,6 +175,6 @@
       return;
     }
     _requestStatistics?.addRequest(request);
-    onRequest(request);
+    sink.add(request);
   }
 }
diff --git a/pkg/analysis_server/lib/src/channel/channel.dart b/pkg/analysis_server/lib/src/channel/channel.dart
index 6b5e95f..37a6e86 100644
--- a/pkg/analysis_server/lib/src/channel/channel.dart
+++ b/pkg/analysis_server/lib/src/channel/channel.dart
@@ -98,17 +98,12 @@
 /// objects that allow an [AnalysisServer] to receive [Request]s and to return
 /// both [Response]s and [Notification]s.
 abstract class ServerCommunicationChannel {
+  /// The single-subscription stream of requests.
+  Stream<Request> get requests;
+
   /// Close the communication channel.
   void close();
 
-  /// Listen to the channel for requests. If a request is received, invoke the
-  /// [onRequest] function. If an error is encountered while trying to read from
-  /// the socket, invoke the [onError] function. If the socket is closed by the
-  /// client, invoke the [onDone] function.
-  /// Only one listener is allowed per channel.
-  void listen(void Function(Request request) onRequest,
-      {Function onError, void Function() onDone});
-
   /// Send the given [notification] to the client.
   void sendNotification(Notification notification);
 
diff --git a/pkg/analysis_server/lib/src/cider/completion.dart b/pkg/analysis_server/lib/src/cider/completion.dart
index 17f00da..4f6aaaa3 100644
--- a/pkg/analysis_server/lib/src/cider/completion.dart
+++ b/pkg/analysis_server/lib/src/cider/completion.dart
@@ -70,7 +70,7 @@
       var lineInfo = resolvedUnit.lineInfo;
       var offset = lineInfo.getOffsetOfLine(line) + column;
 
-      _dartCompletionRequest = DartCompletionRequest(
+      _dartCompletionRequest = DartCompletionRequest.forResolvedUnit(
         resolvedUnit: resolvedUnit,
         offset: offset,
       );
diff --git a/pkg/analysis_server/lib/src/cider/rename.dart b/pkg/analysis_server/lib/src/cider/rename.dart
index 6ff6528..4c38533 100644
--- a/pkg/analysis_server/lib/src/cider/rename.dart
+++ b/pkg/analysis_server/lib/src/cider/rename.dart
@@ -14,17 +14,46 @@
 class CanRenameResponse {
   final LineInfo lineInfo;
   final RenameRefactoringElement refactoringElement;
-  final String oldName;
+  final FileResolver _fileResolver;
+  final String filePath;
 
-  CanRenameResponse(this.lineInfo, this.refactoringElement, this.oldName);
+  CanRenameResponse(this.lineInfo, this.refactoringElement, this._fileResolver,
+      this.filePath);
+
+  String get oldName => refactoringElement.element.displayName;
+
+  CheckNameResponse? checkNewName(String name) {
+    var element = refactoringElement.element;
+    RefactoringStatus? status;
+    if (element is LocalVariableElement) {
+      status = validateVariableName(name);
+    } else if (element is ParameterElement) {
+      status = validateParameterName(name);
+    } else if (element is FunctionElement) {
+      status = validateFunctionName(name);
+    }
+    if (status == null) {
+      return null;
+    }
+    return CheckNameResponse(status, this);
+  }
 }
 
 class CheckNameResponse {
-  final LineInfo lineInfo;
   final RefactoringStatus status;
-  final String oldName;
+  final CanRenameResponse canRename;
 
-  CheckNameResponse(this.lineInfo, this.status, this.oldName);
+  CheckNameResponse(this.status, this.canRename);
+
+  LineInfo get lineInfo => canRename.lineInfo;
+
+  String get oldName => canRename.refactoringElement.element.displayName;
+
+  RenameResponse? computeRenameRanges() {
+    var matches = canRename._fileResolver
+        .findReferences(canRename.refactoringElement.element);
+    return RenameResponse(matches, this);
+  }
 }
 
 class CiderRenameComputer {
@@ -45,7 +74,7 @@
     if (node == null || element == null) {
       return null;
     }
-    if (element.source != null && element.source!.isInSystemLibrary) {
+    if (element.source != null && element.source!.uri.isScheme('dart')) {
       return null;
     }
     if (element is MethodElement && element.isOperator) {
@@ -56,11 +85,12 @@
     }
     var refactoring = RenameRefactoring.getElementToRename(node, element);
     if (refactoring != null) {
-      return CanRenameResponse(lineInfo, refactoring, element.displayName);
+      return CanRenameResponse(lineInfo, refactoring, _fileResolver, filePath);
     }
     return null;
   }
 
+  @deprecated
   CheckNameResponse? checkNewName(
       String filePath, int line, int column, String name) {
     var resolvedUnit = _fileResolver.resolve(path: filePath);
@@ -74,6 +104,10 @@
       return null;
     }
 
+    var refactoring = RenameRefactoring.getElementToRename(node, element);
+    if (refactoring == null) {
+      return null;
+    }
     RefactoringStatus? status;
     if (element is LocalVariableElement) {
       status = validateVariableName(name);
@@ -85,7 +119,9 @@
     if (status == null) {
       return null;
     }
-    return CheckNameResponse(lineInfo, status, element.displayName);
+
+    return CheckNameResponse(status,
+        CanRenameResponse(lineInfo, refactoring, _fileResolver, filePath));
   }
 
   bool _canRenameElement(Element element) {
@@ -103,3 +139,10 @@
     return false;
   }
 }
+
+class RenameResponse {
+  final List<CiderSearchMatch> matches;
+  final CheckNameResponse checkName;
+
+  RenameResponse(this.matches, this.checkName);
+}
diff --git a/pkg/analysis_server/lib/src/computer/computer_color.dart b/pkg/analysis_server/lib/src/computer/computer_color.dart
new file mode 100644
index 0000000..56352d1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/computer/computer_color.dart
@@ -0,0 +1,361 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/utilities/flutter.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/constant/value.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/constant/value.dart' show GenericState;
+import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
+import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:analyzer/src/lint/linter.dart';
+import 'package:collection/collection.dart';
+
+/// Computer for dart:ui/Flutter Color references.
+class ColorComputer {
+  final ResolvedUnitResult resolvedUnit;
+  final LinterContext _linterContext;
+  final List<ColorReference> _colors = [];
+  final Flutter _flutter = Flutter.instance;
+
+  ColorComputer(this.resolvedUnit)
+      : _linterContext = LinterContextImpl(
+          [], // unused
+          LinterContextUnit(resolvedUnit.content, resolvedUnit.unit),
+          resolvedUnit.session.declaredVariables,
+          resolvedUnit.typeProvider,
+          resolvedUnit.typeSystem as TypeSystemImpl,
+          InheritanceManager3(), // unused
+          resolvedUnit.session.analysisContext.analysisOptions,
+          null,
+        );
+
+  /// Returns information about the color references in [resolvedUnit].
+  ///
+  /// This method should only be called once for any instance of this class.
+  List<ColorReference> compute() {
+    final visitor = _ColorBuilder(this);
+    resolvedUnit.unit.accept(visitor);
+    return _colors;
+  }
+
+  /// Tries to add a color for the [expression].
+  ///
+  /// If [target] is supplied, will be used instead of [expression] allowing
+  /// a value to be read from the member [memberName] or from a swatch value
+  /// with index [index].
+  bool tryAddColor(
+    Expression expression, {
+    Expression? target,
+    String? memberName,
+    int? index,
+  }) {
+    if (!_isColor(expression.staticType)) return false;
+
+    target ??= expression;
+
+    // Try to evaluate the constant target.
+    final colorConstResult = _linterContext.evaluateConstant(target);
+    var colorConst = colorConstResult.value;
+    if (colorConstResult.errors.isNotEmpty || colorConst == null) return false;
+
+    // If we want a specific member or swatch index, read that.
+    if (memberName != null) {
+      colorConst = _getMember(colorConst, memberName);
+    } else if (index != null) {
+      colorConst = _getSwatchValue(colorConst, index);
+    }
+
+    return _tryRecordColor(expression, colorConst);
+  }
+
+  /// Tries to add a color for the instance creation [expression].
+  ///
+  /// This handles constructor calls that cannot be evaluated (for example
+  /// because they are not const) but are simple well-known dart:ui/Flutter
+  /// color constructors that we can manually parse.
+  bool tryAddKnownColorConstructor(InstanceCreationExpression expression) {
+    if (!_isColor(expression.staticType)) return false;
+
+    final constructor = expression.constructorName;
+    final staticElement = constructor.staticElement;
+    final classElement = staticElement?.enclosingElement;
+    final className = classElement?.name;
+    final constructorName = constructor.name?.name;
+    final constructorArgs = expression.argumentList.arguments
+        .map((e) => e is Literal ? e : null)
+        .toList();
+
+    int? colorValue;
+    if (_isDartUi(classElement) && className == 'Color') {
+      colorValue = _getDartUiColorValue(constructorName, constructorArgs);
+    } else if (_isFlutterPainting(classElement) && className == 'ColorSwatch') {
+      colorValue =
+          _getFlutterSwatchColorValue(constructorName, constructorArgs);
+    } else if (_isFlutterMaterial(classElement) &&
+        className == 'MaterialAccentColor') {
+      colorValue =
+          _getFlutterMaterialAccentColorValue(constructorName, constructorArgs);
+    }
+
+    return _tryRecordColorValue(expression, colorValue);
+  }
+
+  /// Creates a [ColorInformation] by extracting the argb values from
+  /// [value] encoded as 0xAARRGGBB as in the dart:ui Color class.
+  ColorInformation _colorInformationForColorValue(int value) {
+    // Extract color information according to dart:ui Color values.
+    final alpha = (0xff000000 & value) >> 24;
+    final red = (0x00ff0000 & value) >> 16;
+    final blue = (0x000000ff & value) >> 0;
+    final green = (0x0000ff00 & value) >> 8;
+
+    return ColorInformation(alpha, red, green, blue);
+  }
+
+  /// Extracts the integer color value from the dart:ui Color constant [color].
+  int? _colorValueForColorConst(DartObject? color) {
+    if (color == null || color.isNull) return null;
+
+    // If the object has a "color" field, walk down to that, because some colors
+    // like CupertinoColors have a "value=0" with an overridden getter that
+    // would always result in a value representing black.
+    color = color.getFieldFromHierarchy('color') ?? color;
+
+    return color.getFieldFromHierarchy('value')?.toIntValue();
+  }
+
+  /// Converts ARGB values into a single int value as 0xAARRGGBB as used by
+  /// the dart:ui Color class.
+  int _colorValueForComponents(int alpha, int red, int green, int blue) {
+    return (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+  }
+
+  /// Extracts the color value from dart:ui Color constructor args.
+  int? _getDartUiColorValue(String? name, List<Literal?> args) {
+    if (name == null && args.length == 1) {
+      final arg0 = args[0];
+      return arg0 is IntegerLiteral ? arg0.value : null;
+    } else if (name == 'fromARGB' && args.length == 4) {
+      final arg0 = args[0];
+      final arg1 = args[1];
+      final arg2 = args[2];
+      final arg3 = args[3];
+
+      final alpha = arg0 is IntegerLiteral ? arg0.value : null;
+      final red = arg1 is IntegerLiteral ? arg1.value : null;
+      final green = arg2 is IntegerLiteral ? arg2.value : null;
+      final blue = arg3 is IntegerLiteral ? arg3.value : null;
+
+      return alpha != null && red != null && green != null && blue != null
+          ? _colorValueForComponents(alpha, red, green, blue)
+          : null;
+    } else if (name == 'fromRGBO' && args.length == 4) {
+      final arg0 = args[0];
+      final arg1 = args[1];
+      final arg2 = args[2];
+      final arg3 = args[3];
+
+      final red = arg0 is IntegerLiteral ? arg0.value : null;
+      final green = arg1 is IntegerLiteral ? arg1.value : null;
+      final blue = arg2 is IntegerLiteral ? arg2.value : null;
+      final opacity = arg3 is IntegerLiteral
+          ? arg3.value
+          : arg3 is DoubleLiteral
+              ? arg3.value
+              : null;
+      final alpha = opacity != null ? (opacity * 255).toInt() : null;
+
+      return alpha != null && red != null && green != null && blue != null
+          ? _colorValueForComponents(alpha, red, green, blue)
+          : null;
+    }
+  }
+
+  /// Extracts the color value from Flutter MaterialAccentColor constructor args.
+  int? _getFlutterMaterialAccentColorValue(String? name, List<Literal?> args) =>
+      // MaterialAccentColor is a subclass of SwatchColor and has the same
+      // constructor.
+      _getFlutterSwatchColorValue(name, args);
+
+  /// Extracts the color value from Flutter ColorSwatch constructor args.
+  int? _getFlutterSwatchColorValue(String? name, List<Literal?> args) {
+    if (name == null && args.isNotEmpty) {
+      final arg0 = args[0];
+      return arg0 is IntegerLiteral ? arg0.value : null;
+    }
+  }
+
+  /// Extracts a named member from a color.
+  ///
+  /// Well-known getters like `shade500` will be mapped onto the swatch value
+  /// with a matching index.
+  DartObject? _getMember(DartObject target, String memberName) {
+    final colorValue = target.getFieldFromHierarchy(memberName);
+    if (colorValue != null) {
+      return colorValue;
+    }
+
+    // If we didn't get a value but it's a getter we know how to read from a
+    // swatch, try that.
+    if (memberName.startsWith('shade')) {
+      final shadeNumber = int.tryParse(memberName.substring(5));
+      if (shadeNumber != null) {
+        return _getSwatchValue(target, shadeNumber);
+      }
+    }
+  }
+
+  /// Extracts a specific shade index from a Flutter SwatchColor.
+  DartObject? _getSwatchValue(DartObject target, int swatchValue) {
+    final swatch = target.getFieldFromHierarchy('_swatch')?.toMapValue();
+    if (swatch == null) return null;
+
+    final key = swatch.keys.firstWhereOrNull(
+      (key) => key?.toIntValue() == swatchValue,
+    );
+    if (key == null) return null;
+
+    return swatch[key];
+  }
+
+  /// Checks whether [type] is - or extends - the dart:ui Color class.
+  bool _isColor(DartType? type) => type != null && _flutter.isColor(type);
+
+  /// Checks whether this elements library is dart:ui.
+  bool _isDartUi(Element? element) => element?.library?.name == 'dart.ui';
+
+  /// Checks whether this elements library is Flutter Material colors.
+  bool _isFlutterMaterial(Element? element) =>
+      element?.library?.identifier ==
+      'package:flutter/src/material/colors.dart';
+
+  /// Checks whether this elements library is Flutter Painting colors.
+  bool _isFlutterPainting(Element? element) =>
+      element?.library?.identifier ==
+      'package:flutter/src/painting/colors.dart';
+
+  /// Tries to record a color value from [colorConst] for [expression].
+  ///
+  /// Returns whether a valid color was found and recorded.
+  bool _tryRecordColor(Expression expression, DartObject? colorConst) =>
+      _tryRecordColorValue(expression, _colorValueForColorConst(colorConst));
+
+  /// Tries to record the [colorValue] for [expression].
+  ///
+  /// Returns whether a valid color was found and recorded.
+  bool _tryRecordColorValue(Expression expression, int? colorValue) {
+    if (colorValue == null) return false;
+
+    // Build color information from the Color value.
+    final color = _colorInformationForColorValue(colorValue);
+
+    // Record the color against the original entire expression.
+    _colors.add(ColorReference(expression.offset, expression.length, color));
+    return true;
+  }
+}
+
+/// Information about a color that is present in a document.
+class ColorInformation {
+  final int alpha;
+  final int red;
+  final int green;
+  final int blue;
+
+  ColorInformation(this.alpha, this.red, this.green, this.blue);
+}
+
+/// Information about a specific known location of a [ColorInformation]
+/// reference in a document.
+class ColorReference {
+  final int offset;
+  final int length;
+  final ColorInformation color;
+
+  ColorReference(this.offset, this.length, this.color);
+}
+
+class _ColorBuilder extends RecursiveAstVisitor<void> {
+  final ColorComputer computer;
+
+  _ColorBuilder(this.computer);
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    // Colors.redAccent[500].
+    final index = node.index;
+    final indexValue = index is IntegerLiteral ? index.value : null;
+    if (indexValue != null) {
+      if (computer.tryAddColor(
+        node,
+        target: node.realTarget,
+        index: indexValue,
+      )) {
+        return;
+      }
+    }
+    super.visitIndexExpression(node);
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    // Usually we return after finding a color, but constructors can
+    // have nested colors in their arguments so we walk all the way down.
+    if (!computer.tryAddColor(node)) {
+      // If we couldn't evaluate the constant, try the well-known color
+      // constructors for dart:ui/Flutter.
+      computer.tryAddKnownColorConstructor(node);
+    }
+
+    super.visitInstanceCreationExpression(node);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    // Try the whole node as a constant (eg. `MyThemeClass.staticField`).
+    if (computer.tryAddColor(node)) {
+      return;
+    }
+
+    // Try a field of a static, (eg. `const MyThemeClass().instanceField`).
+    if (computer.tryAddColor(
+      node,
+      target: node.prefix,
+      memberName: node.identifier.name,
+    )) {
+      return;
+    }
+
+    super.visitPrefixedIdentifier(node);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    // Handle things like CupterinoColors.activeBlue.darkColor where we can't
+    // evaluate the whole expression, but can evaluate CupterinoColors.activeBlue
+    // and read the darkColor.
+    if (computer.tryAddColor(
+      node,
+      target: node.realTarget,
+      memberName: node.propertyName.name,
+    )) {
+      return;
+    }
+
+    super.visitPropertyAccess(node);
+  }
+}
+
+extension _DartObjectExtensions on DartObject {
+  /// Reads the value of the field [field] from this object.
+  ///
+  /// If the field is not found, recurses up the super classes.
+  DartObject? getFieldFromHierarchy(String fieldName) =>
+      getField(fieldName) ??
+      getField(GenericState.SUPERCLASS_FIELD)?.getFieldFromHierarchy(fieldName);
+}
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 1f568f7..b6df480 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -18,7 +18,6 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/pub.dart';
 import 'package:analyzer/src/manifest/manifest_validator.dart';
@@ -222,7 +221,7 @@
       this._performanceLog,
       this._scheduler,
       this._instrumentationService,
-      {required enableBazelWatcher})
+      {required bool enableBazelWatcher})
       : pathContext = resourceProvider.pathContext {
     if (enableBazelWatcher) {
       bazelWatcherService = BazelFileWatcherService(_instrumentationService);
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index b1b2b36..60c81b6 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:collection';
 
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
@@ -16,6 +17,7 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/fuzzy_filter_sort.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/completion/yaml/analysis_options_generator.dart';
 import 'package:analysis_server/src/services/completion/yaml/fix_data_generator.dart';
 import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
@@ -29,6 +31,7 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:collection/collection.dart';
 
 /// Instances of the class [CompletionDomainHandler] implement a
 /// [RequestHandler] that handles requests in the completion domain.
@@ -45,9 +48,6 @@
   /// The next completion response id.
   int _nextCompletionId = 0;
 
-  /// Code completion performance for the last completion operation.
-  CompletionPerformance? performance;
-
   /// A list of code completion performance measurements for the latest
   /// completion operation up to [performanceListMaxLength] measurements.
   final RecentBuffer<CompletionPerformance> performanceList =
@@ -75,7 +75,7 @@
     Set<ElementKind>? includedElementKinds,
     Set<String>? includedElementNames,
     List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
-    List<Uri>? librariesToImport,
+    Map<CompletionSuggestion, Uri>? notImportedSuggestions,
   }) async {
     //
     // Allow plugins to start computing fixes.
@@ -94,7 +94,7 @@
         includedElementKinds: includedElementKinds,
         includedElementNames: includedElementNames,
         includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
-        librariesToImport: librariesToImport,
+        notImportedSuggestions: notImportedSuggestions,
       );
 
       suggestions.addAll(
@@ -267,16 +267,34 @@
 
   /// Implement the 'completion.getSuggestions2' request.
   void getSuggestions2(Request request) async {
-    var budget = CompletionBudget(budgetDuration);
-
     var params = CompletionGetSuggestions2Params.fromRequest(request);
     var file = params.file;
     var offset = params.offset;
 
+    var timeoutMilliseconds = params.timeout;
+    var budget = CompletionBudget(
+      timeoutMilliseconds != null
+          ? Duration(milliseconds: timeoutMilliseconds)
+          : budgetDuration,
+    );
+
     var provider = server.resourceProvider;
     var pathContext = provider.pathContext;
 
-    // TODO(scheglov) Support non-Dart files.
+    if (file.endsWith('.yaml')) {
+      final suggestions = computeYamlSuggestions(file, offset);
+      server.sendResponse(
+        CompletionGetSuggestions2Result(
+          suggestions.replacementOffset,
+          suggestions.replacementLength,
+          suggestions.suggestions,
+          [],
+          false,
+        ).toResponse(request.id),
+      );
+      return;
+    }
+
     if (!file_paths.isDart(pathContext, file)) {
       server.sendResponse(
         CompletionGetSuggestions2Result(offset, 0, [], [], false)
@@ -285,81 +303,125 @@
       return;
     }
 
-    var resolvedUnit = await server.getResolvedUnit(file);
-    if (resolvedUnit == null) {
-      server.sendResponse(Response.fileNotAnalyzed(request, file));
-      return;
-    }
-
-    server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
-
-    if (offset < 0 || offset > resolvedUnit.content.length) {
-      server.sendResponse(Response.invalidParameter(
-          request,
-          'params.offset',
-          'Expected offset between 0 and source length inclusive,'
-              ' but found $offset'));
-      return;
-    }
-
-    final completionPerformance = CompletionPerformance();
-    recordRequest(completionPerformance, file, resolvedUnit.content, offset);
-
-    await completionPerformance.runRequestOperation((performance) async {
-      var completionRequest = DartCompletionRequest(
-        resolvedUnit: resolvedUnit,
-        offset: offset,
-        dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
-          resolvedUnit,
-        ),
-        documentationCache: server.getDocumentationCacheFor(resolvedUnit),
-      );
-      setNewRequest(completionRequest);
-
-      var librariesToImport = <Uri>[];
-      var suggestions = <CompletionSuggestion>[];
-      try {
-        suggestions = await computeSuggestions(
-          budget: budget,
-          performance: performance,
-          request: completionRequest,
-          librariesToImport: librariesToImport,
+    var performance = OperationPerformanceImpl('<root>');
+    performance.runAsync(
+      'request',
+      (performance) async {
+        var resolvedUnit = performance.run(
+          'resolveForCompletion',
+          (performance) {
+            return server.resolveForCompletion(
+              path: file,
+              offset: offset,
+              performance: performance,
+            );
+          },
         );
-      } on AbortCompletion {
-        return server.sendResponse(
-          CompletionGetSuggestions2Result(
-            completionRequest.replacementOffset,
-            completionRequest.replacementLength,
-            [],
-            [],
-            true,
-          ).toResponse(request.id),
+        if (resolvedUnit == null) {
+          server.sendResponse(Response.fileNotAnalyzed(request, file));
+          return;
+        }
+
+        if (offset < 0 || offset > resolvedUnit.content.length) {
+          server.sendResponse(Response.invalidParameter(
+              request,
+              'params.offset',
+              'Expected offset between 0 and source length inclusive,'
+                  ' but found $offset'));
+          return;
+        }
+
+        final completionPerformance = CompletionPerformance(
+          operation: performance,
+          path: file,
+          content: resolvedUnit.content,
+          offset: offset,
         );
-      }
+        performanceList.add(completionPerformance);
 
-      performance.run('filter', (performance) {
-        performance.getDataInt('count').add(suggestions.length);
-        suggestions = fuzzyFilterSort(
-          pattern: completionRequest.targetPrefix,
-          suggestions: suggestions,
+        var analysisSession = resolvedUnit.analysisSession;
+        var enclosingNode =
+            resolvedUnit.resolvedNodes.lastOrNull ?? resolvedUnit.parsedUnit;
+
+        var completionRequest = DartCompletionRequest(
+          analysisSession: analysisSession,
+          filePath: resolvedUnit.path,
+          fileContent: resolvedUnit.content,
+          unitElement: resolvedUnit.unitElement,
+          enclosingNode: enclosingNode,
+          offset: offset,
+          dartdocDirectiveInfo:
+              server.getDartdocDirectiveInfoForSession(analysisSession),
+          documentationCache:
+              server.getDocumentationCacheForSession(analysisSession),
         );
-        performance.getDataInt('matchCount').add(suggestions.length);
-      });
+        setNewRequest(completionRequest);
 
-      var lengthRestricted = suggestions.take(params.maxResults).toList();
-      var isIncomplete = lengthRestricted.length < suggestions.length;
-      completionPerformance.suggestionCount = lengthRestricted.length;
+        var notImportedSuggestions =
+            HashMap<CompletionSuggestion, Uri>.identity();
+        var suggestions = <CompletionSuggestion>[];
+        try {
+          suggestions = await computeSuggestions(
+            budget: budget,
+            performance: performance,
+            request: completionRequest,
+            notImportedSuggestions: notImportedSuggestions,
+          );
+        } on AbortCompletion {
+          return server.sendResponse(
+            CompletionGetSuggestions2Result(
+              completionRequest.replacementOffset,
+              completionRequest.replacementLength,
+              [],
+              [],
+              true,
+            ).toResponse(request.id),
+          );
+        }
 
-      server.sendResponse(
-        CompletionGetSuggestions2Result(
-          completionRequest.replacementOffset,
-          completionRequest.replacementLength,
-          lengthRestricted,
-          librariesToImport.map((e) => '$e').toList(),
-          isIncomplete,
-        ).toResponse(request.id),
-      );
-    });
+        performance.run('filter', (performance) {
+          performance.getDataInt('count').add(suggestions.length);
+          suggestions = fuzzyFilterSort(
+            pattern: completionRequest.targetPrefix,
+            suggestions: suggestions,
+          );
+          performance.getDataInt('matchCount').add(suggestions.length);
+        });
+
+        var lengthRestricted = suggestions.take(params.maxResults).toList();
+        var isIncomplete = lengthRestricted.length < suggestions.length;
+        completionPerformance.suggestionCount = lengthRestricted.length;
+
+        // Update `libraryUriToImportIndex` for not yet imported.
+        // Gather referenced unique libraries to import.
+        var librariesToImport = <Uri, int>{};
+        for (var i = 0; i < lengthRestricted.length; i++) {
+          var suggestion = lengthRestricted[i];
+          var libraryToImport = notImportedSuggestions[suggestion];
+          if (libraryToImport != null) {
+            var index = librariesToImport.putIfAbsent(
+              libraryToImport,
+              () => librariesToImport.length,
+            );
+            lengthRestricted[i] = suggestion.copyWith(
+              libraryUriToImportIndex: CopyWithValue(index),
+            );
+          }
+        }
+
+        performance.run('sendResponse', (_) {
+          server.sendResponse(
+            CompletionGetSuggestions2Result(
+              completionRequest.replacementOffset,
+              completionRequest.replacementLength,
+              lengthRestricted,
+              librariesToImport.keys.map((e) => '$e').toList(),
+              isIncomplete,
+            ).toResponse(request.id),
+          );
+        });
+      },
+    );
   }
 
   @override
@@ -410,161 +472,160 @@
   Future<void> processRequest(Request request) async {
     var budget = CompletionBudget(budgetDuration);
 
-    final performance = this.performance = CompletionPerformance();
+    // extract and validate params
+    var params = CompletionGetSuggestionsParams.fromRequest(request);
+    var file = params.file;
+    var offset = params.offset;
 
-    await performance.runRequestOperation((perf) async {
-      // extract and validate params
-      var params = CompletionGetSuggestionsParams.fromRequest(request);
-      var file = params.file;
-      var offset = params.offset;
-
-      if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
-        return;
-      }
-      if (file.endsWith('.yaml')) {
-        // Return the response without results.
-        var completionId = (_nextCompletionId++).toString();
-        server.sendResponse(CompletionGetSuggestionsResult(completionId)
-            .toResponse(request.id));
-        // Send a notification with results.
-        final suggestions = computeYamlSuggestions(file, offset);
-        sendCompletionNotification(
-          completionId,
-          suggestions.replacementOffset,
-          suggestions.replacementLength,
-          suggestions.suggestions,
-          null,
-          null,
-          null,
-          null,
-        );
-        return;
-      } else if (!file.endsWith('.dart')) {
-        // Return the response without results.
-        var completionId = (_nextCompletionId++).toString();
-        server.sendResponse(CompletionGetSuggestionsResult(completionId)
-            .toResponse(request.id));
-        // Send a notification with results.
-        sendCompletionNotification(
-            completionId, offset, 0, [], null, null, null, null);
-        return;
-      }
-
-      var resolvedUnit = await server.getResolvedUnit(file);
-      if (resolvedUnit == null) {
-        server.sendResponse(Response.fileNotAnalyzed(request, 'params.offset'));
-        return;
-      }
-
-      server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
-
-      if (offset < 0 || offset > resolvedUnit.content.length) {
-        server.sendResponse(Response.invalidParameter(
-            request,
-            'params.offset',
-            'Expected offset between 0 and source length inclusive,'
-                ' but found $offset'));
-        return;
-      }
-
-      recordRequest(performance, file, resolvedUnit.content, offset);
-
-      var declarationsTracker = server.declarationsTracker;
-      if (declarationsTracker == null) {
-        server.sendResponse(Response.unsupportedFeature(
-            request.id, 'Completion is not enabled.'));
-        return;
-      }
-
-      var completionRequest = DartCompletionRequest(
-        resolvedUnit: resolvedUnit,
-        offset: offset,
-        dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
-          resolvedUnit,
-        ),
-        documentationCache: server.getDocumentationCacheFor(resolvedUnit),
-      );
-
-      var completionId = (_nextCompletionId++).toString();
-
-      setNewRequest(completionRequest);
-
-      // initial response without results
-      server.sendResponse(
-          CompletionGetSuggestionsResult(completionId).toResponse(request.id));
-
-      // If the client opted into using available suggestion sets,
-      // create the kinds set, so signal the completion manager about opt-in.
-      Set<ElementKind>? includedElementKinds;
-      Set<String>? includedElementNames;
-      List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
-      if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
-        includedElementKinds = <ElementKind>{};
-        includedElementNames = <String>{};
-        includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
-      }
-
-      // Compute suggestions in the background
-      try {
-        var suggestions = <CompletionSuggestion>[];
-        try {
-          suggestions = await computeSuggestions(
-            budget: budget,
-            performance: perf,
-            request: completionRequest,
-            includedElementKinds: includedElementKinds,
-            includedElementNames: includedElementNames,
-            includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
-          );
-        } on AbortCompletion {
-          // Continue with empty suggestions list.
-        }
-        String? libraryFile;
-        var includedSuggestionSets = <IncludedSuggestionSet>[];
-        if (includedElementKinds != null && includedElementNames != null) {
-          libraryFile = resolvedUnit.libraryElement.source.fullName;
-          server.sendNotification(
-            createExistingImportsNotification(resolvedUnit),
-          );
-          computeIncludedSetList(
-            declarationsTracker,
-            resolvedUnit,
-            includedSuggestionSets,
-            includedElementNames,
-          );
-        }
-
-        const SEND_NOTIFICATION_TAG = 'send notification';
-        perf.run(SEND_NOTIFICATION_TAG, (_) {
-          sendCompletionNotification(
-            completionId,
-            completionRequest.replacementOffset,
-            completionRequest.replacementLength,
-            suggestions,
-            libraryFile,
-            includedSuggestionSets,
-            includedElementKinds?.toList(),
-            includedSuggestionRelevanceTags,
-          );
-        });
-
-        performance.suggestionCount = suggestions.length;
-      } finally {
-        ifMatchesRequestClear(completionRequest);
-      }
-    });
-  }
-
-  /// If tracking code completion performance over time, then
-  /// record addition information about the request in the performance record.
-  void recordRequest(CompletionPerformance performance, String path,
-      String content, int offset) {
-    performance.path = path;
-    if (performanceListMaxLength == 0) {
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
       return;
     }
-    performance.setContentsAndOffset(content, offset);
-    performanceList.add(performance);
+
+    var performance = OperationPerformanceImpl('<root>');
+    performance.runAsync(
+      'request',
+      (performance) async {
+        if (file.endsWith('.yaml')) {
+          // Return the response without results.
+          var completionId = (_nextCompletionId++).toString();
+          server.sendResponse(CompletionGetSuggestionsResult(completionId)
+              .toResponse(request.id));
+          // Send a notification with results.
+          final suggestions = computeYamlSuggestions(file, offset);
+          sendCompletionNotification(
+            completionId,
+            suggestions.replacementOffset,
+            suggestions.replacementLength,
+            suggestions.suggestions,
+            null,
+            null,
+            null,
+            null,
+          );
+          return;
+        } else if (!file.endsWith('.dart')) {
+          // Return the response without results.
+          var completionId = (_nextCompletionId++).toString();
+          server.sendResponse(CompletionGetSuggestionsResult(completionId)
+              .toResponse(request.id));
+          // Send a notification with results.
+          sendCompletionNotification(
+              completionId, offset, 0, [], null, null, null, null);
+          return;
+        }
+
+        var resolvedUnit = await server.getResolvedUnit(file);
+        if (resolvedUnit == null) {
+          server
+              .sendResponse(Response.fileNotAnalyzed(request, 'params.offset'));
+          return;
+        }
+
+        server.requestStatistics?.addItemTimeNow(request, 'resolvedUnit');
+
+        if (offset < 0 || offset > resolvedUnit.content.length) {
+          server.sendResponse(Response.invalidParameter(
+              request,
+              'params.offset',
+              'Expected offset between 0 and source length inclusive,'
+                  ' but found $offset'));
+          return;
+        }
+
+        final completionPerformance = CompletionPerformance(
+          operation: performance,
+          path: file,
+          content: resolvedUnit.content,
+          offset: offset,
+        );
+        performanceList.add(completionPerformance);
+
+        var declarationsTracker = server.declarationsTracker;
+        if (declarationsTracker == null) {
+          server.sendResponse(Response.unsupportedFeature(
+              request.id, 'Completion is not enabled.'));
+          return;
+        }
+
+        var completionRequest = DartCompletionRequest.forResolvedUnit(
+          resolvedUnit: resolvedUnit,
+          offset: offset,
+          dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(
+            resolvedUnit,
+          ),
+          documentationCache: server.getDocumentationCacheFor(resolvedUnit),
+        );
+
+        var completionId = (_nextCompletionId++).toString();
+
+        setNewRequest(completionRequest);
+
+        // initial response without results
+        server.sendResponse(CompletionGetSuggestionsResult(completionId)
+            .toResponse(request.id));
+
+        // If the client opted into using available suggestion sets,
+        // create the kinds set, so signal the completion manager about opt-in.
+        Set<ElementKind>? includedElementKinds;
+        Set<String>? includedElementNames;
+        List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
+        if (subscriptions
+            .contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+          includedElementKinds = <ElementKind>{};
+          includedElementNames = <String>{};
+          includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+        }
+
+        // Compute suggestions in the background
+        try {
+          var suggestions = <CompletionSuggestion>[];
+          try {
+            suggestions = await computeSuggestions(
+              budget: budget,
+              performance: performance,
+              request: completionRequest,
+              includedElementKinds: includedElementKinds,
+              includedElementNames: includedElementNames,
+              includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+            );
+          } on AbortCompletion {
+            // Continue with empty suggestions list.
+          }
+          String? libraryFile;
+          var includedSuggestionSets = <IncludedSuggestionSet>[];
+          if (includedElementKinds != null && includedElementNames != null) {
+            libraryFile = resolvedUnit.libraryElement.source.fullName;
+            server.sendNotification(
+              createExistingImportsNotification(resolvedUnit),
+            );
+            computeIncludedSetList(
+              declarationsTracker,
+              completionRequest,
+              includedSuggestionSets,
+              includedElementNames,
+            );
+          }
+
+          const SEND_NOTIFICATION_TAG = 'send notification';
+          performance.run(SEND_NOTIFICATION_TAG, (_) {
+            sendCompletionNotification(
+              completionId,
+              completionRequest.replacementOffset,
+              completionRequest.replacementLength,
+              suggestions,
+              libraryFile,
+              includedSuggestionSets,
+              includedElementKinds?.toList(),
+              includedSuggestionRelevanceTags,
+            );
+          });
+
+          completionPerformance.suggestionCount = suggestions.length;
+        } finally {
+          ifMatchesRequestClear(completionRequest);
+        }
+      },
+    );
   }
 
   /// Send completion notification results.
@@ -670,11 +731,8 @@
   _RequestToPlugins? _sendRequestToPlugins(
     DartCompletionRequest completionRequest,
   ) {
-    var resolvedUnit = completionRequest.result;
-    var analysisContext = resolvedUnit.session.analysisContext;
-
     var pluginRequestParameters = plugin.CompletionGetSuggestionsParams(
-      resolvedUnit.path,
+      completionRequest.path,
       completionRequest.offset,
     );
 
@@ -683,7 +741,7 @@
       parameters: pluginRequestParameters,
       futures: server.pluginManager.broadcastRequest(
         pluginRequestParameters,
-        contextRoot: analysisContext.contextRoot,
+        contextRoot: completionRequest.analysisContext.contextRoot,
       ),
     );
   }
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index f047af1..5550f0b 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -8,7 +8,6 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source.dart';
 
 /// Instances of the class [ExecutionDomainHandler] implement a [RequestHandler]
 /// that handles requests in the `execution` domain.
@@ -122,10 +121,10 @@
       }
 
       var source = driver.fsState.getFileForPath(file).source;
-      if (source.uriKind != UriKind.FILE_URI) {
+      if (!source.uri.isScheme('file')) {
         uri = source.uri.toString();
       } else {
-        uri = sourceFactory.restoreUri(source).toString();
+        uri = sourceFactory.pathToUri(file).toString();
       }
       return ExecutionMapUriResult(uri: uri).toResponse(request.id);
     } else if (uri != null) {
diff --git a/pkg/analysis_server/lib/src/domain_server.dart b/pkg/analysis_server/lib/src/domain_server.dart
index 5dca197..559f3b8 100644
--- a/pkg/analysis_server/lib/src/domain_server.dart
+++ b/pkg/analysis_server/lib/src/domain_server.dart
@@ -19,7 +19,9 @@
 
   /// Return the version number of the analysis server.
   Response getVersion(Request request) {
-    return ServerGetVersionResult(PROTOCOL_VERSION).toResponse(request.id);
+    return ServerGetVersionResult(
+      server.options.reportProtocolVersion ?? PROTOCOL_VERSION,
+    ).toResponse(request.id);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index 1d4b4b5..e8838ce 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -3,29 +3,29 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 
-/// Compute which suggestion sets should be included into completion inside
-/// the given [resolvedUnit] of a file.  Depending on the file path, it might
+/// Compute which suggestion sets should be included into completion for
+/// the given completion [request].  Depending on the file path, it might
 /// include different sets, e.g. inside the `lib/` directory of a `Pub` package
 /// only regular dependencies can be referenced, but `test/` can reference
 /// both regular and "dev" dependencies.
 void computeIncludedSetList(
   DeclarationsTracker tracker,
-  ResolvedUnitResult resolvedUnit,
+  DartCompletionRequest request,
   List<protocol.IncludedSuggestionSet> includedSetList,
   Set<String> includedElementNames,
 ) {
-  var analysisContext = resolvedUnit.session.analysisContext;
-  var context = tracker.getContext(analysisContext);
+  var context = tracker.getContext(request.analysisContext);
   if (context == null) return;
 
-  var librariesObject = context.getLibraries(resolvedUnit.path);
+  var librariesObject = context.getLibraries(request.path);
 
-  var importedUriSet = resolvedUnit.libraryElement.importedLibraries
+  var importedUriSet = request.libraryElement.importedLibraries
       .map((importedLibrary) => importedLibrary.source.uri)
       .toSet();
 
@@ -48,7 +48,7 @@
       protocol.IncludedSuggestionSet(
         library.id,
         relevance,
-        displayUri: _getRelativeFileUri(resolvedUnit, library.uri),
+        displayUri: _getRelativeFileUri(request, library.uri),
       ),
     );
 
@@ -172,11 +172,11 @@
 }
 
 /// Computes the best URI to import [what] into the [unit] library.
-String? _getRelativeFileUri(ResolvedUnitResult unit, Uri what) {
+String? _getRelativeFileUri(DartCompletionRequest request, Uri what) {
   if (what.scheme == 'file') {
-    var pathContext = unit.session.resourceProvider.pathContext;
+    var pathContext = request.analysisSession.resourceProvider.pathContext;
 
-    var libraryPath = unit.libraryElement.source.fullName;
+    var libraryPath = request.libraryElement.source.fullName;
     var libraryFolder = pathContext.dirname(libraryPath);
 
     var whatPath = pathContext.fromUri(what);
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index a2f6ea6..e0eedc4 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -69,7 +69,7 @@
       return RuntimeCompletionResult([], []);
     }
 
-    var dartRequest = DartCompletionRequest(
+    var dartRequest = DartCompletionRequest.forResolvedUnit(
       resolvedUnit: targetResult,
       offset: targetOffset,
     );
diff --git a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
index ed1ea21..a86e794 100644
--- a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
@@ -80,7 +80,7 @@
       return;
     }
     _instrumentationService.logRequest(data);
-    final Map<String, Object?> json = jsonDecode(data);
+    final json = jsonDecode(data) as Map<String, Object?>;
     if (RequestMessage.canParse(json, nullLspJsonReporter)) {
       onMessage(RequestMessage.fromJson(json));
     } else if (NotificationMessage.canParse(json, nullLspJsonReporter)) {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
index 20c4d27..4de8bfe 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
@@ -120,7 +120,7 @@
         final refactor = ExtractMethodRefactoring(
             server.searchEngine, result, offset, length);
 
-        var preferredName = options != null ? options['name'] : null;
+        var preferredName = options != null ? options['name'] as String : null;
         // checkInitialConditions will populate names with suggestions.
         if (preferredName == null) {
           await refactor.checkInitialConditions();
@@ -138,7 +138,7 @@
       case RefactoringKind.EXTRACT_LOCAL_VARIABLE:
         final refactor = ExtractLocalRefactoring(result, offset, length);
 
-        var preferredName = options != null ? options['name'] : null;
+        var preferredName = options != null ? options['name'] as String : null;
         // checkInitialConditions will populate names with suggestions.
         if (preferredName == null) {
           await refactor.checkInitialConditions();
@@ -162,7 +162,7 @@
         // to handle this better.
         // https://github.com/microsoft/language-server-protocol/issues/764
         refactor.name =
-            (options != null ? options['name'] : null) ?? 'NewWidget';
+            options != null ? options['name'] as String : 'NewWidget';
         return success(refactor);
 
       case RefactoringKind.INLINE_LOCAL_VARIABLE:
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 9f7152c..ecc14cc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -36,10 +36,11 @@
   // CodeAction class).
   final codeActionPriorities = Expando<int>();
 
-  /// A comparator that can be used to sort [CodeActions]s using priorties
-  /// in [codeActionPriorities]. The highest number priority will be sorted
-  /// before lower number priorityies. Items with the same relevance are sorted
-  /// alphabetically by their title.
+  /// A comparator that can be used to sort [CodeActions]s using priorities
+  /// in [codeActionPriorities].
+  ///
+  /// The highest number priority will be sorted before lower number priorities.
+  /// Items with the same priority are sorted alphabetically by their title.
   late final Comparator<CodeAction> _codeActionComparator =
       (CodeAction a, CodeAction b) {
     // We should never be sorting actions without priorities.
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 85f3765..10e4cf9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -26,6 +26,7 @@
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -202,216 +203,223 @@
     String? triggerCharacter,
     CancellationToken token,
   ) async {
-    final performance = CompletionPerformance();
-    performance.path = unit.path;
-    performance.setContentsAndOffset(unit.content, offset);
-    server.performanceStats.completion.add(performance);
-
-    return await performance.runRequestOperation((perf) async {
-      final completionRequest = DartCompletionRequest(
-        resolvedUnit: unit,
-        offset: offset,
-        dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(unit),
-        completionPreference: CompletionPreference.replace,
-      );
-      final target = completionRequest.target;
-
-      if (triggerCharacter != null) {
-        if (!_triggerCharacterValid(offset, triggerCharacter, target)) {
-          return success([]);
-        }
-      }
-
-      Set<ElementKind>? includedElementKinds;
-      Set<String>? includedElementNames;
-      List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
-      if (includeSuggestionSets) {
-        includedElementKinds = <ElementKind>{};
-        includedElementNames = <String>{};
-        includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
-      }
-
-      try {
-        var contributor = DartCompletionManager(
-          budget: CompletionBudget(CompletionBudget.defaultDuration),
-          includedElementKinds: includedElementKinds,
-          includedElementNames: includedElementNames,
-          includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+    var performance = OperationPerformanceImpl('<root>');
+    return await performance.runAsync(
+      'request',
+      (performance) async {
+        final completionPerformance = CompletionPerformance(
+          operation: performance,
+          path: unit.path,
+          content: unit.content,
+          offset: offset,
         );
+        server.performanceStats.completion.add(completionPerformance);
 
-        final serverSuggestions = await contributor.computeSuggestions(
-          completionRequest,
-          perf,
+        final completionRequest = DartCompletionRequest.forResolvedUnit(
+          resolvedUnit: unit,
+          offset: offset,
+          dartdocDirectiveInfo: server.getDartdocDirectiveInfoFor(unit),
+          completionPreference: CompletionPreference.replace,
         );
+        final target = completionRequest.target;
 
-        final insertLength = _computeInsertLength(
-          offset,
-          completionRequest.replacementOffset,
-          completionRequest.replacementLength,
-        );
-
-        if (token.isCancellationRequested) {
-          return cancelled();
+        if (triggerCharacter != null) {
+          if (!_triggerCharacterValid(offset, triggerCharacter, target)) {
+            return success([]);
+          }
         }
 
-        /// completeFunctionCalls should be suppressed if the target is an
-        /// invocation that already has an argument list, otherwise we would
-        /// insert dupes.
-        final completeFunctionCalls = _hasExistingArgList(target.entity)
-            ? false
-            : server.clientConfiguration.global.completeFunctionCalls;
+        Set<ElementKind>? includedElementKinds;
+        Set<String>? includedElementNames;
+        List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags;
+        if (includeSuggestionSets) {
+          includedElementKinds = <ElementKind>{};
+          includedElementNames = <String>{};
+          includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+        }
 
-        final results = serverSuggestions.map(
-          (item) {
-            var itemReplacementOffset =
-                item.replacementOffset ?? completionRequest.replacementOffset;
-            var itemReplacementLength =
-                item.replacementLength ?? completionRequest.replacementLength;
-            var itemInsertLength = insertLength;
-
-            // Recompute the insert length if it may be affected by the above.
-            if (item.replacementOffset != null ||
-                item.replacementLength != null) {
-              itemInsertLength = _computeInsertLength(
-                  offset, itemReplacementOffset, itemInsertLength);
-            }
-
-            return toCompletionItem(
-              capabilities,
-              unit.lineInfo,
-              item,
-              itemReplacementOffset,
-              itemInsertLength,
-              itemReplacementLength,
-              // TODO(dantup): Including commit characters in every completion
-              // increases the payload size. The LSP spec is ambigious
-              // about how this should be handled (and VS Code requires it) but
-              // this should be removed (or made conditional based on a capability)
-              // depending on how the spec is updated.
-              // https://github.com/microsoft/vscode-languageserver-node/issues/673
-              includeCommitCharacters:
-                  server.clientConfiguration.global.previewCommitCharacters,
-              completeFunctionCalls: completeFunctionCalls,
-            );
-          },
-        ).toList();
-
-        // Now compute items in suggestion sets.
-        var includedSuggestionSets = <IncludedSuggestionSet>[];
-        final declarationsTracker = server.declarationsTracker;
-        if (declarationsTracker != null &&
-            includedElementKinds != null &&
-            includedElementNames != null &&
-            includedSuggestionRelevanceTags != null) {
-          computeIncludedSetList(
-            declarationsTracker,
-            unit,
-            includedSuggestionSets,
-            includedElementNames,
+        try {
+          var contributor = DartCompletionManager(
+            budget: CompletionBudget(CompletionBudget.defaultDuration),
+            includedElementKinds: includedElementKinds,
+            includedElementNames: includedElementNames,
+            includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
           );
 
-          // Build a fast lookup for imported symbols so that we can filter out
-          // duplicates.
-          final alreadyImportedSymbols = _buildLookupOfImportedSymbols(unit);
+          final serverSuggestions = await contributor.computeSuggestions(
+            completionRequest,
+            performance,
+          );
 
-          includedSuggestionSets.forEach((includedSet) {
-            final library = declarationsTracker.getLibrary(includedSet.id);
-            if (library == null) {
-              return;
-            }
+          final insertLength = _computeInsertLength(
+            offset,
+            completionRequest.replacementOffset,
+            completionRequest.replacementLength,
+          );
 
-            // Make a fast lookup for tag relevance.
-            final tagBoosts = <String, int>{};
-            includedSuggestionRelevanceTags!
-                .forEach((t) => tagBoosts[t.tag] = t.relevanceBoost);
+          if (token.isCancellationRequested) {
+            return cancelled();
+          }
 
-            // Only specific types of child declarations should be included.
-            // This list matches what's in _protocolAvailableSuggestion in
-            // the DAS implementation.
-            bool shouldIncludeChild(Declaration child) =>
-                child.kind == DeclarationKind.CONSTRUCTOR ||
-                child.kind == DeclarationKind.ENUM_CONSTANT ||
-                (child.kind == DeclarationKind.GETTER && child.isStatic) ||
-                (child.kind == DeclarationKind.FIELD && child.isStatic);
+          /// completeFunctionCalls should be suppressed if the target is an
+          /// invocation that already has an argument list, otherwise we would
+          /// insert dupes.
+          final completeFunctionCalls = _hasExistingArgList(target.entity)
+              ? false
+              : server.clientConfiguration.global.completeFunctionCalls;
 
-            // Collect declarations and their children.
-            final allDeclarations = library.declarations
-                .followedBy(library.declarations
-                    .expand((decl) => decl.children.where(shouldIncludeChild)))
-                .toList();
+          final results = serverSuggestions.map(
+            (item) {
+              var itemReplacementOffset =
+                  item.replacementOffset ?? completionRequest.replacementOffset;
+              var itemReplacementLength =
+                  item.replacementLength ?? completionRequest.replacementLength;
+              var itemInsertLength = insertLength;
 
-            final setResults = allDeclarations
-                // Filter to only the kinds we should return.
-                .where((item) => includedElementKinds!
-                    .contains(protocolElementKind(item.kind)))
-                .where((item) {
-              // Check existing imports to ensure we don't already import
-              // this element (this exact element from its declaring
-              // library, not just something with the same name). If we do
-              // we'll want to skip it.
-              final declaringUri =
-                  item.parent?.locationLibraryUri ?? item.locationLibraryUri!;
+              // Recompute the insert length if it may be affected by the above.
+              if (item.replacementOffset != null ||
+                  item.replacementLength != null) {
+                itemInsertLength = _computeInsertLength(
+                    offset, itemReplacementOffset, itemInsertLength);
+              }
 
-              // For enums and named constructors, only the parent enum/class is in
-              // the list of imported symbols so we use the parents name.
-              final nameKey = item.kind == DeclarationKind.ENUM_CONSTANT ||
-                      item.kind == DeclarationKind.CONSTRUCTOR
-                  ? item.parent!.name
-                  : item.name;
-              final key = _createImportedSymbolKey(nameKey, declaringUri);
-              final importingUris = alreadyImportedSymbols[key];
+              return toCompletionItem(
+                capabilities,
+                unit.lineInfo,
+                item,
+                itemReplacementOffset,
+                itemInsertLength,
+                itemReplacementLength,
+                // TODO(dantup): Including commit characters in every completion
+                // increases the payload size. The LSP spec is ambigious
+                // about how this should be handled (and VS Code requires it) but
+                // this should be removed (or made conditional based on a capability)
+                // depending on how the spec is updated.
+                // https://github.com/microsoft/vscode-languageserver-node/issues/673
+                includeCommitCharacters:
+                    server.clientConfiguration.global.previewCommitCharacters,
+                completeFunctionCalls: completeFunctionCalls,
+              );
+            },
+          ).toList();
 
-              // Keep it only if:
-              // - no existing imports include it
-              //     (in which case all libraries will be offered as
-              //     auto-imports)
-              // - this is the first imported URI that includes it
-              //     (we don't want to repeat it for each imported library that
-              //     includes it)
-              return importingUris == null ||
-                  importingUris.first == '${library.uri}';
-            }).map((item) => declarationToCompletionItem(
-                      capabilities,
-                      unit.path,
-                      offset,
-                      includedSet,
-                      library,
-                      tagBoosts,
-                      unit.lineInfo,
-                      item,
-                      completionRequest.replacementOffset,
-                      insertLength,
-                      completionRequest.replacementLength,
-                      // TODO(dantup): Including commit characters in every completion
-                      // increases the payload size. The LSP spec is ambigious
-                      // about how this should be handled (and VS Code requires it) but
-                      // this should be removed (or made conditional based on a capability)
-                      // depending on how the spec is updated.
-                      // https://github.com/microsoft/vscode-languageserver-node/issues/673
-                      includeCommitCharacters: server
-                          .clientConfiguration.global.previewCommitCharacters,
-                      completeFunctionCalls: completeFunctionCalls,
-                    ));
-            results.addAll(setResults);
-          });
+          // Now compute items in suggestion sets.
+          var includedSuggestionSets = <IncludedSuggestionSet>[];
+          final declarationsTracker = server.declarationsTracker;
+          if (declarationsTracker != null &&
+              includedElementKinds != null &&
+              includedElementNames != null &&
+              includedSuggestionRelevanceTags != null) {
+            computeIncludedSetList(
+              declarationsTracker,
+              completionRequest,
+              includedSuggestionSets,
+              includedElementNames,
+            );
+
+            // Build a fast lookup for imported symbols so that we can filter out
+            // duplicates.
+            final alreadyImportedSymbols = _buildLookupOfImportedSymbols(unit);
+
+            includedSuggestionSets.forEach((includedSet) {
+              final library = declarationsTracker.getLibrary(includedSet.id);
+              if (library == null) {
+                return;
+              }
+
+              // Make a fast lookup for tag relevance.
+              final tagBoosts = <String, int>{};
+              includedSuggestionRelevanceTags!
+                  .forEach((t) => tagBoosts[t.tag] = t.relevanceBoost);
+
+              // Only specific types of child declarations should be included.
+              // This list matches what's in _protocolAvailableSuggestion in
+              // the DAS implementation.
+              bool shouldIncludeChild(Declaration child) =>
+                  child.kind == DeclarationKind.CONSTRUCTOR ||
+                  child.kind == DeclarationKind.ENUM_CONSTANT ||
+                  (child.kind == DeclarationKind.GETTER && child.isStatic) ||
+                  (child.kind == DeclarationKind.FIELD && child.isStatic);
+
+              // Collect declarations and their children.
+              final allDeclarations = library.declarations
+                  .followedBy(library.declarations.expand(
+                      (decl) => decl.children.where(shouldIncludeChild)))
+                  .toList();
+
+              final setResults = allDeclarations
+                  // Filter to only the kinds we should return.
+                  .where((item) => includedElementKinds!
+                      .contains(protocolElementKind(item.kind)))
+                  .where((item) {
+                // Check existing imports to ensure we don't already import
+                // this element (this exact element from its declaring
+                // library, not just something with the same name). If we do
+                // we'll want to skip it.
+                final declaringUri =
+                    item.parent?.locationLibraryUri ?? item.locationLibraryUri!;
+
+                // For enums and named constructors, only the parent enum/class is in
+                // the list of imported symbols so we use the parents name.
+                final nameKey = item.kind == DeclarationKind.ENUM_CONSTANT ||
+                        item.kind == DeclarationKind.CONSTRUCTOR
+                    ? item.parent!.name
+                    : item.name;
+                final key = _createImportedSymbolKey(nameKey, declaringUri);
+                final importingUris = alreadyImportedSymbols[key];
+
+                // Keep it only if:
+                // - no existing imports include it
+                //     (in which case all libraries will be offered as
+                //     auto-imports)
+                // - this is the first imported URI that includes it
+                //     (we don't want to repeat it for each imported library that
+                //     includes it)
+                return importingUris == null ||
+                    importingUris.first == '${library.uri}';
+              }).map((item) => declarationToCompletionItem(
+                        capabilities,
+                        unit.path,
+                        offset,
+                        includedSet,
+                        library,
+                        tagBoosts,
+                        unit.lineInfo,
+                        item,
+                        completionRequest.replacementOffset,
+                        insertLength,
+                        completionRequest.replacementLength,
+                        // TODO(dantup): Including commit characters in every completion
+                        // increases the payload size. The LSP spec is ambigious
+                        // about how this should be handled (and VS Code requires it) but
+                        // this should be removed (or made conditional based on a capability)
+                        // depending on how the spec is updated.
+                        // https://github.com/microsoft/vscode-languageserver-node/issues/673
+                        includeCommitCharacters: server
+                            .clientConfiguration.global.previewCommitCharacters,
+                        completeFunctionCalls: completeFunctionCalls,
+                      ));
+              results.addAll(setResults);
+            });
+          }
+
+          // Perform fuzzy matching based on the identifier in front of the caret to
+          // reduce the size of the payload.
+          final fuzzyPattern = completionRequest.targetPrefix;
+          final fuzzyMatcher =
+              FuzzyMatcher(fuzzyPattern, matchStyle: MatchStyle.TEXT);
+
+          final matchingResults =
+              results.where((e) => fuzzyMatcher.score(e.label) > 0).toList();
+
+          completionPerformance.suggestionCount = results.length;
+
+          return success(matchingResults);
+        } on AbortCompletion {
+          return success([]);
         }
-
-        // Perform fuzzy matching based on the identifier in front of the caret to
-        // reduce the size of the payload.
-        final fuzzyPattern = completionRequest.targetPrefix;
-        final fuzzyMatcher =
-            FuzzyMatcher(fuzzyPattern, matchStyle: MatchStyle.TEXT);
-
-        final matchingResults =
-            results.where((e) => fuzzyMatcher.score(e.label) > 0).toList();
-
-        performance.suggestionCount = results.length;
-
-        return success(matchingResults);
-      } on AbortCompletion {
-        return success([]);
-      }
-    });
+      },
+    );
   }
 
   Future<ErrorOr<List<CompletionItem>>> _getServerYamlItems(
@@ -474,7 +482,9 @@
     return (node is ast.InvocationExpression &&
             !node.argumentList.beginToken.isSynthetic) ||
         (node is ast.InstanceCreationExpression &&
-            !node.argumentList.beginToken.isSynthetic);
+            !node.argumentList.beginToken.isSynthetic) ||
+        // "ClassName.^()" will appear as accessing a property named '('.
+        (node is ast.PropertyAccess && node.propertyName.name.startsWith('('));
   }
 
   Iterable<CompletionItem> _pluginResultsToItems(
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
index 30935d6..72903a8 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
@@ -60,11 +60,12 @@
           'Requests not before server is initilized');
     }
 
-    final lineInfo = server.getLineInfo(data.file);
+    final file = data.file;
+    final lineInfo = server.getLineInfo(file);
     if (lineInfo == null) {
       return error(
         ErrorCodes.InternalError,
-        'Line info not available for ${data.file}',
+        'Line info not available for $file',
         null,
       );
     }
@@ -99,7 +100,7 @@
     _latestCompletionItem = item;
     while (item == _latestCompletionItem && timer.elapsed < timeout) {
       try {
-        final analysisDriver = server.getAnalysisDriver(data.file);
+        final analysisDriver = server.getAnalysisDriver(file);
         final session = analysisDriver?.currentSession;
 
         // We shouldn't not get a driver/session, but if we did perhaps the file
@@ -139,7 +140,7 @@
 
         var newInsertText = item.insertText ?? item.label;
         final builder = ChangeBuilder(session: session);
-        await builder.addDartFileEdit(data.file, (builder) {
+        await builder.addDartFileEdit(file, (builder) {
           final result = builder.importLibraryElement(library.uri);
           if (result.prefix != null) {
             newInsertText = '${result.prefix}.$newInsertText';
@@ -152,9 +153,9 @@
 
         final changes = builder.sourceChange;
         final thisFilesChanges =
-            changes.edits.where((e) => e.file == data.file).toList();
+            changes.edits.where((e) => e.file == file).toList();
         final otherFilesChanges =
-            changes.edits.where((e) => e.file != data.file).toList();
+            changes.edits.where((e) => e.file != file).toList();
 
         // If this completion involves editing other files, we'll need to build
         // a command that the client will call to apply those edits later.
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_color.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_color.dart
new file mode 100644
index 0000000..07bf25b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_color.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/computer/computer_color.dart'
+    show ColorComputer, ColorReference;
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+/// Handles textDocument/documentColor requests.
+///
+/// This request is sent by the client to the server to request the locations
+/// of any colors in the document so that it can render color previews. If the
+/// editor has a color picker, it may also call textDocument/colorPresentation
+/// to obtain the code to insert when a new color is selected (see
+/// [DocumentColorPresentationHandler]).
+class DocumentColorHandler
+    extends MessageHandler<DocumentColorParams, List<ColorInformation>> {
+  DocumentColorHandler(LspAnalysisServer server) : super(server);
+  @override
+  Method get handlesMessage => Method.textDocument_documentColor;
+
+  @override
+  LspJsonHandler<DocumentColorParams> get jsonHandler =>
+      DocumentColorParams.jsonHandler;
+
+  @override
+  Future<ErrorOr<List<ColorInformation>>> handle(
+      DocumentColorParams params, CancellationToken token) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success([]);
+    }
+
+    final path = pathOfDoc(params.textDocument);
+    final unit = await path.mapResult(requireResolvedUnit);
+    return unit.mapResult((unit) => _getColors(unit));
+  }
+
+  ErrorOr<List<ColorInformation>> _getColors(ResolvedUnitResult unit) {
+    ColorInformation _toColorInformation(ColorReference reference) {
+      return ColorInformation(
+        range: toRange(unit.lineInfo, reference.offset, reference.length),
+        color: Color(
+          // LSP colors are decimal in the range 0-1 but our internal references
+          // are 0-255, so divide them.
+          alpha: reference.color.alpha / 255,
+          red: reference.color.red / 255,
+          green: reference.color.green / 255,
+          blue: reference.color.blue / 255,
+        ),
+      );
+    }
+
+    final computer = ColorComputer(unit);
+    final colors = computer.compute();
+    return success(colors.map(_toColorInformation).toList());
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_color_presentation.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_color_presentation.dart
new file mode 100644
index 0000000..06fdd44
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_color_presentation.dart
@@ -0,0 +1,169 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/utilities/flutter.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+
+/// Handles textDocument/colorPresentation.
+///
+/// This request is sent by the client if it allowed the user to pick a color
+/// using a color picker (in a location returned by textDocument/documentColor)
+/// and needs a representation of this color, including the edits to insert it
+/// into the source file.
+class DocumentColorPresentationHandler
+    extends MessageHandler<ColorPresentationParams, List<ColorPresentation>> {
+  DocumentColorPresentationHandler(LspAnalysisServer server) : super(server);
+  @override
+  Method get handlesMessage => Method.textDocument_colorPresentation;
+
+  @override
+  LspJsonHandler<ColorPresentationParams> get jsonHandler =>
+      ColorPresentationParams.jsonHandler;
+
+  @override
+  Future<ErrorOr<List<ColorPresentation>>> handle(
+    ColorPresentationParams params,
+    CancellationToken token,
+  ) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success([]);
+    }
+
+    final path = pathOfDoc(params.textDocument);
+    final unit = await path.mapResult(requireResolvedUnit);
+    return unit.mapResult((unit) => _getPresentations(params, unit));
+  }
+
+  /// Converts individual 0-255 ARGB values into a single int value as
+  /// 0xAARRGGBB as used by the dart:ui Color class.
+  int _colorValueForComponents(int alpha, int red, int green, int blue) {
+    return (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+  }
+
+  /// Creates a [ColorPresentation] for inserting code to produce a dart:ui
+  /// or Flutter Color at [editRange].
+  ///
+  /// [colorType] is the Type of the Color class whose constructor will be
+  /// called. This will be replaced into [editRange] and any required import
+  /// statement will produce additional edits.
+  ///
+  /// [label] is the visible label shown to the user and should roughly reflect
+  /// the code that will be inserted.
+  ///
+  /// [invocationString] is written immediately after [colorType] in [editRange].
+  Future<ColorPresentation> _createColorPresentation(
+    ResolvedUnitResult unit,
+    SourceRange editRange,
+    ClassElement colorType,
+    String label,
+    String invocationString,
+  ) async {
+    final builder = ChangeBuilder(session: unit.session);
+    await builder.addDartFileEdit(unit.path, (builder) {
+      builder.addReplacement(editRange, (builder) {
+        builder.writeType(colorType.thisType);
+        builder.write(invocationString);
+      });
+    });
+
+    // We can only apply changes to the same file, so filter any change from the
+    // builder to only include this file, otherwise we may corrupt the users
+    // source (although hopefully we don't produce edits for other files).
+    final editsForThisFile = builder.sourceChange.edits
+        .where((edit) => edit.file == unit.path)
+        .expand((edit) => edit.edits)
+        .toList();
+
+    // LSP requires that we separate the main edit (changing the color code)
+    // from anything else (imports).
+    final mainEdit =
+        editsForThisFile.singleWhere((edit) => edit.offset == editRange.offset);
+    final otherEdits =
+        editsForThisFile.where((edit) => edit.offset != editRange.offset);
+
+    return ColorPresentation(
+      label: label,
+      textEdit: toTextEdit(unit.lineInfo, mainEdit),
+      additionalTextEdits: otherEdits.isNotEmpty
+          ? otherEdits.map((edit) => toTextEdit(unit.lineInfo, edit)).toList()
+          : null,
+    );
+  }
+
+  /// Builds a list of valid color presentations for the requested color.
+  Future<ErrorOr<List<ColorPresentation>>> _getPresentations(
+    ColorPresentationParams params,
+    ResolvedUnitResult unit,
+  ) async {
+    // The values in LSP are decimals 0-1 so should be scaled up to 255 that
+    // we use internally (except for opacity is which 0-1).
+    final alpha = (params.color.alpha * 255).toInt();
+    final red = (params.color.red * 255).toInt();
+    final green = (params.color.green * 255).toInt();
+    final blue = (params.color.blue * 255).toInt();
+    final opacity = params.color.alpha;
+
+    final editStart = toOffset(unit.lineInfo, params.range.start);
+    final editEnd = toOffset(unit.lineInfo, params.range.end);
+
+    if (editStart.isError) return failure(editStart);
+    if (editEnd.isError) return failure(editEnd);
+
+    final editRange =
+        SourceRange(editStart.result, editEnd.result - editStart.result);
+
+    final sessionHelper = AnalysisSessionHelper(unit.session);
+    final flutter = Flutter.instance;
+    final colorType = await sessionHelper.getClass(flutter.widgetsUri, 'Color');
+    if (colorType == null) {
+      // If we can't find the class (perhaps because this isn't a Flutter
+      // project) we will not include any results. In theory the client should
+      // not be calling this request in that case.
+      return success([]);
+    }
+
+    final colorValue = _colorValueForComponents(alpha, red, green, blue);
+    final colorValueHex =
+        '0x${colorValue.toRadixString(16).toUpperCase().padLeft(8, '0')}';
+
+    final colorFromARGB = await _createColorPresentation(
+      unit,
+      editRange,
+      colorType,
+      'Color.fromARGB($alpha, $red, $green, $blue)',
+      '.fromARGB($alpha, $red, $green, $blue)',
+    );
+
+    final colorFromRGBO = await _createColorPresentation(
+      unit,
+      editRange,
+      colorType,
+      'Color.fromRGBO($red, $green, $blue, $opacity)',
+      '.fromRGBO($red, $green, $blue, $opacity)',
+    );
+
+    final colorDefault = await _createColorPresentation(
+      unit,
+      editRange,
+      colorType,
+      'Color($colorValueHex)',
+      '($colorValueHex)',
+    );
+
+    return success([
+      colorFromARGB,
+      colorFromRGBO,
+      colorDefault,
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index c0e413d..0d9eb19 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -15,6 +15,8 @@
 import 'package:analysis_server/src/lsp/handlers/handler_completion.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_completion_resolve.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_definition.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_document_color.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_document_color_presentation.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_document_highlights.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_document_symbols.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_execute_command.dart';
@@ -77,6 +79,8 @@
       server,
       server.initializationOptions.suggestFromUnimportedLibraries,
     ));
+    registerHandler(DocumentColorHandler(server));
+    registerHandler(DocumentColorPresentationHandler(server));
     registerHandler(CompletionResolveHandler(server));
     registerHandler(SignatureHelpHandler(server));
     registerHandler(DefinitionHandler(server));
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
index 96a2cae..435013c 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
@@ -7,7 +7,7 @@
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
-import 'package:analysis_server/src/search/workspace_symbols.dart' as search;
+import 'package:analyzer/src/dart/analysis/search.dart' as search;
 
 class WorkspaceSymbolHandler
     extends MessageHandler<WorkspaceSymbolParams, List<SymbolInformation>> {
@@ -52,24 +52,19 @@
     // huge numbers on large projects.
     var remainingResults = 500;
 
-    final filePathsHashSet = <String>{};
-    final tracker = server.declarationsTracker!;
-    final declarations = search.WorkspaceSymbols(tracker).declarations(
-      regex,
-      remainingResults,
-      filePathsHashSet,
-    );
-
-    // Convert the file paths to something we can quickly index into since
-    // we'll be looking things up by index a lot.
-    final filePaths = filePathsHashSet.toList();
+    var workspaceSymbols = search.WorkspaceSymbols();
+    var analysisDrivers = server.driverMap.values.toList();
+    for (var analysisDriver in analysisDrivers) {
+      await analysisDriver.search
+          .declarations(workspaceSymbols, regex, remainingResults);
+    }
 
     // Map the results to SymbolInformations and flatten the list of lists.
-    final symbols = declarations
+    final symbols = workspaceSymbols.declarations
         .map((declaration) => _asSymbolInformation(
               declaration,
               supportedSymbolKinds,
-              filePaths,
+              workspaceSymbols.files,
             ))
         .toList();
 
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 6b87d05..6b2ed52 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -134,7 +134,8 @@
   FutureOr<ErrorOr<R>> handleMessage(
       IncomingMessage message, CancellationToken token) {
     final reporter = LspJsonReporter('params');
-    if (!jsonHandler.validateParams(message.params, reporter)) {
+    final paramsJson = message.params as Map<String, Object?>?;
+    if (!jsonHandler.validateParams(paramsJson, reporter)) {
       return error(
         ErrorCodes.InvalidParams,
         'Invalid params for ${message.method}:\n'
@@ -144,9 +145,8 @@
       );
     }
 
-    final params = message.params != null
-        ? jsonHandler.convertParams(message.params)
-        : null as P;
+    final params =
+        paramsJson != null ? jsonHandler.convertParams(paramsJson) : null as P;
     return handle(params, token);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index d33a96e..cf22460 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -374,17 +374,18 @@
 
   /// Logs an exception by sending it to the client (window/logMessage) and
   /// recording it in a buffer on the server for diagnostics.
-  void logException(String message, exception, stackTrace) {
+  void logException(String message, Object exception, StackTrace? stackTrace) {
     var fullMessage = message;
     if (exception is CaughtException) {
       stackTrace ??= exception.stackTrace;
       fullMessage = '$fullMessage: ${exception.exception}';
-    } else if (exception != null) {
+    } else {
       fullMessage = '$fullMessage: $exception';
     }
 
     final fullError =
         stackTrace == null ? fullMessage : '$fullMessage\n$stackTrace';
+    stackTrace ??= StackTrace.current;
 
     // Log the full message since showMessage above may be truncated or
     // formatted badly (eg. VS Code takes the newlines out).
@@ -394,7 +395,7 @@
     exceptions.add(ServerException(
       message,
       exception,
-      stackTrace is StackTrace ? stackTrace : StackTrace.current,
+      stackTrace,
       false,
     ));
 
@@ -550,9 +551,10 @@
   }
 
   @override
-  void sendServerErrorNotification(String message, exception, stackTrace,
+  void sendServerErrorNotification(
+      String message, Object exception, StackTrace? stackTrace,
       {bool fatal = false}) {
-    message = exception == null ? message : '$message: $exception';
+    message = '$message: $exception';
 
     // Show message (without stack) to the user.
     showErrorMessageToUser(message);
@@ -652,9 +654,9 @@
 
   /// There was an error related to the socket from which messages are being
   /// read.
-  void socketError(error, stack) {
+  void socketError(Object error, StackTrace? stackTrace) {
     // Don't send to instrumentation service; not an internal error.
-    sendServerErrorNotification('Socket error', error, stack);
+    sendServerErrorNotification('Socket error', error, stackTrace);
   }
 
   Future<void> updateWorkspaceFolders(
@@ -670,7 +672,7 @@
     _refreshAnalysisRoots();
   }
 
-  void _afterOverlayChanged(String path, dynamic changeForPlugins) {
+  void _afterOverlayChanged(String path, plugin.HasToJson changeForPlugins) {
     driverMap.values.forEach((driver) => driver.changeFile(path));
     pluginManager.setAnalysisUpdateContentParams(
       plugin.AnalysisUpdateContentParams({path: changeForPlugins}),
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 3a3e421..ffabd19 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -20,12 +20,12 @@
 import 'package:analysis_server/src/lsp/source_edits.dart';
 import 'package:analysis_server/src/protocol_server.dart' as server
     hide AnalysisError;
-import 'package:analysis_server/src/search/workspace_symbols.dart' as server
-    show DeclarationKind;
 import 'package:analyzer/dart/analysis/results.dart' as server;
 import 'package:analyzer/error/error.dart' as server;
 import 'package:analyzer/source/line_info.dart' as server;
 import 'package:analyzer/source/source_range.dart' as server;
+import 'package:analyzer/src/dart/analysis/search.dart' as server
+    show DeclarationKind;
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/services/available_declarations.dart' as dec;
@@ -1225,12 +1225,12 @@
 ErrorOr<int> toOffset(
   server.LineInfo lineInfo,
   lsp.Position pos, {
-  failureIsCritial = false,
+  bool failureIsCritical = false,
 }) {
   // line is zero-based so cannot equal lineCount
   if (pos.line >= lineInfo.lineCount) {
     return ErrorOr<int>.error(lsp.ResponseError(
-        code: failureIsCritial
+        code: failureIsCritical
             ? lsp.ServerErrorCodes.ClientServerInconsistentState
             : lsp.ServerErrorCodes.InvalidFileLineCol,
         message: 'Invalid line number',
diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
index 36bff9b..5a009f5 100644
--- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -30,6 +30,7 @@
     Method.textDocument_signatureHelp,
     Method.textDocument_references,
     Method.textDocument_documentHighlight,
+    Method.textDocument_documentColor,
     Method.textDocument_formatting,
     Method.textDocument_onTypeFormatting,
     Method.textDocument_rangeFormatting,
@@ -52,6 +53,9 @@
   bool get codeActions =>
       _capabilities.textDocument?.foldingRange?.dynamicRegistration ?? false;
 
+  bool get colorProvider =>
+      _capabilities.textDocument?.colorProvider?.dynamicRegistration ?? false;
+
   bool get completion =>
       _capabilities.textDocument?.completion?.dynamicRegistration ?? false;
 
@@ -130,8 +134,15 @@
   Set<Registration> currentRegistrations = {};
   var _lastRegistrationId = 0;
 
-  ServerCapabilitiesComputer(this._server);
+  final dartFiles = DocumentFilter(language: 'dart', scheme: 'file');
+  final pubspecFile = DocumentFilter(
+      language: 'yaml', scheme: 'file', pattern: '**/pubspec.yaml');
+  final analysisOptionsFile = DocumentFilter(
+      language: 'yaml', scheme: 'file', pattern: '**/analysis_options.yaml');
+  final fixDataFile = DocumentFilter(
+      language: 'yaml', scheme: 'file', pattern: '**/lib/fix_data.yaml');
 
+  ServerCapabilitiesComputer(this._server);
   ServerCapabilities computeServerCapabilities(
       LspClientCapabilities clientCapabilities) {
     final codeActionLiteralSupport = clientCapabilities.literalCodeActions;
@@ -210,6 +221,11 @@
                   codeActionKinds: DartCodeActionKind.serverSupportedKinds,
                 ))
               : Either2<bool, CodeActionOptions>.t1(true),
+      colorProvider: dynamicRegistrations.colorProvider
+          ? null
+          : Either3<bool, DocumentColorOptions,
+                  DocumentColorRegistrationOptions>.t3(
+              DocumentColorRegistrationOptions(documentSelector: [dartFiles])),
       documentFormattingProvider: dynamicRegistrations.formatting
           ? null
           : Either2<bool, DocumentFormattingOptions>.t1(enableFormatter),
@@ -279,14 +295,6 @@
   /// support and it will be up to them to decide which file types they will
   /// send requests for.
   Future<void> performDynamicRegistration() async {
-    final dartFiles = DocumentFilter(language: 'dart', scheme: 'file');
-    final pubspecFile = DocumentFilter(
-        language: 'yaml', scheme: 'file', pattern: '**/pubspec.yaml');
-    final analysisOptionsFile = DocumentFilter(
-        language: 'yaml', scheme: 'file', pattern: '**/analysis_options.yaml');
-    final fixDataFile = DocumentFilter(
-        language: 'yaml', scheme: 'file', pattern: '**/lib/fix_data.yaml');
-
     final pluginTypes = _server.pluginManager.plugins
         .expand((plugin) => plugin.currentSession?.interestingFiles ?? const [])
         // All published plugins use something like `*.extension` as
@@ -410,6 +418,12 @@
       TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
     );
     register(
+      dynamicRegistrations.colorProvider,
+      // This registration covers both documentColor and colorPresentation.
+      Method.textDocument_documentColor,
+      DocumentColorRegistrationOptions(documentSelector: [dartFiles]),
+    );
+    register(
       enableFormatter && dynamicRegistrations.formatting,
       Method.textDocument_formatting,
       TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
index 2a5834e..1e2b464 100644
--- a/pkg/analysis_server/lib/src/lsp/source_edits.dart
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart
@@ -31,7 +31,7 @@
           Either2<TextDocumentContentChangeEvent1,
               TextDocumentContentChangeEvent2>>
       changes, {
-  failureIsCritical = false,
+  bool failureIsCritical = false,
 }) {
   var newContent = oldContent;
   final serverEdits = <server.SourceEdit>[];
@@ -45,9 +45,9 @@
       (change) {
         final lines = LineInfo.fromContent(newContent);
         final offsetStart = toOffset(lines, change.range.start,
-            failureIsCritial: failureIsCritical);
+            failureIsCritical: failureIsCritical);
         final offsetEnd = toOffset(lines, change.range.end,
-            failureIsCritial: failureIsCritical);
+            failureIsCritical: failureIsCritical);
         if (offsetStart.isError) {
           return ErrorOr.error(offsetStart.error);
         }
@@ -180,7 +180,10 @@
       // To handle this, if both unformatted/formatted contain at least one
       // newline, split this change into two around the last newline so that the
       // final part (likely leading whitespace) can be included without
-      // including the whole change.
+      // including the whole change. This cannot be done if the newline is at
+      // the end of the source whitespace though, as this would create a split
+      // where the first part is the same and the second part is empty,
+      // resulting in an infinite loop/stack overflow.
       //
       // Without this, functionality like VS Code's "format modified lines"
       // (which uses Git status to know which lines are edited) may appear to
@@ -188,7 +191,8 @@
       if (unformattedStart < rangeStart.result &&
           unformattedEnd > rangeStart.result &&
           unformattedWhitespace.contains('\n') &&
-          formattedWhitespace.contains('\n')) {
+          formattedWhitespace.contains('\n') &&
+          !unformattedWhitespace.endsWith('\n')) {
         // Find the offsets of the character after the last newlines.
         final unformattedOffset = unformattedWhitespace.lastIndexOf('\n') + 1;
         final formattedOffset = formattedWhitespace.lastIndexOf('\n') + 1;
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 632f7f8..04542a8 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -5,12 +5,14 @@
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/protocol/protocol_internal.dart'
+    show ResponseResult;
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/search/element_references.dart';
 import 'package:analysis_server/src/search/type_hierarchy.dart';
-import 'package:analysis_server/src/search/workspace_symbols.dart' as search;
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/search.dart' as search;
 
 /// Instances of the class [SearchDomainHandler] implement a [RequestHandler]
 /// that handles requests in the search domain.
@@ -161,21 +163,21 @@
       }
     }
 
-    var tracker = server.declarationsTracker;
-    if (tracker == null) {
+    if (!server.options.featureSet.completion) {
       server.sendResponse(Response.unsupportedFeature(
           request.id, 'Completion is not enabled.'));
       return;
     }
-    var files = <String>{};
-    var remainingMaxResults = params.maxResults;
-    var declarations = search.WorkspaceSymbols(tracker).declarations(
-      regExp,
-      remainingMaxResults,
-      files,
-      onlyForFile: params.file,
-    );
 
+    var workspaceSymbols = search.WorkspaceSymbols();
+    var analysisDrivers = server.driverMap.values.toList();
+    for (var analysisDriver in analysisDrivers) {
+      await analysisDriver.search.declarations(
+          workspaceSymbols, regExp, params.maxResults,
+          onlyForFile: params.file);
+    }
+
+    var declarations = workspaceSymbols.declarations;
     var elementDeclarations = declarations.map((declaration) {
       return protocol.ElementDeclaration(
           declaration.name,
@@ -192,7 +194,7 @@
     }).toList();
 
     server.sendResponse(protocol.SearchGetElementDeclarationsResult(
-            elementDeclarations, files.toList())
+            elementDeclarations, workspaceSymbols.files)
         .toResponse(request.id));
   }
 
@@ -262,8 +264,8 @@
   }
 
   /// Send a search response with the given [result] to the given [request].
-  void _sendSearchResult(protocol.Request request, result) {
-    protocol.Response response = result.toResponse(request.id);
+  void _sendSearchResult(protocol.Request request, ResponseResult result) {
+    var response = result.toResponse(request.id);
     server.sendResponse(response);
   }
 
diff --git a/pkg/analysis_server/lib/src/search/workspace_symbols.dart b/pkg/analysis_server/lib/src/search/workspace_symbols.dart
deleted file mode 100644
index bbcf5ac..0000000
--- a/pkg/analysis_server/lib/src/search/workspace_symbols.dart
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/services/available_declarations.dart';
-import 'package:analyzer/src/services/available_declarations.dart' as ad;
-
-class Declaration {
-  final int fileIndex;
-  final LineInfo lineInfo;
-  final String name;
-  final DeclarationKind kind;
-  final int offset;
-  final int line;
-  final int column;
-  final int codeOffset;
-  final int codeLength;
-  final String? className;
-  final String? mixinName;
-  final String? parameters;
-
-  Declaration(
-    this.fileIndex,
-    this.lineInfo,
-    this.name,
-    this.kind,
-    this.offset,
-    this.line,
-    this.column,
-    this.codeOffset,
-    this.codeLength,
-    this.className,
-    this.mixinName,
-    this.parameters,
-  );
-}
-
-enum DeclarationKind {
-  CLASS,
-  CLASS_TYPE_ALIAS,
-  CONSTRUCTOR,
-  ENUM,
-  ENUM_CONSTANT,
-  EXTENSION,
-  FIELD,
-  FUNCTION,
-  FUNCTION_TYPE_ALIAS,
-  GETTER,
-  METHOD,
-  MIXIN,
-  SETTER,
-  TYPE_ALIAS,
-  VARIABLE
-}
-
-class WorkspaceSymbols {
-  final DeclarationsTracker tracker;
-
-  WorkspaceSymbols(this.tracker);
-
-  List<Declaration> declarations(
-      RegExp? regExp, int? maxResults, Set<String> files,
-      {String? onlyForFile}) {
-    _doTrackerWork();
-
-    var declarations = <Declaration>[];
-
-    var pathToIndex = <String, int>{};
-
-    int getPathIndex(String path) {
-      var index = pathToIndex[path];
-      if (index == null) {
-        index = files.length;
-        files.add(path);
-        pathToIndex[path] = index;
-      }
-      return index;
-    }
-
-    if (maxResults != null && declarations.length >= maxResults) {
-      throw const _MaxNumberOfDeclarationsError();
-    }
-
-    void addDeclaration(ad.Declaration declaration) {
-      if (maxResults != null && declarations.length >= maxResults) {
-        throw const _MaxNumberOfDeclarationsError();
-      }
-
-      var path = declaration.locationPath;
-      if (onlyForFile != null && path != onlyForFile) {
-        return;
-      }
-
-      declaration.children.forEach(addDeclaration);
-
-      var name = declaration.name;
-      if (name.isEmpty) {
-        return;
-      }
-      if (name.endsWith('=')) {
-        name = name.substring(0, name.length - 1);
-      }
-      if (regExp != null && !regExp.hasMatch(name)) {
-        return;
-      }
-
-      var parent = declaration.parent;
-
-      String? className;
-      if (parent != null && parent.kind == ad.DeclarationKind.CLASS) {
-        className = parent.name;
-      }
-
-      String? mixinName;
-      if (parent != null && parent.kind == ad.DeclarationKind.MIXIN) {
-        mixinName = parent.name;
-      }
-
-      var topKind = _getTopKind(declaration.kind);
-      if (topKind == null) {
-        return;
-      }
-
-      declarations.add(
-        Declaration(
-          getPathIndex(path),
-          declaration.lineInfo,
-          name,
-          topKind,
-          declaration.locationOffset,
-          declaration.locationStartLine,
-          declaration.locationStartColumn,
-          declaration.codeOffset,
-          declaration.codeLength,
-          className,
-          mixinName,
-          declaration.parameters,
-        ),
-      );
-    }
-
-    var libraries = tracker.allLibraries;
-    try {
-      for (var library in libraries) {
-        library.declarations.forEach(addDeclaration);
-      }
-    } on _MaxNumberOfDeclarationsError {
-      // Uses an exception to short circuit the recursion when there are too
-      // many declarations.
-    }
-
-    return declarations;
-  }
-
-  void _doTrackerWork() {
-    while (tracker.hasWork) {
-      tracker.doWork();
-    }
-  }
-
-  static DeclarationKind? _getTopKind(ad.DeclarationKind kind) {
-    switch (kind) {
-      case ad.DeclarationKind.CLASS:
-        return DeclarationKind.CLASS;
-      case ad.DeclarationKind.CLASS_TYPE_ALIAS:
-        return DeclarationKind.CLASS_TYPE_ALIAS;
-      case ad.DeclarationKind.CONSTRUCTOR:
-        return DeclarationKind.CONSTRUCTOR;
-      case ad.DeclarationKind.ENUM:
-        return DeclarationKind.ENUM;
-      case ad.DeclarationKind.ENUM_CONSTANT:
-        return DeclarationKind.ENUM_CONSTANT;
-      case ad.DeclarationKind.EXTENSION:
-        return DeclarationKind.EXTENSION;
-      case ad.DeclarationKind.FIELD:
-        return DeclarationKind.FIELD;
-      case ad.DeclarationKind.FUNCTION_TYPE_ALIAS:
-        return DeclarationKind.FUNCTION_TYPE_ALIAS;
-      case ad.DeclarationKind.METHOD:
-        return DeclarationKind.METHOD;
-      case ad.DeclarationKind.MIXIN:
-        return DeclarationKind.MIXIN;
-      case ad.DeclarationKind.FUNCTION:
-        return DeclarationKind.FUNCTION;
-      case ad.DeclarationKind.GETTER:
-        return DeclarationKind.GETTER;
-      case ad.DeclarationKind.SETTER:
-        return DeclarationKind.SETTER;
-      case ad.DeclarationKind.TYPE_ALIAS:
-        return DeclarationKind.TYPE_ALIAS;
-      case ad.DeclarationKind.VARIABLE:
-        return DeclarationKind.VARIABLE;
-      default:
-        return null;
-    }
-  }
-}
-
-/// The marker class that is thrown to stop adding declarations.
-class _MaxNumberOfDeclarationsError {
-  const _MaxNumberOfDeclarationsError();
-}
diff --git a/pkg/analysis_server/lib/src/server/debounce_requests.dart b/pkg/analysis_server/lib/src/server/debounce_requests.dart
new file mode 100644
index 0000000..4ee01d6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/server/debounce_requests.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_constants.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/channel/channel.dart';
+
+/// Return the stream of requests that is filtered to exclude requests for
+/// which the client does not need actual responses.
+///
+/// If there is one completion request, and then another completion request,
+/// then most probably the user continued typing, and there is no need to
+/// compute results for the first request. But we will have to respond, an
+/// empty response is enough.
+///
+/// Discarded requests are reported into [discardedRequests].
+Stream<Request> debounceRequests(
+  ServerCommunicationChannel channel,
+  StreamController<Request> discardedRequests,
+) {
+  return _DebounceRequests(channel, discardedRequests).requests;
+}
+
+class _DebounceRequests {
+  final ServerCommunicationChannel channel;
+  final StreamController<Request> discardedRequests;
+  late final Stream<Request> requests;
+
+  _DebounceRequests(this.channel, this.discardedRequests) {
+    var buffer = <Request>[];
+    Timer? timer;
+
+    requests = channel.requests.transform(
+      StreamTransformer.fromHandlers(
+        handleData: (request, sink) {
+          buffer.add(request);
+          // Accumulate requests for a short period of time.
+          // When we were busy processing a request, the client could put
+          // multiple requests into the event queue. So, when we look, we will
+          // quickly get all of them. So, even 1 ms should be enough.
+          timer ??= Timer(const Duration(milliseconds: 1), () {
+            timer = null;
+            var filtered = _filterCompletion(buffer);
+            buffer = [];
+            for (var request in filtered) {
+              sink.add(request);
+            }
+          });
+        },
+      ),
+    );
+  }
+
+  List<Request> _filterCompletion(List<Request> requests) {
+    var reversed = <Request>[];
+    var abortCompletionRequests = false;
+    for (var request in requests.reversed) {
+      if (request.method == ANALYSIS_REQUEST_UPDATE_CONTENT) {
+        abortCompletionRequests = true;
+      }
+      if (request.method == COMPLETION_REQUEST_GET_SUGGESTIONS2) {
+        if (abortCompletionRequests) {
+          discardedRequests.add(request);
+          var params = CompletionGetSuggestions2Params.fromRequest(request);
+          var offset = params.offset;
+          channel.sendResponse(
+            CompletionGetSuggestions2Result(offset, 0, [], [], true)
+                .toResponse(request.id),
+          );
+          continue;
+        } else {
+          abortCompletionRequests = true;
+        }
+      }
+      reversed.add(request);
+    }
+    return reversed.reversed.toList();
+  }
+}
diff --git a/pkg/analysis_server/lib/src/server/dev_server.dart b/pkg/analysis_server/lib/src/server/dev_server.dart
index 62886da6..b11c418 100644
--- a/pkg/analysis_server/lib/src/server/dev_server.dart
+++ b/pkg/analysis_server/lib/src/server/dev_server.dart
@@ -165,21 +165,11 @@
   Stream<Notification> get onNotification => _notificationController.stream;
 
   @override
-  void close() {
-    _notificationController.close();
-  }
+  Stream<Request> get requests => _requestController.stream;
 
   @override
-  void listen(
-    void Function(Request request) onRequest, {
-    Function? onError,
-    void Function()? onDone,
-  }) {
-    _requestController.stream.listen(
-      onRequest,
-      onError: onError,
-      onDone: onDone,
-    );
+  void close() {
+    _notificationController.close();
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 025eb5b..5016f76 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -101,6 +101,9 @@
   /// The path to the package config file override.
   static const String PACKAGES_FILE = 'packages';
 
+  /// The forced protocol version that the server will report to the client.
+  static const String REPORT_PROTOCOL_VERSION = 'report-protocol-version';
+
   /// The name of the flag specifying the server protocol to use.
   static const String SERVER_PROTOCOL = 'protocol';
   static const String PROTOCOL_ANALYZER = 'analyzer';
@@ -160,6 +163,8 @@
     analysisServerOptions.clientVersion = results[CLIENT_VERSION];
     analysisServerOptions.cacheFolder = results[CACHE_FOLDER];
     analysisServerOptions.packagesFile = results[PACKAGES_FILE];
+    analysisServerOptions.reportProtocolVersion =
+        results[REPORT_PROTOCOL_VERSION];
 
     // Read in any per-SDK overrides specified in <sdk>/config/settings.json.
     var sdkConfig = SdkConfiguration.readFromSdk();
@@ -688,6 +693,14 @@
         defaultsTo: false,
         negatable: false,
         hide: true);
+    parser.addOption(
+      REPORT_PROTOCOL_VERSION,
+      valueHelp: 'version',
+      help: 'The protocol version that the server will report to the client, '
+          'can be used to temporary enabling features that we expect to be '
+          'available in future versions.',
+      hide: true,
+    );
 
     //
     // Hidden; these are deprecated and no longer read from.
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
index b0c2ac4..7815def 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
@@ -35,16 +35,19 @@
 
 /// Overall performance of a code completion operation.
 class CompletionPerformance {
-  String? path;
-  String snippet = '';
+  final OperationPerformance operation;
+  final String path;
+  final String snippet;
   int suggestionCount = -1;
-  OperationPerformance? _operation;
+
+  CompletionPerformance({
+    required this.operation,
+    required this.path,
+    required String content,
+    required int offset,
+  }) : snippet = _computeCompletionSnippet(content, offset);
 
   int get elapsedInMilliseconds {
-    var operation = _operation;
-    if (operation == null) {
-      throw StateError('Access of elapsed time before the operation is run');
-    }
     return operation.elapsed.inMilliseconds;
   }
 
@@ -52,21 +55,4 @@
     if (suggestionCount < 1) return '';
     return '$suggestionCount';
   }
-
-  Future<T> runRequestOperation<T>(
-    Future<T> Function(OperationPerformanceImpl) operation,
-  ) async {
-    var rootOperation = OperationPerformanceImpl('<root>');
-    try {
-      return rootOperation.runAsync('<request>', (performance) async {
-        return await operation(performance);
-      });
-    } finally {
-      _operation = rootOperation.children.first;
-    }
-  }
-
-  void setContentsAndOffset(String contents, int offset) {
-    snippet = _computeCompletionSnippet(contents, offset);
-  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 78fef2f..90da0ef 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -37,6 +37,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
@@ -90,10 +91,11 @@
   /// suggestions, or `null` if no notification should occur.
   final SuggestionListener? listener;
 
-  /// If specified, will be filled with URIs of libraries that are not yet
-  /// imported, but could be imported into the requested target. Corresponding
-  /// [CompletionSuggestion] will have the import index into this list.
-  final List<Uri>? librariesToImport;
+  /// If specified, will be filled with suggestions and URIs from libraries
+  /// that are not yet imported, but could be imported into the requested
+  /// target. It is up to the client to make copies of [CompletionSuggestion]s
+  /// with the import index property updated.
+  final Map<protocol.CompletionSuggestion, Uri>? notImportedSuggestions;
 
   /// Initialize a newly created completion manager. The parameters
   /// [includedElementKinds], [includedElementNames], and
@@ -105,7 +107,7 @@
     this.includedElementNames,
     this.includedSuggestionRelevanceTags,
     this.listener,
-    this.librariesToImport,
+    this.notImportedSuggestions,
   }) : assert((includedElementKinds != null &&
                 includedElementNames != null &&
                 includedSuggestionRelevanceTags != null) ||
@@ -121,7 +123,7 @@
   }) async {
     request.checkAborted();
     var pathContext = request.resourceProvider.pathContext;
-    if (!file_paths.isDart(pathContext, request.result.path)) {
+    if (!file_paths.isDart(pathContext, request.path)) {
       return const <CompletionSuggestion>[];
     }
 
@@ -163,10 +165,11 @@
       );
     }
 
-    final librariesToImport = this.librariesToImport;
-    if (librariesToImport != null) {
+    final notImportedSuggestions = this.notImportedSuggestions;
+    if (notImportedSuggestions != null) {
       contributors.add(
-        NotImportedContributor(request, builder, budget, librariesToImport),
+        NotImportedContributor(
+            request, builder, budget, notImportedSuggestions),
       );
     }
 
@@ -274,8 +277,14 @@
 
 /// The information about a requested list of completions within a Dart file.
 class DartCompletionRequest {
+  /// The analysis session that produced the elements of the request.
+  final AnalysisSessionImpl analysisSession;
+
   final CompletionPreference completionPreference;
 
+  /// The content of the file in which completion is requested.
+  final String content;
+
   /// Return the type imposed on the target's `containingNode` based on its
   /// context, or `null` if the context does not impose any type.
   final DartType? contextType;
@@ -289,6 +298,9 @@
   /// compute relevance scores for suggestions.
   final FeatureComputer featureComputer;
 
+  /// The library element of the file in which completion is requested.
+  final LibraryElement libraryElement;
+
   /// Return the offset within the source at which the completion is being
   /// requested.
   final int offset;
@@ -297,14 +309,13 @@
   /// request.
   final OpType opType;
 
+  /// The absolute path of the file where completion is requested.
+  final String path;
+
   /// The source range that represents the region of text that should be
   /// replaced when a suggestion is selected.
   final SourceRange replacementRange;
 
-  /// The analysis result for the file in which the completion is being
-  /// requested.
-  final ResolvedUnitResult result;
-
   /// Return the source in which the completion is being requested.
   final Source source;
 
@@ -317,17 +328,22 @@
   bool _aborted = false;
 
   factory DartCompletionRequest({
-    required ResolvedUnitResult resolvedUnit,
+    required AnalysisSession analysisSession,
+    required String filePath,
+    required String fileContent,
+    required CompilationUnitElement unitElement,
+    required AstNode enclosingNode,
     required int offset,
     DartdocDirectiveInfo? dartdocDirectiveInfo,
     CompletionPreference completionPreference = CompletionPreference.insert,
     DocumentationCache? documentationCache,
   }) {
-    var target = CompletionTarget.forOffset(resolvedUnit.unit, offset);
+    var target = CompletionTarget.forOffset(enclosingNode, offset);
 
+    var libraryElement = unitElement.library;
     var featureComputer = FeatureComputer(
-      resolvedUnit.typeSystem,
-      resolvedUnit.typeProvider,
+      libraryElement.typeSystem,
+      libraryElement.typeProvider,
     );
 
     var contextType = featureComputer.computeContextType(
@@ -341,34 +357,65 @@
     }
 
     return DartCompletionRequest._(
+      analysisSession: analysisSession as AnalysisSessionImpl,
       completionPreference: completionPreference,
+      content: fileContent,
       contextType: contextType,
       dartdocDirectiveInfo: dartdocDirectiveInfo ?? DartdocDirectiveInfo(),
       documentationCache: documentationCache,
       featureComputer: featureComputer,
+      libraryElement: libraryElement,
       offset: offset,
       opType: opType,
+      path: filePath,
       replacementRange: target.computeReplacementRange(offset),
-      result: resolvedUnit,
-      source: resolvedUnit.unit.declaredElement!.source,
+      source: unitElement.source,
       target: target,
     );
   }
 
+  factory DartCompletionRequest.forResolvedUnit({
+    required ResolvedUnitResult resolvedUnit,
+    required int offset,
+    DartdocDirectiveInfo? dartdocDirectiveInfo,
+    CompletionPreference completionPreference = CompletionPreference.insert,
+    DocumentationCache? documentationCache,
+  }) {
+    return DartCompletionRequest(
+      analysisSession: resolvedUnit.session,
+      filePath: resolvedUnit.path,
+      fileContent: resolvedUnit.content,
+      unitElement: resolvedUnit.unit.declaredElement!,
+      enclosingNode: resolvedUnit.unit,
+      offset: offset,
+      dartdocDirectiveInfo: dartdocDirectiveInfo,
+      completionPreference: completionPreference,
+      documentationCache: documentationCache,
+    );
+  }
+
   DartCompletionRequest._({
+    required this.analysisSession,
     required this.completionPreference,
+    required this.content,
     required this.contextType,
     required this.dartdocDirectiveInfo,
     required this.documentationCache,
     required this.featureComputer,
+    required this.libraryElement,
     required this.offset,
     required this.opType,
+    required this.path,
     required this.replacementRange,
-    required this.result,
     required this.source,
     required this.target,
   });
 
+  DriverBasedAnalysisContext get analysisContext {
+    var analysisContext = analysisSession.analysisContext;
+    return analysisContext as DriverBasedAnalysisContext;
+  }
+
   /// Return the feature set that was used to analyze the compilation unit in
   /// which suggestions are being made.
   FeatureSet get featureSet => libraryElement.featureSet;
@@ -384,10 +431,6 @@
     return entity is Expression && entity.inConstantContext;
   }
 
-  /// Return the library element which contains the unit in which the completion
-  /// is occurring.
-  LibraryElement get libraryElement => result.libraryElement;
-
   /// Answer the [DartType] for Object in dart:core
   DartType get objectType => libraryElement.typeProvider.objectType;
 
@@ -406,16 +449,11 @@
   int get replacementOffset => replacementRange.offset;
 
   /// Return the resource provider associated with this request.
-  ResourceProvider get resourceProvider => result.session.resourceProvider;
-
-  /// Return the content of the [source] in which the completion is being
-  /// requested, or `null` if the content could not be accessed.
-  String? get sourceContents => result.content;
+  ResourceProvider get resourceProvider => analysisSession.resourceProvider;
 
   /// Return the [SourceFactory] of the request.
   SourceFactory get sourceFactory {
-    var context = result.session.analysisContext as DriverBasedAnalysisContext;
-    return context.driver.sourceFactory;
+    return analysisContext.driver.sourceFactory;
   }
 
   /// Return prefix that already exists in the document for [target] or empty
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 734a36e..2441362 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -163,13 +163,8 @@
       return;
     }
 
-    var libraryUnits = request.result.unit.declaredElement?.library.units;
-    if (libraryUnits == null) {
-      return;
-    }
-
     var visitor = LibraryElementSuggestionBuilder(request, builder);
-    for (var unit in libraryUnits) {
+    for (var unit in request.libraryElement.units) {
       if (unit.source != request.source) {
         unit.accept(visitor);
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
index 629fe475..53550d8 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
@@ -4,40 +4,33 @@
 
 import 'dart:async';
 
+import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/extension_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/lint/pub.dart';
 import 'package:analyzer/src/workspace/pub.dart';
 import 'package:collection/collection.dart';
-import 'package:meta/meta.dart';
 
 /// A contributor of suggestions from not yet imported libraries.
 class NotImportedContributor extends DartCompletionContributor {
-  /// Tests set this function to abort the current request.
-  @visibleForTesting
-  static void Function(FileState)? onFile;
-
   final CompletionBudget budget;
-  final List<Uri> librariesToImport;
+  final Map<protocol.CompletionSuggestion, Uri> notImportedSuggestions;
 
   NotImportedContributor(
     DartCompletionRequest request,
     SuggestionBuilder builder,
     this.budget,
-    this.librariesToImport,
+    this.notImportedSuggestions,
   ) : super(request, builder);
 
   @override
   Future<void> computeSuggestions() async {
-    var session = request.result.session as AnalysisSessionImpl;
-    var analysisDriver = session.getDriver(); // ignore: deprecated_member_use
+    var analysisDriver = request.analysisContext.driver;
 
     var fsState = analysisDriver.fsState;
     var filter = _buildFilter(fsState);
@@ -53,9 +46,6 @@
 
     var knownFiles = fsState.knownFiles.toList();
     for (var file in knownFiles) {
-      onFile?.call(file);
-      request.checkAborted();
-
       if (budget.isEmpty) {
         return;
       }
@@ -64,15 +54,18 @@
         continue;
       }
 
-      var elementResult = await session.getLibraryByUri(file.uriStr);
-      if (elementResult is! LibraryElementResult) {
+      var element = analysisDriver.getLibraryByFile(file);
+      if (element == null) {
         continue;
       }
 
-      var exportNamespace = elementResult.element.exportNamespace;
+      var exportNamespace = element.exportNamespace;
       var exportElements = exportNamespace.definedNames.values.toList();
 
-      var newSuggestions = builder.markSuggestions();
+      builder.laterReplacesEarlier = false;
+      builder.suggestionAdded = (suggestion) {
+        notImportedSuggestions[suggestion] = file.uri;
+      };
 
       if (request.includeIdentifiers) {
         _buildSuggestions(exportElements);
@@ -81,16 +74,14 @@
       extensionContributor.addExtensions(
         exportElements.whereType<ExtensionElement>().toList(),
       );
-
-      newSuggestions.setLibraryUriToImportIndex(() {
-        librariesToImport.add(file.uri);
-        return librariesToImport.length - 1;
-      });
     }
+
+    builder.laterReplacesEarlier = true;
+    builder.suggestionAdded = null;
   }
 
   _Filter _buildFilter(FileSystemState fsState) {
-    var file = fsState.getFileForPath(request.result.path);
+    var file = fsState.getFileForPath(request.path);
     var workspacePackage = file.workspacePackage;
     if (workspacePackage is PubWorkspacePackage) {
       return _PubFilter(workspacePackage, file.path);
@@ -154,14 +145,15 @@
 
   @override
   bool shouldInclude(FileState file) {
-    var uri = file.uri;
-    if (uri.isScheme('dart')) {
+    var uri = file.uriProperties;
+    if (uri.isDart) {
       return true;
     }
 
     // Normally only package URIs are available.
     // But outside of lib/ we allow any files of this package.
-    if (!uri.isScheme('package')) {
+    var packageName = uri.packageName;
+    if (packageName == null) {
       if (targetInLib) {
         return false;
       } else {
@@ -171,20 +163,13 @@
       }
     }
 
-    // Sanity check.
-    var uriPathSegments = uri.pathSegments;
-    if (uriPathSegments.length < 2) {
-      return false;
-    }
-
     // Any `package:` library from the same package.
-    var packageName = uriPathSegments[0];
     if (packageName == targetPackageName) {
       return true;
     }
 
     // If not the same package, must be public.
-    if (uriPathSegments[1] == 'src') {
+    if (uri.isSrc) {
       return false;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 7de9949..8ffc7d4 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -25,6 +25,16 @@
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
+/// Wrapper around a potentially nullable value.
+///
+/// When the wrapper instance is provided for a property, the property
+/// value is replaced, even if the value to set is `null` itself.
+class CopyWithValue<T> {
+  final T value;
+
+  CopyWithValue(this.value);
+}
+
 /// This class provides suggestions based upon the visible instance members in
 /// an interface type.
 class MemberSuggestionBuilder {
@@ -138,54 +148,6 @@
   }
 }
 
-class NewSuggestionsProcessor {
-  final SuggestionBuilder _builder;
-  final Set<protocol.CompletionSuggestion> _current = Set.identity();
-
-  NewSuggestionsProcessor._(this._builder) {
-    _current.addAll(_builder._suggestionMap.values);
-  }
-
-  /// Update suggestions added since this marker was created.
-  void setLibraryUriToImportIndex(int Function() produce) {
-    int? libraryUriToImportIndex;
-    var suggestionMap = _builder._suggestionMap;
-    for (var entry in suggestionMap.entries.toList()) {
-      var suggestion = entry.value;
-      if (!_current.contains(suggestion)) {
-        libraryUriToImportIndex ??= produce();
-        suggestionMap[entry.key] = protocol.CompletionSuggestion(
-          suggestion.kind,
-          suggestion.relevance,
-          suggestion.completion,
-          suggestion.selectionOffset,
-          suggestion.selectionLength,
-          suggestion.isDeprecated,
-          suggestion.isPotential,
-          displayText: suggestion.displayText,
-          replacementOffset: suggestion.replacementOffset,
-          replacementLength: suggestion.replacementLength,
-          docSummary: suggestion.docSummary,
-          docComplete: suggestion.docComplete,
-          declaringType: suggestion.declaringType,
-          defaultArgumentListString: suggestion.defaultArgumentListString,
-          defaultArgumentListTextRanges:
-              suggestion.defaultArgumentListTextRanges,
-          element: suggestion.element,
-          returnType: suggestion.returnType,
-          parameterNames: suggestion.parameterNames,
-          parameterTypes: suggestion.parameterTypes,
-          requiredParameterCount: suggestion.requiredParameterCount,
-          hasNamedParameters: suggestion.hasNamedParameters,
-          parameterName: suggestion.parameterName,
-          parameterType: suggestion.parameterType,
-          libraryUriToImportIndex: libraryUriToImportIndex,
-        );
-      }
-    }
-  }
-}
-
 /// An object used to build a list of suggestions in response to a single
 /// completion request.
 class SuggestionBuilder {
@@ -212,6 +174,9 @@
   /// suggestions, or `null` if no notification should occur.
   final SuggestionListener? listener;
 
+  /// The function to be invoked when a new suggestion is added.
+  void Function(protocol.CompletionSuggestion)? suggestionAdded;
+
   /// A map from a completion identifier to a completion suggestion.
   final Map<String, CompletionSuggestion> _suggestionMap =
       <String, CompletionSuggestion>{};
@@ -264,11 +229,6 @@
   bool get _isNonNullableByDefault =>
       request.libraryElement.isNonNullableByDefault;
 
-  /// Return an object that knows which suggestions exist, and which are new.
-  NewSuggestionsProcessor markSuggestions() {
-    return NewSuggestionsProcessor._(this);
-  }
-
   /// Add a suggestion for an [accessor] declared within a class or extension.
   /// If the accessor is being invoked with a target of `super`, then the
   /// [containingMemberName] should be the name of the member containing the
@@ -778,8 +738,8 @@
   Future<void> suggestOverride(SimpleIdentifier targetId,
       ExecutableElement element, bool invokeSuper) async {
     var displayTextBuffer = StringBuffer();
-    var builder = ChangeBuilder(session: request.result.session);
-    await builder.addDartFileEdit(request.result.path, (builder) {
+    var builder = ChangeBuilder(session: request.analysisSession);
+    await builder.addDartFileEdit(request.path, (builder) {
       builder.addReplacement(range.node(targetId), (builder) {
         builder.writeOverride(
           element,
@@ -979,10 +939,9 @@
         key = '$key()';
       }
       listener?.builtSuggestion(suggestion);
-      if (laterReplacesEarlier) {
+      if (laterReplacesEarlier || !_suggestionMap.containsKey(key)) {
         _suggestionMap[key] = suggestion;
-      } else {
-        _suggestionMap.putIfAbsent(key, () => suggestion);
+        suggestionAdded?.call(suggestion);
       }
     }
   }
@@ -1314,3 +1273,45 @@
         other.prefix == prefix;
   }
 }
+
+extension CompletionSuggestionExtension on CompletionSuggestion {
+  CompletionSuggestion copyWith({
+    CopyWithValue<int?>? libraryUriToImportIndex,
+  }) {
+    return protocol.CompletionSuggestion(
+      kind,
+      relevance,
+      completion,
+      selectionOffset,
+      selectionLength,
+      isDeprecated,
+      isPotential,
+      displayText: displayText,
+      replacementOffset: replacementOffset,
+      replacementLength: replacementLength,
+      docSummary: docSummary,
+      docComplete: docComplete,
+      declaringType: declaringType,
+      defaultArgumentListString: defaultArgumentListString,
+      defaultArgumentListTextRanges: defaultArgumentListTextRanges,
+      element: element,
+      returnType: returnType,
+      parameterNames: parameterNames,
+      parameterTypes: parameterTypes,
+      requiredParameterCount: requiredParameterCount,
+      hasNamedParameters: hasNamedParameters,
+      parameterName: parameterName,
+      parameterType: parameterType,
+      libraryUriToImportIndex: libraryUriToImportIndex.orElse(
+        this.libraryUriToImportIndex,
+      ),
+    );
+  }
+}
+
+extension _CopyWithValueExtension<T> on CopyWithValue<T>? {
+  T orElse(T defaultValue) {
+    final self = this;
+    return self != null ? self.value : defaultValue;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
index 703acf8..4a11a87 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
@@ -57,7 +57,7 @@
             // Quoted empty string
             visitSimpleStringLiteral(uri);
           } else {
-            var data = request.sourceContents!;
+            var data = request.content;
             if (end == data.length) {
               var ch = data[end - 1];
               if (ch != '"' && ch != "'") {
@@ -69,7 +69,7 @@
           }
         }
       } else if (offset == start && offset == end) {
-        var data = request.sourceContents!;
+        var data = request.content;
         if (end == data.length) {
           var ch = data[end - 1];
           if (ch == '"' || ch == "'") {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
index 19d86b0..33d20fe 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -197,7 +197,7 @@
 }
 
 String getRequestLineIndent(DartCompletionRequest request) {
-  var content = request.result.content;
+  var content = request.content;
   var lineStartOffset = request.offset;
   var notWhitespaceOffset = request.offset;
   for (; lineStartOffset > 0; lineStartOffset--) {
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/fix_data_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/fix_data_generator.dart
index 15ef594..d57592a 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/fix_data_generator.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/fix_data_generator.dart
@@ -16,27 +16,7 @@
       'title': EmptyProducer(),
       'date': EmptyProducer(),
       'bulkApply': BooleanProducer(),
-      'element': MapProducer({
-        // TODO(brianwilkerson) Support suggesting uris.
-        'uris': EmptyProducer(),
-        'class': EmptyProducer(),
-        'constant': EmptyProducer(),
-        'constructor': EmptyProducer(),
-        'enum': EmptyProducer(),
-        'extension': EmptyProducer(),
-        'field': EmptyProducer(),
-        'function': EmptyProducer(),
-        'getter': EmptyProducer(),
-        'method': EmptyProducer(),
-        'mixin': EmptyProducer(),
-        'setter': EmptyProducer(),
-        'typedef': EmptyProducer(),
-        'variable': EmptyProducer(),
-        'inClass': EmptyProducer(),
-        'inEnum': EmptyProducer(),
-        'inExtension': EmptyProducer(),
-        'inMixin': EmptyProducer(),
-      }),
+      'element': _elementProducer,
       'changes': _changesProducer,
       'oneOf': ListProducer(MapProducer({
         'if': EmptyProducer(),
@@ -56,6 +36,7 @@
       'removeParameter',
       'rename',
       'renameParameter',
+      'replacedBy',
     ]),
     'index': EmptyProducer(),
     'name': EmptyProducer(),
@@ -69,8 +50,32 @@
     'extends': EmptyProducer(),
     'oldName': EmptyProducer(),
     'newName': EmptyProducer(),
+    'newElement': _elementProducer,
   }));
 
+  /// The producer representing the known valid structure of an element.
+  static const MapProducer _elementProducer = MapProducer({
+    // TODO(brianwilkerson) Support suggesting uris.
+    'uris': EmptyProducer(),
+    'class': EmptyProducer(),
+    'constant': EmptyProducer(),
+    'constructor': EmptyProducer(),
+    'enum': EmptyProducer(),
+    'extension': EmptyProducer(),
+    'field': EmptyProducer(),
+    'function': EmptyProducer(),
+    'getter': EmptyProducer(),
+    'method': EmptyProducer(),
+    'mixin': EmptyProducer(),
+    'setter': EmptyProducer(),
+    'typedef': EmptyProducer(),
+    'variable': EmptyProducer(),
+    'inClass': EmptyProducer(),
+    'inEnum': EmptyProducer(),
+    'inExtension': EmptyProducer(),
+    'inMixin': EmptyProducer(),
+  });
+
   /// Initialize a newly created suggestion generator for fix data files.
   FixDataGenerator(ResourceProvider resourceProvider)
       : super(resourceProvider, null);
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 47624e2..c7233ba 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -73,7 +73,7 @@
   );
   static const CONVERT_INTO_ASYNC_BODY = AssistKind(
     'dart.assist.convert.bodyToAsync',
-    29,
+    31,
     'Convert to async function body',
   );
   static const CONVERT_INTO_BLOCK_BODY = AssistKind(
@@ -222,77 +222,77 @@
   // Flutter wrap specific assists
   static const FLUTTER_WRAP_GENERIC = AssistKind(
     'dart.assist.flutter.wrap.generic',
-    31,
+    29,
     'Wrap with widget...',
   );
 
   static const FLUTTER_WRAP_BUILDER = AssistKind(
     'dart.assist.flutter.wrap.builder',
-    32,
+    28,
     'Wrap with Builder',
   );
   static const FLUTTER_WRAP_CENTER = AssistKind(
     'dart.assist.flutter.wrap.center',
-    32,
+    28,
     'Wrap with Center',
   );
   static const FLUTTER_WRAP_COLUMN = AssistKind(
     'dart.assist.flutter.wrap.column',
-    32,
+    28,
     'Wrap with Column',
   );
   static const FLUTTER_WRAP_CONTAINER = AssistKind(
     'dart.assist.flutter.wrap.container',
-    32,
+    28,
     'Wrap with Container',
   );
   static const FLUTTER_WRAP_PADDING = AssistKind(
     'dart.assist.flutter.wrap.padding',
-    32,
+    28,
     'Wrap with Padding',
   );
   static const FLUTTER_WRAP_ROW = AssistKind(
     'dart.assist.flutter.wrap.row',
-    32,
+    28,
     'Wrap with Row',
   );
   static const FLUTTER_WRAP_SIZED_BOX = AssistKind(
     'dart.assist.flutter.wrap.sizedBox',
-    32,
+    28,
     'Wrap with SizedBox',
   );
   static const FLUTTER_WRAP_STREAM_BUILDER = AssistKind(
     'dart.assist.flutter.wrap.streamBuilder',
-    32,
+    28,
     'Wrap with StreamBuilder',
   );
 
   // Flutter re-order assists
   static const FLUTTER_SWAP_WITH_CHILD = AssistKind(
     'dart.assist.flutter.swap.withChild',
-    33,
+    27,
     'Swap with child',
   );
   static const FLUTTER_SWAP_WITH_PARENT = AssistKind(
     'dart.assist.flutter.swap.withParent',
-    33,
+    27,
     'Swap with parent',
   );
   static const FLUTTER_MOVE_DOWN = AssistKind(
     'dart.assist.flutter.move.down',
-    34,
+    26,
     'Move widget down',
   );
   static const FLUTTER_MOVE_UP = AssistKind(
     'dart.assist.flutter.move.up',
-    34,
+    26,
     'Move widget up',
   );
 
   // Flutter remove assist
   static const FLUTTER_REMOVE_WIDGET = AssistKind(
     'dart.assist.flutter.removeWidget',
-    35,
+    25,
     'Remove this widget',
   );
 
@@ -334,7 +334,7 @@
   static const REMOVE_TYPE_ANNOTATION = AssistKind(
     // todo (pq): unify w/ fix
     'dart.assist.remove.typeAnnotation',
-    29,
+    31,
     'Remove type annotation',
   );
   static const REPLACE_CONDITIONAL_WITH_IF_ELSE = AssistKind(
@@ -374,47 +374,47 @@
   );
   static const SURROUND_WITH_BLOCK = AssistKind(
     'dart.assist.surround.block',
-    22,
+    38,
     'Surround with block',
   );
   static const SURROUND_WITH_DO_WHILE = AssistKind(
     'dart.assist.surround.doWhile',
-    27,
+    33,
     "Surround with 'do-while'",
   );
   static const SURROUND_WITH_FOR = AssistKind(
     'dart.assist.surround.forEach',
-    26,
+    34,
     "Surround with 'for'",
   );
   static const SURROUND_WITH_FOR_IN = AssistKind(
     'dart.assist.surround.forIn',
-    25,
+    35,
     "Surround with 'for-in'",
   );
   static const SURROUND_WITH_IF = AssistKind(
     'dart.assist.surround.if',
-    23,
+    37,
     "Surround with 'if'",
   );
   static const SURROUND_WITH_SET_STATE = AssistKind(
     'dart.assist.surround.setState',
-    27,
+    33,
     "Surround with 'setState'",
   );
   static const SURROUND_WITH_TRY_CATCH = AssistKind(
     'dart.assist.surround.tryCatch',
-    28,
+    32,
     "Surround with 'try-catch'",
   );
   static const SURROUND_WITH_TRY_FINALLY = AssistKind(
     'dart.assist.surround.tryFinally',
-    29,
+    31,
     "Surround with 'try-finally'",
   );
   static const SURROUND_WITH_WHILE = AssistKind(
     'dart.assist.surround.while',
-    24,
+    36,
     "Surround with 'while'",
   );
   static const USE_CURLY_BRACES = AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index a09c3b7..0b6145c 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -7,10 +7,13 @@
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
+import 'package:analysis_server/src/services/correction/dart/organize_imports.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unused_import.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set_parser.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/error/error.dart';
@@ -226,28 +229,109 @@
     return builder;
   }
 
+  Future<void> _applyProducer(
+      CorrectionProducerContext context, CorrectionProducer producer) async {
+    producer.configure(context);
+    try {
+      var localBuilder = builder.copy();
+      await producer.compute(localBuilder);
+      builder = localBuilder;
+    } on ConflictingEditException {
+      // If a conflicting edit was added in [compute], then the [localBuilder]
+      // is discarded and we revert to the previous state of the builder.
+    }
+  }
+
   /// Use the change [builder] to create fixes for the diagnostics in the
   /// library associated with the analysis [result].
   Future<void> _fixErrorsInLibrary(ResolvedLibraryResult result) async {
     var analysisOptions = result.session.analysisContext.analysisOptions;
-    for (var unitResult in result.units) {
-      var overrideSet = _readOverrideSet(unitResult);
 
-      var errors = List.from(unitResult.errors, growable: false);
+    Iterable<AnalysisError> filteredErrors(ResolvedUnitResult result) sync* {
+      var errors = result.errors.toList();
       errors.sort((a, b) => a.offset.compareTo(b.offset));
-
+      // Only fix errors not filtered out in analysis options.
       for (var error in errors) {
         var processor = ErrorProcessor.getProcessor(analysisOptions, error);
-        // Only fix errors not filtered out in analysis options.
         if (processor == null || processor.severity != null) {
-          final fixContext = DartFixContextImpl(
-            instrumentationService,
-            workspace,
-            unitResult,
-            error,
-            (name) => [],
-          );
-          await _fixSingleError(fixContext, unitResult, error, overrideSet);
+          yield error;
+        }
+      }
+    }
+
+    DartFixContextImpl fixContext(
+        ResolvedUnitResult result, AnalysisError diagnostic) {
+      return DartFixContextImpl(
+        instrumentationService,
+        workspace,
+        result,
+        diagnostic,
+        (name) => [],
+      );
+    }
+
+    CorrectionProducerContext? correctionContext(
+        ResolvedUnitResult result, AnalysisError diagnostic) {
+      var overrideSet = _readOverrideSet(result);
+      return CorrectionProducerContext.create(
+        applyingBulkFixes: true,
+        dartFixContext: fixContext(result, diagnostic),
+        diagnostic: diagnostic,
+        overrideSet: overrideSet,
+        resolvedResult: result,
+        selectionOffset: diagnostic.offset,
+        selectionLength: diagnostic.length,
+        workspace: workspace,
+      );
+    }
+
+    //
+    // Attempt to apply the fixes that aren't related to directives.
+    //
+    for (var unitResult in result.units) {
+      var overrideSet = _readOverrideSet(unitResult);
+      for (var error in filteredErrors(unitResult)) {
+        await _fixSingleError(
+            fixContext(unitResult, error), unitResult, error, overrideSet);
+      }
+    }
+    //
+    // If there are no such fixes in the defining compilation unit, then apply
+    // the fixes related to directives.
+    //
+    var definingUnit = result.units[0];
+    AnalysisError? directivesOrderingError;
+    var unusedImportErrors = <AnalysisError>[];
+    if (!builder.hasEditsFor(definingUnit.path)) {
+      for (var error in filteredErrors(definingUnit)) {
+        var errorCode = error.errorCode;
+        if (errorCode is LintCode) {
+          var lintName = errorCode.name;
+          if (lintName == LintNames.directives_ordering) {
+            directivesOrderingError = error;
+            break;
+          }
+        } else if (errorCode == HintCode.DUPLICATE_IMPORT ||
+            errorCode == HintCode.UNNECESSARY_IMPORT ||
+            errorCode == HintCode.UNUSED_IMPORT) {
+          unusedImportErrors.add(error);
+        }
+      }
+      if (directivesOrderingError != null) {
+        // `OrganizeImports` will also remove some of the unused imports, so we
+        // apply it first.
+        var context = correctionContext(definingUnit, directivesOrderingError);
+        if (context != null) {
+          await _generateFix(context, OrganizeImports.newInstance(),
+              directivesOrderingError.errorCode.name);
+        }
+      } else {
+        for (var error in unusedImportErrors) {
+          var context = correctionContext(definingUnit, error);
+          if (context != null) {
+            await _generateFix(context, RemoveUnusedImport.newInstance(),
+                error.errorCode.name);
+          }
         }
       }
     }
@@ -275,44 +359,21 @@
       return;
     }
 
-    Future<void> compute(CorrectionProducer producer) async {
-      producer.configure(context);
-      try {
-        var localBuilder = builder.copy();
-        await producer.compute(localBuilder);
-        builder = localBuilder;
-      } on ConflictingEditException {
-        // If a conflicting edit was added in [compute], then the [localBuilder]
-        // is discarded and we revert to the previous state of the builder.
-      }
-    }
-
-    int computeChangeHash() => (builder as ChangeBuilderImpl).changeHash;
-
-    Future<void> generate(CorrectionProducer producer, String code) async {
-      var oldHash = computeChangeHash();
-      await compute(producer);
-      var newHash = computeChangeHash();
-      if (newHash != oldHash) {
-        changeMap.add(result.path, code);
-      }
-    }
-
     Future<void> bulkApply(
         List<ProducerGenerator> generators, String codeName) async {
       for (var generator in generators) {
         var producer = generator();
         if (producer.canBeAppliedInBulk) {
-          await generate(producer, codeName);
+          await _generateFix(context, producer, codeName);
         }
       }
     }
 
     var errorCode = diagnostic.errorCode;
+    var codeName = errorCode.name;
     try {
-      var codeName = errorCode.name;
       if (errorCode is LintCode) {
-        var generators = FixProcessor.lintProducerMap[errorCode.name] ?? [];
+        var generators = FixProcessor.lintProducerMap[codeName] ?? [];
         await bulkApply(generators, codeName);
       } else {
         var generators = FixProcessor.nonLintProducerMap[errorCode] ?? [];
@@ -323,16 +384,26 @@
             var multiProducer = multiGenerator();
             multiProducer.configure(context);
             for (var producer in multiProducer.producers) {
-              await generate(producer, codeName);
+              await _generateFix(context, producer, codeName);
             }
           }
         }
       }
     } catch (e, s) {
       throw CaughtException.withMessage(
-          'Exception generating fix for ${errorCode.name} in ${result.path}',
-          e,
-          s);
+          'Exception generating fix for $codeName in ${result.path}', e, s);
+    }
+  }
+
+  Future<void> _generateFix(CorrectionProducerContext context,
+      CorrectionProducer producer, String code) async {
+    int computeChangeHash() => (builder as ChangeBuilderImpl).changeHash;
+
+    var oldHash = computeChangeHash();
+    await _applyProducer(context, producer);
+    var newHash = computeChangeHash();
+    if (newHash != oldHash) {
+      changeMap.add(context.resolvedResult.path, code.toLowerCase());
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_field.dart
index ec42942..3073989 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_field.dart
@@ -96,7 +96,7 @@
     if (targetClassElement == null) {
       return;
     }
-    if (targetClassElement.librarySource.isInSystemLibrary) {
+    if (targetClassElement.librarySource.uri.isScheme('dart')) {
       return;
     }
     utils.targetClassElement = targetClassElement;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
index 3c9c661..cdc8339 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
@@ -74,7 +74,7 @@
       return;
     }
     var targetSource = targetElement.source;
-    if (targetSource == null || targetSource.isInSystemLibrary) {
+    if (targetSource == null || targetSource.uri.isScheme('dart')) {
       return;
     }
     // prepare target declaration
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
index 9009561..1774efe 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_method.dart
@@ -139,7 +139,7 @@
         return;
       }
       targetElement = targetClassElement;
-      if (targetClassElement.librarySource.isInSystemLibrary) {
+      if (targetClassElement.librarySource.uri.isScheme('dart')) {
         return;
       }
       // prepare target ClassDeclaration
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart
index 8958731..569e134 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart
@@ -73,7 +73,7 @@
       return;
     }
     var targetSource = targetElement.source;
-    if (targetSource == null || targetSource.isInSystemLibrary) {
+    if (targetSource == null || targetSource.uri.isScheme('dart')) {
       return;
     }
     // prepare target declaration
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
index 415f155..4a949c4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
@@ -16,6 +16,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/src/utilities/library.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -150,22 +151,6 @@
     return false;
   }
 
-  /// Returns the relative URI from the passed [library] to the given [path].
-  ///
-  /// If the [path] is not in the [library]'s directory, `null` is returned.
-  String? _getRelativeUriFromLibrary(LibraryElement library, String path) {
-    var librarySource = library.librarySource;
-    var pathContext = resourceProvider.pathContext;
-    var libraryDirectory = pathContext.dirname(librarySource.fullName);
-    var sourceDirectory = pathContext.dirname(path);
-    if (pathContext.isWithin(libraryDirectory, path) ||
-        pathContext.isWithin(sourceDirectory, libraryDirectory)) {
-      var relativeFile = pathContext.relative(path, from: libraryDirectory);
-      return pathContext.split(relativeFile).join('/');
-    }
-    return null;
-  }
-
   Iterable<CorrectionProducer> _importExtensionInLibrary(
       Uri uri, DartType targetType, String memberName) sync* {
     // Look to see whether the library at the [uri] is already imported. If it
@@ -207,25 +192,28 @@
 
   /// Returns a list of one or two import corrections.
   ///
-  /// If [relativeUri] is `null`, only one correction, with an absolute import
-  /// path, is returned. Otherwise, a correction with an absolute import path
-  /// and a correction with a relative path are returned. If the
+  /// If [includeRelativeFix] is `false`, only one correction, with an absolute
+  /// import path, is returned. Otherwise, a correction with an absolute import
+  /// path and a correction with a relative path are returned. If the
   /// `prefer_relative_imports` lint rule is enabled, the relative path is
   /// returned first.
-  Iterable<CorrectionProducer> _importLibrary(FixKind fixKind, Uri library,
-      [String? relativeUri]) {
-    if (relativeUri == null || relativeUri.isEmpty) {
+  Iterable<CorrectionProducer> _importLibrary(
+    FixKind fixKind,
+    Uri library, {
+    bool includeRelativeFix = false,
+  }) {
+    if (!includeRelativeFix) {
       return [_ImportAbsoluteLibrary(fixKind, library)];
     }
     if (isLintEnabled(LintNames.prefer_relative_imports)) {
       return [
-        _ImportRelativeLibrary(fixKind, relativeUri),
+        _ImportRelativeLibrary(fixKind, library),
         _ImportAbsoluteLibrary(fixKind, library),
       ];
     } else {
       return [
         _ImportAbsoluteLibrary(fixKind, library),
-        _ImportRelativeLibrary(fixKind, relativeUri),
+        _ImportRelativeLibrary(fixKind, library),
       ];
     }
   }
@@ -312,10 +300,13 @@
         // Good: direct declaration.
         fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
       }
-      // Add the fix.
-      var relativeUri =
-          _getRelativeUriFromLibrary(libraryElement, declaration.path);
-      yield* _importLibrary(fixKind, declaration.uri, relativeUri);
+      // If both files are in the same package's lib folder, also include a
+      // relative import.
+      var includeRelativeUri = canBeRelativeImport(
+          declaration.uri, libraryElement.librarySource.uri);
+      // Add the fix(es).
+      yield* _importLibrary(fixKind, declaration.uri,
+          includeRelativeFix: includeRelativeUri);
     }
   }
 
@@ -415,7 +406,9 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
-      _uriText = builder.importLibrary(_library);
+      if (builder is DartFileEditBuilderImpl) {
+        _uriText = builder.importLibraryWithAbsoluteUri(_library);
+      }
     });
   }
 }
@@ -532,12 +525,14 @@
 class _ImportRelativeLibrary extends CorrectionProducer {
   final FixKind _fixKind;
 
-  final String _relativeURI;
+  final Uri _library;
 
-  _ImportRelativeLibrary(this._fixKind, this._relativeURI);
+  String _uriText = '';
+
+  _ImportRelativeLibrary(this._fixKind, this._library);
 
   @override
-  List<Object> get fixArguments => [_relativeURI];
+  List<Object> get fixArguments => [_uriText];
 
   @override
   FixKind get fixKind => _fixKind;
@@ -546,7 +541,7 @@
   Future<void> compute(ChangeBuilder builder) async {
     await builder.addDartFileEdit(file, (builder) {
       if (builder is DartFileEditBuilderImpl) {
-        builder.importLibraryWithRelativeUri(_relativeURI);
+        _uriText = builder.importLibraryWithRelativeUri(_library);
       }
     });
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.dart b/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.dart
index d5cf7c0..d655cc3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/organize_imports.dart
@@ -11,7 +11,8 @@
 
 class OrganizeImports extends CorrectionProducer {
   @override
-  bool get canBeAppliedInBulk => true;
+  // Bulk application is supported by a distinct import cleanup fix phase.
+  bool get canBeAppliedInBulk => false;
 
   @override
   // The fix is to sort all the directives, which will already fix all of the
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.dart
index a3fb8b1..4da8683 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_kind.dart
@@ -20,6 +20,38 @@
 }
 
 extension ElementKindUtilities on ElementKind {
+  /// Return a human readable name for the kind.
+  String get displayName {
+    switch (this) {
+      case ElementKind.classKind:
+        return 'class';
+      case ElementKind.constantKind:
+        return 'constant';
+      case ElementKind.constructorKind:
+        return 'constructor';
+      case ElementKind.enumKind:
+        return 'enum';
+      case ElementKind.extensionKind:
+        return 'extension';
+      case ElementKind.fieldKind:
+        return 'field';
+      case ElementKind.functionKind:
+        return 'function';
+      case ElementKind.getterKind:
+        return 'getter';
+      case ElementKind.methodKind:
+        return 'method';
+      case ElementKind.mixinKind:
+        return 'mixin';
+      case ElementKind.setterKind:
+        return 'setter';
+      case ElementKind.typedefKind:
+        return 'typedef';
+      case ElementKind.variableKind:
+        return 'variable';
+    }
+  }
+
   /// Return the element kind corresponding to the given [name].
   static ElementKind? fromName(String name) {
     for (var kind in ElementKind.values) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
index 49751f1..837025a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart
@@ -342,20 +342,27 @@
           // If the old class has been removed then this might have been a
           // constructor invocation.
           ElementKind.constructorKind,
+          ElementKind.functionKind, // tear-off
           ElementKind.getterKind,
           ElementKind.setterKind,
           ElementKind.variableKind
         ];
       }
       return const [
+        ElementKind.constantKind,
         ElementKind.fieldKind,
+        ElementKind.functionKind, // tear-off
         ElementKind.getterKind,
+        ElementKind.methodKind, // tear-off
         ElementKind.setterKind
       ];
     } else if (node is PropertyAccess) {
       return const [
+        ElementKind.constantKind,
         ElementKind.fieldKind,
+        ElementKind.functionKind, // tear-off, prefixed
         ElementKind.getterKind,
+        ElementKind.methodKind, // tear-off, prefixed
         ElementKind.setterKind
       ];
     } else if (node is SimpleIdentifier) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/replaced_by.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/replaced_by.dart
new file mode 100644
index 0000000..92e23b9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/replaced_by.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+/// The data related to an element that has been replaced by another element.
+class ReplacedBy extends Change<_Data> {
+  /// The replacing element.
+  final ElementDescriptor newElement;
+
+  /// Initialize a newly created transform to describe a replacement of an old
+  /// element by a [newElement].
+  ReplacedBy({required this.newElement});
+
+  @override
+  void apply(DartFileEditBuilder builder, DataDrivenFix fix, _Data data) {
+    var referenceRange = data.referenceRange;
+    builder.addSimpleReplacement(referenceRange, _referenceTo(newElement));
+  }
+
+  @override
+  _Data? validate(DataDrivenFix fix) {
+    var node = fix.node;
+    if (node is SimpleIdentifier) {
+      var components = fix.element.components;
+      if (components.isEmpty) {
+        return null;
+      } else if (components.length == 1) {
+        if (components[0] != node.name) {
+          return null;
+        }
+        // We have an '<element>' pattern, so we replace the name.
+        return _Data(range.node(node));
+      }
+      // The element being replaced is a member in a top-level element.
+      var containerName = components[1];
+      if (components[0].isEmpty && containerName == node.name) {
+        // We have a '<className>()' pattern, so we replace the class name.
+        return _Data(range.node(node));
+      }
+      var parent = node.parent;
+      if (parent is MethodInvocation) {
+        var target = parent.target;
+        if (target == null) {
+          // We have a '<member>()' pattern, so we replace the member name.
+          return _Data(range.node(node));
+        } else if (target is SimpleIdentifier && target.name == containerName) {
+          // We have a '<container>.<member>()' pattern, so we replace both parts.
+          return _Data(range.startEnd(target, node));
+        } else if (target is PrefixedIdentifier) {
+          if (target.prefix.staticElement is PrefixElement &&
+              target.identifier.name == containerName) {
+            // We have a '<prefix>.<container>.<member>()' pattern so we leave
+            // the prefix while replacing the rest.
+            return _Data(range.startEnd(target.identifier, node));
+          }
+          // We shouldn't get here.
+          return null;
+        }
+      } else if (parent is PrefixedIdentifier) {
+        if (parent.prefix.staticElement is PrefixElement) {
+          // We have a '<prefix>.<topLevel>' pattern so we leave the prefix
+          // while replacing the rest.
+          return _Data(range.node(node));
+        }
+        // We have a '<container>.<member>' pattern so we replace both parts.
+        return _Data(range.node(parent));
+      } else if (parent is PropertyAccess) {
+        var target = parent.target;
+        if (target is PrefixedIdentifier) {
+          // We have a '<prefix>.<container>.<member>' pattern so we leave the
+          // prefix while replacing the rest.
+          return _Data(range.startEnd(target.identifier, node));
+        }
+        // We have a '<container>.<member>' pattern so we replace both parts.
+        return _Data(range.node(parent));
+      }
+      // We have a '<member>' pattern so we replace the member name.
+      return _Data(range.node(node));
+    } else if (node is PrefixedIdentifier) {
+      var parent = node.parent;
+      if (parent is NamedType) {
+        var identifier = node.identifier;
+        var components = fix.element.components;
+        if (components.length > 1 &&
+            components[0].isEmpty &&
+            components[1] == identifier.name) {
+          // We have a '<prefix>.<className>' pattern, so we replace only the
+          // class name.
+          return _Data(range.node(identifier));
+        }
+      }
+    } else if (node is ConstructorName) {
+      var typeName = node.type2.name;
+      SimpleIdentifier classNameNode;
+      if (typeName is SimpleIdentifier) {
+        classNameNode = typeName;
+      } else if (typeName is PrefixedIdentifier) {
+        classNameNode = typeName.identifier;
+      } else {
+        return null;
+      }
+      var constructorNameNode = node.name;
+      var constructorName = constructorNameNode?.name ?? '';
+      var components = fix.element.components;
+      if (components.length == 2 &&
+          constructorName == components[0] &&
+          classNameNode.name == components[1]) {
+        if (constructorNameNode != null) {
+          return _Data(range.startEnd(classNameNode, constructorNameNode));
+        }
+        return _Data(range.node(classNameNode));
+      }
+    }
+    return null;
+  }
+
+  String _referenceTo(ElementDescriptor element) {
+    var components = element.components;
+    if (components[0].isEmpty) {
+      return components[1];
+    }
+    return components.reversed.join('.');
+  }
+}
+
+/// The data about a reference to an element that's been replaced.
+class _Data {
+  final SourceRange referenceRange;
+
+  _Data(this.referenceRange);
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
index 1c992e0..42aeba2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
@@ -25,6 +25,26 @@
 
   /**
    * Parameters:
+   * 0: the old kind
+   * 1: the new kind
+   */
+  static const TransformSetErrorCode incompatibleElementKind =
+      TransformSetErrorCode(
+          'incompatible_element_kind',
+          "An element of kind '{0}' can't be replaced by "
+              "an element of kind '{1}'.");
+
+  /**
+   * Parameters:
+   * 0: the change kind that is invalid
+   * 1: the element kind for the transform
+   */
+  static const TransformSetErrorCode invalidChangeForKind =
+      TransformSetErrorCode('invalid_change_for_kind',
+          "A change of type '{0}' can't be used for an element of kind '{1}'.");
+
+  /**
+   * Parameters:
    * 0: the character that is invalid
    */
   static const TransformSetErrorCode invalidCharacter =
@@ -136,6 +156,14 @@
   /**
    * No parameters.
    */
+  static const TransformSetErrorCode unsupportedUriChange = TransformSetErrorCode(
+      'unsupported_uri_change',
+      "The set of URIs for the replacement element must match the transformed "
+          "element.");
+
+  /**
+   * No parameters.
+   */
   static const TransformSetErrorCode unsupportedVersion = TransformSetErrorCode(
       'unsupported_version', "Only version '1' is supported at this time.");
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index 4605bd6..dc8184c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -14,6 +14,7 @@
 import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/rename_parameter.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/replaced_by.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
@@ -64,6 +65,7 @@
   static const String _methodKey = 'method';
   static const String _mixinKey = 'mixin';
   static const String _nameKey = 'name';
+  static const String _newElementKey = 'newElement';
   static const String _newNameKey = 'newName';
   static const String _oldNameKey = 'oldName';
   static const String _oneOfKey = 'oneOf';
@@ -97,6 +99,7 @@
   static const String _removeParameterKind = 'removeParameter';
   static const String _renameKind = 'rename';
   static const String _renameParameterKind = 'renameParameter';
+  static const String _replacedByKind = 'replacedBy';
 
   /// The valid values for the [_styleKey] in an [_addParameterKind] change.
   static const List<String> validStyles = [
@@ -106,6 +109,11 @@
     'required_positional'
   ];
 
+  /// A table mapping the kinds of elements that can be replaced by a different
+  /// element to a set of the kinds of elements with which they can be replaced.
+  static final Map<ElementKind, Set<ElementKind>> compatibleReplacementTypes =
+      _createCompatibleReplacementTypes();
+
   static const String _openComponent = '{%';
   static const String _closeComponent = '%}';
 
@@ -125,6 +133,12 @@
   /// found.
   final String packageName;
 
+  /// The description of the element that is being transformed by the current
+  /// transformation, or `null` if we are not in the process of parsing a
+  /// transformation or if the element associated with the transformation is not
+  /// valid.
+  ElementDescriptor? elementBeingTransformed;
+
   /// The variable scope defined for the current transform.
   VariableScope transformVariableScope = VariableScope.empty;
 
@@ -147,6 +161,13 @@
     return _translateTransformSet(map);
   }
 
+  bool _equalUris(List<Uri> oldUris, List<Uri> newUris) {
+    var oldSet = oldUris.toSet();
+    var newSet = newUris.toSet();
+    return oldSet.difference(newSet).isEmpty &&
+        newSet.difference(oldSet).isEmpty;
+  }
+
   /// Convert the given [template] into a list of components. Variable
   /// references in the template are looked up in the map of [generators].
   List<TemplateComponent> _extractTemplateComponents(
@@ -446,6 +467,8 @@
         return _translateRenameChange(node);
       } else if (kind == _renameParameterKind) {
         return _translateRenameParameterChange(node);
+      } else if (kind == _replacedByKind) {
+        return _translateReplacedByChange(node);
       }
       return _reportInvalidValueOneOf(kindNode, kindContext, [
         _addParameterKind,
@@ -453,6 +476,7 @@
         _removeParameterKind,
         _renameKind,
         _renameParameterKind,
+        _replacedByKind,
       ]);
     } else {
       return _reportInvalidValue(node, context, 'Map');
@@ -821,6 +845,41 @@
     return RenameParameter(newName: newName, oldName: oldName);
   }
 
+  /// Translate the [node] into a replaced_by change. Return the resulting
+  /// change, or `null` if the [node] does not represent a valid replaced_by
+  /// change.
+  ReplacedBy? _translateReplacedByChange(YamlMap node) {
+    _reportUnsupportedKeys(node, const {_kindKey, _newElementKey});
+    var newElement = _translateElement(node.valueAt(_newElementKey),
+        ErrorContext(key: _newElementKey, parentNode: node));
+    if (newElement == null) {
+      // The error has already been reported.
+      return null;
+    }
+    var oldElement = elementBeingTransformed;
+    if (oldElement != null) {
+      if (!_equalUris(oldElement.libraryUris, newElement.libraryUris)) {
+        _reportError(TransformSetErrorCode.unsupportedUriChange,
+            (node.valueAt(_newElementKey) as YamlMap).valueAt(_urisKey)!);
+      }
+      var compatibleTypes = compatibleReplacementTypes[oldElement.kind];
+      if (compatibleTypes == null) {
+        _reportError(
+            TransformSetErrorCode.invalidChangeForKind,
+            node.valueAt(_newElementKey)!,
+            [_replacedByKind, oldElement.kind.displayName]);
+        return null;
+      } else if (!compatibleTypes.contains(newElement.kind)) {
+        _reportError(
+            TransformSetErrorCode.incompatibleElementKind,
+            node.valueAt(_newElementKey)!,
+            [oldElement.kind.displayName, newElement.kind.displayName]);
+        return null;
+      }
+    }
+    return ReplacedBy(newElement: newElement);
+  }
+
   /// Translate the [node] into a string. Return the resulting string, or `null`
   /// if the [node] doesn't represent a valid string. If the [node] isn't valid,
   /// use the [context] to report the error. If the [node] doesn't exist and
@@ -893,6 +952,7 @@
           true;
       var element = _translateElement(node.valueAt(_elementKey),
           ErrorContext(key: _elementKey, parentNode: node));
+      elementBeingTransformed = element;
       transformVariableScope = _translateTemplateVariables(
           node.valueAt(_variablesKey),
           ErrorContext(key: _variablesKey, parentNode: node));
@@ -1032,4 +1092,43 @@
       return _reportInvalidValue(node, context, 'Map');
     }
   }
+
+  static Map<ElementKind, Set<ElementKind>>
+      _createCompatibleReplacementTypes() {
+    var types = <ElementKind, Set<ElementKind>>{};
+
+    void addSet(Set<ElementKind> set) {
+      for (var kind in set) {
+        types.putIfAbsent(kind, () => {}).addAll(set);
+      }
+    }
+
+    // Constructors can replace constructors.
+    addSet({
+      ElementKind.constructorKind,
+    });
+    // Static methods and top-level functions can replace each other.
+    addSet({
+      ElementKind.functionKind,
+      ElementKind.methodKind,
+    });
+    // Static getters and getter-inducing elements can replace each other.
+    addSet({
+      ElementKind.constantKind,
+      ElementKind.fieldKind,
+      ElementKind.getterKind,
+      ElementKind.variableKind,
+    });
+    // Static setters and setter-inducing elements can replace each other.
+    // TODO(brianwilkerson) We can't currently distinguish between final and
+    //  non-final elements, but we don't support replacing setters with final
+    //  elements, nor vice versa. We need a way to distinguish these cases if we
+    //  want to be able to report an error.
+    addSet({
+      ElementKind.fieldKind,
+      ElementKind.setterKind,
+      ElementKind.variableKind,
+    });
+    return types;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
index 3708b48..e4438f2 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
@@ -2,15 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:math' as math;
+
 import 'package:analysis_server/src/utilities/strings.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/ignore_comments/ignore_info.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     hide AnalysisError, Element;
+import 'package:collection/collection.dart';
+import 'package:meta/meta_meta.dart';
 
 /// Organizer of imports (and other directives) in the [unit].
 class ImportOrganizer {
@@ -67,6 +72,13 @@
     var lineInfo = unit.lineInfo ?? LineInfo.fromContent(code);
     var hasLibraryDirective = false;
     var directives = <_DirectiveInfo>[];
+    // Track the end offset of any library-level comment/annotations that should
+    // remain at the top of the file regardless of whether it was attached to a
+    // directive that's moved/removed.
+    // Code up to this offset will be excluded from the comment/docs/annotation
+    // text for the computed DirectiveInfo and also its range for replacement
+    // in the document.
+    int? libraryDocsAndAnnotationsEndOffset;
     for (var directive in unit.directives) {
       if (directive is LibraryDirective) {
         hasLibraryDirective = true;
@@ -77,15 +89,60 @@
           var offset = directive.offset;
           var end = directive.end;
 
-          final leadingComment = getLeadingComment(unit, directive, lineInfo);
-          final trailingComment =
-              getTrailingComment(unit, directive, lineInfo, end);
+          final isPsuedoLibraryDirective = directive == unit.directives.first;
+          Annotation? lastLibraryAnnotation;
+          if (isPsuedoLibraryDirective) {
+            // Find the last library-level annotation that does not come
+            // after any non-library annotation. If there are already
+            // non-library annotations before library annotations, we will not
+            // try to correct those.
+            lastLibraryAnnotation = directive.metadata
+                .takeWhile(_isLibraryTargetAnnotation)
+                .lastOrNull;
+            if (lastLibraryAnnotation != null) {
+              libraryDocsAndAnnotationsEndOffset =
+                  lineInfo.getOffsetOfLineAfter(lastLibraryAnnotation.end);
+              // In the case of a blank line after the last library annotation
+              // we should include that in the library part. Otherwise it will
+              // be included in the top of the following directive and may
+              // result in an extra blank line in the annotation block if it
+              // is moved.
+              final nextLineOffset = lineInfo
+                  .getOffsetOfLineAfter(libraryDocsAndAnnotationsEndOffset);
+              if (code
+                  .substring(libraryDocsAndAnnotationsEndOffset, nextLineOffset)
+                  .trim()
+                  .isEmpty) {
+                libraryDocsAndAnnotationsEndOffset = nextLineOffset;
+              }
+            }
+          }
+
+          // Usually we look for leading comments on the directive. However if
+          // some library annotations were trimmed off, those comments are part
+          // of that and should not also be included here.
+          final leadingToken =
+              lastLibraryAnnotation == null ? directive.beginToken : null;
+          final leadingComment = leadingToken != null
+              ? getLeadingComment(unit, leadingToken, lineInfo)
+              : null;
+          final trailingComment = getTrailingComment(unit, directive, lineInfo);
+
+          /// Computes the offset to use for the start of directive-specific
+          /// code below taking into account code already included by
+          /// [libraryDocsAndAnnotationsEndOffset].
+          final clampedOffset = libraryDocsAndAnnotationsEndOffset == null
+              ? (int offset) => offset
+              : (int offset) =>
+                  math.max(libraryDocsAndAnnotationsEndOffset!, offset);
 
           String? leadingCommentText;
-          if (leadingComment != null) {
-            leadingCommentText =
-                code.substring(leadingComment.offset, directive.offset);
-            offset = leadingComment.offset;
+          if (leadingComment != null && leadingToken != null) {
+            offset = clampedOffset(leadingComment.offset);
+            leadingCommentText = code.substring(
+              offset,
+              clampedOffset(leadingToken.offset),
+            );
           }
           String? trailingCommentText;
           if (trailingComment != null) {
@@ -97,13 +154,33 @@
           var documentationComment = directive.documentationComment;
           if (documentationComment != null) {
             documentationText = code.substring(
-                documentationComment.offset, documentationComment.end);
+              clampedOffset(documentationComment.offset),
+              clampedOffset(documentationComment.end),
+            );
           }
           String? annotationText;
+          String? postAnnotationCommentText;
           var beginToken = directive.metadata.beginToken;
           var endToken = directive.metadata.endToken;
           if (beginToken != null && endToken != null) {
-            annotationText = code.substring(beginToken.offset, endToken.end);
+            var annotationOffset = clampedOffset(beginToken.offset);
+            var annotationEnd = clampedOffset(endToken.end);
+            if (annotationOffset != annotationEnd) {
+              annotationText = code.substring(
+                annotationOffset,
+                annotationEnd,
+              );
+            }
+            // Capture text between the end of the annotation and the directive
+            // text as there may be end-of line or line comments between.
+            // If not, this will capture the newline between the two, as it
+            // cannot be assumed there is a newline after annotationText because
+            // of the possibility of comments.
+            if (annotationEnd <
+                directive.firstTokenAfterCommentAndMetadata.offset) {
+              postAnnotationCommentText = code.substring(annotationEnd,
+                  directive.firstTokenAfterCommentAndMetadata.offset);
+            }
           }
           var text = code.substring(
               directive.firstTokenAfterCommentAndMetadata.offset,
@@ -116,9 +193,12 @@
               leadingCommentText,
               documentationText,
               annotationText,
+              postAnnotationCommentText,
               uriContent,
               trailingCommentText,
-              offset,
+              isPsuedoLibraryDirective
+                  ? (libraryDocsAndAnnotationsEndOffset ?? offset)
+                  : offset,
               end,
               text,
             ),
@@ -151,7 +231,7 @@
         sb.write(libraryDocumentationDirective.documentationText);
         sb.write(endOfLine);
       }
-      var currentPriority = directives.first.priority;
+      _DirectivePriority? currentPriority;
       for (var directiveInfo in directives) {
         if (!hasUnresolvedIdentifierError) {
           var directive = directiveInfo.directive;
@@ -160,7 +240,9 @@
           }
         }
         if (currentPriority != directiveInfo.priority) {
-          sb.write(endOfLine);
+          if (currentPriority != null) {
+            sb.write(endOfLine);
+          }
           currentPriority = directiveInfo.priority;
         }
         if (directiveInfo.leadingCommentText != null) {
@@ -173,7 +255,9 @@
         }
         if (directiveInfo.annotationText != null) {
           sb.write(directiveInfo.annotationText);
-          sb.write(endOfLine);
+        }
+        if (directiveInfo.postAnnotationCommentText != null) {
+          sb.write(directiveInfo.postAnnotationCommentText);
         }
         sb.write(directiveInfo.text);
         if (directiveInfo.trailingCommentText != null) {
@@ -230,7 +314,7 @@
   }
 
   /// Gets the first comment token considered to be the leading comment for this
-  /// directive.
+  /// token.
   ///
   /// Leading comments for the first directive in a file are considered library
   /// comments and not returned unless they contain blank lines, in which case
@@ -239,12 +323,12 @@
   /// '// ignore:' comment which should always be treated as attached to the
   /// import.
   static Token? getLeadingComment(
-      CompilationUnit unit, UriBasedDirective directive, LineInfo lineInfo) {
-    if (directive.beginToken.precedingComments == null) {
+      CompilationUnit unit, Token beginToken, LineInfo lineInfo) {
+    if (beginToken.precedingComments == null) {
       return null;
     }
 
-    Token? firstComment = directive.beginToken.precedingComments;
+    Token? firstComment = beginToken.precedingComments;
     var comment = firstComment;
     var nextComment = comment?.next;
     // Don't connect comments that have a blank line between them
@@ -274,7 +358,7 @@
     // Skip over any comments on the same line as the previous directive
     // as they will be attached to the end of it.
     var previousDirectiveLine =
-        lineInfo.getLocation(directive.beginToken.previous!.end).lineNumber;
+        lineInfo.getLocation(beginToken.previous!.end).lineNumber;
     comment = firstComment;
     while (comment != null &&
         previousDirectiveLine ==
@@ -289,9 +373,9 @@
   ///
   /// To be considered a trailing comment, the comment must be on the same line
   /// as the directive.
-  static Token? getTrailingComment(CompilationUnit unit,
-      UriBasedDirective directive, LineInfo lineInfo, int end) {
-    var line = lineInfo.getLocation(end).lineNumber;
+  static Token? getTrailingComment(
+      CompilationUnit unit, UriBasedDirective directive, LineInfo lineInfo) {
+    var line = lineInfo.getLocation(directive.end).lineNumber;
     Token? comment = directive.endToken.next!.precedingComments;
     while (comment != null) {
       if (lineInfo.getLocation(comment.offset).lineNumber == line) {
@@ -306,6 +390,10 @@
   /// '// ignore_for_file:' comment).
   static bool _isIgnoreComment(Token token) =>
       IgnoreInfo.IGNORE_MATCHER.matchAsPrefix(token.lexeme) != null;
+
+  static bool _isLibraryTargetAnnotation(Annotation annotation) =>
+      annotation.elementAnnotation?.targetKinds.contains(TargetKind.library) ??
+      false;
 }
 
 class _DirectiveInfo implements Comparable<_DirectiveInfo> {
@@ -314,6 +402,7 @@
   final String? leadingCommentText;
   final String? documentationText;
   final String? annotationText;
+  final String? postAnnotationCommentText;
   final String uri;
   final String? trailingCommentText;
 
@@ -332,6 +421,7 @@
     this.leadingCommentText,
     this.documentationText,
     this.annotationText,
+    this.postAnnotationCommentText,
     this.uri,
     this.trailingCommentText,
     this.offset,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 6e97072..f3cae42 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -158,9 +158,7 @@
     var refDir = pathContext.dirname(reference.file);
     // Try to keep package: URI
     if (_isPackageReference(reference)) {
-      Source newSource =
-          NonExistingSource(newFile, pathos.toUri(newFile), UriKind.FILE_URI);
-      var restoredUri = driver.sourceFactory.restoreUri(newSource);
+      var restoredUri = driver.sourceFactory.pathToUri(newFile);
       // If the new URI is not a package: URI, fall back to computing a relative
       // URI below.
       if (restoredUri?.isScheme('package') ?? false) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index 3ca9d77..8fbe15a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -73,7 +73,7 @@
   @override
   Future<RefactoringStatus> checkInitialConditions() {
     var result = RefactoringStatus();
-    if (element.source!.isInSystemLibrary) {
+    if (element.source!.uri.isScheme('dart')) {
       var message = format(
           "The {0} '{1}' is defined in the SDK, so cannot be renamed.",
           getElementKindName(element),
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 59cafe6..8e938ef 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -62,7 +62,7 @@
       var error = RequestError(
           RequestErrorCode.SERVER_ALREADY_STARTED, 'Server already started');
       serverChannel.sendResponse(Response('', error: error));
-      serverChannel.listen((Request request) {
+      serverChannel.requests.listen((Request request) {
         serverChannel.sendResponse(Response(request.id, error: error));
       });
       return;
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 0d4629c..5ab8cff 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -206,7 +206,7 @@
     buf.writeln(
         '<tr><th>Time</th><th>Results</th><th>Source</th><th>Snippet</th></tr>');
     for (var completion in completions) {
-      var shortName = pathContext.basename(completion.path ?? '<missing path>');
+      var shortName = pathContext.basename(completion.path);
       buf.writeln('<tr>'
           '<td class="pre right">${printMilliseconds(completion.elapsedInMilliseconds)}</td>'
           '<td class="right">${completion.suggestionCountStr}</td>'
diff --git a/pkg/analysis_server/lib/src/utilities/mocks.dart b/pkg/analysis_server/lib/src/utilities/mocks.dart
index 9c581cd..bef5102 100644
--- a/pkg/analysis_server/lib/src/utilities/mocks.dart
+++ b/pkg/analysis_server/lib/src/utilities/mocks.dart
@@ -36,6 +36,9 @@
   MockServerChannel();
 
   @override
+  Stream<Request> get requests => requestController.stream;
+
+  @override
   void close() {
     _closed = true;
   }
@@ -46,13 +49,6 @@
   }
 
   @override
-  void listen(void Function(Request request) onRequest,
-      {Function? onError, void Function()? onDone}) {
-    requestController.stream
-        .listen(onRequest, onError: onError, onDone: onDone);
-  }
-
-  @override
   void sendNotification(Notification notification) {
     // Don't deliver notifications after the connection is closed.
     if (_closed) {
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index d727774..09fdeee 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -5,8 +5,6 @@
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
@@ -23,24 +21,6 @@
 
 import 'src/utilities/mock_packages.dart';
 
-/// Finds an [Element] with the given [name].
-Element? findChildElement(Element root, String name, [ElementKind? kind]) {
-  Element? result;
-  root.accept(_ElementVisitorFunctionWrapper((Element element) {
-    if (element.name != name) {
-      return;
-    }
-    if (kind != null && element.kind != kind) {
-      return;
-    }
-    result = element;
-  }));
-  return result;
-}
-
-/// A function to be called for every [Element].
-typedef _ElementVisitorFunction = void Function(Element element);
-
 class AbstractContextTest with ResourceProviderMixin {
   static bool _lintRulesAreRegistered = false;
 
@@ -65,6 +45,13 @@
     throw 0;
   }
 
+  /// Return a list of the experiments that are to be enabled for tests in this
+  /// class, an empty list if there are no experiments that should be enabled.
+  List<String> get experiments => [
+        EnableString.constructor_tearoffs,
+        EnableString.named_arguments_anywhere,
+      ];
+
   String get latestLanguageVersion =>
       '${ExperimentStatus.currentVersion.major}.'
       '${ExperimentStatus.currentVersion.minor}';
@@ -192,6 +179,10 @@
     );
 
     writeTestPackageConfig();
+
+    createAnalysisOptionsFile(
+      experiments: experiments,
+    );
   }
 
   void setupResourceProvider() {}
@@ -302,16 +293,3 @@
     verifyCreatedCollection();
   }
 }
-
-/// Wraps the given [_ElementVisitorFunction] into an instance of
-/// [engine.GeneralizingElementVisitor].
-class _ElementVisitorFunctionWrapper extends GeneralizingElementVisitor<void> {
-  final _ElementVisitorFunction function;
-  _ElementVisitorFunctionWrapper(this.function);
-
-  @override
-  void visitElement(Element element) {
-    function(element);
-    super.visitElement(element);
-  }
-}
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index b18416c..67aa683 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -94,6 +94,6 @@
   @override
   void setUp() {
     super.setUp();
-    testFile = convertPath('/home/test/lib/test.dart');
+    testFile = convertPath('$testPackageLibPath/test.dart');
   }
 }
diff --git a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
index 0724bfe..d89741d 100644
--- a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
+++ b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
@@ -135,7 +135,7 @@
     errorStream = errorStreamController.stream;
     var doneCompleter = Completer();
     doneFuture = doneCompleter.future;
-    channel.listen((Request request) {
+    channel.requests.listen((Request request) {
       requestStreamController.add(request);
     }, onError: (error) {
       errorStreamController.add(error);
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 8ea43c3..317cc59 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -18,6 +18,8 @@
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:analyzer_plugin/src/protocol/protocol_internal.dart'
+    show HasToJson;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -1580,7 +1582,7 @@
   }
 
   /// Send an `updateContent` request for [testFile].
-  void sendContentChange(dynamic contentChange) {
+  void sendContentChange(HasToJson contentChange) {
     var request =
         AnalysisUpdateContentParams({testFile: contentChange}).toRequest('0');
     handleSuccessfulRequest(request);
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 2a46330..c3ec9c3 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -11,7 +11,6 @@
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
-import 'package:analysis_server/src/services/completion/dart/not_imported_contributor.dart';
 import 'package:analysis_server/src/utilities/mocks.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/service.dart';
@@ -21,12 +20,15 @@
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'domain_completion_util.dart';
 import 'mocks.dart';
 import 'src/plugin/plugin_manager_test.dart';
+import 'utils/change_check.dart';
 
 void main() {
   defineReflectiveSuite(() {
@@ -42,30 +44,31 @@
   Future<void> test_alreadyImported() async {
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 import 'dart:math';
 void f() {
   Rand^
 }
 ''', completion: 'Random', libraryUri: 'dart:math');
-    validator
-      ..hasCompletion('Random')
-      ..hasChange().assertNoFileEdits();
+    check(details)
+      ..completion.isEqualTo('Random')
+      ..change.edits.isEmpty;
   }
 
   Future<void> test_import_dart() async {
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 void f() {
   R^
 }
 ''', completion: 'Random', libraryUri: 'dart:math');
-    validator
-      ..hasCompletion('Random')
-      ..hasChange()
+    check(details)
+      ..completion.isEqualTo('Random')
+      ..change
           .hasFileEdit(testFilePathPlatform)
-          .whenApplied(testFileContent, r'''
+          .appliedTo(testFileContent)
+          .isEqualTo(r'''
 import 'dart:math';
 
 void f() {
@@ -75,8 +78,7 @@
   }
 
   Future<void> test_import_package_dependencies() async {
-    // TODO(scheglov) Switch to PubspecYamlFileConfig
-    newPubspecYamlFile(testPackageRootPath, r'''
+    writeTestPackagePubspecYamlFile(r'''
 name: test
 dependencies:
   aaa: any
@@ -94,16 +96,17 @@
 
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 void f() {
   T^
 }
 ''', completion: 'Test', libraryUri: 'package:aaa/a.dart');
-    validator
-      ..hasCompletion('Test')
-      ..hasChange()
+    check(details)
+      ..completion.isEqualTo('Test')
+      ..change
           .hasFileEdit(testFilePathPlatform)
-          .whenApplied(testFileContent, r'''
+          .appliedTo(testFileContent)
+          .isEqualTo(r'''
 import 'package:aaa/a.dart';
 
 void f() {
@@ -119,16 +122,17 @@
 
     await _configureWithWorkspaceRoot();
 
-    var validator = await _getTestCodeDetails('''
+    var details = await _getTestCodeDetails('''
 void f() {
   T^
 }
 ''', completion: 'Test', libraryUri: 'package:test/a.dart');
-    validator
-      ..hasCompletion('Test')
-      ..hasChange()
+    check(details)
+      ..completion.isEqualTo('Test')
+      ..change
           .hasFileEdit(testFilePathPlatform)
-          .whenApplied(testFileContent, r'''
+          .appliedTo(testFileContent)
+          .isEqualTo(r'''
 import 'package:test/a.dart';
 
 void f() {
@@ -160,7 +164,7 @@
     expect(response.error?.code, RequestErrorCode.INVALID_FILE_PATH_FORMAT);
   }
 
-  Future<GetSuggestionDetails2Validator> _getCodeDetails({
+  Future<CompletionGetSuggestionDetails2Result> _getCodeDetails({
     required String path,
     required String content,
     required String completion,
@@ -184,7 +188,7 @@
     );
   }
 
-  Future<GetSuggestionDetails2Validator> _getDetails({
+  Future<CompletionGetSuggestionDetails2Result> _getDetails({
     required String path,
     required int completionOffset,
     required String completion,
@@ -198,11 +202,10 @@
     ).toRequest('0');
 
     var response = await _handleSuccessfulRequest(request);
-    var result = CompletionGetSuggestionDetails2Result.fromResponse(response);
-    return GetSuggestionDetails2Validator(result);
+    return CompletionGetSuggestionDetails2Result.fromResponse(response);
   }
 
-  Future<GetSuggestionDetails2Validator> _getTestCodeDetails(
+  Future<CompletionGetSuggestionDetails2Result> _getTestCodeDetails(
     String content, {
     required String completion,
     required String libraryUri,
@@ -225,24 +228,75 @@
     completionDomain.budgetDuration = const Duration(seconds: 30);
   }
 
-  void tearDown() {
-    NotImportedContributor.onFile = null;
-  }
+  Future<void> test_abort_onAnotherCompletionRequest() async {
+    var abortedIdSet = <String>{};
+    server.discardedRequests.stream.listen((request) {
+      abortedIdSet.add(request.id);
+    });
 
-  Future<void> test_notImported_abort() async {
+    newFile(testFilePath, content: '');
+
     await _configureWithWorkspaceRoot();
 
-    NotImportedContributor.onFile = (file) {
-      if (file.uriStr == 'dart:math') {
-        unawaited(
-          _getSuggestions(
-            path: convertPath(testFilePath),
-            completionOffset: 0,
-            maxResults: 100,
-          ),
-        );
-      }
-    };
+    // Send three requests, the first two should be aborted.
+    var response0 = _sendTestCompletionRequest('0', 0);
+    var response1 = _sendTestCompletionRequest('1', 0);
+    var response2 = _sendTestCompletionRequest('2', 0);
+
+    // Wait for all three.
+    var validator0 = await response0.toResult();
+    var validator1 = await response1.toResult();
+    var validator2 = await response2.toResult();
+
+    // The first two should be aborted.
+    expect(abortedIdSet, {'0', '1'});
+
+    validator0
+      ..assertIncomplete()
+      ..suggestions.assertEmpty();
+
+    validator1
+      ..assertIncomplete()
+      ..suggestions.assertEmpty();
+
+    validator2
+      ..assertComplete()
+      ..suggestions.assertCompletionsContainsAll(
+        ['int', 'double', 'Future', 'Directory'],
+      );
+  }
+
+  Future<void> test_abort_onUpdateContent() async {
+    var abortedIdSet = <String>{};
+    server.discardedRequests.stream.listen((request) {
+      abortedIdSet.add(request.id);
+    });
+
+    newFile(testFilePath, content: '');
+
+    await _configureWithWorkspaceRoot();
+
+    // Schedule a completion request.
+    var response = _sendTestCompletionRequest('0', 0);
+
+    // Simulate typing in the IDE.
+    await _handleSuccessfulRequest(
+      AnalysisUpdateContentParams({
+        testFilePathPlatform: AddContentOverlay('void f() {}'),
+      }).toRequest('1'),
+    );
+
+    // The request should be aborted.
+    var validator = await response.toResult();
+    expect(abortedIdSet, {'0'});
+
+    validator
+      ..assertIncomplete()
+      ..suggestions.assertEmpty();
+  }
+
+  Future<void> test_notImported_dart() async {
+    await _configureWithWorkspaceRoot();
 
     var responseValidator = await _getTestCodeSuggestions('''
 void f() {
@@ -251,14 +305,21 @@
 ''');
 
     responseValidator
-      ..assertIncomplete()
+      ..assertComplete()
       ..assertReplacementBack(4)
-      ..assertLibrariesToImport(includes: [], excludes: [
-        'dart:core',
+      ..assertLibrariesToImport(includes: [
         'dart:math',
+      ], excludes: [
+        'dart:async',
+        'dart:core',
+        'package:test/test.dart',
       ]);
 
-    responseValidator.suggestions.assertEmpty();
+    var classes = responseValidator.suggestions.withElementClass();
+    classes.assertCompletions(['Random']);
+    classes.withCompletion('Random').assertSingle()
+      ..assertClass()
+      ..assertLibraryToImport('dart:math');
   }
 
   Future<void> test_notImported_emptyBudget() async {
@@ -285,8 +346,7 @@
   }
 
   Future<void> test_notImported_pub_dependencies_inLib() async {
-    // TODO(scheglov) Switch to PubspecYamlFileConfig
-    newPubspecYamlFile(testPackageRootPath, r'''
+    writeTestPackagePubspecYamlFile(r'''
 name: test
 dependencies:
   aaa: any
@@ -343,8 +403,7 @@
   }
 
   Future<void> test_notImported_pub_dependencies_inTest() async {
-    // TODO(scheglov) Switch to PubspecYamlFileConfig
-    newPubspecYamlFile(testPackageRootPath, r'''
+    writeTestPackagePubspecYamlFile(r'''
 name: test
 dependencies:
   aaa: any
@@ -407,8 +466,6 @@
       ..assertLibraryToImport('package:bbb/f.dart');
   }
 
-  /// TODO(scheglov) Only lib/ libraries in lib/, no test/.
-  /// TODO(scheglov) Suggestions from available Pub packages.
   Future<void> test_notImported_pub_this() async {
     newFile('$testPackageLibPath/a.dart', content: '''
 class A01 {}
@@ -430,12 +487,12 @@
       ..assertComplete()
       ..assertReplacementBack(2)
       ..assertLibrariesToImport(includes: [
-        'dart:async',
-        'dart:math',
         'package:test/a.dart',
         'package:test/b.dart',
       ], excludes: [
+        'dart:async',
         'dart:core',
+        'dart:math',
         'package:test/test.dart',
       ]);
 
@@ -473,11 +530,11 @@
       ..assertComplete()
       ..assertReplacementBack(2)
       ..assertLibrariesToImport(includes: [
-        'dart:async',
-        'dart:math',
         'package:test/b.dart',
       ], excludes: [
+        'dart:async',
         'dart:core',
+        'dart:math',
         'package:test/a.dart',
         'package:test/test.dart',
       ]);
@@ -519,12 +576,12 @@
       ..assertComplete()
       ..assertReplacementBack(2)
       ..assertLibrariesToImport(includes: [
-        'dart:async',
-        'dart:math',
         'package:test/a.dart',
         'package:test/b.dart',
       ], excludes: [
+        'dart:async',
         'dart:core',
+        'dart:math',
         'package:test/test.dart',
       ]);
 
@@ -542,8 +599,7 @@
   }
 
   Future<void> test_notImported_pub_this_inLib_excludesTest() async {
-    // TODO(scheglov) Switch to PubspecYamlFileConfig
-    newPubspecYamlFile(testPackageRootPath, r'''
+    writeTestPackagePubspecYamlFile(r'''
 name: test
 ''');
 
@@ -582,8 +638,7 @@
   }
 
   Future<void> test_notImported_pub_this_inLib_includesThisSrc() async {
-    // TODO(scheglov) Switch to PubspecYamlFileConfig
-    newPubspecYamlFile(testPackageRootPath, r'''
+    writeTestPackagePubspecYamlFile(r'''
 name: test
 ''');
 
@@ -625,8 +680,7 @@
   }
 
   Future<void> test_notImported_pub_this_inTest_includesTest() async {
-    // TODO(scheglov) Switch to PubspecYamlFileConfig
-    newPubspecYamlFile(testPackageRootPath, r'''
+    writeTestPackagePubspecYamlFile(r'''
 name: test
 ''');
 
@@ -673,8 +727,7 @@
   }
 
   Future<void> test_notImported_pub_this_inTest_includesThisSrc() async {
-    // TODO(scheglov) Switch to PubspecYamlFileConfig
-    newPubspecYamlFile(testPackageRootPath, r'''
+    writeTestPackagePubspecYamlFile(r'''
 name: test
 ''');
 
@@ -1398,6 +1451,71 @@
     suggestionsValidator.assertCompletions(['foo02', 'foo01']);
   }
 
+  Future<void> test_yaml_analysisOptions_root() async {
+    await _configureWithWorkspaceRoot();
+
+    var path = convertPath('$testPackageRootPath/analysis_options.yaml');
+    var responseValidator = await _getCodeSuggestions(
+      path: path,
+      content: '^',
+    );
+
+    responseValidator
+      ..assertComplete()
+      ..assertEmptyReplacement();
+
+    responseValidator.suggestions
+        .withKindIdentifier()
+        .assertCompletionsContainsAll([
+      'analyzer: ',
+      'include: ',
+      'linter: ',
+    ]);
+  }
+
+  Future<void> test_yaml_fixData_root() async {
+    await _configureWithWorkspaceRoot();
+
+    var path = convertPath('$testPackageRootPath/fix_data.yaml');
+    var responseValidator = await _getCodeSuggestions(
+      path: path,
+      content: '^',
+    );
+
+    responseValidator
+      ..assertComplete()
+      ..assertEmptyReplacement();
+
+    responseValidator.suggestions
+        .withKindIdentifier()
+        .assertCompletionsContainsAll([
+      'version: ',
+      'transforms:',
+    ]);
+  }
+
+  Future<void> test_yaml_pubspec_root() async {
+    await _configureWithWorkspaceRoot();
+
+    var path = convertPath('$testPackageRootPath/pubspec.yaml');
+    var responseValidator = await _getCodeSuggestions(
+      path: path,
+      content: '^',
+    );
+
+    responseValidator
+      ..assertComplete()
+      ..assertEmptyReplacement();
+
+    responseValidator.suggestions
+        .withKindIdentifier()
+        .assertCompletionsContainsAll([
+      'name: ',
+      'dependencies: ',
+      'dev_dependencies: ',
+    ]);
+  }
+
   Future<CompletionGetSuggestions2ResponseValidator> _getCodeSuggestions({
     required String path,
     required String content,
@@ -1446,6 +1564,16 @@
       maxResults: maxResults,
     );
   }
+
+  RequestWithFutureResponse _sendTestCompletionRequest(String id, int offset) {
+    var request = CompletionGetSuggestions2Params(
+      testFilePathPlatform,
+      0,
+      1 << 10,
+    ).toRequest(id);
+    var futureResponse = _handleRequest(request);
+    return RequestWithFutureResponse(offset, request, futureResponse);
+  }
 }
 
 @reflectiveTest
@@ -2387,20 +2515,6 @@
   }
 }
 
-class GetSuggestionDetails2Validator {
-  final CompletionGetSuggestionDetails2Result result;
-
-  GetSuggestionDetails2Validator(this.result);
-
-  SourceChangeValidator hasChange() {
-    return SourceChangeValidator(result.change);
-  }
-
-  void hasCompletion(Object completion) {
-    expect(result.completion, completion);
-  }
-}
-
 class PubPackageAnalysisServerTest with ResourceProviderMixin {
   late final MockServerChannel serverChannel;
   late final AnalysisServer server;
@@ -2493,6 +2607,10 @@
     writePackageConfig(testPackageRoot, config);
   }
 
+  void writeTestPackagePubspecYamlFile(String content) {
+    newPubspecYamlFile(testPackageRootPath, content);
+  }
+
   Future<void> _configureWithWorkspaceRoot() async {
     await setRoots(included: [workspaceRootPath], excluded: []);
     await server.onAnalysisComplete;
@@ -2510,6 +2628,21 @@
   }
 }
 
+class RequestWithFutureResponse {
+  final int offset;
+  final Request request;
+  final Future<Response> futureResponse;
+
+  RequestWithFutureResponse(this.offset, this.request, this.futureResponse);
+
+  Future<CompletionGetSuggestions2ResponseValidator> toResult() async {
+    var response = await futureResponse;
+    expect(response, isResponseSuccess(request.id));
+    var result = CompletionGetSuggestions2Result.fromResponse(response);
+    return CompletionGetSuggestions2ResponseValidator(offset, result);
+  }
+}
+
 class SingleSuggestionValidator {
   final CompletionSuggestion suggestion;
   final List<String>? libraryUrisToImport;
@@ -2559,32 +2692,6 @@
   }
 }
 
-class SourceChangeValidator {
-  final SourceChange change;
-
-  SourceChangeValidator(this.change);
-
-  void assertNoFileEdits() {
-    expect(change.edits, isEmpty);
-  }
-
-  SourceFileEditValidator hasFileEdit(String path) {
-    var edit = change.edits.singleWhere((e) => e.file == path);
-    return SourceFileEditValidator(edit);
-  }
-}
-
-class SourceFileEditValidator {
-  final SourceFileEdit edit;
-
-  SourceFileEditValidator(this.edit);
-
-  void whenApplied(String applyTo, Object expected) {
-    var actual = SourceEdit.applySequence(applyTo, edit.edits);
-    expect(actual, expected);
-  }
-}
-
 class SuggestionsValidator {
   final List<CompletionSuggestion> suggestions;
   final List<String>? libraryUrisToImport;
@@ -2605,8 +2712,17 @@
     expect(actual, completions);
   }
 
+  /// Assert that this has suggestions with all [expected] completions.
+  /// There might be more suggestions, with other completions.
+  ///
+  /// Does not check the order, kinds, elements, etc.
+  void assertCompletionsContainsAll(Iterable<String> expected) {
+    var actual = suggestions.map((e) => e.completion).toSet();
+    expect(actual, containsAll(expected));
+  }
+
   void assertEmpty() {
-    expect(suggestions, isEmpty);
+    check(suggestions).isEmpty;
   }
 
   void assertLength(Object matcher) {
@@ -2650,4 +2766,35 @@
       libraryUrisToImport: libraryUrisToImport,
     );
   }
+
+  SuggestionsValidator withKind(CompletionSuggestionKind kind) {
+    return SuggestionsValidator(
+      suggestions.where((suggestion) {
+        return suggestion.kind == kind;
+      }).toList(),
+      libraryUrisToImport: libraryUrisToImport,
+    );
+  }
+
+  SuggestionsValidator withKindIdentifier() {
+    return withKind(CompletionSuggestionKind.IDENTIFIER);
+  }
+}
+
+extension on CheckTarget<CompletionGetSuggestionDetails2Result> {
+  @useResult
+  CheckTarget<String> get completion {
+    return nest(
+      value.completion,
+      (selected) => 'has completion ${valueStr(selected)}',
+    );
+  }
+
+  @useResult
+  CheckTarget<SourceChange> get change {
+    return nest(
+      value.change,
+      (selected) => 'has change ${valueStr(selected)}',
+    );
+  }
 }
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index 9a707cf..aa0d470 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1020,9 +1020,11 @@
   ///   True if the number of suggestions after filtering was greater than the
   ///   requested maxResults.
   Future<CompletionGetSuggestions2Result> sendCompletionGetSuggestions2(
-      String file, int offset, int maxResults) async {
-    var params =
-        CompletionGetSuggestions2Params(file, offset, maxResults).toJson();
+      String file, int offset, int maxResults,
+      {int? timeout}) async {
+    var params = CompletionGetSuggestions2Params(file, offset, maxResults,
+            timeout: timeout)
+        .toJson();
     var result = await server.send('completion.getSuggestions2', params);
     var decoder = ResponseDecoder(null);
     return CompletionGetSuggestions2Result.fromJson(decoder, 'result', result);
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart
index 6ca048e..3ef73c2 100644
--- a/pkg/analysis_server/test/integration/support/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -41,7 +41,7 @@
 Matcher isOneOf(List<Matcher> choiceMatchers) => _OneOf(choiceMatchers);
 
 /// Assert that [actual] matches [matcher].
-void outOfTestExpect(actual, Matcher matcher,
+void outOfTestExpect(Object? actual, Matcher matcher,
     {String? reason, skip, bool verbose = false}) {
   var matchState = {};
   try {
@@ -377,8 +377,8 @@
       description.add(this.description);
 
   @override
-  void populateMismatches(item, List<MismatchDescriber> mismatches) {
-    if (item is! Map) {
+  void populateMismatches(Object? item, List<MismatchDescriber> mismatches) {
+    if (item is! Map<String, Object?>) {
       mismatches.add(simpleDescription('is not a map'));
       return;
     }
@@ -535,7 +535,7 @@
       _recordStdio('<== $trimmedLine');
       Map message;
       try {
-        message = json.decoder.convert(trimmedLine);
+        message = json.decoder.convert(trimmedLine) as Map<Object?, Object?>;
       } catch (exception) {
         _badDataFromServer('JSON decode failure: $exception');
         return;
@@ -543,7 +543,7 @@
       outOfTestExpect(message, isMap);
       if (message.containsKey('id')) {
         outOfTestExpect(message['id'], isString);
-        String id = message['id'];
+        var id = message['id'] as String;
         var completer = _pendingCommands[id];
         if (completer == null) {
           fail('Unexpected response from server: id=$id');
@@ -553,7 +553,7 @@
         if (message.containsKey('error')) {
           completer.completeError(ServerErrorMessage(message));
         } else {
-          completer.complete(message['result']);
+          completer.complete(message['result'] as Map<String, Object?>?);
         }
         // Check that the message is well-formed.  We do this after calling
         // completer.complete() or completer.completeError() so that we don't
@@ -564,7 +564,8 @@
         // params.
         outOfTestExpect(message, contains('event'));
         outOfTestExpect(message['event'], isString);
-        notificationProcessor(message['event'], message['params']);
+        notificationProcessor(message['event'] as String,
+            message['params'] as Map<Object?, Object?>);
         // Check that the message is well-formed.  We do this after calling
         // notificationController.add() so that we don't stall the test in the
         // event of an error.
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 5fd8c3c..70848d4 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -2139,7 +2139,8 @@
 /// }
 final Matcher isCompletionGetSuggestions2Params = LazyMatcher(() =>
     MatchesJsonObject('completion.getSuggestions2 params',
-        {'file': isFilePath, 'offset': isInt, 'maxResults': isInt}));
+        {'file': isFilePath, 'offset': isInt, 'maxResults': isInt},
+        optionalFields: {'timeout': isInt}));
 
 /// completion.getSuggestions2 result
 ///
diff --git a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
index 2797109..cf67637f 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -393,6 +393,39 @@
     }
   }
 
+  Future<void> test_sort() async {
+    const content = '''
+    import 'package:flutter/widgets.dart';
+
+    build() => Contai^ner(child: Container());
+    ''';
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
+      workspaceCapabilities:
+          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
+    );
+
+    final codeActions = await getCodeActions(mainFileUri.toString(),
+        position: positionFromMarker(content));
+    final names = codeActions.map(
+      (e) => e.map((command) => command.title, (action) => action.title),
+    );
+
+    expect(
+      names,
+      containsAllInOrder([
+        // Check the ordering for two well-known assists that should always be
+        // sorted this way.
+        // https://github.com/Dart-Code/Dart-Code/issues/3646
+        'Wrap with widget...',
+        'Remove this widget',
+      ]),
+    );
+  }
+
   List<TextDocumentEdit> _extractTextDocumentEdits(
           Either2<
                   List<TextDocumentEdit>,
@@ -424,5 +457,5 @@
   _RawParams(this._json);
 
   @override
-  Object toJson() => jsonDecode(_json);
+  Object toJson() => jsonDecode(_json) as Object;
 }
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 9ccf020..cbacc55 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -4,9 +4,11 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:collection/collection.dart';
+import 'package:linter/src/rules.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -234,6 +236,21 @@
         insertText: 'myFunction',
       );
 
+  Future<void> test_completeFunctionCalls_existingArgList_member_noPrefix() =>
+      // https://github.com/Dart-Code/Dart-Code/issues/3672
+      checkCompleteFunctionCallInsertText(
+        '''
+        class Aaaaa {
+          static foo(int a) {}
+        }
+        void f() {
+          Aaaaa.[[^]]()
+        }
+        ''',
+        'foo(…)',
+        insertText: 'foo',
+      );
+
   Future<void> test_completeFunctionCalls_existingArgList_namedConstructor() =>
       checkCompleteFunctionCallInsertText(
         '''
@@ -1606,6 +1623,36 @@
     expect(resolved.detail, isNull);
   }
 
+  Future<void> test_suggestionSets_importsPackageUri() async {
+    newFile(
+      join(projectFolderPath, 'lib', 'my_class.dart'),
+      content: 'class MyClass {}',
+    );
+
+    final content = '''
+void f() {
+  MyClas^
+}
+    ''';
+
+    final expectedContent = '''
+import 'package:test/my_class.dart';
+
+void f() {
+  MyClass
+}
+    ''';
+
+    final completionLabel = 'MyClass';
+
+    await _checkCompletionEdits(
+      mainFileUri,
+      content,
+      completionLabel,
+      expectedContent,
+    );
+  }
+
   Future<void>
       test_suggestionSets_includesReexportedSymbolsForEachFile() async {
     newFile(
@@ -2003,6 +2050,78 @@
     '''));
   }
 
+  Future<void> test_suggestionSets_preferRelativeImportsLib_insideLib() async {
+    _enableLints([LintNames.prefer_relative_imports]);
+    final importingFilePath =
+        join(projectFolderPath, 'lib', 'nested1', 'main.dart');
+    final importingFileUri = Uri.file(importingFilePath);
+    final importedFilePath =
+        join(projectFolderPath, 'lib', 'nested2', 'imported.dart');
+
+    // Create a file that will be auto-imported from completion.
+    newFile(importedFilePath, content: 'class MyClass {}');
+
+    final content = '''
+void f() {
+  MyClas^
+}
+    ''';
+
+    final expectedContent = '''
+import '../nested2/imported.dart';
+
+void f() {
+  MyClass
+}
+    ''';
+
+    final completionLabel = 'MyClass';
+
+    await _checkCompletionEdits(
+      importingFileUri,
+      content,
+      completionLabel,
+      expectedContent,
+    );
+  }
+
+  Future<void> test_suggestionSets_preferRelativeImportsLib_outsideLib() async {
+    // Files outside of the lib folder should still get absolute imports to
+    // files inside lib, even with the lint enabled.
+    _enableLints([LintNames.prefer_relative_imports]);
+    final importingFilePath =
+        join(projectFolderPath, 'bin', 'nested1', 'main.dart');
+    final importingFileUri = Uri.file(importingFilePath);
+    final importedFilePath =
+        join(projectFolderPath, 'lib', 'nested2', 'imported.dart');
+
+    // Create a file that will be auto-imported from completion.
+    newFile(importedFilePath, content: 'class MyClass {}');
+
+    final content = '''
+void f() {
+  MyClas^
+}
+    ''';
+
+    final expectedContent = '''
+import 'package:test/nested2/imported.dart';
+
+void f() {
+  MyClass
+}
+    ''';
+
+    final completionLabel = 'MyClass';
+
+    await _checkCompletionEdits(
+      importingFileUri,
+      content,
+      completionLabel,
+      expectedContent,
+    );
+  }
+
   Future<void> test_suggestionSets_unavailableIfDisabled() async {
     newFile(
       join(projectFolderPath, 'other_file.dart'),
@@ -2085,6 +2204,39 @@
     expect(updated, contains('a.abcdefghij'));
   }
 
+  /// Sets up the server with a file containing [content] and checks that
+  /// accepting a specific completion produces [expectedContent].
+  ///
+  /// [content] should contain a `^` at the location where completion should be
+  /// invoked/accepted.
+  Future<void> _checkCompletionEdits(
+    Uri fileUri,
+    String content,
+    String completionLabel,
+    String expectedContent,
+  ) async {
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(fileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(fileUri, positionFromMarker(content));
+
+    final completion = res.where((c) => c.label == completionLabel).single;
+    final resolvedCompletion = await resolveCompletion(completion);
+
+    // Apply both the main completion edit and the additionalTextEdits atomically.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [toTextEdit(resolvedCompletion.textEdit!)]
+          .followedBy(resolvedCompletion.additionalTextEdits!)
+          .toList(),
+    );
+
+    expect(newContent, equals(expectedContent));
+  }
+
   Future<void> _checkResultsForTriggerCharacters(String content,
       List<String> triggerCharacters, Matcher expectedResults) async {
     await initialize();
@@ -2099,6 +2251,16 @@
       expect(res, expectedResults);
     }
   }
+
+  void _enableLints(List<String> lintNames) {
+    registerLintRules();
+    final lintsYaml = lintNames.map((name) => '    - $name\n').join();
+    newFile(analysisOptionsPath, content: '''
+linter:
+  rules:
+$lintsYaml
+''');
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index fc6dffe..3b7fc18 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -88,7 +88,7 @@
 linter:
   rules:
     - invalid_lint_rule_name
-''').path;
+''');
 
     final firstDiagnosticsUpdate = waitForDiagnostics(analysisOptionsUri);
     await initialize();
@@ -102,7 +102,7 @@
   Future<void> test_analysisOptionsFile_packageInclude() async {
     newFile(analysisOptionsPath, content: '''
 include: package:pedantic/analysis_options.yaml
-''').path;
+''');
 
     // Verify there's an error for the import.
     final firstDiagnosticsUpdate = waitForDiagnostics(analysisOptionsUri);
diff --git a/pkg/analysis_server/test/lsp/document_color_test.dart b/pkg/analysis_server/test/lsp/document_color_test.dart
new file mode 100644
index 0000000..55dbf74
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/document_color_test.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DocumentColorTest);
+    defineReflectiveTests(DocumentColorPresentationTest);
+  });
+}
+
+@reflectiveTest
+class DocumentColorPresentationTest extends AbstractLspAnalysisServerTest {
+  late Range colorRange, importRange;
+  final uiImportUri = 'package:ui/ui.dart';
+
+  @override
+  void setUp() {
+    super.setUp();
+    writePackageConfig(projectFolderPath, flutter: true);
+  }
+
+  Future<void> test_includesImportEdit() async {
+    // Create a file that doesn't already import the required library.
+    //
+    // We don't need a real color reference in the file right now, as we're
+    // calling colorPresentation directly to get the new code (and not fetching
+    // colors already in the file).
+    const content = '''
+[[]]const white = [[]];
+''';
+
+    final ranges = rangesFromMarkers(content);
+    importRange = ranges[0];
+    colorRange = ranges[1];
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize();
+
+    final colorPresentations = await getColorPresentation(
+      mainFileUri.toString(),
+      colorRange,
+      Color(alpha: 1, red: 1, green: 1, blue: 1),
+    );
+
+    expect(
+      colorPresentations,
+      equals([
+        _color('Color.fromARGB(255, 255, 255, 255)', importUri: uiImportUri),
+        _color('Color.fromRGBO(255, 255, 255, 1)', importUri: uiImportUri),
+        _color('Color(0xFFFFFFFF)', importUri: uiImportUri),
+      ]),
+    );
+  }
+
+  Future<void> test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final colors = await getColorPresentation(
+      pubspecFileUri.toString(),
+      startOfDocRange,
+      Color(alpha: 1, red: 1, green: 1, blue: 1),
+    );
+    expect(colors, isEmpty);
+  }
+
+  Future<void> test_simpleColor() async {
+    const content = '''
+    import 'package:flutter/material.dart';
+
+    const white = [[Color(0xFFFFFFFF)]];
+    ''';
+    colorRange = rangeFromMarkers(content);
+
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize();
+
+    final colorPresentations = await getColorPresentation(
+      mainFileUri.toString(),
+      colorRange,
+      // Send a different color to what's in the source to simulate the user
+      // having changed in the color picker. This is the one that we should be
+      // creating a presentation for, not the one in the source.
+      Color(alpha: 1, red: 1, green: 0, blue: 0),
+    );
+
+    expect(
+      colorPresentations,
+      equals([
+        _color('Color.fromARGB(255, 255, 0, 0)'),
+        _color('Color.fromRGBO(255, 0, 0, 1)'),
+        _color('Color(0xFFFF0000)'),
+      ]),
+    );
+  }
+
+  /// Creates a [ColorPresentation] for comparing against actual results.
+  ColorPresentation _color(
+    String label, {
+    String? colorCode,
+    String? importUri,
+  }) {
+    final edit = TextEdit(range: colorRange, newText: colorCode ?? label);
+    final additionalEdits = importUri != null
+        ? [TextEdit(range: importRange, newText: "import '$importUri';\n\n")]
+        : null;
+
+    return ColorPresentation(
+      label: label,
+      textEdit: edit,
+      additionalTextEdits: additionalEdits,
+    );
+  }
+}
+
+@reflectiveTest
+class DocumentColorTest extends AbstractLspAnalysisServerTest {
+  @override
+  void setUp() {
+    super.setUp();
+    writePackageConfig(projectFolderPath, flutter: true);
+  }
+
+  Future<void> test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final colors = await getDocumentColors(pubspecFileUri.toString());
+    expect(colors, isEmpty);
+  }
+
+  Future<void> test_simpleColor() async {
+    const content = '''
+    import 'package:flutter/material.dart';
+
+    const red = [[Colors.red]];
+    ''';
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize();
+
+    final colors = await getDocumentColors(mainFileUri.toString());
+    expect(colors, hasLength(1));
+
+    final color = colors[0];
+    expect(color.range, rangeFromMarkers(content));
+    expect(color.color.alpha, equals(1));
+    expect(color.color.red, equals(1));
+    expect(color.color.green, equals(0));
+    expect(color.color.blue, equals(0));
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 61bac2e..7ffff8a 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -295,6 +295,26 @@
     await expectRangeFormattedContents(mainFileUri, contents, expected);
   }
 
+  Future<void> test_formatRange_trailingNewline_47702() async {
+    // Check we complete when a formatted block ends with a newline.
+    // https://github.com/dart-lang/sdk/issues/47702
+    const contents = '''
+int a;
+[[
+    int b;
+]]
+''';
+    final expected = '''
+int a;
+
+int b;
+
+''';
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    await expectRangeFormattedContents(mainFileUri, contents, expected);
+  }
+
   Future<void> test_invalidSyntax() async {
     const contents = '''void f(((( {
   print('test');
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index b6bbc58..4d006be 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -230,6 +230,7 @@
     expect(initResult.capabilities.hoverProvider, isNotNull);
     expect(initResult.capabilities.signatureHelpProvider, isNotNull);
     expect(initResult.capabilities.referencesProvider, isNotNull);
+    expect(initResult.capabilities.colorProvider, isNotNull);
     expect(initResult.capabilities.documentHighlightProvider, isNotNull);
     expect(initResult.capabilities.documentFormattingProvider, isNotNull);
     expect(initResult.capabilities.documentOnTypeFormattingProvider, isNotNull);
@@ -289,6 +290,7 @@
     expect(initResult.capabilities.hoverProvider, isNull);
     expect(initResult.capabilities.signatureHelpProvider, isNull);
     expect(initResult.capabilities.referencesProvider, isNull);
+    expect(initResult.capabilities.colorProvider, isNull);
     expect(initResult.capabilities.documentHighlightProvider, isNull);
     expect(initResult.capabilities.documentFormattingProvider, isNull);
     expect(initResult.capabilities.documentOnTypeFormattingProvider, isNull);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 6b8ba52..851966e 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -261,9 +261,11 @@
 
   void mergeJson(Map<String, dynamic> source, Map<String, dynamic> dest) {
     source.keys.forEach((key) {
-      if (source[key] is Map<String, dynamic> &&
-          dest[key] is Map<String, dynamic>) {
-        mergeJson(source[key], dest[key]);
+      var sourceValue = source[key];
+      var destValue = dest[key];
+      if (sourceValue is Map<String, dynamic> &&
+          destValue is Map<String, dynamic>) {
+        mergeJson(sourceValue, destValue);
       } else {
         dest[key] = source[key];
       }
@@ -284,6 +286,7 @@
       'references': {'dynamicRegistration': true},
       'documentHighlight': {'dynamicRegistration': true},
       'documentSymbol': {'dynamicRegistration': true},
+      'colorProvider': {'dynamicRegistration': true},
       'formatting': {'dynamicRegistration': true},
       'onTypeFormatting': {'dynamicRegistration': true},
       'rangeFormatting': {'dynamicRegistration': true},
@@ -877,7 +880,7 @@
     return expectSuccessfulResponseTo(request, (result) => result);
   }
 
-  void expect(actual, matcher, {String? reason}) =>
+  void expect(Object? actual, Matcher matcher, {String? reason}) =>
       test.expect(actual, matcher, reason: reason);
 
   void expectDocumentVersion(
@@ -1035,6 +1038,22 @@
     );
   }
 
+  Future<List<ColorPresentation>> getColorPresentation(
+      String fileUri, Range range, Color color) {
+    final request = makeRequest(
+      Method.textDocument_colorPresentation,
+      ColorPresentationParams(
+        textDocument: TextDocumentIdentifier(uri: fileUri),
+        range: range,
+        color: color,
+      ),
+    );
+    return expectSuccessfulResponseTo(
+      request,
+      _fromJsonList(ColorPresentation.fromJson),
+    );
+  }
+
   Future<List<CompletionItem>> getCompletion(Uri uri, Position pos,
       {CompletionContext? context}) {
     final request = makeRequest(
@@ -1093,6 +1112,19 @@
     return expectSuccessfulResponseTo(request, DartDiagnosticServer.fromJson);
   }
 
+  Future<List<ColorInformation>> getDocumentColors(String fileUri) {
+    final request = makeRequest(
+      Method.textDocument_documentColor,
+      DocumentColorParams(
+        textDocument: TextDocumentIdentifier(uri: fileUri),
+      ),
+    );
+    return expectSuccessfulResponseTo(
+      request,
+      _fromJsonList(ColorInformation.fromJson),
+    );
+  }
+
   Future<List<DocumentHighlight>?> getDocumentHighlights(
       Uri uri, Position pos) {
     final request = makeRequest(
@@ -1164,7 +1196,7 @@
   Future<List<Location>> getReferences(
     Uri uri,
     Position pos, {
-    includeDeclarations = false,
+    bool includeDeclarations = false,
   }) {
     final request = makeRequest(
       Method.textDocument_references,
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
index 752d3f1..bd22081 100644
--- a/pkg/analysis_server/test/lsp/test_all.dart
+++ b/pkg/analysis_server/test/lsp/test_all.dart
@@ -20,6 +20,7 @@
 import 'definition_test.dart' as definition;
 import 'diagnostic_test.dart' as diagnostic;
 import 'document_changes_test.dart' as document_changes;
+import 'document_color_test.dart' as document_color;
 import 'document_highlights_test.dart' as document_highlights;
 import 'document_symbols_test.dart' as document_symbols;
 import 'file_modification_test.dart' as file_modification;
@@ -63,6 +64,7 @@
     document_changes.main();
     document_highlights.main();
     document_symbols.main();
+    document_color.main();
     file_modification.main();
     flutter_outline.main();
     folding.main();
diff --git a/pkg/analysis_server/test/mock_packages/flutter/lib/cupertino.dart b/pkg/analysis_server/test/mock_packages/flutter/lib/cupertino.dart
new file mode 100644
index 0000000..828a456
--- /dev/null
+++ b/pkg/analysis_server/test/mock_packages/flutter/lib/cupertino.dart
@@ -0,0 +1,5 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+export 'src/cupertino/colors.dart';
diff --git a/pkg/analysis_server/test/mock_packages/flutter/lib/material.dart b/pkg/analysis_server/test/mock_packages/flutter/lib/material.dart
index 466ed8e..a1cecbd 100644
--- a/pkg/analysis_server/test/mock_packages/flutter/lib/material.dart
+++ b/pkg/analysis_server/test/mock_packages/flutter/lib/material.dart
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 export 'src/material/app_bar.dart';
+export 'src/material/colors.dart';
 export 'src/material/icons.dart';
 export 'src/material/scaffold.dart';
 export 'widgets.dart';
diff --git a/pkg/analysis_server/test/mock_packages/flutter/lib/painting.dart b/pkg/analysis_server/test/mock_packages/flutter/lib/painting.dart
index a3323f6..6eec7c5 100644
--- a/pkg/analysis_server/test/mock_packages/flutter/lib/painting.dart
+++ b/pkg/analysis_server/test/mock_packages/flutter/lib/painting.dart
@@ -5,6 +5,7 @@
 export 'src/painting/alignment.dart';
 export 'src/painting/basic_types.dart';
 export 'src/painting/box_decoration.dart';
+export 'src/painting/colors.dart';
 export 'src/painting/decoration.dart';
 export 'src/painting/edge_insets.dart';
 export 'src/painting/text_painter.dart';
diff --git a/pkg/analysis_server/test/mock_packages/flutter/lib/src/cupertino/colors.dart b/pkg/analysis_server/test/mock_packages/flutter/lib/src/cupertino/colors.dart
new file mode 100644
index 0000000..62356d5
--- /dev/null
+++ b/pkg/analysis_server/test/mock_packages/flutter/lib/src/cupertino/colors.dart
@@ -0,0 +1,102 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/painting.dart';
+
+class CupertinoColors {
+  CupertinoColors._();
+
+  static const CupertinoDynamicColor activeBlue = systemBlue;
+
+  static const Color black = Color(0xFF000000);
+  static const Color white = Color(0xFFFFFFFF);
+
+  static const CupertinoDynamicColor systemBlue =
+      CupertinoDynamicColor.withBrightnessAndContrast(
+    color: Color.fromARGB(255, 0, 0, 0xFF),
+    darkColor: Color.fromARGB(255, 0, 0, 0x99),
+    highContrastColor: Color.fromARGB(255, 0, 0, 0x66),
+    darkHighContrastColor: Color.fromARGB(255, 0, 0, 0x33),
+  );
+}
+
+class CupertinoDynamicColor extends Color {
+  const CupertinoDynamicColor({
+    Color color,
+    Color darkColor,
+    Color highContrastColor,
+    Color darkHighContrastColor,
+    Color elevatedColor,
+    Color darkElevatedColor,
+    Color highContrastElevatedColor,
+    Color darkHighContrastElevatedColor,
+  }) : this._(
+          color,
+          color,
+          darkColor,
+          highContrastColor,
+          darkHighContrastColor,
+          elevatedColor,
+          darkElevatedColor,
+          highContrastElevatedColor,
+          darkHighContrastElevatedColor,
+          null,
+        );
+
+  const CupertinoDynamicColor.withBrightnessAndContrast({
+    Color color,
+    Color darkColor,
+    Color highContrastColor,
+    Color darkHighContrastColor,
+  }) : this(
+          color: color,
+          darkColor: darkColor,
+          highContrastColor: highContrastColor,
+          darkHighContrastColor: darkHighContrastColor,
+          elevatedColor: color,
+          darkElevatedColor: darkColor,
+          highContrastElevatedColor: highContrastColor,
+          darkHighContrastElevatedColor: darkHighContrastColor,
+        );
+
+  const CupertinoDynamicColor.withBrightness({
+    Color color,
+    Color darkColor,
+  }) : this(
+          color: color,
+          darkColor: darkColor,
+          highContrastColor: color,
+          darkHighContrastColor: darkColor,
+          elevatedColor: color,
+          darkElevatedColor: darkColor,
+          highContrastElevatedColor: color,
+          darkHighContrastElevatedColor: darkColor,
+        );
+
+  const CupertinoDynamicColor._(
+    this._effectiveColor,
+    this.color,
+    this.darkColor,
+    this.highContrastColor,
+    this.darkHighContrastColor,
+    this.elevatedColor,
+    this.darkElevatedColor,
+    this.highContrastElevatedColor,
+    this.darkHighContrastElevatedColor,
+  ) : super(0);
+
+  final Color _effectiveColor;
+
+  @override
+  int get value => _effectiveColor.value;
+
+  final Color color;
+  final Color darkColor;
+  final Color highContrastColor;
+  final Color darkHighContrastColor;
+  final Color elevatedColor;
+  final Color darkElevatedColor;
+  final Color highContrastElevatedColor;
+  final Color darkHighContrastElevatedColor;
+}
diff --git a/pkg/analysis_server/test/mock_packages/flutter/lib/src/material/colors.dart b/pkg/analysis_server/test/mock_packages/flutter/lib/src/material/colors.dart
new file mode 100644
index 0000000..803f7a5
--- /dev/null
+++ b/pkg/analysis_server/test/mock_packages/flutter/lib/src/material/colors.dart
@@ -0,0 +1,71 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/painting.dart';
+
+class MaterialColor extends ColorSwatch<int> {
+  const MaterialColor(int primary, Map<int, Color> swatch)
+      : super(primary, swatch);
+
+  Color get shade100 => this[100];
+  Color get shade200 => this[200];
+  Color get shade300 => this[300];
+  Color get shade400 => this[400];
+  Color get shade50 => this[50];
+  Color get shade500 => this[500];
+  Color get shade600 => this[600];
+  Color get shade700 => this[700];
+  Color get shade800 => this[800];
+  Color get shade900 => this[900];
+}
+
+class MaterialAccentColor extends ColorSwatch<int> {
+  const MaterialAccentColor(int primary, Map<int, Color> swatch)
+      : super(primary, swatch);
+
+  Color get shade50 => this[50];
+  Color get shade100 => this[100];
+  Color get shade200 => this[200];
+  Color get shade400 => this[400];
+  Color get shade700 => this[700];
+}
+
+class Colors {
+  Colors._();
+
+  static const Color black = Color(0xFF000000);
+  static const Color white = Color(0xFFFFFFFF);
+
+  static const MaterialColor red = MaterialColor(
+    _redPrimaryValue,
+    <int, Color>{
+      // For simpler testing, these values are not the real Flutter values
+      // but just varying alphas on a primary value.
+      50: Color(0x05FF0000),
+      100: Color(0x10FF0000),
+      200: Color(0x20FF0000),
+      300: Color(0x30FF0000),
+      400: Color(0x40FF0000),
+      500: Color(0x50FF0000),
+      600: Color(0x60FF0000),
+      700: Color(0x70FF0000),
+      800: Color(0x80FF0000),
+      900: Color(0x90FF0000),
+    },
+  );
+  static const int _redPrimaryValue = 0xFFFF0000;
+
+  static const MaterialAccentColor redAccent = MaterialAccentColor(
+    _redAccentValue,
+    <int, Color>{
+      // For simpler testing, these values are not the real Flutter values
+      // but just varying alphas on a primary value.
+      100: Color(0x10FFAA00),
+      200: Color(0x20FFAA00),
+      400: Color(0x40FFAA00),
+      700: Color(0x70FFAA00),
+    },
+  );
+  static const int _redAccentValue = 0xFFFFAA00;
+}
diff --git a/pkg/analysis_server/test/mock_packages/flutter/lib/src/painting/colors.dart b/pkg/analysis_server/test/mock_packages/flutter/lib/src/painting/colors.dart
new file mode 100644
index 0000000..f0dbfae
--- /dev/null
+++ b/pkg/analysis_server/test/mock_packages/flutter/lib/src/painting/colors.dart
@@ -0,0 +1,16 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/painting.dart';
+
+@immutable
+class ColorSwatch<T> extends Color {
+  const ColorSwatch(int primary, this._swatch) : super(primary);
+
+  @protected
+  final Map<T, Color> _swatch;
+
+  Color operator [](T index) => _swatch[index];
+}
diff --git a/pkg/analysis_server/test/mock_packages/meta/lib/meta_meta.dart b/pkg/analysis_server/test/mock_packages/meta/lib/meta_meta.dart
new file mode 100644
index 0000000..18902be
--- /dev/null
+++ b/pkg/analysis_server/test/mock_packages/meta/lib/meta_meta.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2020, 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.
+
+/// Annotations that describe the intended use of other annotations.
+library meta_meta;
+
+/// An annotation used on classes that are intended to be used as annotations
+/// to indicate the kinds of declarations and directives for which the
+/// annotation is appropriate.
+///
+/// The kinds are represented by the constants defined in [TargetKind].
+///
+/// Tools, such as the analyzer, can provide feedback if
+///
+/// * the annotation is associated with anything other than a class, where the
+///   class must be usable as an annotation (that is, contain at least one
+///   `const` constructor).
+/// * the annotated annotation is associated with anything other than the kinds
+///   of declarations listed as valid targets.
+@Target({TargetKind.classType})
+class Target {
+  /// The kinds of declarations with which the annotated annotation can be
+  /// associated.
+  final Set<TargetKind> kinds;
+
+  const Target(this.kinds);
+}
+
+/// An enumeration of the kinds of targets to which an annotation can be
+/// applied.
+enum TargetKind {
+  /// Indicates that an annotation is valid on any class declaration.
+  classType,
+
+  /// Indicates that an annotation is valid on any enum declaration.
+  enumType,
+
+  /// Indicates that an annotation is valid on any extension declaration.
+  extension,
+
+  /// Indicates that an annotation is valid on any field declaration, both
+  /// instance and static fields, whether it's in a class, mixin or extension.
+  field,
+
+  /// Indicates that an annotation is valid on any top-level function
+  /// declaration.
+  function,
+
+  /// Indicates that an annotation is valid on the first directive in a library,
+  /// whether that's a `library`, `import`, `export` or `part` directive. This
+  /// doesn't include the `part of` directive in a part file.
+  library,
+
+  /// Indicates that an annotation is valid on any getter declaration, both
+  /// instance or static getters, whether it's in a class, mixin, extension, or
+  /// at the top-level of a library.
+  getter,
+
+  /// Indicates that an annotation is valid on any method declaration, both
+  /// instance and static methods, whether it's in a class, mixin or extension.
+  method,
+
+  /// Indicates that an annotation is valid on any mixin declaration.
+  mixinType,
+
+  /// Indicates that an annotation is valid on any formal parameter declaration,
+  /// whether it's in a function, method, constructor, or closure.
+  parameter,
+
+  /// Indicates that an annotation is valid on any setter declaration, both
+  /// instance or static setters, whether it's in a class, mixin, extension, or
+  /// at the top-level of a library.
+  setter,
+
+  /// Indicates that an annotation is valid on any top-level variable
+  /// declaration.
+  topLevelVariable,
+
+  /// Indicates that an annotation is valid on any declaration that introduces a
+  /// type. This includes classes, enums, mixins and typedefs, but does not
+  /// include extensions because extensions don't introduce a type.
+  type,
+
+  /// Indicates that an annotation is valid on any typedef declaration.
+  typedefType,
+}
+
+extension TargetKindExtension on TargetKind {
+  /// Return a user visible string used to describe this target kind.
+  String get displayString {
+    switch (this) {
+      case TargetKind.classType:
+        return 'classes';
+      case TargetKind.enumType:
+        return 'enums';
+      case TargetKind.extension:
+        return 'extensions';
+      case TargetKind.field:
+        return 'fields';
+      case TargetKind.function:
+        return 'top-level functions';
+      case TargetKind.library:
+        return 'libraries';
+      case TargetKind.getter:
+        return 'getters';
+      case TargetKind.method:
+        return 'methods';
+      case TargetKind.mixinType:
+        return 'mixins';
+      case TargetKind.parameter:
+        return 'parameters';
+      case TargetKind.setter:
+        return 'setters';
+      case TargetKind.topLevelVariable:
+        return 'top-level variables';
+      case TargetKind.type:
+        return 'types (classes, enums, mixins, or typedefs)';
+      case TargetKind.typedefType:
+        return 'typedefs';
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/search/declarations_test.dart b/pkg/analysis_server/test/search/declarations_test.dart
index 3d64012..3c0a02f 100644
--- a/pkg/analysis_server/test/search/declarations_test.dart
+++ b/pkg/analysis_server/test/search/declarations_test.dart
@@ -208,8 +208,8 @@
     assertHas('s', ElementKind.SETTER);
     assertHas('f', ElementKind.FUNCTION);
     assertHas('v', ElementKind.TOP_LEVEL_VARIABLE);
-    assertHas('tf1', ElementKind.FUNCTION_TYPE_ALIAS);
-    assertHas('tf2', ElementKind.FUNCTION_TYPE_ALIAS);
+    assertHas('tf1', ElementKind.TYPE_ALIAS);
+    assertHas('tf2', ElementKind.TYPE_ALIAS);
     assertHas('td3', ElementKind.TYPE_ALIAS);
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 690b251..4c2e182 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -123,7 +123,7 @@
 class ArgListContributorTest extends DartCompletionContributorTest
     with ArgListContributorMixin {
   Future<void> test_Annotation_imported_constructor_named_param() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library libA; class A { const A({int one, String two: 'defaultValue'}); }''');
     addTestSource('import "a.dart"; @A(^) main() { }');
     await computeSuggestions();
@@ -132,7 +132,7 @@
   }
 
   Future<void> test_Annotation_importedConstructor_prefixed() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   const A({int value});
 }
@@ -581,7 +581,8 @@
 
   Future<void> test_ArgumentList_imported_constructor_named_param() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement
-    addSource('/home/test/lib/a.dart', 'library libA; class A{A({int one}); }');
+    addSource(
+        '$testPackageLibPath/a.dart', 'library libA; class A{A({int one}); }');
     addTestSource('import "a.dart"; main() { new A(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'});
@@ -589,8 +590,8 @@
 
   Future<void> test_ArgumentList_imported_constructor_named_param2() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement
-    addSource(
-        '/home/test/lib/a.dart', 'library libA; class A{A.foo({int one}); }');
+    addSource('$testPackageLibPath/a.dart',
+        'library libA; class A{A.foo({int one}); }');
     addTestSource('import "a.dart"; main() { new A.foo(^);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'});
@@ -599,7 +600,7 @@
   Future<void>
       test_ArgumentList_imported_constructor_named_typed_param() async {
     // ArgumentList  InstanceCreationExpression  VariableDeclaration
-    addSource('/home/test/lib/a.dart',
+    addSource('$testPackageLibPath/a.dart',
         'library libA; class A { A({int i, String s, d}) {} }}');
     addTestSource('import "a.dart"; main() { var a = new A(^);}');
     await computeSuggestions();
@@ -609,7 +610,7 @@
 
   Future<void> test_ArgumentList_imported_factory_named_param() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement
-    addSource('/home/test/lib/a.dart',
+    addSource('$testPackageLibPath/a.dart',
         'library libA; class A{factory A({int one}) => throw 0;}');
     addTestSource('import "a.dart"; main() { new A(^);}');
     await computeSuggestions();
@@ -618,7 +619,7 @@
 
   Future<void> test_ArgumentList_imported_factory_named_param2() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement
-    addSource('/home/test/lib/a.dart',
+    addSource('$testPackageLibPath/a.dart',
         'library libA; abstract class A{factory A.foo({int one});}');
     addTestSource('import "a.dart"; main() { new A.foo(^);}');
     await computeSuggestions();
@@ -627,7 +628,7 @@
 
   Future<void> test_ArgumentList_imported_factory_named_typed_param() async {
     // ArgumentList  InstanceCreationExpression  VariableDeclaration
-    addSource('/home/test/lib/a.dart',
+    addSource('$testPackageLibPath/a.dart',
         'library libA; class A {factory A({int i, String s, d}) {} }}');
     addTestSource('import "a.dart"; main() { var a = new A(^);}');
     await computeSuggestions();
@@ -637,7 +638,7 @@
 
   Future<void> test_ArgumentList_imported_function_0() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
       library A;
       bool hasLength(int expected) { }
       expect() { }
@@ -653,7 +654,7 @@
 
   Future<void> test_ArgumentList_imported_function_3a() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
       library A;
       bool hasLength(int expected) { }
       expect(String arg1, int arg2, {bool arg3}) { }
@@ -669,7 +670,7 @@
 
   Future<void> test_ArgumentList_imported_function_3b() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
       library A;
       bool hasLength(int expected) { }
       expect(String arg1, int arg2, {bool arg3}) { }
@@ -685,7 +686,7 @@
 
   Future<void> test_ArgumentList_imported_function_3c() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
       library A;
       bool hasLength(int expected) { }
       expect(String arg1, int arg2, {bool arg3}) { }
@@ -701,7 +702,7 @@
 
   Future<void> test_ArgumentList_imported_function_3d() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
       library A;
       bool hasLength(int expected) { }
       expect(String arg1, int arg2, {bool arg3}) { }
@@ -1084,7 +1085,7 @@
 
   Future<void> test_ArgumentList_local_method_0() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
       library A;
       bool hasLength(int expected) { }
       void baz() { }''');
@@ -1111,7 +1112,7 @@
   }
 
   Future<void> test_ArgumentList_nnbd_function_named_param_imported() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 f({int? nullable, int nonnullable}) {}''');
     createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
     addTestSource(r'''
@@ -1126,7 +1127,7 @@
   }
 
   Future<void> test_ArgumentList_nnbd_function_named_param_legacy() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 // @dart = 2.8
 f({int named}) {}''');
     addTestSource(r'''
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index 3099fcf..a04f0be 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -41,17 +41,17 @@
 
   Future<void> test_Combinator_hide() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
       library libAB;
       part "ab_part.dart";
       class A { }
       class B { }''');
-    addSource('/home/test/lib/ab_part.dart', '''
+    addSource('$testPackageLibPath/ab_part.dart', '''
       part of libAB;
       var T1;
       PB F1() => new PB();
       class PB { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
       class C { }
       class D { }''');
     addTestSource('''
@@ -81,20 +81,20 @@
 
   Future<void> test_Combinator_show() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
       library libAB;
       part "ab_part.dart";
       class A { }
       class B { }
       class _AB''');
-    addSource('/home/test/lib/ab_part.dart', '''
+    addSource('$testPackageLibPath/ab_part.dart', '''
       part of libAB;
       var T1;
       PB F1() => new PB();
       typedef PB2 F2(int blat);
       class Clz = Object with Object;
       class PB { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
       class C { }
       class D { }''');
     addTestSource('''
@@ -129,11 +129,11 @@
   }
 
   Future<void> test_Combinator_show_export_withShow() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {}
 class B {}
 ''');
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 export 'a.dart' show A;
 ''');
     addTestSource(r'''
@@ -152,10 +152,10 @@
   }
 
   Future<void> test_Combinator_show_recursive() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {}
 ''');
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 export 'a.dart';
 export 'b.dart';
 class B {}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 4926490..a8c7e39 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -5,7 +5,6 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionRequest;
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
@@ -530,24 +529,21 @@
 
   Future computeSuggestions({int times = 200}) async {
     result = await session.getResolvedUnit(testFile) as ResolvedUnitResult;
-    return await CompletionPerformance().runRequestOperation(
-      (performance) async {
-        // Build the request
-        var request = DartCompletionRequest(
-          resolvedUnit: result,
-          offset: completionOffset,
-          dartdocDirectiveInfo: dartdocInfo,
-        );
 
-        var range = request.target.computeReplacementRange(request.offset);
-        replacementOffset = range.offset;
-        replacementLength = range.length;
-
-        // Request completions
-        suggestions = await computeContributedSuggestions(request);
-        expect(suggestions, isNotNull, reason: 'expected suggestions');
-      },
+    // Build the request
+    var request = DartCompletionRequest.forResolvedUnit(
+      resolvedUnit: result,
+      offset: completionOffset,
+      dartdocDirectiveInfo: dartdocInfo,
     );
+
+    var range = request.target.computeReplacementRange(request.offset);
+    replacementOffset = range.offset;
+    replacementLength = range.length;
+
+    // Request completions
+    suggestions = await computeContributedSuggestions(request);
+    expect(suggestions, isNotNull, reason: 'expected suggestions');
   }
 
   Never failedCompletion(String message,
@@ -613,7 +609,7 @@
   @override
   void setUp() {
     super.setUp();
-    testFile = convertPath('/home/test/lib/test.dart');
+    testFile = convertPath('$testPackageLibPath/test.dart');
   }
 
   CompletionSuggestion suggestionWith(
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index 972198c..be920e7 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -52,12 +52,12 @@
     // Build the request
     var resolvedUnit =
         await session.getResolvedUnit(testFile) as ResolvedUnitResult;
-    request = DartCompletionRequest(
+    request = DartCompletionRequest.forResolvedUnit(
       resolvedUnit: resolvedUnit,
       offset: completionOffset,
     );
 
-    var directives = request.target.unit.directives;
+    var directives = resolvedUnit.unit.directives;
 
     var imports = request.libraryElement.imports;
     expect(imports, hasLength(directives.length + 1));
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 6f277c3..534635b 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -36,7 +36,7 @@
 class ImportedReferenceContributorTest extends DartCompletionContributorTest
     with ImportedReferenceContributorMixin {
   Future<void> test_Annotation_typeArguments() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class C {}
 typedef T1 = void Function();
 typedef T2 = List<int>;
@@ -67,7 +67,7 @@
   Future<void> test_ArgDefaults_function_with_required_named() async {
     writeTestPackageConfig(meta: true);
 
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 lib B;
 import 'package:meta/meta.dart';
 
@@ -85,7 +85,7 @@
 
   Future<void> test_ArgumentList() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         void baz() { }''');
@@ -110,7 +110,7 @@
 
   Future<void> test_ArgumentList_imported_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         expect(arg) { }
@@ -137,7 +137,7 @@
   Future<void>
       test_ArgumentList_InstanceCreationExpression_functionalArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         class A { A(f()) { } }
         bool hasLength(int expected) { }
@@ -167,7 +167,7 @@
 
   Future<void> test_ArgumentList_InstanceCreationExpression_typedefArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         typedef Funct();
         class A { A(Funct f) { } }
@@ -198,7 +198,7 @@
 
   Future<void> test_ArgumentList_local_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         void baz() { }''');
@@ -224,7 +224,7 @@
 
   Future<void> test_ArgumentList_local_method() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         void baz() { }''');
@@ -250,7 +250,7 @@
 
   Future<void> test_ArgumentList_MethodInvocation_functionalArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         class A { A(f()) { } }
         bool hasLength(int expected) { }
@@ -280,7 +280,7 @@
 
   Future<void> test_ArgumentList_MethodInvocation_methodArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         class A { A(f()) { } }
         bool hasLength(int expected) { }
@@ -309,7 +309,7 @@
   Future<void> test_ArgumentList_namedParam() async {
     // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
     // ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }''');
     addTestSource('''
@@ -331,7 +331,7 @@
   }
 
   Future<void> test_AsExpression() async {
-    // SimpleIdentifier  TypeName  AsExpression
+    // SimpleIdentifier  NamedType  AsExpression
     addTestSource('''
         class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
 
@@ -351,8 +351,8 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  AsExpression  IfStatement
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  AsExpression  IfStatement
+    addSource('$testPackageLibPath/b.dart', '''
           foo() { }
           class A {} class B extends A {} class C extends B {}
           class X {X.c(); X._d(); z() {}}''');
@@ -378,8 +378,8 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  AsExpression  IfStatement
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  AsExpression  IfStatement
+    addSource('$testPackageLibPath/b.dart', '''
           foo() { }
           class A {} class B implements A {} class C implements B {}
           class X {X.c(); X._d(); z() {}}''');
@@ -423,7 +423,7 @@
   }
 
   Future<void> test_AssignmentExpression_type() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -446,7 +446,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_newline() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -468,7 +468,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_partial() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -491,7 +491,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_partial_newline() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -528,7 +528,7 @@
   }
 
   Future<void> test_AwaitExpression_function() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 Future y() async {return 0;}
 ''');
     addTestSource('''
@@ -548,7 +548,7 @@
 
   Future<void> test_AwaitExpression_inherited() async {
     // SimpleIdentifier  AwaitExpression  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib libB;
 class A {
   Future y() async { return 0; }
@@ -602,21 +602,21 @@
 
   Future<void> test_Block() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         export "dart:math" hide max;
         class A {int x;}
         @deprecated D1() {int x;}
         class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         String T1;
         var _T2;
         class C { }
         class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
         class EE { }
         class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
         class H { }
         int T3;
         var _T4;'''); // not imported
@@ -657,7 +657,7 @@
     assertNotSuggested('x');
     assertNotSuggested('partT8');
 
-    assertSuggestClass('A', elemFile: '/home/test/lib/ab.dart');
+    assertSuggestClass('A', elemFile: '$testPackageLibPath/ab.dart');
     if (suggestConstructorsWithoutNew) {
       assertSuggestConstructor('A');
     }
@@ -705,21 +705,21 @@
 
   Future<void> test_Block_final() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         export "dart:math" hide max;
         class A {int x;}
         @deprecated D1() {int x;}
         class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         String T1;
         var _T2;
         class C { }
         class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
         class EE { }
         class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
         class H { }
         int T3;
         var _T4;'''); // not imported
@@ -818,21 +818,21 @@
 
   Future<void> test_Block_final_final() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         export "dart:math" hide max;
         class A {int x;}
         @deprecated D1() {int x;}
         class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         String T1;
         var _T2;
         class C { }
         class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
         class EE { }
         class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
         class H { }
         int T3;
         var _T4;'''); // not imported
@@ -919,21 +919,21 @@
 
   Future<void> test_Block_final_var() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         export "dart:math" hide max;
         class A {int x;}
         @deprecated D1() {int x;}
         class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         String T1;
         var _T2;
         class C { }
         class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
         class EE { }
         class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
         class H { }
         int T3;
         var _T4;'''); // not imported
@@ -1017,21 +1017,21 @@
   }
 
   Future<void> test_Block_identifier_partial() async {
-    resolveSource('/home/test/lib/ab.dart', '''
+    resolveSource('$testPackageLibPath/ab.dart', '''
         export "dart:math" hide max;
         class A {int x;}
         @deprecated D1() {int x;}
         class _B { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         String T1;
         var _T2;
         class C { }
         class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
         class EE { }
         class DF { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
         class H { }
         class D3 { }
         int T3;
@@ -1094,7 +1094,7 @@
 
   Future<void> test_Block_inherited_imported() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
         class E extends F { var e1; e2() { } }
@@ -1148,21 +1148,21 @@
   }
 
   Future<void> test_Block_local_function() async {
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         export "dart:math" hide max;
         class A {int x;}
         @deprecated D1() {int x;}
         class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         String T1;
         var _T2;
         class C { }
         class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
         class EE { }
         class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
         class H { }
         int T3;
         var _T4;'''); // not imported
@@ -1200,21 +1200,21 @@
 
   Future<void> test_Block_partial_results() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         export "dart:math" hide max;
         class A {int x;}
         @deprecated D1() {int x;}
         class _B { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         String T1;
         var _T2;
         class C { }
         class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
         class EE { }
         class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
         class H { }
         int T3;
         var _T4;'''); // not imported
@@ -1252,7 +1252,7 @@
 
   Future<void> test_CascadeExpression_selector1() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import 'b.dart';
@@ -1277,7 +1277,7 @@
 
   Future<void> test_CascadeExpression_selector2() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import 'b.dart';
@@ -1300,7 +1300,7 @@
 
   Future<void> test_CascadeExpression_selector2_withTrailingReturn() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import 'b.dart';
@@ -1342,7 +1342,7 @@
   }
 
   Future<void> test_CatchClause_onType() async {
-    // TypeName  CatchClause  TryStatement
+    // NamedType  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^ {}}}');
 
     await computeSuggestions();
@@ -1355,7 +1355,7 @@
   }
 
   Future<void> test_CatchClause_onType_noBrackets() async {
-    // TypeName  CatchClause  TryStatement
+    // NamedType  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^}}');
 
     await computeSuggestions();
@@ -1395,7 +1395,7 @@
 
   Future<void> test_ClassDeclaration_body() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1420,7 +1420,7 @@
 
   Future<void> test_ClassDeclaration_body_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1441,7 +1441,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1462,7 +1462,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field2() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as Soo;
@@ -1483,7 +1483,7 @@
 
   Future<void> test_ClassDeclaration_body_final_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1504,7 +1504,7 @@
 
   Future<void> test_ClassDeclaration_body_final_var() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1525,7 +1525,7 @@
 
   Future<void> test_Combinator_hide() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         library libAB;
         part 'partAB.dart';
         class A { }
@@ -1535,7 +1535,7 @@
         var T1;
         PB F1() => new PB();
         class PB { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         class C { }
         class D { }''');
     addTestSource('''
@@ -1549,7 +1549,7 @@
 
   Future<void> test_Combinator_show() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
         library libAB;
         part 'partAB.dart';
         class A { }
@@ -1561,7 +1561,7 @@
         typedef PB2 F2(int blat);
         class Clz = Object with Object;
         class PB { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
         class C { }
         class D { }''');
     addTestSource('''
@@ -1575,7 +1575,7 @@
 
   Future<void> test_ConditionalExpression_elseExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1595,7 +1595,7 @@
 
   Future<void> test_ConditionalExpression_elseExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1624,7 +1624,7 @@
 
   Future<void> test_ConditionalExpression_partial_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1644,7 +1644,7 @@
 
   Future<void> test_ConditionalExpression_partial_thenExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1673,7 +1673,7 @@
 
   Future<void> test_ConditionalExpression_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1692,9 +1692,9 @@
   }
 
   Future<void> test_ConstructorName_importedClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
@@ -1717,9 +1717,9 @@
   }
 
   Future<void> test_ConstructorName_importedFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
@@ -1742,7 +1742,7 @@
   }
 
   Future<void> test_ConstructorName_importedFactory2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         void f() {new String.fr^omCharCodes([]);}''');
@@ -1760,7 +1760,7 @@
   }
 
   Future<void> test_ConstructorName_localClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         int T1;
@@ -1781,7 +1781,7 @@
   }
 
   Future<void> test_ConstructorName_localFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         int T1;
@@ -1820,7 +1820,7 @@
   }
 
   Future<void> test_doc_class() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 library A;
 /// My class.
 /// Short description.
@@ -1842,7 +1842,7 @@
   }
 
   Future<void> test_doc_function() async {
-    resolveSource('/home/test/lib/a.dart', r'''
+    resolveSource('$testPackageLibPath/a.dart', r'''
 library A;
 /// My function.
 /// Short description.
@@ -1861,7 +1861,7 @@
   }
 
   Future<void> test_doc_function_c_style() async {
-    resolveSource('/home/test/lib/a.dart', r'''
+    resolveSource('$testPackageLibPath/a.dart', r'''
 library A;
 /**
  * My function.
@@ -1882,7 +1882,7 @@
   }
 
   Future<void> test_enum() async {
-    addSource('/home/test/lib/a.dart', 'library A; enum E { one, two }');
+    addSource('$testPackageLibPath/a.dart', 'library A; enum E { one, two }');
     addTestSource('import "a.dart"; void f() {^}');
     await computeSuggestions();
     assertSuggestEnum('E');
@@ -1891,8 +1891,8 @@
   }
 
   Future<void> test_enum_deprecated() async {
-    addSource(
-        '/home/test/lib/a.dart', 'library A; @deprecated enum E { one, two }');
+    addSource('$testPackageLibPath/a.dart',
+        'library A; @deprecated enum E { one, two }');
     addTestSource('import "a.dart"; void f() {^}');
     await computeSuggestions();
     // TODO(danrube) investigate why suggestion/element is not deprecated
@@ -1903,7 +1903,7 @@
   }
 
   Future<void> test_enum_filter() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 enum E { one, two }
 enum F { three, four }
 ''');
@@ -1929,7 +1929,7 @@
 
   Future<void> test_ExpressionStatement_identifier() async {
     // SimpleIdentifier  ExpressionStatement  Block
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         _B F1() { }
         class A {int x;}
         class _B { }''');
@@ -1959,7 +1959,7 @@
 
   Future<void> test_ExpressionStatement_name() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         B T1;
         class B{}''');
     addTestSource('''
@@ -1971,7 +1971,7 @@
   }
 
   Future<void> test_ExtendsClause() async {
-    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('$testPackageLibPath/a.dart', content: 'class A {}');
     addTestSource('''
 import 'a.dart';
 
@@ -1982,7 +1982,7 @@
   }
 
   Future<void> test_ExtensionDeclaration_extendedType() async {
-    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('$testPackageLibPath/a.dart', content: 'class A {}');
     addTestSource('''
 import 'a.dart';
 
@@ -1994,7 +1994,7 @@
   }
 
   Future<void> test_ExtensionDeclaration_extendedType2() async {
-    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('$testPackageLibPath/a.dart', content: 'class A {}');
     addTestSource('''
 import 'a.dart';
 
@@ -2006,7 +2006,7 @@
   }
 
   Future<void> test_ExtensionDeclaration_member() async {
-    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('$testPackageLibPath/a.dart', content: 'class A {}');
     addTestSource('''
 import 'a.dart';
 
@@ -2019,7 +2019,7 @@
   Future<void> test_FieldDeclaration_name_typed() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         class C {A ^}''');
@@ -2031,7 +2031,7 @@
   Future<void> test_FieldDeclaration_name_var() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         class C {var ^}''');
@@ -2043,7 +2043,7 @@
   Future<void> test_FieldDeclaration_type() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         class C {^ foo;) ''');
@@ -2056,7 +2056,7 @@
   Future<void> test_FieldDeclaration_type_after_comment1() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         class C {
@@ -2072,7 +2072,7 @@
   Future<void> test_FieldDeclaration_type_after_comment2() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         class C {
@@ -2088,7 +2088,7 @@
   Future<void> test_FieldDeclaration_type_after_comment3() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         class C {
@@ -2104,7 +2104,7 @@
   Future<void> test_FieldDeclaration_type_without_semicolon() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         class C {^ foo} ''');
@@ -2287,7 +2287,7 @@
   }
 
   Future<void> test_function_parameters_mixed_required_and_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 int m(x, {int y}) {}
 ''');
     addTestSource('''
@@ -2310,7 +2310,7 @@
   }
 
   Future<void> test_function_parameters_mixed_required_and_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m(x, [int y]) {}
 ''');
     addTestSource('''
@@ -2333,7 +2333,7 @@
   }
 
   Future<void> test_function_parameters_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m({x, int y}) {}
 ''');
     addTestSource('''
@@ -2357,7 +2357,7 @@
 
   Future<void> test_function_parameters_nnbd_required() async {
     createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m(int? nullable, int nonNullable) {}
 ''');
     addTestSource('''
@@ -2380,7 +2380,7 @@
 
   Future<void> test_function_parameters_nnbd_required_into_legacy() async {
     createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m(int? nullable, int nonNullable) {}
 ''');
     addTestSource('''
@@ -2404,7 +2404,7 @@
 
   Future<void> test_function_parameters_nnbd_required_legacy() async {
     createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 // @dart = 2.8
 void m(int param) {}
 ''');
@@ -2425,7 +2425,7 @@
   }
 
   Future<void> test_function_parameters_none() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m() {}
 ''');
     addTestSource('''
@@ -2444,7 +2444,7 @@
   }
 
   Future<void> test_function_parameters_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m([x, int y]) {}
 ''');
     addTestSource('''
@@ -2467,7 +2467,7 @@
   }
 
   Future<void> test_function_parameters_required() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m(x, int y) {}
 ''');
     addTestSource('''
@@ -2491,7 +2491,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2522,7 +2522,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment2() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2553,7 +2553,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment3() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2600,7 +2600,7 @@
   }
 
   Future<void> test_functionTypeAlias_genericTypeAlias() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef F = void Function();
 ''');
     addTestSource(r'''
@@ -2616,7 +2616,7 @@
   }
 
   Future<void> test_functionTypeAlias_old() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef void F();
 ''');
     addTestSource(r'''
@@ -2697,7 +2697,7 @@
   }
 
   Future<void> test_implementsClause() async {
-    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('$testPackageLibPath/a.dart', content: 'class A {}');
     addTestSource('''
 import 'a.dart';
 
@@ -2708,7 +2708,7 @@
   }
 
   Future<void> test_implicitCreation() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   A.a1();
   A.a2();
@@ -2748,7 +2748,7 @@
 
   Future<void> test_IndexExpression() async {
     // ExpressionStatement  Block
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -2777,7 +2777,7 @@
 
   Future<void> test_IndexExpression2() async {
     // SimpleIdentifier IndexExpression ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -2796,7 +2796,7 @@
   }
 
   Future<void> test_InstanceCreationExpression() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {foo(){var f; {var x;}}}
 class B {B(this.x, [String boo]) { } int x;}
 class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
@@ -2850,7 +2850,7 @@
   }
 
   Future<void> test_InstanceCreationExpression_abstractClass() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 abstract class A {
   A();
   A.generative();
@@ -2873,7 +2873,7 @@
 
   Future<void>
       test_InstanceCreationExpression_abstractClass_implicitConstructor() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 abstract class A {}
 ''');
     addTestSource('''
@@ -2889,7 +2889,7 @@
   }
 
   Future<void> test_InstanceCreationExpression_filter() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {}
 class B extends A {}
 class C implements A {}
@@ -2911,8 +2911,8 @@
   }
 
   Future<void> test_InstanceCreationExpression_imported() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource('/home/test/lib/a.dart', '''
+    // SimpleIdentifier  NamedType  ConstructorName  InstanceCreationExpression
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {A(this.x) { } int x;}''');
@@ -2954,8 +2954,8 @@
   }
 
   Future<void> test_InstanceCreationExpression_unimported() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource('/home/test/lib/ab.dart', 'class Clip { }');
+    // SimpleIdentifier  NamedType  ConstructorName  InstanceCreationExpression
+    addSource('$testPackageLibPath/ab.dart', 'class Clip { }');
     addTestSource('class A {foo(){new C^}}');
 
     await computeSuggestions();
@@ -2979,7 +2979,7 @@
 
   Future<void> test_InterpolationExpression() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3013,7 +3013,7 @@
 
   Future<void> test_InterpolationExpression_block() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3087,8 +3087,8 @@
   }
 
   Future<void> test_IsExpression() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo() { }
         class X {X.c(); X._d(); z() {}}''');
@@ -3127,7 +3127,7 @@
   }
 
   Future<void> test_IsExpression_type() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
         class A {int x; int y() => 0;}
         void f(){var a; if (a is ^)}''');
@@ -3142,7 +3142,7 @@
   }
 
   Future<void> test_IsExpression_type_partial() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
         class A {int x; int y() => 0;}
         void f(){var a; if (a is Obj^)}''');
@@ -3162,8 +3162,8 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
+    addSource('$testPackageLibPath/b.dart', '''
         foo() { }
         class A {} class B extends A {} class C extends B {}
         class X {X.c(); X._d(); z() {}}''');
@@ -3189,8 +3189,8 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
+    addSource('$testPackageLibPath/b.dart', '''
         foo() { }
         class A {} class B implements A {} class C implements B {}
         class X {X.c(); X._d(); z() {}}''');
@@ -3211,7 +3211,7 @@
   }
 
   Future<void> test_keyword() async {
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
         lib B;
         int newT1;
         int T1;
@@ -3272,7 +3272,7 @@
 
   Future<void> test_MapLiteralEntry() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3310,7 +3310,7 @@
 
   Future<void> test_MapLiteralEntry1() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3337,7 +3337,7 @@
 
   Future<void> test_MapLiteralEntry2() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3358,7 +3358,7 @@
   }
 
   Future<void> test_method_parameters_mixed_required_and_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m(x, {int y}) {}
 ''');
     addTestSource('''
@@ -3381,7 +3381,7 @@
   }
 
   Future<void> test_method_parameters_mixed_required_and_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m(x, [int y]) {}
 ''');
     addTestSource('''
@@ -3404,7 +3404,7 @@
   }
 
   Future<void> test_method_parameters_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m({x, int y}) {}
 ''');
     addTestSource('''
@@ -3427,7 +3427,7 @@
   }
 
   Future<void> test_method_parameters_none() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m() {}
 ''');
     addTestSource('''
@@ -3446,7 +3446,7 @@
   }
 
   Future<void> test_method_parameters_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m([x, int y]) {}
 ''');
     addTestSource('''
@@ -3469,7 +3469,7 @@
   }
 
   Future<void> test_method_parameters_required() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 void m(x, int y) {}
 ''');
     addTestSource('''
@@ -3505,7 +3505,7 @@
 
   Future<void> test_MethodDeclaration_body_static() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/c.dart', '''
+    addSource('$testPackageLibPath/c.dart', '''
         class C {
           c1() {}
           var c2;
@@ -3591,7 +3591,7 @@
 
   Future<void> test_MethodDeclaration_returnType() async {
     // ClassDeclaration  CompilationUnit
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3621,7 +3621,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3651,7 +3651,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3681,7 +3681,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment3() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3745,7 +3745,7 @@
   }
 
   Future<void> test_MethodTypeArgumentList() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {}
 class B {}
 ''');
@@ -3786,7 +3786,7 @@
   }
 
   Future<void> test_mixin_ordering() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class B {}
 class M1 {
   void m() {}
@@ -3820,7 +3820,7 @@
   }
 
   Future<void> test_no_parameters_field() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int x;
 ''');
     addTestSource('''
@@ -3835,7 +3835,7 @@
   }
 
   Future<void> test_no_parameters_getter() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 int get x => null;
 ''');
     addTestSource('''
@@ -3850,7 +3850,7 @@
   }
 
   Future<void> test_no_parameters_setter() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 set x(int value) {};
 ''');
     addTestSource('''
@@ -3872,7 +3872,7 @@
   }
 
   Future<void> test_partFile_TypeName() async {
-    // SimpleIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  NamedType  ConstructorName
     addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
@@ -3909,13 +3909,13 @@
   }
 
   Future<void> test_partFile_TypeName2() async {
-    // SimpleIdentifier  TypeName  ConstructorName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  ConstructorName
+    addSource('$testPackageLibPath/b.dart', '''
         lib libB;
         int T1;
         F1() { }
         class X {X.c(); X._d(); z() {}}''');
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         part of libA;
         class B { }''');
     addTestSource('''
@@ -3945,7 +3945,7 @@
 
   Future<void> test_PrefixedIdentifier_class_const() async {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class I {
           static const scI = 'boo';
@@ -3992,7 +3992,7 @@
 
   Future<void> test_PrefixedIdentifier_class_imported() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class I {X get f => new A();get _g => new A();}
         class A implements I {
@@ -4071,7 +4071,7 @@
 
   Future<void> test_PrefixedIdentifier_library() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         var T1;
         class X { }
@@ -4097,8 +4097,8 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         var T1;
         class X { }
@@ -4124,8 +4124,8 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         var T1;
         class X { }
@@ -4152,7 +4152,7 @@
 
   Future<void> test_PrefixedIdentifier_parameter() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class _W {M y; var _z;}
         class X extends _W {}
@@ -4171,7 +4171,7 @@
 
   Future<void> test_PrefixedIdentifier_prefix() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         class A {static int bar = 10;}
         _B() {}''');
     addTestSource('''
@@ -4317,7 +4317,7 @@
 
   Future<void> test_PropertyAccess_noTarget() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/home/test/lib/ab.dart', 'class Foo { }');
+    addSource('$testPackageLibPath/ab.dart', 'class Foo { }');
     addTestSource('class C {foo(){.^}}');
 
     await computeSuggestions();
@@ -4326,7 +4326,7 @@
 
   Future<void> test_PropertyAccess_noTarget2() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/home/test/lib/ab.dart', 'class Foo { }');
+    addSource('$testPackageLibPath/ab.dart', 'class Foo { }');
     addTestSource('void f() {.^}');
 
     await computeSuggestions();
@@ -4598,7 +4598,7 @@
   Future<void> test_TopLevelVariableDeclaration_type() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         ^ foo; ''');
@@ -4611,7 +4611,7 @@
   Future<void> test_TopLevelVariableDeclaration_type_after_comment1() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         // comment
@@ -4625,7 +4625,7 @@
   Future<void> test_TopLevelVariableDeclaration_type_after_comment2() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         /* comment */
@@ -4639,7 +4639,7 @@
   Future<void> test_TopLevelVariableDeclaration_type_after_comment3() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         /// some dartdoc
@@ -4653,7 +4653,7 @@
   Future<void> test_TopLevelVariableDeclaration_type_without_semicolon() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import 'a.dart';
         ^ foo ''');
@@ -4730,7 +4730,7 @@
 
   Future<void> test_TypeArgumentList() async {
     // SimpleIdentifier  BinaryExpression  ExpressionStatement
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
         class C1 {int x;}
         F1() => 0;
         typedef String T1(int blat);''');
@@ -4756,8 +4756,8 @@
   }
 
   Future<void> test_TypeArgumentList2() async {
-    // TypeName  TypeArgumentList  TypeName
-    addSource('/home/test/lib/a.dart', '''
+    // NamedType  TypeArgumentList  NamedType
+    addSource('$testPackageLibPath/a.dart', '''
         class C1 {int x;}
         F1() => 0;
         typedef String T1(int blat);''');
@@ -4795,10 +4795,10 @@
   }
 
   Future<void> test_TypeArgumentList_recursive() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {}
 ''');
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 export 'a.dart';
 export 'b.dart';
 class B {}
@@ -4817,7 +4817,7 @@
   Future<void> test_VariableDeclaration_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo() { }
         class _B { }
@@ -4844,7 +4844,7 @@
   Future<void> test_VariableDeclarationStatement_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo() { }
         class _B { }
@@ -4869,7 +4869,7 @@
   Future<void> test_VariableDeclarationStatement_RHS_missing_semicolon() async {
     // VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo1() { }
         void bar1() { }
@@ -4898,7 +4898,7 @@
   }
 
   Future<void> test_withClause_mixin() async {
-    newFile('/home/test/lib/a.dart', content: 'mixin M {}');
+    newFile('$testPackageLibPath/a.dart', content: 'mixin M {}');
     addTestSource('''
 import 'a.dart';
 
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index 5c1db88..d9dc05e 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -29,7 +29,7 @@
 
   Future<void> test_extension() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 extension MyExt on int {}
 ''');
     addTestSource('''
@@ -134,7 +134,7 @@
 
   Future<void> test_PrefixedIdentifier_library() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         var T1;
         class X { }
@@ -158,11 +158,11 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_export_withShow() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {}
 class B {}
 ''');
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 export 'a.dart' show A;
 ''');
     addTestSource(r'''
@@ -177,7 +177,7 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_import_withShow() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {}
 class B {}
 ''');
@@ -224,7 +224,7 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
     newFile('$testPackageLibPath/b.dart', content: '''
         lib B;
         var T1;
@@ -257,7 +257,7 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
     newFile('$testPackageLibPath/b.dart', content: '''
         lib B;
         var T1;
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
index aa2e6a2..34904db 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
@@ -45,21 +45,21 @@
 
   Future<void> test_Block() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 export "dart:math" hide max;
 class A {int x;}
 @deprecated D1() {int x;}
 class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 String T1;
 var _T2;
 class C { }
 class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
 class EE { }
 class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
 class H { }
 int T3;
 var _T4;'''); // not imported
@@ -186,7 +186,7 @@
 
   Future<void> test_ClassDeclaration_body() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -201,7 +201,7 @@
 
   Future<void> test_ClassDeclaration_body_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -216,7 +216,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -231,7 +231,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field2() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as Soo;
@@ -246,7 +246,7 @@
 
   Future<void> test_ClassDeclaration_body_final_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -261,7 +261,7 @@
 
   Future<void> test_ClassDeclaration_body_final_var() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -275,7 +275,7 @@
   }
 
   Future<void> test_InstanceCreationExpression() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {foo(){var f; {var x;}}}
 class B {B(this.x, [String boo]) { } int x;}
 class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
@@ -294,11 +294,11 @@
   }
 
   Future<void> test_InstanceCreationExpression_inPart() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {foo(){var f; {var x;}}}
 class B {B(this.x, [String boo]) { } int x;}
 class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 library testB;
 import "a.dart" as t;
 import "dart:math" as math;
@@ -313,11 +313,11 @@
   }
 
   Future<void> test_InstanceCreationExpression_inPart_detached() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {foo(){var f; {var x;}}}
 class B {B(this.x, [String boo]) { } int x;}
 class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 library testB;
 import "a.dart" as t;
 import "dart:math" as math;
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index 3a6fa56..52c6b90 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -28,7 +28,7 @@
   }
 
   Future<void> test_partFile_Constructor() async {
-    // SimpleIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  NamedType  ConstructorName
     newFile('$testPackageLibPath/b.dart', content: '''
         lib B;
         int T1;
@@ -63,7 +63,7 @@
   }
 
   Future<void> test_partFile_Constructor2() async {
-    // SimpleIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  NamedType  ConstructorName
     newFile('$testPackageLibPath/b.dart', content: '''
         lib B;
         int T1;
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 6e7253d..804bc3a 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -81,7 +81,7 @@
 
   Future<void> test_ArgDefaults_inherited_method_with_required_named() async {
     writeTestPackageConfig(meta: true);
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 import 'package:meta/meta.dart';
 
 lib libB;
@@ -120,7 +120,7 @@
 
   Future<void> test_ArgumentList() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 bool hasLength(int expected) { }
 void baz() { }''');
@@ -145,7 +145,7 @@
 
   Future<void> test_ArgumentList_imported_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 bool hasLength(int expected) { }
 expect(arg) { }
@@ -172,7 +172,7 @@
   Future<void>
       test_ArgumentList_InstanceCreationExpression_functionalArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 class A { A(f()) { } }
 bool hasLength(int expected) { }
@@ -201,7 +201,7 @@
 
   Future<void> test_ArgumentList_InstanceCreationExpression_typedefArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 typedef Funct();
 class A { A(Funct f) { } }
@@ -231,7 +231,7 @@
 
   Future<void> test_ArgumentList_local_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 bool hasLength(int expected) { }
 void baz() { }''');
@@ -257,7 +257,7 @@
 
   Future<void> test_ArgumentList_local_method() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 bool hasLength(int expected) { }
 void baz() { }''');
@@ -283,7 +283,7 @@
 
   Future<void> test_ArgumentList_MethodInvocation_functionalArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 class A { A(f()) { } }
 bool hasLength(int expected) { }
@@ -314,7 +314,7 @@
 
   Future<void> test_ArgumentList_MethodInvocation_functionalArg2() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 class A { A(f()) { } }
 bool hasLength(int expected) { }
@@ -350,7 +350,7 @@
 
   Future<void> test_ArgumentList_MethodInvocation_methodArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 class A { A(f()) { } }
 bool hasLength(int expected) { }
@@ -375,7 +375,7 @@
   }
 
   Future<void> test_ArgumentList_namedFieldParam_tear_off() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 typedef void VoidCallback();
 
 class Button {
@@ -406,7 +406,7 @@
   Future<void> test_ArgumentList_namedParam() async {
     // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
     // ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library A;
 bool hasLength(int expected) { }''');
     addTestSource('''
@@ -452,7 +452,7 @@
   }
 
   Future<void> test_ArgumentList_namedParam_tear_off() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 typedef void VoidCallback();
 
 class Button {
@@ -480,7 +480,7 @@
   }
 
   Future<void> test_ArgumentList_namedParam_tear_off_1() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 typedef void VoidCallback();
 
 class Button {
@@ -508,7 +508,7 @@
   }
 
   Future<void> test_ArgumentList_namedParam_tear_off_2() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 typedef void VoidCallback();
 
 class Button {
@@ -536,7 +536,7 @@
   }
 
   Future<void> test_AsExpression_type() async {
-    // SimpleIdentifier  TypeName  AsExpression
+    // SimpleIdentifier  NamedType  AsExpression
     addTestSource('''
         class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
     await computeSuggestions();
@@ -556,7 +556,7 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  AsExpression
+    // SimpleIdentifier  NamedType  AsExpression
     addTestSource('''
 class A {} class B extends A {} class C extends A {} class D {}
 f(A a){ (a as ^) }''');
@@ -577,7 +577,7 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  AsExpression
+    // SimpleIdentifier  NamedType  AsExpression
     addTestSource('''
 class A {} class B implements A {} class C implements A {} class D {}
 f(A a){ (a as ^) }''');
@@ -593,7 +593,7 @@
   }
 
   Future<void> test_AsExpression_type_filter_undefined_type() async {
-    // SimpleIdentifier  TypeName  AsExpression
+    // SimpleIdentifier  NamedType  AsExpression
     addTestSource('''
 class A {}
 f(U u){ (u as ^) }''');
@@ -628,7 +628,7 @@
   }
 
   Future<void> test_AssignmentExpression_type() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
 class A {} void f() {
@@ -652,7 +652,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_newline() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
 class A {} void f() {
@@ -675,7 +675,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_partial() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
 class A {} void f() {
@@ -699,7 +699,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_partial_newline() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
 class A {} void f() {
@@ -755,7 +755,7 @@
 
   Future<void> test_AwaitExpression_inherited() async {
     // SimpleIdentifier  AwaitExpression  ExpressionStatement
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 lib libB;
 class A {
   Future y() async {return 0;}
@@ -812,21 +812,21 @@
 
   Future<void> test_Block() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 export "dart:math" hide max;
 class A {int x;}
 @deprecated D1() {int x;}
 class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 String T1;
 var _T2;
 class C { }
 class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
 class EE { }
 class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
 class H { }
 int T3;
 var _T4;'''); // not imported
@@ -905,21 +905,21 @@
 
   Future<void> test_Block_final() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 export "dart:math" hide max;
 class A {int x;}
 @deprecated D1() {int x;}
 class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 String T1;
 var _T2;
 class C { }
 class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
 class EE { }
 class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
 class H { }
 int T3;
 var _T4;'''); // not imported
@@ -1018,21 +1018,21 @@
 
   Future<void> test_Block_final_final() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 export "dart:math" hide max;
 class A {int x;}
 @deprecated D1() {int x;}
 class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 String T1;
 var _T2;
 class C { }
 class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
 class EE { }
 class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
 class H { }
 int T3;
 var _T4;'''); // not imported
@@ -1117,21 +1117,21 @@
 
   Future<void> test_Block_final_var() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 export "dart:math" hide max;
 class A {int x;}
 @deprecated D1() {int x;}
 class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 String T1;
 var _T2;
 class C { }
 class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
 class EE { }
 class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
 class H { }
 int T3;
 var _T4;'''); // not imported
@@ -1215,21 +1215,21 @@
   }
 
   Future<void> test_Block_identifier_partial() async {
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 export "dart:math" hide max;
 class A {int x;}
 @deprecated D1() {int x;}
 class _B { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 String T1;
 var _T2;
 class C { }
 class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
 class EE { }
 class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
 class H { }
 class D3 { }
 int T3;
@@ -1294,7 +1294,7 @@
 
   Future<void> test_Block_inherited_imported() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 lib B;
 class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
 class E extends F { var e1; e2() { } }
@@ -1322,7 +1322,7 @@
 
   Future<void> test_Block_inherited_imported_from_constructor() async {
     // Block  BlockFunctionBody  ConstructorDeclaration  ClassDeclaration
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
       lib B;
       class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
       class E extends F { var e1; e2() { } }
@@ -1349,7 +1349,7 @@
 
   Future<void> test_Block_inherited_imported_from_method() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
       lib B;
       class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
       class E extends F { var e1; e2() { } }
@@ -1448,21 +1448,21 @@
   }
 
   Future<void> test_Block_local_function() async {
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 export "dart:math" hide max;
 class A {int x;}
 @deprecated D1() {int x;}
 class _B {boo() { partBoo() {}} }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 String T1;
 var _T2;
 class C { }
 class D { }''');
-    addSource('/home/test/lib/eef.dart', '''
+    addSource('$testPackageLibPath/eef.dart', '''
 class EE { }
 class F { }''');
-    addSource('/home/test/lib/g.dart', 'class G { }');
-    addSource('/home/test/lib/h.dart', '''
+    addSource('$testPackageLibPath/g.dart', 'class G { }');
+    addSource('$testPackageLibPath/h.dart', '''
 class H { }
 int T3;
 var _T4;'''); // not imported
@@ -1526,7 +1526,7 @@
 
   Future<void> test_CascadeExpression_selector1() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart";
@@ -1551,7 +1551,7 @@
 
   Future<void> test_CascadeExpression_selector2() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart";
@@ -1574,7 +1574,7 @@
 
   Future<void> test_CascadeExpression_selector2_withTrailingReturn() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart";
@@ -1616,7 +1616,7 @@
   }
 
   Future<void> test_CatchClause_onType() async {
-    // TypeName  CatchClause  TryStatement
+    // NamedType  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^ {}}}');
     await computeSuggestions();
 
@@ -1629,7 +1629,7 @@
   }
 
   Future<void> test_CatchClause_onType_noBrackets() async {
-    // TypeName  CatchClause  TryStatement
+    // NamedType  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^}}');
     await computeSuggestions();
 
@@ -1680,7 +1680,7 @@
 
   Future<void> test_ClassDeclaration_body() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -1709,7 +1709,7 @@
 
   Future<void> test_ClassDeclaration_body_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -1730,7 +1730,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -1751,7 +1751,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field2() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as Soo;
@@ -1772,7 +1772,7 @@
 
   Future<void> test_ClassDeclaration_body_final_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -1793,7 +1793,7 @@
 
   Future<void> test_ClassDeclaration_body_final_var() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -1839,7 +1839,7 @@
 
   Future<void> test_Combinator_hide() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 library libAB;
 part 'partAB.dart';
 class A { }
@@ -1849,7 +1849,7 @@
 var T1;
 PB F1() => new PB();
 class PB { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 class C { }
 class D { }''');
     addTestSource('''
@@ -1863,7 +1863,7 @@
 
   Future<void> test_Combinator_show() async {
     // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource('/home/test/lib/ab.dart', '''
+    addSource('$testPackageLibPath/ab.dart', '''
 library libAB;
 part 'partAB.dart';
 class A { }
@@ -1875,7 +1875,7 @@
 typedef PB2 F2(int blat);
 class Clz = Object with Object;
 class PB { }''');
-    addSource('/home/test/lib/cd.dart', '''
+    addSource('$testPackageLibPath/cd.dart', '''
 class C { }
 class D { }''');
     addTestSource('''
@@ -1889,7 +1889,7 @@
 
   Future<void> test_ConditionalExpression_elseExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {int x;}''');
@@ -1909,7 +1909,7 @@
 
   Future<void> test_ConditionalExpression_elseExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {int x;}''');
@@ -1935,7 +1935,7 @@
 
   Future<void> test_ConditionalExpression_partial_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {int x;}''');
@@ -1955,7 +1955,7 @@
 
   Future<void> test_ConditionalExpression_partial_thenExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {int x;}''');
@@ -1981,7 +1981,7 @@
 
   Future<void> test_ConditionalExpression_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {int x;}''');
@@ -2066,9 +2066,9 @@
   }
 
   Future<void> test_ConstructorName_importedClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 int T1;
 F1() { }
@@ -2091,9 +2091,9 @@
   }
 
   Future<void> test_ConstructorName_importedFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 int T1;
 F1() { }
@@ -2116,7 +2116,7 @@
   }
 
   Future<void> test_ConstructorName_importedFactory2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         void f() {new String.fr^omCharCodes([]);}''');
@@ -2134,7 +2134,7 @@
   }
 
   Future<void> test_ConstructorName_localClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
 int T1;
@@ -2155,7 +2155,7 @@
   }
 
   Future<void> test_ConstructorName_localFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
 int T1;
@@ -2572,7 +2572,7 @@
 
   Future<void> test_ExpressionStatement_identifier() async {
     // SimpleIdentifier  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 _B F1() { }
 class A {int x;}
 class _B { }''');
@@ -2600,7 +2600,7 @@
 
   Future<void> test_ExpressionStatement_name() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         B T1;
         class B{}''');
     addTestSource('''
@@ -2670,7 +2670,7 @@
 
   Future<void> test_extensionDeclaration_notInBody() async {
     // ExtensionDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -2723,7 +2723,7 @@
   Future<void> test_FieldDeclaration_name_typed() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import "a.dart";
         class C {A ^}''');
@@ -2735,7 +2735,7 @@
   Future<void> test_FieldDeclaration_name_var() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import "a.dart";
         class C {var ^}''');
@@ -3232,7 +3232,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -3263,7 +3263,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment2() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -3294,7 +3294,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment3() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -3560,7 +3560,7 @@
 
   Future<void> test_IndexExpression() async {
     // ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {int x;}''');
@@ -3586,7 +3586,7 @@
 
   Future<void> test_IndexExpression2() async {
     // SimpleIdentifier IndexExpression ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {int x;}''');
@@ -3611,7 +3611,7 @@
   }
 
   Future<void> test_inherited() async {
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 lib libB;
 class A2 {
   int x;
@@ -3762,8 +3762,8 @@
   }
 
   Future<void> test_InstanceCreationExpression_imported() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource('/home/test/lib/a.dart', '''
+    // SimpleIdentifier  NamedType  ConstructorName  InstanceCreationExpression
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 class A {A(this.x) { } int x;}''');
@@ -3822,7 +3822,7 @@
   }
 
   Future<void> test_InstanceCreationExpression_unimported() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    // SimpleIdentifier  NamedType  ConstructorName  InstanceCreationExpression
     addSource('/testAB.dart', 'class Foo { }');
     addTestSource('class C {foo(){new F^}}');
     await computeSuggestions();
@@ -3865,7 +3865,7 @@
 
   Future<void> test_InterpolationExpression_block() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -3937,8 +3937,8 @@
   }
 
   Future<void> test_IsExpression() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 foo() { }
 class X {X.c(); X._d(); z() {}}''');
@@ -3977,7 +3977,7 @@
   }
 
   Future<void> test_IsExpression_type() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
 class A {int x; int y() => 0;}
 void f(){var a; if (a is ^)}''');
@@ -3997,7 +3997,7 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
 class A {} class B extends A {} class C extends A {} class D {}
 f(A a){ if (a is ^) {}}''');
@@ -4018,7 +4018,7 @@
     // suggesting types. We ought to do so because there's no reason to cast a
     // value to the type it already has.
 
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
 class A {} class B implements A {} class C implements A {} class D {}
 f(A a){ if (a is ^) {}}''');
@@ -4034,7 +4034,7 @@
   }
 
   Future<void> test_IsExpression_type_filter_undefined_type() async {
-    // SimpleIdentifier  TypeName  AsExpression
+    // SimpleIdentifier  NamedType  AsExpression
     addTestSource('''
 class A {}
 f(U u){ (u as ^) }''');
@@ -4046,7 +4046,7 @@
   }
 
   Future<void> test_IsExpression_type_partial() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
 class A {int x; int y() => 0;}
 void f(){var a; if (a is Obj^)}''');
@@ -4061,7 +4061,7 @@
   }
 
   Future<void> test_keyword() async {
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 int newT1;
 int T1;
@@ -4214,7 +4214,7 @@
 
   Future<void> test_MapLiteralEntry() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -4244,7 +4244,7 @@
 
   Future<void> test_MapLiteralEntry1() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -4266,7 +4266,7 @@
 
   Future<void> test_MapLiteralEntry2() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -4322,7 +4322,7 @@
   }
 
   Future<void> test_method_parameters_mixed_required_and_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   void m(x, {int y}) {}
 }
@@ -4369,7 +4369,7 @@
   }
 
   Future<void> test_method_parameters_mixed_required_and_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   void m(x, [int y]) {}
 }
@@ -4417,7 +4417,7 @@
   }
 
   Future<void> test_method_parameters_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   void m({x, int y}) {}
 }
@@ -4464,7 +4464,7 @@
   }
 
   Future<void> test_method_parameters_none() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   void m() {}
 }
@@ -4501,7 +4501,7 @@
   }
 
   Future<void> test_method_parameters_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   void m([x, int y]) {}
 }
@@ -4548,7 +4548,7 @@
   }
 
   Future<void> test_method_parameters_required() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   void m(x, int y) {}
 }
@@ -4607,7 +4607,7 @@
 
   Future<void> test_MethodDeclaration_body_static() async {
     // Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/c.dart', '''
+    addSource('$testPackageLibPath/c.dart', '''
 class C {
   c1() {}
   var c2;
@@ -4784,7 +4784,7 @@
 
   Future<void> test_MethodDeclaration_returnType() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -4814,7 +4814,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -4844,7 +4844,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -4874,7 +4874,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment3() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 int T1;
 F1() { }
 typedef D1();
@@ -5008,7 +5008,7 @@
   }
 
   Future<void> test_mixin_ordering() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class B {}
 class M1 {
   void m() {}
@@ -5031,7 +5031,7 @@
 
   Future<void> test_MixinDeclaration_body() async {
     // MixinDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 class B { }''');
     addTestSource('''
 import "b.dart" as x;
@@ -5115,7 +5115,7 @@
   }
 
   Future<void> test_no_parameters_field() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   int x;
 }
@@ -5132,7 +5132,7 @@
   }
 
   Future<void> test_no_parameters_getter() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   int get x => null;
 }
@@ -5149,7 +5149,7 @@
   }
 
   Future<void> test_no_parameters_setter() async {
-    resolveSource('/home/test/lib/a.dart', '''
+    resolveSource('$testPackageLibPath/a.dart', '''
 class A {
   set x(int value) {};
 }
@@ -5166,7 +5166,7 @@
   }
 
   Future<void> test_outside_class() async {
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 lib libB;
 class A2 {
   int x;
@@ -5253,7 +5253,7 @@
 
   Future<void> test_PrefixedIdentifier_class_const() async {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 class I {
   static const scI = 'boo';
@@ -5300,7 +5300,7 @@
 
   Future<void> test_PrefixedIdentifier_class_imported() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 class I {X get f => new A();get _g => new A();}
 class A implements I {
@@ -5379,7 +5379,7 @@
 
   Future<void> test_PrefixedIdentifier_library() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 var T1;
 class X { }
@@ -5405,8 +5405,8 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 var T1;
 class X { }
@@ -5432,8 +5432,8 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 var T1;
 class X { }
@@ -5460,7 +5460,7 @@
 
   Future<void> test_PrefixedIdentifier_parameter() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 class _W {M y; var _z;}
 class X extends _W {}
@@ -5479,7 +5479,7 @@
 
   Future<void> test_PrefixedIdentifier_prefix() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {static int bar = 10;}
 _B() {}''');
     addTestSource('''
@@ -5643,7 +5643,7 @@
 
   Future<void> test_PropertyAccess_noTarget() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/home/test/lib/ab.dart', 'class Foo { }');
+    addSource('$testPackageLibPath/ab.dart', 'class Foo { }');
     addTestSource('class C {foo(){.^}}');
     await computeSuggestions();
 
@@ -5652,7 +5652,7 @@
 
   Future<void> test_PropertyAccess_noTarget2() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/home/test/lib/ab.dart', 'class Foo { }');
+    addSource('$testPackageLibPath/ab.dart', 'class Foo { }');
     addTestSource('void f() {.^}');
     await computeSuggestions();
 
@@ -5680,7 +5680,7 @@
   }
 
   Future<void> test_static_field() async {
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 lib libB;
 class A2 {
   int x;
@@ -5722,7 +5722,7 @@
   }
 
   Future<void> test_static_method() async {
-    resolveSource('/home/test/lib/b.dart', '''
+    resolveSource('$testPackageLibPath/b.dart', '''
 lib libB;
 class A2 {
   int x;
@@ -6107,7 +6107,7 @@
 
   Future<void> test_TypeArgumentList() async {
     // SimpleIdentifier  BinaryExpression  ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class C1 {int x;}
 F1() => 0;
 typedef String T1(int blat);''');
@@ -6133,8 +6133,8 @@
   }
 
   Future<void> test_TypeArgumentList2() async {
-    // TypeName  TypeArgumentList  TypeName
-    addSource('/home/test/lib/a.dart', '''
+    // NamedType  TypeArgumentList  NamedType
+    addSource('$testPackageLibPath/a.dart', '''
 class C1 {int x;}
 F1() => 0;
 typedef String T1(int blat);''');
@@ -6198,7 +6198,7 @@
   Future<void> test_VariableDeclaration_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 foo() { }
 class _B { }
@@ -6225,7 +6225,7 @@
   Future<void> test_VariableDeclarationStatement_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 foo() { }
 class _B { }
@@ -6250,7 +6250,7 @@
   Future<void> test_VariableDeclarationStatement_RHS_missing_semicolon() async {
     // VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 lib B;
 foo1() { }
 void bar1() { }
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
index a671eeb..7c9b3d8 100644
--- a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
@@ -290,9 +290,9 @@
   }
 
   Future<void> test_ConstructorName_importedClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
@@ -318,9 +318,9 @@
   }
 
   Future<void> test_ConstructorName_importedClass_unresolved() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
@@ -347,9 +347,9 @@
   }
 
   Future<void> test_ConstructorName_importedFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
@@ -375,7 +375,7 @@
   }
 
   Future<void> test_ConstructorName_importedFactory2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         main() {new String.fr^omCharCodes([]);}''');
@@ -395,7 +395,7 @@
   }
 
   Future<void> test_ConstructorName_localClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         int T1;
@@ -422,7 +422,7 @@
   }
 
   Future<void> test_ConstructorName_localFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         int T1;
@@ -450,7 +450,7 @@
 
   Future<void>
       test_importPrefix_className_typeArguments_period_nothing_functionTypeContext_matchingReturnType() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A<T> {
   A.named();
   A.new();
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index e8eff71..0e65414 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -153,7 +153,7 @@
   }
 
   Future<void> test_fromPart() async {
-    addSource('/home/test/lib/myLib.dart', '''
+    addSource('$testPackageLibPath/myLib.dart', '''
 library myLib;
 part 'test.dart';
 part 'otherPart.dart';
@@ -162,7 +162,7 @@
   B suggested2(String y) => null;
 }
 ''');
-    addSource('/home/test/lib/otherPart.dart', '''
+    addSource('$testPackageLibPath/otherPart.dart', '''
 part of myLib;
 class B extends A {
   B suggested2(String y) => null;
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index e4bc0d3..7c2a610 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -28,7 +28,7 @@
   }
 
   Future<void> test_class_static_notPrivate() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   static int _f;
   static String get _g => '';
@@ -138,7 +138,7 @@
   }
 
   Future<void> test_extension_static_notPrivate() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 extension E {
   static int _f;
   static String get _g => '';
@@ -160,7 +160,7 @@
   }
 
   Future<void> test_implicitCreation() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   A.foo();
   A.bar();
@@ -181,7 +181,7 @@
 
   Future<void>
       test_implicitCreation_functionContextType_matchingReturnType() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   A.foo();
   A.bar();
@@ -202,7 +202,7 @@
 
   Future<void>
       test_implicitCreation_functionContextType_notMatchingReturnType() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   A.foo();
   A.bar();
@@ -365,7 +365,7 @@
 
   Future<void> test_PrefixedIdentifier_class_const() async {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class I {
           static const scI = 'boo';
@@ -409,7 +409,7 @@
   }
 
   Future<void> test_simpleIdentifier_typeAlias_interfaceType_class() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   static int _privateField = 0;
   static int get _privateGetter => 0;
@@ -451,7 +451,7 @@
   }
 
   Future<void> test_simpleIdentifier_typeAlias_interfaceType_enum() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 enum E {
   aaa,
   _bbb,
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index c7f9a18..47000b2 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -114,7 +114,7 @@
 
   Future<void> test_ArgumentList() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         void baz() { }''');
@@ -138,7 +138,7 @@
 
   Future<void> test_ArgumentList_imported_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         expect(arg) { }
@@ -164,7 +164,7 @@
   Future<void>
       test_ArgumentList_InstanceCreationExpression_functionalArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         class A { A(f()) { } }
         bool hasLength(int expected) { }
@@ -191,7 +191,7 @@
 
   Future<void> test_ArgumentList_InstanceCreationExpression_typedefArg() async {
     // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         typedef Funct();
         class A { A(Funct f) { } }
@@ -219,7 +219,7 @@
 
   Future<void> test_ArgumentList_local_function() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         void baz() { }''');
@@ -244,7 +244,7 @@
 
   Future<void> test_ArgumentList_local_method() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }
         void baz() { }''');
@@ -269,7 +269,7 @@
 
   Future<void> test_ArgumentList_MethodInvocation_functionalArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         class A { A(f()) { } }
         bool hasLength(int expected) { }
@@ -296,7 +296,7 @@
 
   Future<void> test_ArgumentList_MethodInvocation_methodArg() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         class A { A(f()) { } }
         bool hasLength(int expected) { }
@@ -322,7 +322,7 @@
   Future<void> test_ArgumentList_namedParam() async {
     // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
     // ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library A;
         bool hasLength(int expected) { }''');
     addTestSource('''
@@ -338,7 +338,7 @@
   }
 
   Future<void> test_AsExpression() async {
-    // SimpleIdentifier  TypeName  AsExpression
+    // SimpleIdentifier  NamedType  AsExpression
     addTestSource('''
         class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
     await computeSuggestions();
@@ -373,7 +373,7 @@
   }
 
   Future<void> test_AssignmentExpression_type() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -395,7 +395,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_newline() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -416,7 +416,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_partial() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -438,7 +438,7 @@
   }
 
   Future<void> test_AssignmentExpression_type_partial_newline() async {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // SimpleIdentifier  NamedType  VariableDeclarationList
     // VariableDeclarationStatement  Block
     addTestSource('''
         class A {} void f() {
@@ -977,7 +977,7 @@
 
   Future<void> test_Block_inherited_imported() async {
     // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
         class E extends F { var e1; e2() { } }
@@ -1093,7 +1093,7 @@
 
   Future<void> test_CascadeExpression_method1() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart";
@@ -1117,7 +1117,7 @@
 
   Future<void> test_CascadeExpression_selector1() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart";
@@ -1141,7 +1141,7 @@
 
   Future<void> test_CascadeExpression_selector2() async {
     // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart";
@@ -1163,7 +1163,7 @@
 
   Future<void> test_CascadeExpression_selector2_withTrailingReturn() async {
     // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart";
@@ -1203,7 +1203,7 @@
   }
 
   Future<void> test_CatchClause_onType() async {
-    // TypeName  CatchClause  TryStatement
+    // NamedType  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^ {}}}');
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
@@ -1215,7 +1215,7 @@
   }
 
   Future<void> test_CatchClause_onType_noBrackets() async {
-    // TypeName  CatchClause  TryStatement
+    // NamedType  CatchClause  TryStatement
     addTestSource('class A {a() {try{var x;} on ^}}');
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
@@ -1252,7 +1252,7 @@
 
   Future<void> test_ClassDeclaration_body() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1271,7 +1271,7 @@
 
   Future<void> test_ClassDeclaration_body_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1290,7 +1290,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1309,7 +1309,7 @@
 
   Future<void> test_ClassDeclaration_body_final_field2() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as Soo;
@@ -1328,7 +1328,7 @@
 
   Future<void> test_ClassDeclaration_body_final_final() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1347,7 +1347,7 @@
 
   Future<void> test_ClassDeclaration_body_final_var() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         class B { }''');
     addTestSource('''
         import "b.dart" as x;
@@ -1414,7 +1414,7 @@
 
   Future<void> test_ConditionalExpression_elseExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1433,7 +1433,7 @@
 
   Future<void> test_ConditionalExpression_elseExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1458,7 +1458,7 @@
 
   Future<void> test_ConditionalExpression_partial_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1477,7 +1477,7 @@
 
   Future<void> test_ConditionalExpression_partial_thenExpression_empty() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1502,7 +1502,7 @@
 
   Future<void> test_ConditionalExpression_thenExpression() async {
     // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -1520,9 +1520,9 @@
   }
 
   Future<void> test_ConstructorName_importedClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
@@ -1544,9 +1544,9 @@
   }
 
   Future<void> test_ConstructorName_importedFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
@@ -1568,7 +1568,7 @@
   }
 
   Future<void> test_ConstructorName_importedFactory2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         void f() {new String.fr^omCharCodes([]);}''');
@@ -1585,7 +1585,7 @@
   }
 
   Future<void> test_ConstructorName_localClass() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         int T1;
@@ -1605,7 +1605,7 @@
   }
 
   Future<void> test_ConstructorName_localFactory() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // SimpleIdentifier  PrefixedIdentifier  NamedType  ConstructorName
     // InstanceCreationExpression
     addTestSource('''
         int T1;
@@ -1706,7 +1706,7 @@
 
   Future<void> test_ExpressionStatement_identifier() async {
     // SimpleIdentifier  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         _B F1() { }
         class A {int x;}
         class _B { }''');
@@ -1732,7 +1732,7 @@
 
   Future<void> test_ExpressionStatement_name() async {
     // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         B T1;
         class B{}''');
     addTestSource('''
@@ -1759,7 +1759,7 @@
   Future<void> test_FieldDeclaration_name_typed() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import "a.dart";
         class C {A ^}''');
@@ -1770,7 +1770,7 @@
   Future<void> test_FieldDeclaration_name_var() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // FieldDeclaration
-    addSource('/home/test/lib/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
     addTestSource('''
         import "a.dart";
         class C {var ^}''');
@@ -1922,7 +1922,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -1951,7 +1951,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment2() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -1980,7 +1980,7 @@
 
   Future<void> test_FunctionDeclaration_returnType_afterComment3() async {
     // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2174,7 +2174,7 @@
 
   Future<void> test_IndexExpression() async {
     // ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -2199,7 +2199,7 @@
 
   Future<void> test_IndexExpression2() async {
     // SimpleIdentifier IndexExpression ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {int x;}''');
@@ -2217,8 +2217,8 @@
   }
 
   Future<void> test_InstanceCreationExpression_imported() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource('/home/test/lib/a.dart', '''
+    // SimpleIdentifier  NamedType  ConstructorName  InstanceCreationExpression
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         class A {A(this.x) { } int x;}''');
@@ -2247,7 +2247,7 @@
   }
 
   Future<void> test_InstanceCreationExpression_unimported() async {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    // SimpleIdentifier  NamedType  ConstructorName  InstanceCreationExpression
     addSource('/testAB.dart', 'class Foo { }');
     addTestSource('class C {foo(){new F^}}');
     await computeSuggestions();
@@ -2304,7 +2304,7 @@
 
   Future<void> test_InterpolationExpression() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2333,7 +2333,7 @@
 
   Future<void> test_InterpolationExpression_block() async {
     // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2398,8 +2398,8 @@
   }
 
   Future<void> test_IsExpression() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo() { }
         class X {X.c(); X._d(); z() {}}''');
@@ -2436,7 +2436,7 @@
   }
 
   Future<void> test_IsExpression_type() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
         class A {int x; int y() => 0;}
         void f(){var a; if (a is ^)}''');
@@ -2450,7 +2450,7 @@
   }
 
   Future<void> test_IsExpression_type_partial() async {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    // SimpleIdentifier  NamedType  IsExpression  IfStatement
     addTestSource('''
         class A {int x; int y() => 0;}
         void f(){var a; if (a is Obj^)}''');
@@ -2472,7 +2472,7 @@
   }
 
   Future<void> test_keyword2() async {
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int newT1;
         int T1;
@@ -2532,8 +2532,8 @@
   }
 
   Future<void> test_libraryPrefix_with_exports() async {
-    addSource('/home/test/lib/a.dart', 'class A { }');
-    addSource('/home/test/lib/b.dart', 'export "a.dart"; class B { }');
+    addSource('$testPackageLibPath/a.dart', 'class A { }');
+    addSource('$testPackageLibPath/b.dart', 'export "a.dart"; class B { }');
     addTestSource('import "b.dart" as foo; void f() {foo.^} class C { }');
     await computeSuggestions();
     // Suggested by LibraryMemberContributor
@@ -2591,7 +2591,7 @@
 
   Future<void> test_MapLiteralEntry() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2618,7 +2618,7 @@
 
   Future<void> test_MapLiteralEntry1() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2638,7 +2638,7 @@
 
   Future<void> test_MapLiteralEntry2() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2937,7 +2937,7 @@
 
   Future<void> test_MethodDeclaration_returnType() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2965,7 +2965,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment() async {
     // ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -2993,7 +2993,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3021,7 +3021,7 @@
 
   Future<void> test_MethodDeclaration_returnType_afterComment3() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         int T1;
         F1() { }
         typedef D1();
@@ -3267,13 +3267,13 @@
   }
 
   Future<void> test_partFile_TypeName() async {
-    // SimpleIdentifier  TypeName  ConstructorName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  ConstructorName
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
         class X {X.c(); X._d(); z() {}}''');
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         library libA;
         import "b.dart";
         part "${resourceProvider.pathContext.basename(testFile)}";
@@ -3299,13 +3299,13 @@
   }
 
   Future<void> test_partFile_TypeName2() async {
-    // SimpleIdentifier  TypeName  ConstructorName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  NamedType  ConstructorName
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         int T1;
         F1() { }
         class X {X.c(); X._d(); z() {}}''');
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         part of libA;
         class B { }''');
     addTestSource('''
@@ -3332,7 +3332,7 @@
 
   Future<void> test_PrefixedIdentifier_class_const() async {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class I {
           static const scI = 'boo';
@@ -3378,7 +3378,7 @@
 
   Future<void> test_PrefixedIdentifier_class_imported() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class I {X get f => new A();get _g => new A();}
         class A implements I {
@@ -3454,7 +3454,7 @@
 
   Future<void> test_PrefixedIdentifier_library() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         var T1;
         class X { }
@@ -3479,8 +3479,8 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         var T1;
         class X { }
@@ -3505,8 +3505,8 @@
   }
 
   Future<void> test_PrefixedIdentifier_library_typesOnly2() async {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource('/home/test/lib/b.dart', '''
+    // SimpleIdentifier  PrefixedIdentifier  NamedType
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         var T1;
         class X { }
@@ -3532,7 +3532,7 @@
 
   Future<void> test_PrefixedIdentifier_parameter() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         class _W {M y; var _z;}
         class X extends _W {}
@@ -3550,7 +3550,7 @@
 
   Future<void> test_PrefixedIdentifier_prefix() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         class A {static int bar = 10;}
         _B() {}''');
     addTestSource('''
@@ -4149,7 +4149,7 @@
 
   Future<void> test_TypeArgumentList() async {
     // SimpleIdentifier  BinaryExpression  ExpressionStatement
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
         class C1 {int x;}
         F1() => 0;
         typedef String T1(int blat);''');
@@ -4173,8 +4173,8 @@
   }
 
   Future<void> test_TypeArgumentList2() async {
-    // TypeName  TypeArgumentList  TypeName
-    addSource('/home/test/lib/a.dart', '''
+    // NamedType  TypeArgumentList  NamedType
+    addSource('$testPackageLibPath/a.dart', '''
         class C1 {int x;}
         F1() => 0;
         typedef String T1(int blat);''');
@@ -4218,7 +4218,7 @@
   Future<void> test_VariableDeclaration_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo() { }
         class _B { }
@@ -4243,7 +4243,7 @@
   Future<void> test_VariableDeclarationStatement_RHS() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo() { }
         class _B { }
@@ -4267,7 +4267,7 @@
   Future<void> test_VariableDeclarationStatement_RHS_missing_semicolon() async {
     // VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
         lib B;
         foo1() { }
         void bar1() { }
diff --git a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
index 5e73ef0..dfc309c 100644
--- a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
@@ -738,7 +738,7 @@
   }
 
   Future<void> test_tryonThrowStatement_nnbd_into_legacy() async {
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 String? x;
 ''');
     await _prepareCompletion('.tryon', '''
@@ -762,7 +762,7 @@
   }
 
   Future<void> test_tryonThrowStatement_nnbd_into_legacy_nested() async {
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 List<String?> x;
 ''');
     await _prepareCompletion('.tryon', '''
@@ -786,7 +786,7 @@
   }
 
   Future<void> test_tryonThrowStatement_nnbd_legacy() async {
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 // @dart = 2.8
 String x;
 ''');
@@ -809,7 +809,7 @@
   }
 
   Future<void> test_tryonThrowStatement_nnbd_legacy_nested() async {
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 // @dart = 2.8
 List<String> x;
 ''');
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
index f28613f..8ecae36 100644
--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -22,6 +22,12 @@
 class OrganizeDirectivesTest extends AbstractSingleUnitTest {
   late List<AnalysisError> testErrors;
 
+  @override
+  void setUp() {
+    super.setUp();
+    writeTestPackageConfig(meta: true);
+  }
+
   Future<void> test_docComment_beforeDirective_hasUnresolvedIdentifier() async {
     await _computeUnitAndErrors(r'''
 /// Library documentation comment A
@@ -682,6 +688,219 @@
 import 'package:b/a.dart';''');
   }
 
+  Future<void> test_sort_libraryAnnotation_movedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+// annotations
+import 'annotations.dart';
+
+// io
+import 'dart:io';
+''');
+    // Validate annotation is not moved with import.
+    _assertOrganize(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+// io
+import 'dart:io';
+
+// annotations
+import 'annotations.dart';
+''');
+  }
+
+  Future<void> test_sort_libraryAnnotation_removedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+// io
+import 'dart:io'; // unused
+// annotations
+import 'annotations.dart'; // used
+''');
+    // Validate annotation is not removed with import.
+    _assertOrganize(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+// annotations
+import 'annotations.dart'; // used
+''', removeUnused: true);
+  }
+
+  Future<void> test_sort_multipleAnnotation_movedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+@nonLibraryAnnotation
+import 'annotations.dart';
+@nonLibraryAnnotation
+import 'dart:io';
+''');
+    // Validate only the non-library annotation is moved with import.
+    _assertOrganize(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+@nonLibraryAnnotation
+import 'dart:io';
+
+@nonLibraryAnnotation
+import 'annotations.dart';
+''');
+  }
+
+  Future<void> test_sort_multipleAnnotation_removedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+@nonLibraryAnnotation
+import 'dart:io';
+@nonLibraryAnnotation
+import 'annotations.dart';
+''');
+    // Validate only the non-library annotation is removed with import.
+    _assertOrganize(r'''
+@libraryAnnotation
+@LibraryAnnotation()
+
+@nonLibraryAnnotation
+import 'annotations.dart';
+''', removeUnused: true);
+  }
+
+  Future<void> test_sort_multipleAnnotationWithComments_movedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+// lib1
+@libraryAnnotation // lib1
+// lib2
+@LibraryAnnotation() // lib2
+
+// nonLib on annotations import
+@nonLibraryAnnotation // nonLib on annotations import
+// annotations import
+import 'annotations.dart'; // annotations import
+// nonLib on io import
+@nonLibraryAnnotation // nonLib on io import
+// io import
+import 'dart:io'; // io import
+''');
+    // Validate only the non-library annotation is moved with import.
+    _assertOrganize(r'''
+// lib1
+@libraryAnnotation // lib1
+// lib2
+@LibraryAnnotation() // lib2
+
+// nonLib on io import
+@nonLibraryAnnotation // nonLib on io import
+// io import
+import 'dart:io'; // io import
+
+// nonLib on annotations import
+@nonLibraryAnnotation // nonLib on annotations import
+// annotations import
+import 'annotations.dart'; // annotations import
+''');
+  }
+
+  Future<void>
+      test_sort_multipleAnnotationWithComments_removedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+// lib1
+@libraryAnnotation // lib1
+// lib2
+@LibraryAnnotation() // lib2
+
+// nonLib on io import
+@nonLibraryAnnotation // nonLib on io import
+// io import
+import 'dart:io'; // io import
+// nonLib on annotations import
+@nonLibraryAnnotation // nonLib on annotations import
+// annotations import
+import 'annotations.dart'; // annotations import
+''');
+    // Validate only the non-library annotation is removed with import.
+    _assertOrganize(r'''
+// lib1
+@libraryAnnotation // lib1
+// lib2
+@LibraryAnnotation() // lib2
+
+// nonLib on annotations import
+@nonLibraryAnnotation // nonLib on annotations import
+// annotations import
+import 'annotations.dart'; // annotations import
+''', removeUnused: true);
+  }
+
+  Future<void> test_sort_nonLibraryAnnotation_movedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+@nonLibraryAnnotation
+import 'annotations.dart';
+
+import 'dart:io';
+''');
+    // Validate annotation is moved with import.
+    _assertOrganize(r'''
+import 'dart:io';
+
+@nonLibraryAnnotation
+import 'annotations.dart';
+''');
+  }
+
+  Future<void> test_sort_nonLibraryAnnotation_removedDirective() async {
+    await _addAnnotationsFile();
+    await _computeUnitAndErrors(r'''
+@nonLibraryAnnotation
+// io
+import 'dart:io'; // unused
+// annotations
+import 'annotations.dart'; // used
+''');
+    // Validate annotation is removed with import.
+    _assertOrganize(r'''
+// annotations
+import 'annotations.dart'; // used
+''', removeUnused: true);
+  }
+
+  Future<void> _addAnnotationsFile() async {
+    final annotationsFile = convertPath('$testPackageLibPath/annotations.dart');
+    const annotationsContent = '''
+import 'package:meta/meta_meta.dart';
+
+const libraryAnnotation = LibraryAnnotation();
+const nonLibraryAnnotation = NonLibraryAnnotation();
+
+@Target({TargetKind.library})
+class LibraryAnnotation {
+  const LibraryAnnotation();
+}
+
+@Target({TargetKind.classType})
+class NonLibraryAnnotation {
+  const NonLibraryAnnotation();
+}
+    ''';
+    addSource(annotationsFile, annotationsContent);
+  }
+
   void _assertOrganize(String expectedCode, {bool removeUnused = false}) {
     var organizer = ImportOrganizer(testCode, testUnit, testErrors,
         removeUnused: removeUnused);
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index b8cc8eb..8b090db 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -89,7 +89,7 @@
   }
 
   Future<void> test_change_multipleFiles() async {
-    await indexUnit('/home/test/lib/other.dart', r'''
+    await indexUnit('$testPackageLibPath/other.dart', r'''
 class A {
   int get test => 1;
 }
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index c95f9e0..58aea84 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
@@ -88,7 +88,7 @@
   }
 
   Future<void> test_change_multipleFiles() async {
-    await indexUnit('/home/test/lib/other.dart', r'''
+    await indexUnit('$testPackageLibPath/other.dart', r'''
 class A {
   int test() => 1;
 }
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 527b60f..98584b89 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -2871,7 +2871,7 @@
   }
 
   void _addLibraryReturningAsync() {
-    addSource('/home/test/lib/asyncLib.dart', r'''
+    addSource('$testPackageLibPath/asyncLib.dart', r'''
 import 'dart:async';
 
 Completer<int> newCompleter() => null;
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index 5094b24..52fe0df 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -57,7 +57,7 @@
   }
 
   Future<void> test_file_imported_with_package_uri_down() async {
-    var file = newFile('/home/test/lib/old_name.dart', content: '');
+    var file = newFile('$testPackageLibPath/old_name.dart', content: '');
     addTestSource(r'''
 import 'package:test/old_name.dart';
 ''');
@@ -69,7 +69,8 @@
     testAnalysisResult =
         await session.getResolvedUnit(file.path) as ResolvedUnitResult;
 
-    _createRefactoring('/home/test/lib/222/new_name.dart', oldFile: file.path);
+    _createRefactoring('$testPackageLibPath/222/new_name.dart',
+        oldFile: file.path);
     await _assertSuccessfulRefactoring();
 
     assertFileChangeResult(testFile, '''
@@ -150,7 +151,7 @@
   }
 
   Future<void> test_file_imported_with_package_uri_sideways() async {
-    var file = newFile('/home/test/lib/111/old_name.dart', content: '');
+    var file = newFile('$testPackageLibPath/111/old_name.dart', content: '');
     addTestSource(r'''
 import 'package:test/111/old_name.dart';
 ''');
@@ -162,7 +163,8 @@
     testAnalysisResult =
         await session.getResolvedUnit(file.path) as ResolvedUnitResult;
 
-    _createRefactoring('/home/test/lib/222/new_name.dart', oldFile: file.path);
+    _createRefactoring('$testPackageLibPath/222/new_name.dart',
+        oldFile: file.path);
     await _assertSuccessfulRefactoring();
 
     assertFileChangeResult(testFile, '''
@@ -171,7 +173,7 @@
   }
 
   Future<void> test_file_imported_with_package_uri_up() async {
-    var file = newFile('/home/test/lib/222/old_name.dart', content: '');
+    var file = newFile('$testPackageLibPath/222/old_name.dart', content: '');
     addTestSource(r'''
 import 'package:test/222/old_name.dart';
 ''');
@@ -183,7 +185,7 @@
     testAnalysisResult =
         await session.getResolvedUnit(file.path) as ResolvedUnitResult;
 
-    _createRefactoring('/home/test/lib/new_name.dart', oldFile: file.path);
+    _createRefactoring('$testPackageLibPath/new_name.dart', oldFile: file.path);
     await _assertSuccessfulRefactoring();
 
     assertFileChangeResult(testFile, '''
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index 872fe9d..af8c5b5 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -157,7 +157,7 @@
   test() {}
 }
 ''');
-    await indexUnit('/home/test/lib/lib.dart', '''
+    await indexUnit('$testPackageLibPath/lib.dart', '''
 library my.lib;
 import 'test.dart';
 
@@ -181,7 +181,7 @@
   var foo = 1;
 }
 ''');
-    await indexUnit('/home/test/lib/lib.dart', '''
+    await indexUnit('$testPackageLibPath/lib.dart', '''
 import 'test.dart';
 
 void f(A a) {
@@ -387,7 +387,7 @@
   newName() {} // marker
 }
 ''';
-    await indexUnit('/home/test/lib/lib.dart', libCode);
+    await indexUnit('$testPackageLibPath/lib.dart', libCode);
     await indexTestUnit('''
 import 'lib.dart';
 class B extends A {
diff --git a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
index 2f37e06..0b6b03c 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
@@ -35,7 +35,7 @@
   }
 
   Future<void> test_createChange() async {
-    addSource('/home/test/lib/part.dart', '''
+    addSource('$testPackageLibPath/part.dart', '''
 part of my.app;
 ''');
     await indexTestUnit('''
@@ -52,13 +52,13 @@
 library the.new.name;
 part 'part.dart';
 ''');
-    assertFileChangeResult('/home/test/lib/part.dart', '''
+    assertFileChangeResult('$testPackageLibPath/part.dart', '''
 part of the.new.name;
 ''');
   }
 
   Future<void> test_createChange_hasWhitespaces() async {
-    addSource('/home/test/lib/part.dart', '''
+    addSource('$testPackageLibPath/part.dart', '''
 part of my .  app;
 ''');
     await indexTestUnit('''
@@ -75,7 +75,7 @@
 library the.new.name;
 part 'part.dart';
 ''');
-    assertFileChangeResult('/home/test/lib/part.dart', '''
+    assertFileChangeResult('$testPackageLibPath/part.dart', '''
 part of the.new.name;
 ''');
   }
diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
index 5c43032..5b42916 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
@@ -442,9 +442,38 @@
 ''');
   }
 
+  Future<void> test_createChange_parameter_named_anywhere() async {
+    await indexTestUnit('''
+myFunction(int a, int b, {required int test}) {
+  test = 1;
+  test += 2;
+  print(test);
+}
+void f() {
+  myFunction(0, test: 2, 1);
+}
+''');
+    // configure refactoring
+    createRenameRefactoringAtString('test}) {');
+    expect(refactoring.refactoringName, 'Rename Parameter');
+    expect(refactoring.elementKindName, 'parameter');
+    refactoring.newName = 'newName';
+    // validate change
+    return assertSuccessfulRefactoring('''
+myFunction(int a, int b, {required int newName}) {
+  newName = 1;
+  newName += 2;
+  print(newName);
+}
+void f() {
+  myFunction(0, newName: 2, 1);
+}
+''');
+  }
+
   Future<void> test_createChange_parameter_named_inOtherFile() async {
-    var a = convertPath('/home/test/lib/a.dart');
-    var b = convertPath('/home/test/lib/b.dart');
+    var a = convertPath('$testPackageLibPath/a.dart');
+    var b = convertPath('$testPackageLibPath/b.dart');
 
     newFile(a, content: r'''
 class A {
@@ -537,7 +566,7 @@
   }
 
   Future<void> test_createChange_parameter_named_updateHierarchy() async {
-    await indexUnit('/home/test/lib/test2.dart', '''
+    await indexUnit('$testPackageLibPath/test2.dart', '''
 library test2;
 class A {
   void foo({int? test}) {
@@ -581,7 +610,7 @@
   }
 }
 ''');
-    assertFileChangeResult('/home/test/lib/test2.dart', '''
+    assertFileChangeResult('$testPackageLibPath/test2.dart', '''
 library test2;
 class A {
   void foo({int? newName}) {
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index a65f922..e0ebb09 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
@@ -71,7 +71,7 @@
     await indexTestUnit('''
 class Test {}
 ''');
-    await indexUnit('/home/test/lib/lib.dart', '''
+    await indexUnit('$testPackageLibPath/lib.dart', '''
 library my.lib;
 import 'test.dart';
 
@@ -112,7 +112,7 @@
     await indexTestUnit('''
 class Test {}
 ''');
-    await indexUnit('/home/test/lib/lib.dart', '''
+    await indexUnit('$testPackageLibPath/lib.dart', '''
 library my.lib;
 import 'test.dart';
 class A {
@@ -610,7 +610,7 @@
   }
 
   Future<void> test_createChange_FunctionElement_imported() async {
-    await indexUnit('/home/test/lib/foo.dart', r'''
+    await indexUnit('$testPackageLibPath/foo.dart', r'''
 test() {}
 foo() {}
 ''');
@@ -637,7 +637,7 @@
   foo();
 }
 ''');
-    assertFileChangeResult('/home/test/lib/foo.dart', '''
+    assertFileChangeResult('$testPackageLibPath/foo.dart', '''
 newName() {}
 foo() {}
 ''');
diff --git a/pkg/analysis_server/test/src/cider/rename_test.dart b/pkg/analysis_server/test/src/cider/rename_test.dart
index 028aaea..626135f 100644
--- a/pkg/analysis_server/test/src/cider/rename_test.dart
+++ b/pkg/analysis_server/test/src/cider/rename_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/cider/rename.dart';
 import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/micro/resolve_file.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -29,7 +30,6 @@
 }
 ''');
 
-    expect(refactor, isNotNull);
     expect(refactor!.refactoringElement.element.name, 'bar');
     expect(refactor.refactoringElement.offset, _correctionContext.offset);
   }
@@ -40,7 +40,6 @@
 }
 ''');
 
-    expect(refactor, isNotNull);
     expect(refactor!.refactoringElement.element.name, 'foo');
     expect(refactor.refactoringElement.offset, _correctionContext.offset);
   }
@@ -68,7 +67,6 @@
 }
 ''');
 
-    expect(refactor, isNotNull);
     expect(refactor!.refactoringElement.element.name, 'a');
     expect(refactor.refactoringElement.offset, _correctionContext.offset);
   }
@@ -80,7 +78,6 @@
 }
 ''');
 
-    expect(refactor, isNotNull);
     expect(refactor!.refactoringElement.element.name, 'foo');
     expect(refactor.refactoringElement.offset, _correctionContext.offset);
   }
@@ -112,9 +109,8 @@
 int ^foo() => 2;
 ''', 'bar');
 
-    expect(result, isNotNull);
-    expect(result?.status.problems.length, 0);
-    expect(result?.oldName, 'foo');
+    expect(result!.status.problems.length, 0);
+    expect(result.oldName, 'foo');
   }
 
   void test_checkName_local() {
@@ -124,9 +120,8 @@
 }
 ''', 'bar');
 
-    expect(result, isNotNull);
-    expect(result?.status.problems.length, 0);
-    expect(result?.oldName, 'a');
+    expect(result!.status.problems.length, 0);
+    expect(result.oldName, 'a');
   }
 
   void test_checkName_local_invalid() {
@@ -136,9 +131,8 @@
 }
 ''', 'Aa');
 
-    expect(result, isNotNull);
-    expect(result?.status.problems.length, 1);
-    expect(result?.oldName, 'a');
+    expect(result!.status.problems.length, 1);
+    expect(result.oldName, 'a');
   }
 
   void test_checkName_parameter() {
@@ -148,9 +142,57 @@
 }
 ''', 'bar');
 
-    expect(result, isNotNull);
-    expect(result?.status.problems.length, 0);
-    expect(result?.oldName, 'a');
+    expect(result!.status.problems.length, 0);
+    expect(result.oldName, 'a');
+  }
+
+  void test_rename_local() {
+    var result = _rename(r'''
+void foo() {
+  var ^a = 0; var b = a + 1;
+}
+''', 'bar');
+
+    expect(result!.matches.length, 1);
+    expect(
+        result.matches[0],
+        CiderSearchMatch(convertPath('/workspace/dart/test/lib/test.dart'),
+            [CharacterLocation(2, 7), CharacterLocation(2, 22)]));
+  }
+
+  void test_rename_method() {
+    var a = newFile('/workspace/dart/test/lib/a.dart', content: r'''
+void foo() {
+  a;
+}
+''');
+    fileResolver.resolve(path: a.path);
+
+    var result = _rename(r'''
+import 'a.dart';
+
+main() {
+^foo();
+}
+''', 'bar');
+
+    expect(result!.matches.length, 2);
+    expect(result.matches, [
+      CiderSearchMatch(convertPath('/workspace/dart/test/lib/a.dart'),
+          [CharacterLocation(1, 6)]),
+      CiderSearchMatch(convertPath('/workspace/dart/test/lib/test.dart'),
+          [CharacterLocation(4, 1)])
+    ]);
+  }
+
+  void test_rename_parameter() {
+    var result = _rename(r'''
+void foo(String ^a) {
+  var b = a + 1;
+}
+''', 'bar');
+    expect(result!.matches.length, 1);
+    expect(result.checkName.oldName, 'a');
   }
 
   CheckNameResponse? _checkName(String content, String newName) {
@@ -158,12 +200,13 @@
 
     return CiderRenameComputer(
       fileResolver,
-    ).checkNewName(
-      convertPath(testPath),
-      _correctionContext.line,
-      _correctionContext.character,
-      newName,
-    );
+    )
+        .canRename(
+          convertPath(testPath),
+          _correctionContext.line,
+          _correctionContext.character,
+        )
+        ?.checkNewName(newName);
   }
 
   CanRenameResponse? _compute(String content) {
@@ -178,6 +221,21 @@
     );
   }
 
+  RenameResponse? _rename(String content, newName) {
+    _updateFile(content);
+
+    return CiderRenameComputer(
+      fileResolver,
+    )
+        .canRename(
+          convertPath(testPath),
+          _correctionContext.line,
+          _correctionContext.character,
+        )
+        ?.checkNewName(newName)
+        ?.computeRenameRanges();
+  }
+
   void _updateFile(String content) {
     var offset = content.indexOf('^');
     expect(offset, isPositive, reason: 'Expected to find ^');
diff --git a/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart b/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
index 83a9954..3c99d77 100644
--- a/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
@@ -23,7 +23,7 @@
   @override
   void setUp() {
     super.setUp();
-    sourcePath = convertPath('/home/test/lib/test.dart');
+    sourcePath = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<void> test_adjacentLinesExcluded() async {
diff --git a/pkg/analysis_server/test/src/computer/color_computer_test.dart b/pkg/analysis_server/test/src/computer/color_computer_test.dart
new file mode 100644
index 0000000..1178812
--- /dev/null
+++ b/pkg/analysis_server/test/src/computer/color_computer_test.dart
@@ -0,0 +1,343 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/computer/computer_color.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:collection/collection.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../abstract_context.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ColorComputerTest);
+  });
+}
+
+@reflectiveTest
+class ColorComputerTest extends AbstractContextTest {
+  /// A map of Dart source code that represents different types/formats
+  /// that are valid in const contexts.
+  ///
+  /// Values are the color that should be discovered (in 0xAARRGGBB format).
+  ///
+  /// Color values may not match the actual Flutter framework but are
+  /// values that are more identifyable for ease of testing. They are
+  /// defined in:
+  ///  - test/mock_packages/flutter/lib/src/material/colors.dart.
+  ///  - test/mock_packages/flutter/lib/src/cupertino/colors.dart.
+  ///
+  /// These values will be iterated in tests and inserted into various
+  /// code snippets for testing.
+  static const colorCodesConst = {
+    // dart:ui Colors
+    'Colors.white': 0xFFFFFFFF,
+    'Color(0xFF0000FF)': 0xFF0000FF,
+    'Color.fromARGB(255, 0, 0, 255)': 0xFF0000FF,
+    'Color.fromRGBO(0, 0, 255, 1)': 0xFF0000FF,
+    // Flutter Painting
+    'ColorSwatch(0xFF89ABCD, {})': 0xFF89ABCD,
+    // Flutter Material
+    'Colors.red': 0xFFFF0000,
+    'Colors.redAccent': 0xFFFFAA00,
+    'MaterialAccentColor(0xFF89ABCD, {})': 0xFF89ABCD,
+    // Flutter Cupertino
+    'CupertinoColors.black': 0xFF000000,
+    'CupertinoColors.systemBlue': 0xFF0000FF,
+    'CupertinoColors.activeBlue': 0xFF0000FF,
+  };
+
+  /// A map of Dart source code that represents different types/formats
+  /// that are not valid in const contexts.
+  ///
+  /// Values are the color that should be discovered (in 0xAARRGGBB format).
+  static const colorCodesNonConst = {
+    // Flutter Material
+    'Colors.red.shade100': 0x10FF0000,
+    'Colors.red[100]': 0x10FF0000,
+    // Flutter Cupertino
+    'CupertinoColors.systemBlue.color': 0xFF0000FF,
+    'CupertinoColors.systemBlue.darkColor': 0xFF000099,
+    'CupertinoColors.activeBlue.color': 0xFF0000FF,
+    'CupertinoColors.activeBlue.darkColor': 0xFF000099,
+    'CupertinoColors.activeBlue.highContrastColor': 0xFF000066,
+    'CupertinoColors.activeBlue.darkHighContrastColor': 0xFF000033,
+    'CupertinoColors.activeBlue.elevatedColor': 0xFF0000FF,
+    'CupertinoColors.activeBlue.darkElevatedColor': 0xFF000099,
+  };
+
+  /// A map of Dart source code that creates multiple nested color references.
+  ///
+  /// The key is the source code, and the value is a map of the expressions and
+  /// colors that should be produced (where the null key represents the
+  /// entire expression).
+  static const colorCodesNested = {
+    // TODO(dantup): Remove this "const" when we can evaluate constructors
+    // in non-const contexts.
+    'const CupertinoDynamicColor.withBrightness(color: CupertinoColors.white, darkColor: CupertinoColors.black)':
+        {
+      null: 0xFFFFFFFF,
+      'CupertinoColors.white': 0xFFFFFFFF,
+      'CupertinoColors.black': 0xFF000000,
+    },
+  };
+
+  late String testPath;
+  late String otherPath;
+
+  late ColorComputer computer;
+
+  /// Tests that all of the known color codes replaced into [code] produce the
+  /// expected nested color values.
+  ///
+  /// If [onlyConst] is `true`, only the test values that are const will be
+  /// tested.
+  Future<void> checkAllColors(String code, {bool onlyConst = false}) async {
+    // Combine the flat and nested colours into the same format.
+    final allColorCodes = <String, Map<String?, int>>{
+      ...colorCodesConst.map((key, value) => MapEntry(key, {key: value})),
+      if (!onlyConst)
+        ...colorCodesNonConst.map((key, value) => MapEntry(key, {key: value})),
+      ...colorCodesNested,
+    };
+
+    for (final entry in allColorCodes.entries) {
+      final colorDartCode = entry.key;
+      final expectedColorValues = entry.value.map(
+        // A null key means we should expect the full code.
+        (key, value) => MapEntry(key ?? colorDartCode, value),
+      );
+
+      await expectColors(
+        code.replaceAll('[[COLOR]]', colorDartCode),
+        expectedColorValues,
+      );
+    }
+  }
+
+  /// Checks that all of [expectedColorValues] are produced for [dartCode].
+  Future<void> expectColors(
+    String dartCode,
+    Map<String, int> expectedColorValues, {
+    String? otherCode,
+  }) async {
+    dartCode = _withCommonImports(dartCode);
+    otherCode = otherCode != null ? _withCommonImports(otherCode) : null;
+
+    newFile(testPath, content: dartCode);
+    if (otherCode != null) {
+      newFile(otherPath, content: otherCode);
+      final otherResult =
+          await session.getResolvedUnit(otherPath) as ResolvedUnitResult;
+      expectNoErrors(otherResult);
+    }
+    final result =
+        await session.getResolvedUnit(testPath) as ResolvedUnitResult;
+    expectNoErrors(result);
+
+    computer = ColorComputer(result);
+    final colors = computer.compute();
+
+    expect(
+      colors,
+      hasLength(expectedColorValues.length),
+      reason: '${expectedColorValues.length} colors should be detected in:\n'
+          '$dartCode',
+    );
+
+    expectedColorValues.entries.forEachIndexed((i, expectedColor) {
+      final color = colors[i];
+      final expectedColorCode = expectedColor.key;
+      final expectedColorValue = expectedColor.value;
+      final expectedAlpha = (0xff000000 & expectedColorValue) >> 24;
+      final expectedRed = (0x00ff0000 & expectedColorValue) >> 16;
+      final expectedGreen = (0x0000ff00 & expectedColorValue) >> 8;
+      final expectedBlue = (0x000000ff & expectedColorValue) >> 0;
+
+      final regionText =
+          dartCode.substring(color.offset, color.offset + color.length);
+      expect(
+        regionText,
+        equals(expectedColorCode),
+        reason: 'Color $i expected $expectedColorCode but was $regionText',
+      );
+
+      void expectComponent(int actual, int expected, String name) => expect(
+            actual,
+            expected,
+            reason: '$name value for $expectedColorCode is not correct',
+          );
+
+      expectComponent(color.color.alpha, expectedAlpha, 'Alpha');
+      expectComponent(color.color.red, expectedRed, 'Red');
+      expectComponent(color.color.green, expectedGreen, 'Green');
+      expectComponent(color.color.blue, expectedBlue, 'Blue');
+    });
+  }
+
+  void expectNoErrors(ResolvedUnitResult result) {
+    // If the test code has errors, generate a suitable failure to help debug.
+    final errors = result.errors
+        .where((error) => error.severity == Severity.error)
+        .toList();
+    if (errors.isNotEmpty) {
+      throw 'Code has errors: $errors\n\n${result.content}';
+    }
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    writeTestPackageConfig(flutter: true);
+    testPath = convertPath('$testPackageLibPath/test.dart');
+    otherPath = convertPath('$testPackageLibPath/other_file.dart');
+  }
+
+  Future<void> test_collectionLiteral_const() async {
+    const testCode = '''
+main() {
+  const colors = [
+    [[COLOR]],
+  ];
+}
+''';
+    await checkAllColors(testCode, onlyConst: true);
+  }
+
+  Future<void> test_collectionLiteral_nonConst() async {
+    const testCode = '''
+main() {
+  final colors = [
+    [[COLOR]],
+  ];
+}
+''';
+    await checkAllColors(testCode);
+  }
+
+  Future<void> test_customClass() async {
+    const testCode = '''
+import 'other_file.dart';
+
+void main() {
+  final a1 = MyTheme.staticWhite;
+  final a2 = MyTheme.staticMaterialRedAccent;
+  const theme = MyTheme();
+  final b1 = theme.instanceWhite;
+  final b2 = theme.instanceMaterialRedAccent;
+}
+''';
+
+    const otherCode = '''
+class MyTheme {
+  static const Color staticWhite = Colors.white;
+  static const MaterialAccentColor staticMaterialRedAccent = Colors.redAccent;
+
+  final Color instanceWhite;
+  final MaterialAccentColor instanceMaterialRedAccent;
+
+  const MyTheme()
+      : instanceWhite = Colors.white,
+        instanceMaterialRedAccent = Colors.redAccent;
+}
+''';
+    await expectColors(
+      testCode,
+      {
+        'MyTheme.staticWhite': 0xFFFFFFFF,
+        'MyTheme.staticMaterialRedAccent': 0xFFFFAA00,
+        'theme.instanceWhite': 0xFFFFFFFF,
+        'theme.instanceMaterialRedAccent': 0xFFFFAA00,
+      },
+      otherCode: otherCode,
+    );
+  }
+
+  Future<void> test_local_const() async {
+    const testCode = '''
+main() {
+  const a = [[COLOR]];
+}
+''';
+    await checkAllColors(testCode, onlyConst: true);
+  }
+
+  Future<void> test_local_nonConst() async {
+    const testCode = '''
+main() {
+  final a = [[COLOR]];
+}
+''';
+    await checkAllColors(testCode);
+  }
+
+  Future<void> test_namedParameter_const() async {
+    const testCode = '''
+main() {
+  const w = Widget(color: [[COLOR]]);
+}
+
+class Widget {
+  final Color? color;
+  const Widget({this.color});
+}
+''';
+    await checkAllColors(testCode, onlyConst: true);
+  }
+
+  Future<void> test_namedParameter_nonConst() async {
+    const testCode = '''
+main() {
+  final w = Widget(color: [[COLOR]]);
+}
+
+class Widget {
+  final Color? color;
+  Widget({this.color});
+}
+''';
+    await checkAllColors(testCode);
+  }
+
+  Future<void> test_nested_const() async {
+    const testCode = '''
+main() {
+  const a = [[COLOR]];
+}
+''';
+    await checkAllColors(testCode, onlyConst: true);
+  }
+
+  Future<void> test_nested_nonConst() async {
+    const testCode = '''
+main() {
+  final a = [[COLOR]];
+}
+''';
+    await checkAllColors(testCode);
+  }
+
+  Future<void> test_topLevel_const() async {
+    const testCode = '''
+const a = [[COLOR]];
+''';
+    await checkAllColors(testCode, onlyConst: true);
+  }
+
+  Future<void> test_topLevel_nonConst() async {
+    const testCode = '''
+final a = [[COLOR]];
+''';
+    await checkAllColors(testCode);
+  }
+
+  String _withCommonImports(String code) => '''
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/painting.dart';
+import 'package:flutter/material.dart';
+
+$code''';
+}
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index f63607d..bba4d0b 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -29,7 +29,7 @@
   @override
   void setUp() {
     super.setUp();
-    sourcePath = convertPath('/home/test/lib/test.dart');
+    sourcePath = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<void> test_annotations() async {
diff --git a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
index 46a6c44..d1a90d3 100644
--- a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
@@ -25,7 +25,7 @@
   @override
   void setUp() {
     super.setUp();
-    sourcePath = convertPath('/home/test/lib/test.dart');
+    sourcePath = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<void> test_comment() async {
diff --git a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
index fed52b7..133ab24 100644
--- a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
@@ -57,7 +57,7 @@
   @override
   void setUp() {
     super.setUp();
-    path = convertPath('/home/test/lib/test.dart');
+    path = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<void> test_createEdits_addImport_noDirectives() async {
diff --git a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
index a63d9bc..cf1cf9a 100644
--- a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
@@ -46,7 +46,7 @@
   @override
   void setUp() {
     super.setUp();
-    sourcePath = convertPath('/home/test/lib/test.dart');
+    sourcePath = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<void> test_dartAsync_noPrefix() async {
diff --git a/pkg/analysis_server/test/src/computer/outline_computer_test.dart b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
index 185338f..7a0837e 100644
--- a/pkg/analysis_server/test/src/computer/outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
@@ -24,7 +24,7 @@
   @override
   void setUp() {
     super.setUp();
-    testPath = convertPath('/home/test/lib/test.dart');
+    testPath = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<Outline> _computeOutline(String code) async {
diff --git a/pkg/analysis_server/test/src/computer/selection_range_computer_test.dart b/pkg/analysis_server/test/src/computer/selection_range_computer_test.dart
index 27e9e7f..ee07e86 100644
--- a/pkg/analysis_server/test/src/computer/selection_range_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/selection_range_computer_test.dart
@@ -22,7 +22,7 @@
   @override
   void setUp() {
     super.setUp();
-    sourcePath = convertPath('/home/test/lib/test.dart');
+    sourcePath = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<void> test_arguments() async {
diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart
index 6f67c7a..af15c51 100644
--- a/pkg/analysis_server/test/src/computer/test_all.dart
+++ b/pkg/analysis_server/test/src/computer/test_all.dart
@@ -5,6 +5,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'closing_labels_computer_test.dart' as closing_labels_computer;
+import 'color_computer_test.dart' as color_computer;
 import 'folding_computer_test.dart' as folding_computer;
 import 'highlights_computer_test.dart' as highlights_computer;
 import 'import_elements_computer_test.dart' as import_elements_computer;
@@ -15,6 +16,7 @@
 void main() {
   defineReflectiveSuite(() {
     closing_labels_computer.main();
+    color_computer.main();
     folding_computer.main();
     highlights_computer.main();
     import_elements_computer.main();
diff --git a/pkg/analysis_server/test/src/domains/execution/completion_test.dart b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
index 81d2594..4f3af62 100644
--- a/pkg/analysis_server/test/src/domains/execution/completion_test.dart
+++ b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
@@ -25,7 +25,7 @@
   late RuntimeCompletionResult result;
 
   void addContextFile(String content) {
-    contextFile = convertPath('/home/test/lib/context.dart');
+    contextFile = convertPath('$testPackageLibPath/context.dart');
     addSource(contextFile, content);
 
     contextOffset = content.indexOf('// context line');
@@ -120,13 +120,13 @@
 
   @FailingTest(reason: 'No support for OverlayResourceProvider')
   Future<void> test_inPart() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 part 'b.dart';
 part 'context.dart';
 
 int a;
 ''');
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 part of 'a.dart';
 
 double b;
diff --git a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
index c224c12..e55c554 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
@@ -27,7 +27,7 @@
   void setUp() {
     super.setUp();
     writeTestPackageConfig(flutter: true);
-    testPath = convertPath('/home/test/lib/test.dart');
+    testPath = convertPath('$testPackageLibPath/test.dart');
   }
 
   Future<void> test_attribute_namedExpression() async {
@@ -234,7 +234,7 @@
   }
 
   Future<void> test_children_closure_blockBody() async {
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 import 'package:flutter/widgets.dart';
 
 class WidgetA extends StatelessWidget {
@@ -270,7 +270,7 @@
   }
 
   Future<void> test_children_closure_expressionBody() async {
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 import 'package:flutter/widgets.dart';
 
 class WidgetA extends StatelessWidget {
@@ -443,7 +443,7 @@
   }
 
   Future<void> test_parentAssociationLabel() async {
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 import 'package:flutter/widgets.dart';
 
 class WidgetA extends StatelessWidget {
diff --git a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart b/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
index 0f7483d..5504afb 100644
--- a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/notification_manager_test.dart
@@ -468,23 +468,10 @@
   server.Notification? sentNotification;
 
   @override
-  void close() {
-    fail('Unexpected invocation of close');
-  }
-
-  @override
-  void listen(void Function(server.Request) onRequest,
-      {Function? onError, void Function()? onDone}) {
-    fail('Unexpected invocation of listen');
-  }
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
   @override
   void sendNotification(server.Notification notification) {
     sentNotification = notification;
   }
-
-  @override
-  void sendResponse(server.Response response) {
-    fail('Unexpected invocation of sendResponse');
-  }
 }
diff --git a/pkg/analysis_server/test/src/services/completion/dart/suggestion_builder_test.dart b/pkg/analysis_server/test/src/services/completion/dart/suggestion_builder_test.dart
index 8c8bc43..9f66816 100644
--- a/pkg/analysis_server/test/src/services/completion/dart/suggestion_builder_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/dart/suggestion_builder_test.dart
@@ -27,7 +27,7 @@
   }
 
   Future<CompletionSuggestion> forTopLevelFunction(String functionName) async {
-    var request = DartCompletionRequest(
+    var request = DartCompletionRequest.forResolvedUnit(
       resolvedUnit: testAnalysisResult,
       offset: 0,
     );
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
index a12a654..c9d3b7f 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
@@ -84,7 +84,7 @@
   }
 
   Future<void> test_declaredIdentifier_addImport_dartUri() async {
-    addSource('/home/test/lib/my_lib.dart', r'''
+    addSource('$testPackageLibPath/my_lib.dart', r'''
 import 'dart:collection';
 List<HashMap<String, int>> getMap() => null;
 ''');
@@ -173,7 +173,7 @@
   }
 
   Future<void> test_local_addImport_dartUri() async {
-    addSource('/home/test/lib/my_lib.dart', r'''
+    addSource('$testPackageLibPath/my_lib.dart', r'''
 import 'dart:collection';
 HashMap<String, int> getMap() => null;
 ''');
@@ -194,7 +194,7 @@
   }
 
   Future<void> test_local_addImport_notLibraryUnit() async {
-    addSource('/home/test/lib/my_lib.dart', r'''
+    addSource('$testPackageLibPath/my_lib.dart', r'''
 import 'dart:collection';
 HashMap<String, int> getMap() => null;
 ''');
@@ -211,7 +211,7 @@
 }
 ''');
 
-    var appPath = convertPath('/home/test/lib/app.dart');
+    var appPath = convertPath('$testPackageLibPath/app.dart');
     addSource(appPath, appCode);
     await analyzeTestPackageFiles();
     await resolveTestFile();
@@ -646,7 +646,7 @@
   }
 
   Future<void> test_privateType_closureParameter() async {
-    addSource('/home/test/lib/my_lib.dart', '''
+    addSource('$testPackageLibPath/my_lib.dart', '''
 library my_lib;
 class A {}
 class _B extends A {}
@@ -662,7 +662,7 @@
   }
 
   Future<void> test_privateType_declaredIdentifier() async {
-    addSource('/home/test/lib/my_lib.dart', '''
+    addSource('$testPackageLibPath/my_lib.dart', '''
 library my_lib;
 class A {}
 class _B extends A {}
@@ -683,7 +683,7 @@
   Future<void> test_privateType_list() async {
     // This is now failing because we're suggesting "List" rather than nothing.
     // Is it really better to produce nothing?
-    addSource('/home/test/lib/my_lib.dart', '''
+    addSource('$testPackageLibPath/my_lib.dart', '''
 library my_lib;
 class A {}
 class _B extends A {}
@@ -721,7 +721,7 @@
   }
 
   Future<void> test_privateType_variable() async {
-    addSource('/home/test/lib/my_lib.dart', '''
+    addSource('$testPackageLibPath/my_lib.dart', '''
 library my_lib;
 class A {}
 class _B extends A {}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart
index 4f99ef9..37f3d66 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart
@@ -20,12 +20,12 @@
   AssistKind get kind => DartAssistKind.CONVERT_PART_OF_TO_URI;
 
   Future<void> test_nonSibling() async {
-    addSource('/home/test/lib/foo.dart', '''
+    addSource('$testPackageLibPath/foo.dart', '''
 library foo;
 part 'src/bar.dart';
 ''');
 
-    testFile = convertPath('/home/test/lib/src/bar.dart');
+    testFile = convertPath('$testPackageLibPath/src/bar.dart');
     addTestSource('''
 part of foo;
 ''');
@@ -38,12 +38,12 @@
   }
 
   Future<void> test_sibling() async {
-    addSource('/home/test/lib/foo.dart', '''
+    addSource('$testPackageLibPath/foo.dart', '''
 library foo;
 part 'bar.dart';
 ''');
 
-    testFile = convertPath('/home/test/lib/bar.dart');
+    testFile = convertPath('$testPackageLibPath/bar.dart');
     addTestSource('''
 part of foo;
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
index 1fe3d84..3665770 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
@@ -21,7 +21,7 @@
   AssistKind get kind => DartAssistKind.CONVERT_TO_PACKAGE_IMPORT;
 
   Future<void> test_fileName_onImport() async {
-    addSource('/home/test/lib/foo.dart', '');
+    addSource('$testPackageLibPath/foo.dart', '');
 
     await resolveTestCode('''
 import 'foo.dart';
@@ -33,7 +33,7 @@
   }
 
   Future<void> test_fileName_onUri() async {
-    addSource('/home/test/lib/foo.dart', '');
+    addSource('$testPackageLibPath/foo.dart', '');
 
     await resolveTestCode('''
 import 'foo.dart';
@@ -52,8 +52,8 @@
   }
 
   Future<void> test_nonPackage_Uri() async {
-    addSource('/home/test/lib/foo.dart', '');
-    testFile = convertPath('/home/test/lib/src/test.dart');
+    addSource('$testPackageLibPath/foo.dart', '');
+    testFile = convertPath('$testPackageLibPath/src/test.dart');
     await resolveTestCode('''
 import 'dart:core';
 ''');
@@ -63,7 +63,7 @@
   }
 
   Future<void> test_packageUri() async {
-    addSource('/home/test/lib/foo.dart', '');
+    addSource('$testPackageLibPath/foo.dart', '');
 
     await resolveTestCode('''
 import 'package:test/foo.dart';
@@ -73,9 +73,9 @@
   }
 
   Future<void> test_path() async {
-    addSource('/home/test/lib/foo/bar.dart', '');
+    addSource('$testPackageLibPath/foo/bar.dart', '');
 
-    testFile = convertPath('/home/test/lib/src/test.dart');
+    testFile = convertPath('$testPackageLibPath/src/test.dart');
 
     await resolveTestCode('''
 import '../foo/bar.dart';
@@ -89,7 +89,7 @@
   Future<void> test_relativeImport_noAssistWithLint() async {
     createAnalysisOptionsFile(lints: [LintNames.avoid_relative_lib_imports]);
     verifyNoTestUnitErrors = false;
-    addSource('/home/test/lib/foo.dart', '');
+    addSource('$testPackageLibPath/foo.dart', '');
 
     await resolveTestCode('''
 import '../lib/foo.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart b/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart
index 58b527a..320890d 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart
@@ -85,7 +85,7 @@
   }
 
   Future<void> test_setterOnDirective() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 void set setter(int i) {}
 ''');
     await resolveTestCode('''
diff --git a/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
index 4fb3e72..b02dad3 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
@@ -120,7 +120,7 @@
   }
 
   Future<void> test_privateType() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   _B b => _B();
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
index 8ff04db..6cc2306 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_late_test.dart
@@ -40,7 +40,7 @@
   FixKind get kind => DartFixKind.ADD_LATE;
 
   Future<void> test_changeInImportedLib() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class C {
   final String s;
 }
@@ -56,11 +56,11 @@
 class C {
   late final String s;
 }
-''', target: '/home/test/lib/a.dart');
+''', target: '$testPackageLibPath/a.dart');
   }
 
   Future<void> test_changeInPart() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 part 'test.dart';
 
 class C {
@@ -80,7 +80,7 @@
 class C {
   late final String s;
 }
-''', target: '/home/test/lib/a.dart');
+''', target: '$testPackageLibPath/a.dart');
   }
 
   Future<void> test_withFinal() async {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
index dc08b79..798725d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
@@ -102,7 +102,7 @@
   }
 
   Future<void> test_constructor_single() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {
   A({required int a}) {}
 }
@@ -126,7 +126,7 @@
   }
 
   Future<void> test_constructor_single_closure() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef void VoidCallback();
 
 class A {
@@ -152,7 +152,7 @@
   }
 
   Future<void> test_constructor_single_closure2() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef void Callback(e);
 
 class A {
@@ -178,7 +178,7 @@
   }
 
   Future<void> test_constructor_single_closure3() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef void Callback(a,b,c);
 
 class A {
@@ -204,7 +204,7 @@
   }
 
   Future<void> test_constructor_single_closure4() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef int Callback(int a, String b,c);
 
 class A {
@@ -230,7 +230,7 @@
   }
 
   Future<void> test_constructor_single_closure_nnbd() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef int Callback(int? a);
 
 class A {
@@ -256,7 +256,7 @@
   }
 
   Future<void> test_constructor_single_closure_nnbd_from_legacy() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 // @dart = 2.8
 import 'package:meta/meta.dart';
 
@@ -287,7 +287,7 @@
   }
 
   Future<void> test_constructor_single_closure_nnbd_into_legacy() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 typedef int Callback(int? a);
 
 class A {
@@ -315,7 +315,7 @@
   }
 
   Future<void> test_constructor_single_list() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {
   A({required List<String> names}) {}
 }
@@ -338,6 +338,28 @@
 ''');
   }
 
+  Future<void> test_constructor_single_namedAnywhere() async {
+    addSource('$testPackageLibPath/a.dart', r'''
+class A {
+  A(int a, int b, {int? c, required int d}) {}
+}
+''');
+    await resolveTestCode('''
+import 'package:test/a.dart';
+
+void f() {
+  A(0, c: 1, 2);
+}
+''');
+    await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+  A(0, c: 1, 2, d: null);
+}
+''');
+  }
+
   Future<void> test_multiple() async {
     await resolveTestCode('''
 test({required int a, required int bcd}) {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
index 5cb45e5..65b56f4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
@@ -363,7 +363,7 @@
 }
 ''',
         errorFilter: (AnalysisError error) =>
-            error.errorCode != CompileTimeErrorCode.YIELD_OF_INVALID_TYPE);
+            error.errorCode != CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE);
   }
 
   Future<void> test_yieldEach_localFunction() async {
@@ -402,7 +402,7 @@
 }
 ''',
         errorFilter: (AnalysisError error) =>
-            error.errorCode != CompileTimeErrorCode.YIELD_OF_INVALID_TYPE);
+            error.errorCode != CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE);
   }
 
   Future<void> test_yieldEach_topLevel() async {
@@ -417,6 +417,6 @@
 }
 ''',
         errorFilter: (AnalysisError error) =>
-            error.errorCode != CompileTimeErrorCode.YIELD_OF_INVALID_TYPE);
+            error.errorCode != CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE);
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
index 1a40007..e00bd37 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_return_type_test.dart
@@ -179,7 +179,7 @@
   }
 
   Future<void> test_privateType() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   _B b => _B();
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
index 63abb76..12c14cf3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
@@ -58,12 +58,12 @@
   }
 
   Future<void> test_method_importType() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {
   static foo() {}
 }
 ''');
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 import 'package:test/a.dart';
 
 class B extends A {}
@@ -142,12 +142,12 @@
   }
 
   Future<void> test_property_importType() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {
   static get foo => null;
 }
 ''');
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 import 'package:test/a.dart';
 
 class B extends A {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
index ca26deb..9db4307 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
@@ -57,7 +57,7 @@
   }
 
   Future<void> test_privateType() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   _B b => _B();
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
index e4952f3..c59880a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_package_import_test.dart
@@ -24,7 +24,7 @@
   @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/44673')
   Future<void> test_singleFile() async {
     writeTestPackageConfig(config: PackageConfigFileBuilder());
-    addSource('/home/test/lib/bar.dart', 'class Bar {}');
+    addSource('$testPackageLibPath/bar.dart', 'class Bar {}');
 
     testFile = convertPath('/home/test/tool/test.dart');
 
@@ -55,7 +55,7 @@
     // This test fails because any attempt to specify a relative path that
     // includes 'lib' (which the lint requires) results in a malformed URI when
     // trying to resolve the import.
-    newFile('/home/test/lib/foo/bar.dart', content: '''
+    newFile('$testPackageLibPath/foo/bar.dart', content: '''
 class C {}
 ''');
     await resolveTestCode('''
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
index 260d20f..dfd5961 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_relative_import_test.dart
@@ -23,13 +23,13 @@
   String get lintCode => LintNames.prefer_relative_imports;
 
   Future<void> test_singleFile() async {
-    addSource('/home/test/lib/foo.dart', '''
+    addSource('$testPackageLibPath/foo.dart', '''
 class C {}
 ''');
-    addSource('/home/test/lib/bar.dart', '''
+    addSource('$testPackageLibPath/bar.dart', '''
 class D {}
 ''');
-    testFile = convertPath('/home/test/lib/src/test.dart');
+    testFile = convertPath('$testPackageLibPath/src/test.dart');
 
     await resolveTestCode('''
 import 'package:test/bar.dart';
@@ -55,10 +55,10 @@
   String get lintCode => LintNames.prefer_relative_imports;
 
   Future<void> test_relativeImport() async {
-    addSource('/home/test/lib/foo.dart', '''
+    addSource('$testPackageLibPath/foo.dart', '''
 class C {}
 ''');
-    testFile = convertPath('/home/test/lib/src/test.dart');
+    testFile = convertPath('$testPackageLibPath/src/test.dart');
     await resolveTestCode('''
 import 'package:test/foo.dart';
 C? c;
@@ -82,8 +82,8 @@
   }
 
   Future<void> test_relativeImportGarbledUri() async {
-    addSource('/home/test/lib/foo.dart', '');
-    testFile = convertPath('/home/test/lib/bar.dart');
+    addSource('$testPackageLibPath/foo.dart', '');
+    testFile = convertPath('$testPackageLibPath/bar.dart');
     await resolveTestCode('''
 import 'package:test/foo';
 ''');
@@ -96,10 +96,10 @@
   }
 
   Future<void> test_relativeImportRespectQuoteStyle() async {
-    addSource('/home/test/lib/foo.dart', '''
+    addSource('$testPackageLibPath/foo.dart', '''
 class C {}
 ''');
-    testFile = convertPath('/home/test/lib/bar.dart');
+    testFile = convertPath('$testPackageLibPath/bar.dart');
     await resolveTestCode('''
 import "package:test/foo.dart";
 C? c;
@@ -112,10 +112,10 @@
   }
 
   Future<void> test_relativeImportSameDirectory() async {
-    addSource('/home/test/lib/foo.dart', '''
+    addSource('$testPackageLibPath/foo.dart', '''
 class C {}
 ''');
-    testFile = convertPath('/home/test/lib/bar.dart');
+    testFile = convertPath('$testPackageLibPath/bar.dart');
     await resolveTestCode('''
 import 'package:test/foo.dart';
 C? c;
@@ -128,10 +128,10 @@
   }
 
   Future<void> test_relativeImportSubDirectory() async {
-    addSource('/home/test/lib/baz/foo.dart', '''
+    addSource('$testPackageLibPath/baz/foo.dart', '''
 class C {}
 ''');
-    testFile = convertPath('/home/test/lib/test.dart');
+    testFile = convertPath('$testPackageLibPath/test.dart');
     await resolveTestCode('''
 import 'package:test/baz/foo.dart';
 C? c;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
index b8df672..976bef5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
@@ -73,7 +73,7 @@
   }
 
   Future<void> test_inLibraryOfPrefix() async {
-    addSource('/home/test/lib/lib.dart', r'''
+    addSource('$testPackageLibPath/lib.dart', r'''
 class A {}
 ''');
 
@@ -92,7 +92,7 @@
 
 class Test {
 }
-''', target: '/home/test/lib/lib.dart');
+''', target: '$testPackageLibPath/lib.dart');
     expect(change.linkedEditGroups, hasLength(1));
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart
index 4831635..5a61202 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart
@@ -50,10 +50,10 @@
   }
 
   Future<void> test_importType() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {}
 ''');
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 import 'package:test/a.dart';
 
 class B {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
index 8b98fb5..96d0f22 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
@@ -41,7 +41,7 @@
   FixKind get kind => DartFixKind.CREATE_CONSTRUCTOR;
 
   Future<void> test_inLibrary_insteadOfSyntheticDefault() async {
-    var a = newFile('/home/test/lib/a.dart', content: '''
+    var a = newFile('$testPackageLibPath/a.dart', content: '''
 /// $_text200
 class A {}
 ''').path;
@@ -61,7 +61,7 @@
   }
 
   Future<void> test_inLibrary_named() async {
-    var a = newFile('/home/test/lib/a.dart', content: '''
+    var a = newFile('$testPackageLibPath/a.dart', content: '''
 /// $_text200
 class A {}
 ''').path;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
index 1e0b056..af26bc4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
@@ -131,7 +131,7 @@
   }
 
   Future<void> test_getter_qualified_instance_differentLibrary() async {
-    addSource('/home/test/lib/other.dart', '''
+    addSource('$testPackageLibPath/other.dart', '''
 /**
  * A comment to push the offset of the braces for the following class
  * declaration past the end of the content of the test file. Used to catch an
@@ -161,7 +161,7 @@
 class A {
   int test;
 }
-''', target: '/home/test/lib/other.dart');
+''', target: '$testPackageLibPath/other.dart');
   }
 
   Future<void> test_getter_qualified_instance_dynamicType() async {
@@ -317,11 +317,11 @@
   }
 
   Future<void> test_importType() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {}
 ''');
 
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 import 'package:test/a.dart';
 
 A getA() => null;
@@ -365,7 +365,7 @@
   }
 
   Future<void> test_inPart_imported() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 part of lib;
 class A {}
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart
index 988c679..f9e4644 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart
@@ -29,7 +29,7 @@
     var fileEdits = change.edits;
     expect(fileEdits, hasLength(1));
     var fileEdit = change.edits[0];
-    expect(fileEdit.file, convertPath('/home/test/lib/my_file.dart'));
+    expect(fileEdit.file, convertPath('$testPackageLibPath/my_file.dart'));
     expect(fileEdit.fileStamp, -1);
     expect(fileEdit.edits, hasLength(1));
     expect(
@@ -47,7 +47,7 @@
     var fileEdits = change.edits;
     expect(fileEdits, hasLength(1));
     var fileEdit = change.edits[0];
-    expect(fileEdit.file, convertPath('/home/test/lib/my_file.dart'));
+    expect(fileEdit.file, convertPath('$testPackageLibPath/my_file.dart'));
     expect(fileEdit.fileStamp, -1);
     expect(fileEdit.edits, hasLength(1));
     expect(
@@ -72,7 +72,7 @@
     var fileEdits = change.edits;
     expect(fileEdits, hasLength(1));
     var fileEdit = change.edits[0];
-    expect(fileEdit.file, convertPath('/home/test/lib/a/bb/my_lib.dart'));
+    expect(fileEdit.file, convertPath('$testPackageLibPath/a/bb/my_lib.dart'));
     expect(fileEdit.fileStamp, -1);
     expect(fileEdit.edits, hasLength(1));
     expect(
@@ -110,7 +110,7 @@
     var fileEdits = change.edits;
     expect(fileEdits, hasLength(1));
     var fileEdit = change.edits[0];
-    expect(fileEdit.file, convertPath('/home/test/lib/my_part.dart'));
+    expect(fileEdit.file, convertPath('$testPackageLibPath/my_part.dart'));
     expect(fileEdit.fileStamp, -1);
     expect(fileEdit.edits, hasLength(1));
     expect(fileEdit.edits[0].replacement, contains("part of 'test.dart';"));
@@ -125,7 +125,7 @@
     var fileEdits = change.edits;
     expect(fileEdits, hasLength(1));
     var fileEdit = change.edits[0];
-    expect(fileEdit.file, convertPath('/home/test/lib/foo/my_part.dart'));
+    expect(fileEdit.file, convertPath('$testPackageLibPath/foo/my_part.dart'));
     expect(fileEdit.fileStamp, -1);
     expect(fileEdit.edits, hasLength(1));
     expect(fileEdit.edits[0].replacement, contains("part of '../test.dart';"));
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
index 2d663fc..1018a76 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
@@ -259,10 +259,10 @@
   }
 
   Future<void> test_functionType_importType() async {
-    addSource('/home/test/lib/a.dart', r'''
+    addSource('$testPackageLibPath/a.dart', r'''
 class A {}
 ''');
-    addSource('/home/test/lib/b.dart', r'''
+    addSource('$testPackageLibPath/b.dart', r'''
 import 'package:test/a.dart';
 
 useFunction(int g(A a)) {}
@@ -348,7 +348,7 @@
   }
 
   Future<void> test_importType() async {
-    addSource('/home/test/lib/lib.dart', r'''
+    addSource('$testPackageLibPath/lib.dart', r'''
 library lib;
 import 'dart:async';
 Future getFuture() => null;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
index 7c382e6..7566168 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
@@ -249,7 +249,7 @@
   }
 
   Future<void> test_qualified_instance_differentLibrary() async {
-    addSource('/home/test/lib/other.dart', '''
+    addSource('$testPackageLibPath/other.dart', '''
 /**
  * A comment to push the offset of the braces for the following class
  * declaration past the end of the content of the test file. Used to catch an
@@ -279,7 +279,7 @@
 class A {
   int get test => null;
 }
-''', target: '/home/test/lib/other.dart');
+''', target: '$testPackageLibPath/other.dart');
   }
 
   Future<void> test_qualified_instance_dynamicType() async {
@@ -307,7 +307,7 @@
   }
 
   Future<void> test_qualified_instance_inPart_imported() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 part of lib;
 
 class A {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
index 185784b..dbfcc51 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
@@ -834,8 +834,8 @@
 }
 ''';
 
-    addSource('/home/test/lib/test2.dart', code2);
-    addSource('/home/test/lib/test3.dart', r'''
+    addSource('$testPackageLibPath/test2.dart', code2);
+    addSource('$testPackageLibPath/test3.dart', r'''
 library test3;
 class E {}
 ''');
@@ -855,11 +855,11 @@
 class D {
   void foo(bbb.E e) {}
 }
-''', target: '/home/test/lib/test2.dart');
+''', target: '$testPackageLibPath/test2.dart');
   }
 
   Future<void> test_parameterType_inTargetUnit() async {
-    addSource('/home/test/lib/test2.dart', r'''
+    addSource('$testPackageLibPath/test2.dart', r'''
 class D {
 }
 
@@ -880,7 +880,7 @@
 }
 
 class E {}
-''', target: '/home/test/lib/test2.dart');
+''', target: '$testPackageLibPath/test2.dart');
   }
 
   Future<void> test_static() async {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart
index b0871a1..fb68eca 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart
@@ -35,7 +35,7 @@
     var libCode = r'''
 class A {}
 ''';
-    addSource('/home/test/lib/lib.dart', libCode);
+    addSource('$testPackageLibPath/lib.dart', libCode);
     await resolveTestCode('''
 import 'lib.dart' as lib;
 
@@ -50,7 +50,7 @@
 
 mixin Test {
 }
-''', target: '/home/test/lib/lib.dart');
+''', target: '$testPackageLibPath/lib.dart');
     expect(change.linkedEditGroups, hasLength(1));
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
index 4534817..fea7674 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
@@ -245,7 +245,7 @@
   }
 
   Future<void> test_qualified_instance_differentLibrary() async {
-    addSource('/home/test/lib/other.dart', '''
+    addSource('$testPackageLibPath/other.dart', '''
 /**
  * A comment to push the offset of the braces for the following class
  * declaration past the end of the content of the test file. Used to catch an
@@ -274,7 +274,7 @@
 class A {
   set test(int test) {}
 }
-''', target: '/home/test/lib/other.dart');
+''', target: '$testPackageLibPath/other.dart');
   }
 
   Future<void> test_qualified_instance_dynamicType() async {
@@ -302,7 +302,7 @@
   }
 
   Future<void> test_qualified_instance_inPart_imported() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 part of lib;
 
 class A {}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test.dart
index cb280c7..82353b0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/data_driven_test.dart
@@ -1134,7 +1134,7 @@
     - kind: 'rename'
       newName: 'New'
 ''');
-    addSource('/home/test/lib/test.config', '''
+    addSource('$testPackageLibPath/test.config', '''
 'Rename to New':
   bulkApply: true
 ''');
@@ -1169,7 +1169,9 @@
 import '$importUri';
 void f(Old p) {}
 ''');
-    await assertNoFix();
+    await assertHasFix('''
+void f(Old p) {}
+''');
   }
 }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/incompatible_element_kind_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/incompatible_element_kind_test.dart
new file mode 100644
index 0000000..4561ddd
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/incompatible_element_kind_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(IncompatibleElementKindTest);
+  });
+}
+
+@reflectiveTest
+class IncompatibleElementKindTest extends AbstractTransformSetParserTest {
+  void test_integer() {
+    assertErrors('''
+version: 1
+transforms:
+- title: 'Replace'
+  date: 2021-11-30
+  element:
+    uris: ['test.dart']
+    method: 'm'
+    inClass: 'C'
+  changes:
+    - kind: 'replacedBy'
+      newElement:
+        uris: ['test.dart']
+        variable: 'v'
+''', [
+      error(TransformSetErrorCode.incompatibleElementKind, 191, 42),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_change_for_kind_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_change_for_kind_test.dart
new file mode 100644
index 0000000..ee118e9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_change_for_kind_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidChangeForKindTest);
+  });
+}
+
+@reflectiveTest
+class InvalidChangeForKindTest extends AbstractTransformSetParserTest {
+  void test_integer() {
+    assertErrors('''
+version: 1
+transforms:
+- title: 'Replace'
+  date: 2021-11-30
+  element:
+    uris: ['test.dart']
+    class: 'C'
+  changes:
+    - kind: 'replacedBy'
+      newElement:
+        uris: ['test.dart']
+        class: 'D'
+''', [
+      error(TransformSetErrorCode.invalidChangeForKind, 173, 39),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
index bb2464ae..375c983 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/test_all.dart
@@ -6,6 +6,8 @@
 
 import 'conflicting_key_test.dart' as conflicting_key;
 import 'expected_primary_test.dart' as expected_primary;
+import 'incompatible_element_kind_test.dart' as incompatible_element_kind;
+import 'invalid_change_for_kind_test.dart' as invalid_change_for_kind;
 import 'invalid_character_test.dart' as invalid_character;
 import 'invalid_key_test.dart' as invalid_key;
 import 'invalid_parameter_style_test.dart' as invalid_parameter_style;
@@ -21,6 +23,7 @@
 import 'unexpected_token_test.dart' as unexpected_token;
 import 'unknown_accessor_test.dart' as unknown_accessor;
 import 'unsupported_key_test.dart' as unsupported_key;
+import 'unsupported_uri_change_test.dart' as unsupported_uri_change;
 import 'unsupported_version_test.dart' as unsupported_version;
 import 'wrong_token_test.dart' as wrong_token;
 import 'yaml_syntax_error_test.dart' as yaml_syntax_error;
@@ -29,6 +32,8 @@
   defineReflectiveSuite(() {
     conflicting_key.main();
     expected_primary.main();
+    incompatible_element_kind.main();
+    invalid_change_for_kind.main();
     invalid_character.main();
     invalid_key.main();
     invalid_parameter_style.main();
@@ -44,6 +49,7 @@
     unexpected_token.main();
     unknown_accessor.main();
     unsupported_key.main();
+    unsupported_uri_change.main();
     unsupported_version.main();
     wrong_token.main();
     yaml_syntax_error.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_uri_change_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_uri_change_test.dart
new file mode 100644
index 0000000..ecc493a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/unsupported_uri_change_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../transform_set_parser_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnsupportedUriChangeTest);
+  });
+}
+
+@reflectiveTest
+class UnsupportedUriChangeTest extends AbstractTransformSetParserTest {
+  void test_integer() {
+    assertErrors('''
+version: 1
+transforms:
+- title: 'Replace'
+  date: 2021-11-30
+  element:
+    uris: ['test.dart']
+    function: 'f'
+  changes:
+    - kind: 'replacedBy'
+      newElement:
+        uris: ['other.dart']
+        function: 'g'
+''', [
+      error(TransformSetErrorCode.unsupportedUriChange, 182, 14),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
index e9e0363..16ec4ae 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart
@@ -41,8 +41,11 @@
 class ElementMatcherComponentAndKindTest extends AbstractElementMatcherTest {
   /// The kinds that are expected where a getter or setter is allowed.
   static List<ElementKind> accessorKinds = [
+    ElementKind.constantKind,
     ElementKind.fieldKind,
+    ElementKind.functionKind, // tear-off
     ElementKind.getterKind,
+    ElementKind.methodKind, // tear-off
     ElementKind.setterKind,
   ];
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/replaced_by_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/replaced_by_test.dart
new file mode 100644
index 0000000..03d89fe
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/replaced_by_test.dart
@@ -0,0 +1,1069 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/element_descriptor.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/replaced_by.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'data_driven_test_support.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplacedByTest);
+  });
+}
+
+@reflectiveTest
+class ReplacedByTest extends DataDrivenFixProcessorTest {
+  Future<void> test_defaultConstructor_defaultConstructor() async {
+    await _assertReplacement(
+      _Element.defaultConstructor(isDeprecated: true, isOld: true),
+      _Element.defaultConstructor(),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_defaultConstructor_defaultConstructor_prefixed() async {
+    await _assertReplacement(
+      _Element.defaultConstructor(isDeprecated: true, isOld: true),
+      _Element.defaultConstructor(),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_defaultConstructor_namedConstructor() async {
+    await _assertReplacement(
+      _Element.defaultConstructor(isDeprecated: true, isOld: true),
+      _Element.namedConstructor(),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_defaultConstructor_namedConstructor_prefixed() async {
+    await _assertReplacement(
+      _Element.defaultConstructor(isDeprecated: true, isOld: true),
+      _Element.namedConstructor(),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_enumConstant_enumConstant() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.constant(),
+    );
+  }
+
+  Future<void> test_enumConstant_enumConstant_prefixed() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.constant(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_enumConstant_staticField() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+    );
+  }
+
+  Future<void> test_enumConstant_staticField_prefixed() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_enumConstant_staticGetter() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.getter(isStatic: true),
+    );
+  }
+
+  Future<void> test_enumConstant_staticGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.getter(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_enumConstant_topLevelGetter() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.topLevelGetter(),
+    );
+  }
+
+  Future<void> test_enumConstant_topLevelGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.topLevelGetter(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_enumConstant_topLevelVariable() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+    );
+  }
+
+  Future<void> test_enumConstant_topLevelVariable_prefixed() async {
+    await _assertReplacement(
+      _Element.constant(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_function_function_invocation() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.topLevelFunction(),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_function_function_invocation_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.topLevelFunction(),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_function_function_tearoff() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.topLevelFunction(),
+    );
+  }
+
+  Future<void> test_function_function_tearoff_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.topLevelFunction(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_function_staticMethod_invocation() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.method(isStatic: true),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_function_staticMethod_invocation_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.method(isStatic: true),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_function_staticMethod_tearoff() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.method(isStatic: true),
+    );
+  }
+
+  Future<void> test_function_staticMethod_tearoff_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelFunction(isDeprecated: true, isOld: true),
+      _Element.method(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_namedConstructor_defaultConstructor() async {
+    await _assertReplacement(
+      _Element.namedConstructor(isDeprecated: true, isOld: true),
+      _Element.defaultConstructor(),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_namedConstructor_defaultConstructor_prefixed() async {
+    await _assertReplacement(
+      _Element.namedConstructor(isDeprecated: true, isOld: true),
+      _Element.defaultConstructor(),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_namedConstructor_namedConstructor() async {
+    await _assertReplacement(
+      _Element.namedConstructor(isDeprecated: true, isOld: true),
+      _Element.namedConstructor(),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_namedConstructor_namedConstructor_prefixed() async {
+    await _assertReplacement(
+      _Element.namedConstructor(isDeprecated: true, isOld: true),
+      _Element.namedConstructor(),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticField_enumConstant() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.constant(),
+    );
+  }
+
+  Future<void> test_staticField_enumConstant_prefixed() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.constant(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticField_staticField() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.field(isStatic: true),
+    );
+  }
+
+  Future<void> test_staticField_staticField_prefixed() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.field(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticField_staticGetter() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.getter(isStatic: true),
+    );
+  }
+
+  Future<void> test_staticField_staticGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.getter(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticField_staticSetter() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_staticField_staticSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticField_topLevelGetter() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelGetter(),
+    );
+  }
+
+  Future<void> test_staticField_topLevelGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelGetter(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticField_topLevelSetter() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_staticField_topLevelSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticField_topLevelVariable() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelVariable(),
+    );
+  }
+
+  Future<void> test_staticField_topLevelVariable_prefixed() async {
+    await _assertReplacement(
+      _Element.field(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelVariable(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticGetter_enumConstant() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.constant(),
+    );
+  }
+
+  Future<void> test_staticGetter_enumConstant_prefixed() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.constant(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticGetter_staticField() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.field(isStatic: true),
+    );
+  }
+
+  Future<void> test_staticGetter_staticField_prefixed() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.field(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticGetter_staticGetter() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.getter(isStatic: true),
+    );
+  }
+
+  Future<void> test_staticGetter_staticGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.getter(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticGetter_topLevelGetter() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelGetter(),
+    );
+  }
+
+  Future<void> test_staticGetter_topLevelGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelGetter(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticGetter_topLevelVariable() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelVariable(),
+    );
+  }
+
+  Future<void> test_staticGetter_topLevelVariable_prefixed() async {
+    await _assertReplacement(
+      _Element.getter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelVariable(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticMethod_function_invocation() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelFunction(),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_staticMethod_function_invocation_prefixed() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelFunction(),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticMethod_function_tearoff() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelFunction(),
+    );
+  }
+
+  Future<void> test_staticMethod_function_tearoff_prefixed() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelFunction(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticMethod_staticMethod_invocation() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.method(isStatic: true),
+      isInvocation: true,
+    );
+  }
+
+  Future<void> test_staticMethod_staticMethod_invocation_prefixed() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.method(isStatic: true),
+      isInvocation: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticMethod_staticMethod_tearoff() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.method(isStatic: true),
+    );
+  }
+
+  Future<void> test_staticMethod_staticMethod_tearoff_prefixed() async {
+    await _assertReplacement(
+      _Element.method(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.method(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticSetter_staticField() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.field(isStatic: true),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_staticSetter_staticField_prefixed() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.field(isStatic: true),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticSetter_staticSetter() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_staticSetter_staticSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticSetter_topLevelSetter() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_staticSetter_topLevelSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_staticSetter_topLevelVariable() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelVariable(),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_staticSetter_topLevelVariable_prefixed() async {
+    await _assertReplacement(
+      _Element.setter(isDeprecated: true, isOld: true, isStatic: true),
+      _Element.topLevelVariable(),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelGetter_enumConstant() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.constant(),
+    );
+  }
+
+  Future<void> test_topLevelGetter_enumConstant_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.constant(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelGetter_staticField() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+    );
+  }
+
+  Future<void> test_topLevelGetter_staticField_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelGetter_staticGetter() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.getter(isStatic: true),
+    );
+  }
+
+  Future<void> test_topLevelGetter_staticGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.getter(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelGetter_topLevelGetter() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.topLevelGetter(),
+    );
+  }
+
+  Future<void> test_topLevelGetter_topLevelGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.topLevelGetter(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelGetter_topLevelVariable() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+    );
+  }
+
+  Future<void> test_topLevelGetter_topLevelVariable_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelGetter(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_staticField() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_staticField_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_staticSetter() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_staticSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_topLevelSetter() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_topLevelSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_topLevelVariable() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_topLevelSetter_topLevelVariable_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelSetter(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_enumConstant() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.constant(),
+    );
+  }
+
+  Future<void> test_topLevelVariable_enumConstant_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.constant(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_staticField() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+    );
+  }
+
+  Future<void> test_topLevelVariable_staticField_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.field(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_staticGetter() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.getter(isStatic: true),
+    );
+  }
+
+  Future<void> test_topLevelVariable_staticGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.getter(isStatic: true),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_staticSetter() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_staticSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.setter(isStatic: true),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_topLevelGetter() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.topLevelGetter(),
+    );
+  }
+
+  Future<void> test_topLevelVariable_topLevelGetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.topLevelGetter(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_topLevelSetter() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_topLevelSetter_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.topLevelSetter(),
+      isAssignment: true,
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> test_topLevelVariable_topLevelVariable() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+    );
+  }
+
+  Future<void> test_topLevelVariable_topLevelVariable_prefixed() async {
+    await _assertReplacement(
+      _Element.topLevelVariable(isDeprecated: true, isOld: true),
+      _Element.topLevelVariable(),
+      isPrefixed: true,
+    );
+  }
+
+  Future<void> _assertReplacement(_Element oldElement, _Element newElement,
+      {bool isAssignment = false,
+      bool isInvocation = false,
+      bool isPrefixed = false}) async {
+    assert(!(isAssignment && isInvocation));
+    setPackageContent('''
+${oldElement.declaration}
+${newElement.declaration}
+''');
+    setPackageData(_replacedBy(oldElement.kind, oldElement.components,
+        newElement.kind, newElement.components));
+    var prefixDeclaration = isPrefixed ? ' as p' : '';
+    var prefixReference = isPrefixed ? 'p.' : '';
+    var invocation = isInvocation ? '()' : '';
+    if (isAssignment) {
+      await resolveTestCode('''
+import '$importUri'$prefixDeclaration;
+
+void g() {
+  $prefixReference${oldElement.reference} = 0;
+}
+''');
+      await assertHasFix('''
+import '$importUri'$prefixDeclaration;
+
+void g() {
+  $prefixReference${newElement.reference} = 0;
+}
+''');
+      return;
+    }
+    await resolveTestCode('''
+import '$importUri'$prefixDeclaration;
+
+var x = $prefixReference${oldElement.reference}$invocation;
+''');
+    await assertHasFix('''
+import '$importUri'$prefixDeclaration;
+
+var x = $prefixReference${newElement.reference}$invocation;
+''');
+  }
+
+  Transform _replacedBy(ElementKind oldKind, List<String> oldComponents,
+      ElementKind newKind, List<String> newComponents) {
+    var uris = [Uri.parse(importUri)];
+    var oldElement = ElementDescriptor(
+        libraryUris: uris, kind: oldKind, components: oldComponents);
+    var newElement2 = ElementDescriptor(
+        libraryUris: uris, kind: newKind, components: newComponents);
+    return Transform(
+        title: 'title',
+        date: DateTime.now(),
+        element: oldElement,
+        bulkApply: true,
+        changesSelector: UnconditionalChangesSelector([
+          ReplacedBy(newElement: newElement2),
+        ]));
+  }
+}
+
+class _Element {
+  final ElementKind kind;
+  final List<String> components;
+  final String declaration;
+
+  _Element(this.kind, this.components, this.declaration);
+
+  // ignore: unused_element
+  factory _Element.class_({bool isDeprecated = false, bool isOld = false}) {
+    var name = isOld ? 'C_old' : 'C_new';
+    var annotation = _annotation(isDeprecated: isDeprecated, isTopLevel: true);
+    return _Element(
+      ElementKind.classKind,
+      [name],
+      '''
+${annotation}class $name {}''',
+    );
+  }
+
+  factory _Element.constant({bool isDeprecated = false, bool isOld = false}) {
+    var enumName = isOld ? 'E_old' : 'E_new';
+    var constantName = isOld ? 'c_old' : 'c_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    return _Element(
+      ElementKind.constantKind,
+      [constantName, enumName],
+      '''
+enum $enumName {
+  $annotation$constantName
+}''',
+    );
+  }
+
+  factory _Element.defaultConstructor(
+      {bool isDeprecated = false, bool isOld = false}) {
+    var className = isOld ? 'C_old' : 'C_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    return _Element(
+      ElementKind.constructorKind,
+      ['', className],
+      '''
+class $className {
+  $annotation$className();
+}''',
+    );
+  }
+
+  // ignore: unused_element
+  factory _Element.enum_({bool isDeprecated = false, bool isOld = false}) {
+    var enumName = isOld ? 'E_old' : 'E_new';
+    var constantName = isOld ? 'c_old' : 'c_new';
+    var annotation = _annotation(isDeprecated: isDeprecated, isTopLevel: true);
+    return _Element(
+      ElementKind.enumKind,
+      [enumName],
+      '''
+${annotation}enum $enumName { $constantName }''',
+    );
+  }
+
+  factory _Element.field(
+      {bool isDeprecated = false, bool isOld = false, bool isStatic = false}) {
+    var fieldName = isOld ? 'sf_old' : 'sf_new';
+    var className = isOld ? 'C_old' : 'C_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    var keyword = isStatic ? 'static ' : '';
+    return _Element(
+      ElementKind.fieldKind,
+      [fieldName, className],
+      '''
+class $className {
+  $annotation${keyword}int $fieldName = 0;
+}''',
+    );
+  }
+
+  factory _Element.getter(
+      {bool isDeprecated = false, bool isOld = false, bool isStatic = false}) {
+    var getterName = isOld ? 'g_old' : 'g_new';
+    var className = isOld ? 'C_old' : 'C_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    var keyword = isStatic ? 'static ' : '';
+    return _Element(
+      ElementKind.getterKind,
+      [getterName, className],
+      '''
+class $className {
+  $annotation${keyword}int get $getterName => 0;
+}''',
+    );
+  }
+
+  factory _Element.method(
+      {bool isDeprecated = false, bool isOld = false, bool isStatic = false}) {
+    var methodName = isOld ? 'm_old' : 'm_new';
+    var className = isOld ? 'C_old' : 'C_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    var keyword = isStatic ? 'static ' : '';
+    return _Element(
+      ElementKind.methodKind,
+      [methodName, className],
+      '''
+class $className {
+  $annotation${keyword}int $methodName() => 0;
+}''',
+    );
+  }
+
+  factory _Element.namedConstructor(
+      {bool isDeprecated = false, bool isOld = false}) {
+    var constructorName = isOld ? 'c_old' : 'c_new';
+    var className = isOld ? 'C_old' : 'C_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    return _Element(
+      ElementKind.constructorKind,
+      [constructorName, className],
+      '''
+class $className {
+  $annotation$className.$constructorName();
+}''',
+    );
+  }
+
+  factory _Element.setter(
+      {bool isDeprecated = false, bool isOld = false, bool isStatic = false}) {
+    var setterName = isOld ? 's_old' : 's_new';
+    var className = isOld ? 'C_old' : 'C_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    var keyword = isStatic ? 'static ' : '';
+    return _Element(
+      ElementKind.setterKind,
+      [setterName, className],
+      '''
+class $className {
+  $annotation${keyword}set $setterName(int v) {}
+}''',
+    );
+  }
+
+  factory _Element.topLevelFunction(
+      {bool isDeprecated = false, bool isOld = false}) {
+    var name = isOld ? 'f_old' : 'f_new';
+    var annotation = _annotation(isDeprecated: isDeprecated, isTopLevel: true);
+    return _Element(
+      ElementKind.functionKind,
+      [name],
+      '''
+${annotation}int $name() => 0;''',
+    );
+  }
+
+  factory _Element.topLevelGetter(
+      {bool isDeprecated = false, bool isOld = false}) {
+    var getterName = isOld ? 'g_old' : 'g_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    return _Element(
+      ElementKind.getterKind,
+      [getterName],
+      '''
+${annotation}int get $getterName => 0;''',
+    );
+  }
+
+  factory _Element.topLevelSetter(
+      {bool isDeprecated = false, bool isOld = false}) {
+    var setterName = isOld ? 's_old' : 's_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    return _Element(
+      ElementKind.setterKind,
+      [setterName],
+      '''
+${annotation}set $setterName(int v) {}''',
+    );
+  }
+
+  factory _Element.topLevelVariable(
+      {bool isDeprecated = false, bool isOld = false}) {
+    var name = isOld ? 'v_old' : 'v_new';
+    var annotation = _annotation(isDeprecated: isDeprecated, isTopLevel: true);
+    return _Element(
+      ElementKind.variableKind,
+      [name],
+      '''
+${annotation}int $name = 0;''',
+    );
+  }
+
+  // ignore: unused_element
+  factory _Element.typedef({bool isDeprecated = false, bool isOld = false}) {
+    var name = isOld ? 'T_old' : 'T_new';
+    var annotation = _annotation(isDeprecated: isDeprecated);
+    return _Element(
+      ElementKind.typedefKind,
+      [name],
+      '''
+${annotation}typedef $name = int Function();''',
+    );
+  }
+
+  String get reference {
+    if (components[0].isEmpty) {
+      return components[1];
+    }
+    return components.reversed.join('.');
+  }
+
+  static String _annotation(
+      {required bool isDeprecated, bool isTopLevel = false}) {
+    var indent = isTopLevel ? '' : '  ';
+    return isDeprecated ? '@deprecated\n$indent' : '';
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
index 64cffa2..544f27c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/test_all.dart
@@ -15,6 +15,7 @@
 import 'modify_parameters_test.dart' as modify_parameters;
 import 'rename_parameter_test.dart' as rename_parameter;
 import 'rename_test.dart' as rename;
+import 'replaced_by_test.dart' as replaced_by;
 import 'sdk_fix_test.dart' as sdk_fix;
 import 'transform_override_set_parser_test.dart'
     as transform_override_set_parser;
@@ -34,6 +35,7 @@
     modify_parameters.main();
     rename_parameter.main();
     rename.main();
+    replaced_by.main();
     sdk_fix.main();
     transform_override_set_parser.main();
     transform_set_manager.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_test.dart
index 42d762b..4205071 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_manager_test.dart
@@ -33,7 +33,7 @@
 
     addSource('/home/test/pubspec.yaml', '');
 
-    var testFile = convertPath('/home/test/lib/test.dart');
+    var testFile = convertPath('$testPackageLibPath/test.dart');
     addSource(testFile, '');
     var result = await session.getResolvedLibraryValid(testFile);
     var sets = manager.forLibrary(result.element);
@@ -44,7 +44,7 @@
     // addTestPackageDependency('p1', '/.pub-cache/p1');
     // addTestPackageDependency('p2', '/.pub-cache/p2');
     addSource('/home/test/pubspec.yaml', '');
-    var testFile = convertPath('/home/test/lib/test.dart');
+    var testFile = convertPath('$testPackageLibPath/test.dart');
     addSource(testFile, '');
     var result = await session.getResolvedLibraryValid(testFile);
     var sets = manager.forLibrary(result.element);
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
index 08c69d5..51421b4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
@@ -7,11 +7,13 @@
 import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/changes_selector.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/code_template.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/element_kind.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/element_matcher.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/expression.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/modify_parameters.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/parameter_reference.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/replaced_by.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/value_generator.dart';
@@ -673,6 +675,34 @@
     expect(rename.newName, 'B');
   }
 
+  void test_replacedBy() {
+    assertNoErrors('''
+version: 1
+transforms:
+- title: 'Replace'
+  date: 2021-11-30
+  element:
+    uris: ['test.dart']
+    function: 'f'
+  changes:
+    - kind: 'replacedBy'
+      newElement:
+        uris: ['test.dart']
+        method: 'm'
+        inClass: 'C'
+''');
+    var transforms = _transforms('f');
+    expect(transforms, hasLength(1));
+    var transform = transforms[0];
+    expect(transform.title, 'Replace');
+    var changes = _changes(transform);
+    expect(changes, hasLength(1));
+    var change = changes[0] as ReplacedBy;
+    var newElement = change.newElement;
+    expect(newElement.kind, ElementKind.methodKind);
+    expect(newElement.components, ['m', 'C']);
+  }
+
   void test_requiredIf() {
     assertNoErrors('''
 version: 1
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index 00f2730..50411cb 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -87,9 +87,11 @@
   /// neither [assertHasFix] nor [assertHasFixAllFix] has been invoked.
   late String resultCode;
 
-  /// Return a list of the experiments that are to be enabled for tests in this
-  /// class, or `null` if there are no experiments that should be enabled.
-  List<String>? get experiments => null;
+  /// The processor used to compute bulk fixes.
+  late BulkFixProcessor processor;
+
+  @override
+  List<String> get experiments => const [];
 
   /// Return the lint code being tested.
   String? get lintCode => null;
@@ -140,7 +142,7 @@
 
   /// Returns the source change for computed fixes in the specified [testUnit].
   Future<SourceChange> _computeSourceChange() async {
-    var processor = await computeFixes();
+    processor = await computeFixes();
     return processor.builder.sourceChange;
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
index 9630237..8779367 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
@@ -39,7 +39,7 @@
   }
 
   Future<void> test_withExtension() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class C {}
 extension E on int {
   static String m() => '';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index 5173579..a677f3a 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -24,7 +24,7 @@
   FixKind get kind => DartFixKind.IMPORT_LIBRARY_PROJECT1;
 
   Future<void> test_alreadyImported_package() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class A {}
 class B {}
 ''');
@@ -40,14 +40,14 @@
   }
 
   Future<void> test_extension_notImported_field_onThisType_fromClass() async {
-    addUnimportedFile('/home/test/lib/lib2.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib2.dart', '''
 import 'package:test/lib1.dart';
 
 extension E on C {
   int m() => 0;
 }
 ''');
-    addSource('/home/test/lib/lib1.dart', '''
+    addSource('$testPackageLibPath/lib1.dart', '''
 class C {}
 ''');
     await resolveTestCode('''
@@ -68,7 +68,7 @@
   }
 
   Future<void> test_extension_notImported_getter() async {
-    addUnimportedFile('/home/test/lib/lib.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib.dart', '''
 extension E on String {
   int get m => 0;
 }
@@ -88,7 +88,7 @@
   }
 
   Future<void> test_extension_notImported_method() async {
-    addUnimportedFile('/home/test/lib/lib.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib.dart', '''
 extension E on String {
   void m() {}
 }
@@ -108,7 +108,7 @@
   }
 
   Future<void> test_extension_notImported_method_extendsGeneric() async {
-    addUnimportedFile('/home/test/lib/lib.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib.dart', '''
 import 'package:test/lib1.dart';
 
 extension E<T extends num> on List<T> {
@@ -130,14 +130,14 @@
   }
 
   Future<void> test_extension_notImported_method_onThisType_fromClass() async {
-    addUnimportedFile('/home/test/lib/lib2.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib2.dart', '''
 import 'package:test/lib1.dart';
 
 extension E on C {
   void m() {}
 }
 ''');
-    addSource('/home/test/lib/lib1.dart', '''
+    addSource('$testPackageLibPath/lib1.dart', '''
 class C {}
 ''');
     await resolveTestCode('''
@@ -163,14 +163,14 @@
 
   Future<void>
       test_extension_notImported_method_onThisType_fromExtension() async {
-    addUnimportedFile('/home/test/lib/lib2.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib2.dart', '''
 import 'package:test/lib1.dart';
 
 extension E on C {
   void m() {}
 }
 ''');
-    addSource('/home/test/lib/lib1.dart', '''
+    addSource('$testPackageLibPath/lib1.dart', '''
 class C {}
 ''');
     await resolveTestCode('''
@@ -195,7 +195,7 @@
   }
 
   Future<void> test_extension_notImported_operator() async {
-    addUnimportedFile('/home/test/lib/lib.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib.dart', '''
 extension E on String {
   String operator -(String other) => this;
 }
@@ -215,7 +215,7 @@
   }
 
   Future<void> test_extension_notImported_setter() async {
-    addUnimportedFile('/home/test/lib/lib.dart', '''
+    addUnimportedFile('$testPackageLibPath/lib.dart', '''
 extension E on String {
   set m(int v) {}
 }
@@ -235,7 +235,7 @@
   }
 
   Future<void> test_invalidUri_interpolation() async {
-    addSource('/home/test/lib/lib.dart', r'''
+    addSource('$testPackageLibPath/lib.dart', r'''
 class Test {
   const Test();
 }
@@ -355,7 +355,7 @@
   }
 
   Future<void> test_relativeDirective() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class Foo {}
 ''');
     await resolveTestCode('''
@@ -377,7 +377,7 @@
   }
 
   Future<void> test_relativeDirective_downOneDirectory() async {
-    addSource('/home/test/lib/dir/a.dart', '''
+    addSource('$testPackageLibPath/dir/a.dart', '''
 class Foo {}
 ''');
     await resolveTestCode('''
@@ -394,7 +394,7 @@
 
   Future<void> test_relativeDirective_preferRelativeImports() async {
     createAnalysisOptionsFile(lints: [LintNames.prefer_relative_imports]);
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class Foo {}
 ''');
     await resolveTestCode('''
@@ -416,10 +416,10 @@
   }
 
   Future<void> test_relativeDirective_upOneDirectory() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class Foo {}
 ''');
-    testFile = convertPath('/home/test/lib/dir/test.dart');
+    testFile = convertPath('$testPackageLibPath/dir/test.dart');
     await resolveTestCode('''
 main() { new Foo(); }
 ''');
@@ -433,7 +433,7 @@
   }
 
   Future<void> test_withClass_annotation() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 library lib;
 class Test {
   const Test(int p);
@@ -454,7 +454,7 @@
   }
 
   Future<void> test_withClass_catchClause() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class Test {}
 ''');
     await resolveTestCode('''
@@ -480,11 +480,11 @@
   }
 
   Future<void> test_withClass_hasOtherLibraryWithPrefix() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 library a;
 class One {}
 ''');
-    addSource('/home/test/lib/b.dart', '''
+    addSource('$testPackageLibPath/b.dart', '''
 library b;
 class One {}
 class Two {}
@@ -573,7 +573,7 @@
   }
 
   Future<void> test_withClass_instanceCreation_const() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class Test {
   const Test();
 }
@@ -593,7 +593,7 @@
   }
 
   Future<void> test_withClass_instanceCreation_const_namedConstructor() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class Test {
   const Test.named();
 }
@@ -613,7 +613,7 @@
   }
 
   Future<void> test_withClass_instanceCreation_implicit() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class Test {
   const Test();
 }
@@ -633,7 +633,7 @@
   }
 
   Future<void> test_withClass_instanceCreation_new() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class Test {
   const Test();
 }
@@ -653,7 +653,7 @@
   }
 
   Future<void> test_withClass_instanceCreation_new_namedConstructor() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class Test {
   Test.named();
 }
@@ -673,7 +673,7 @@
   }
 
   Future<void> test_withFunction() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 library lib;
 myFunction() {}
 ''');
@@ -692,7 +692,7 @@
   }
 
   Future<void> test_withFunction_functionTopLevelVariable() async {
-    addSource('/home/test/lib/lib.dart', 'var myFunction = () {};');
+    addSource('$testPackageLibPath/lib.dart', 'var myFunction = () {};');
     await resolveTestCode('''
 main() {
   myFunction();
@@ -708,7 +708,7 @@
   }
 
   Future<void> test_withFunction_functionTopLevelVariableIdentifier() async {
-    addSource('/home/test/lib/lib.dart', 'var myFunction = () {};');
+    addSource('$testPackageLibPath/lib.dart', 'var myFunction = () {};');
     await resolveTestCode('''
 main() {
   myFunction;
@@ -724,7 +724,7 @@
   }
 
   Future<void> test_withFunction_identifier() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 library lib;
 myFunction() {}
 ''');
@@ -744,7 +744,7 @@
 
   @failingTest
   Future<void> test_withFunction_nonFunctionType() async {
-    addSource('/home/test/lib/lib.dart', 'int zero = 0;');
+    addSource('$testPackageLibPath/lib.dart', 'int zero = 0;');
     await resolveTestCode('''
 main() {
   zero();
@@ -754,7 +754,7 @@
   }
 
   Future<void> test_withFunction_unresolvedMethod() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 library lib;
 myFunction() {}
 ''');
@@ -777,7 +777,7 @@
   }
 
   Future<void> test_withFunctionTypeAlias() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 library lib;
 typedef MyFunction();
 ''');
@@ -798,7 +798,7 @@
   }
 
   Future<void> test_withMixin() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 mixin Test {}
 ''');
     await resolveTestCode('''
@@ -812,7 +812,7 @@
   }
 
   Future<void> test_withTopLevelVariable() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 library lib;
 int MY_VAR = 42;
 ''');
@@ -955,7 +955,7 @@
   }
 
   Future<void> test_inLibSrc_thisContextRoot() async {
-    addSource('/home/test/lib/src/lib.dart', 'class Test {}');
+    addSource('$testPackageLibPath/src/lib.dart', 'class Test {}');
     await resolveTestCode('''
 main() {
   Test t;
@@ -973,7 +973,7 @@
   }
 
   Future<void> test_inLibSrc_thisContextRoot_extension() async {
-    addSource('/home/test/lib/src/lib.dart', '''
+    addSource('$testPackageLibPath/src/lib.dart', '''
 extension E on int {
   static String m() => '';
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart
index 05ba8ce..7c57f67 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart
@@ -20,7 +20,7 @@
   FixKind get kind => DartFixKind.IMPORT_LIBRARY_SHOW;
 
   Future<void> test_extension_notShown_getter() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class C {}
 extension E on String {
   int get m => 0;
@@ -43,7 +43,7 @@
   }
 
   Future<void> test_extension_notShown_method() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class C {}
 extension E on String {
   void m() {}
@@ -66,7 +66,7 @@
   }
 
   Future<void> test_extension_notShown_operator() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class C {}
 extension E on String {
   String operator -(String other) => this;
@@ -89,7 +89,7 @@
   }
 
   Future<void> test_extension_notShown_setter() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class C {}
 extension E on String {
   set m(int v) {}
@@ -112,7 +112,7 @@
   }
 
   Future<void> test_override_samePackage() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class A {}
 extension E on int {
   String m() => '';
@@ -133,7 +133,7 @@
   }
 
   Future<void> test_package() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class A {}
 class B {}
 ''');
@@ -175,7 +175,7 @@
   }
 
   Future<void> test_static_samePackage() async {
-    addSource('/home/test/lib/lib.dart', '''
+    addSource('$testPackageLibPath/lib.dart', '''
 class A {}
 extension E on int {
   static String m() => '';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
index 4a54aa0..8d5d664 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
@@ -42,12 +42,12 @@
   }
 
   Future<void> test_organizePathImports() async {
-    newFile('/home/test/lib/a.dart', content: '''
+    newFile('$testPackageLibPath/a.dart', content: '''
 class A {
   static void m() {}
 }
 ''');
-    newFile('/home/test/lib/a/b.dart', content: '''
+    newFile('$testPackageLibPath/a/b.dart', content: '''
 class B {
   static void m() {}
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart
index 5c92c08..6d3cf03 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart
@@ -43,7 +43,7 @@
   }
 
   Future<void> test_class_imported() async {
-    newFile('/home/test/lib/a.dart', content: '''
+    newFile('$testPackageLibPath/a.dart', content: '''
 class A {
   static void m() {}
 }
@@ -60,7 +60,7 @@
   }
 
   Future<void> test_class_importedWithPrefix() async {
-    newFile('/home/test/lib/a.dart', content: '''
+    newFile('$testPackageLibPath/a.dart', content: '''
 class A {
   static void m() {}
 }
@@ -104,12 +104,12 @@
   }
 
   Future<void> test_class_notImported() async {
-    newFile('/home/test/lib/a.dart', content: '''
+    newFile('$testPackageLibPath/a.dart', content: '''
 class A {
   static void m() {}
 }
 ''');
-    newFile('/home/test/lib/b.dart', content: '''
+    newFile('$testPackageLibPath/b.dart', content: '''
 import 'a.dart';
 class B extends A {}
 ''');
@@ -148,7 +148,7 @@
   }
 
   Future<void> test_extension_imported() async {
-    newFile('/home/test/lib/a.dart', content: '''
+    newFile('$testPackageLibPath/a.dart', content: '''
 class A {
   static void m() {}
 }
@@ -165,7 +165,7 @@
   }
 
   Future<void> test_extension_importedWithPrefix() async {
-    newFile('/home/test/lib/a.dart', content: '''
+    newFile('$testPackageLibPath/a.dart', content: '''
 class A {
   static void m() {}
 }
@@ -209,12 +209,12 @@
   }
 
   Future<void> test_extension_notImported() async {
-    newFile('/home/test/lib/a.dart', content: '''
+    newFile('$testPackageLibPath/a.dart', content: '''
 class A {
   static void m() {}
 }
 ''');
-    newFile('/home/test/lib/b.dart', content: '''
+    newFile('$testPackageLibPath/b.dart', content: '''
 import 'a.dart';
 class B extends A {}
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
index 736da8c..9d27944 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_argument_test.dart
@@ -21,7 +21,7 @@
   @override
   String get lintCode => LintNames.avoid_redundant_argument_values;
 
-  Future<void> test_singleFile() async {
+  Future<void> test_independentInvocations() async {
     await resolveTestCode('''
 void f({bool valWithDefault = true, bool val}) {}
 void f2({bool valWithDefault = true, bool val}) {}
@@ -41,6 +41,45 @@
 }
 ''');
   }
+
+  Future<void> test_multipleInSingleInvocation_actual() async {
+    await resolveTestCode('''
+void f() {
+  g(a: 0, b: 1, c: 2);
+}
+
+void g({int a = 0, int b = 1, int c = 2}) {}
+''');
+    await assertHasFix('''
+void f() {
+  g(b: 1);
+}
+
+void g({int a = 0, int b = 1, int c = 2}) {}
+''');
+  }
+
+  @failingTest
+  Future<void> test_multipleInSingleInvocation_ideal() async {
+    // The edits currently conflict with each other because they're overlapping,
+    // so one of them isn't applied. This only impacts the fix-all-in-file case
+    // because the bulk-fix case catches the remaining argument on the second
+    // pass.
+    await resolveTestCode('''
+void f() {
+  g(a: 0, b: 1, c: 2);
+}
+
+void g({int a = 0, int b = 1, int c = 2}) {}
+''');
+    await assertHasFix('''
+void f() {
+  g();
+}
+
+void g({int a = 0, int b = 1, int c = 2}) {}
+''');
+  }
 }
 
 @reflectiveTest
@@ -51,7 +90,7 @@
   @override
   String get lintCode => LintNames.avoid_redundant_argument_values;
 
-  Future<void> test_named_param() async {
+  Future<void> test_named() async {
     await resolveTestCode('''
 void f({bool valWithDefault = true, bool? val}) {}
 
@@ -68,7 +107,27 @@
 ''');
   }
 
-  Future<void> test_named_param_2() async {
+  @FailingTest(
+    issue: 'https://github.com/dart-lang/linter/issues/3082',
+  )
+  Future<void> test_named_betweenRequiredPositional() async {
+    await resolveTestCode('''
+void foo(int a, int b, {bool c = true}) {}
+
+void f() {
+  foo(0, c: true, 1);
+}
+''');
+    await assertHasFix('''
+void foo(int a, int b, {bool c = true}) {}
+
+void f() {
+  foo(0, 1);
+}
+''');
+  }
+
+  Future<void> test_named_hasOtherNamed() async {
     await resolveTestCode('''
 void f({bool valWithDefault = true, bool? val}) {}
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart
index 33821d3..4dec631 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart
@@ -126,7 +126,7 @@
   @FailingTest(issue: 'https://github.com/dart-lang/linter/issues/1997')
   Future<void> test_method_nullSafety_optIn_fromOptOut() async {
     createAnalysisOptionsFile(lints: [lintCode]);
-    newFile('/home/test/lib/a.dart', content: r'''
+    newFile('$testPackageLibPath/a.dart', content: r'''
 class A {
   int foo() => 0;
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
index 6fbc9d8..0dd8430 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
@@ -5,40 +5,97 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'fix_processor.dart';
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(RemoveUnusedImportTest);
+    defineReflectiveTests(RemoveUnusedImportBulkTest);
     defineReflectiveTests(RemoveUnusedImportMultiTest);
+    defineReflectiveTests(RemoveUnusedImportTest);
   });
 }
 
 @reflectiveTest
+class RemoveUnusedImportBulkTest extends BulkFixProcessorTest {
+  @FailingTest(reason: 'multiple deletions conflict')
+  Future<void> test_multipleOnSingleLine() async {
+    // TODO(brianwilkerson) Remove test_multipleOnSingleLine_temporary when this
+    //  test starts to pass.
+    await resolveTestCode('''
+import 'dart:collection'; import 'dart:math'; import 'dart:async';
+void f() {}
+''');
+    await assertHasFix('''
+
+void f() {}
+''');
+  }
+
+  Future<void> test_multipleOnSingleLine_temporary() async {
+    await resolveTestCode('''
+import 'dart:collection'; import 'dart:math'; import 'dart:async';
+void f() {}
+''');
+    await assertHasFix('''
+import 'dart:math';
+void f() {}
+''');
+  }
+
+  Future<void> test_multipleUnused() async {
+    await resolveTestCode('''
+import 'dart:collection';
+import 'dart:math';
+import 'dart:async';
+void f() {}
+''');
+    await assertHasFix('''
+void f() {}
+''');
+    var details = processor.fixDetails;
+    expect(details, hasLength(1));
+    var fixes = details[0].fixes;
+    expect(fixes, hasLength(1));
+    expect(fixes[0].occurrences, 3);
+  }
+
+  Future<void> test_usedAndUnused() async {
+    await resolveTestCode('''
+import 'dart:async';
+import 'dart:math' as math;
+import 'dart:async';
+
+var tau = math.pi * 2;
+
+void f() {}
+''');
+    await assertHasFix('''
+import 'dart:math' as math;
+
+var tau = math.pi * 2;
+
+void f() {}
+''');
+  }
+}
+
+@reflectiveTest
 class RemoveUnusedImportMultiTest extends FixProcessorTest {
   @override
   FixKind get kind => DartFixKind.REMOVE_UNUSED_IMPORT_MULTI;
 
-  @override
-  void setUp() {
-    super.setUp();
-    // TODO(dantup): Get these tests passing with either line ending.
-    useLineEndingsForPlatform = false;
-  }
-
   Future<void> test_all_diverseImports() async {
     await resolveTestCode('''
 import 'dart:math';
 import 'dart:math';
 import 'dart:async';
-main() {
-}
+void f() {}
 ''');
     await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
-main() {
-}
+void f() {}
 ''');
   }
 
@@ -50,29 +107,39 @@
 
 var tau = math.pi * 2;
 
-main() {
-}
+void f() {}
 ''');
     await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
 import 'dart:math' as math;
 
 var tau = math.pi * 2;
 
-main() {
-}
+void f() {}
 ''');
   }
 
-  @FailingTest(reason: 'one unused import remains unremoved')
+  @FailingTest(reason: 'multiple deletions conflict')
   Future<void> test_all_singleLine() async {
+    // TODO(brianwilkerson) Remove test_multipleOnSingleLine_temporary when this
+    //  test starts to pass.
     await resolveTestCode('''
 import 'dart:math'; import 'dart:math'; import 'dart:math';
-main() {
-}
+void f() {}
 ''');
     await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
-main() {
-}
+
+void f() {}
+''');
+  }
+
+  Future<void> test_all_singleLine_temporary() async {
+    await resolveTestCode('''
+import 'dart:math'; import 'dart:math'; import 'dart:math';
+void f() {}
+''');
+    await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
+import 'dart:math';
+void f() {}
 ''');
   }
 
@@ -81,12 +148,10 @@
 import 'dart:math';
 import 'dart:math';
 import 'dart:math';
-main() {
-}
+void f() {}
 ''');
     await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
-main() {
-}
+void f() {}
 ''');
   }
 }
@@ -96,13 +161,6 @@
   @override
   FixKind get kind => DartFixKind.REMOVE_UNUSED_IMPORT;
 
-  @override
-  void setUp() {
-    super.setUp();
-    // TODO(dantup): Get these tests passing with either line ending.
-    useLineEndingsForPlatform = false;
-  }
-
   Future<void> test_anotherImportOnLine() async {
     await resolveTestCode('''
 import 'dart:math'; import 'dart:async';
@@ -125,14 +183,14 @@
 import 'dart:math';
 import 'dart:math';
 
-main() {
+void f() {
   print(min(0, 1));
 }
 ''');
     await assertHasFix('''
 import 'dart:math';
 
-main() {
+void f() {
   print(min(0, 1));
 }
 ''');
@@ -142,11 +200,11 @@
     await resolveTestCode('''
 import
   'dart:math';
-main() {
+void f() {
 }
 ''');
     await assertHasFix('''
-main() {
+void f() {
 }
 ''');
   }
@@ -154,11 +212,11 @@
   Future<void> test_single() async {
     await resolveTestCode('''
 import 'dart:math';
-main() {
+void f() {
 }
 ''');
     await assertHasFix('''
-main() {
+void f() {
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_test.dart
index da085a6..ac72607 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_test.dart
@@ -172,7 +172,7 @@
   }
 
   Future<void> test_privateType() async {
-    addSource('/home/test/lib/a.dart', '''
+    addSource('$testPackageLibPath/a.dart', '''
 class A {
   _B b => _B();
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart
index 0bf4a84..eaf03e1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart
@@ -62,7 +62,7 @@
   }
 
   Future<void> test_qualified() async {
-    newFile('/home/test/lib/ext.dart', content: '''
+    newFile('$testPackageLibPath/ext.dart', content: '''
 extension E on String {
   static int m() => 0;
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
index 49f9041..e3245f3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
@@ -82,7 +82,6 @@
 ''');
   }
 
-  // @soloTest
   Future<void> test_constructorTearOff_nameUnnamed() async {
     await resolveTestCode('''
 class C {
diff --git a/pkg/analysis_server/test/stress/completion/completion_runner.dart b/pkg/analysis_server/test/stress/completion/completion_runner.dart
index 136684a..2f7a688 100644
--- a/pkg/analysis_server/test/stress/completion/completion_runner.dart
+++ b/pkg/analysis_server/test/stress/completion/completion_runner.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/utilities/null_string_sink.dart';
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
@@ -11,6 +10,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/file_system/overlay_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
 /// A runner that can request code completion at the location of each identifier
@@ -60,7 +60,6 @@
     var contributor = DartCompletionManager(
       budget: CompletionBudget(const Duration(seconds: 30)),
     );
-    var statistics = CompletionPerformance();
     var stamp = 1;
 
     var fileCount = 0;
@@ -100,17 +99,13 @@
           }
 
           timer.start();
-          var dartRequest = DartCompletionRequest(
+          var dartRequest = DartCompletionRequest.forResolvedUnit(
             resolvedUnit: result,
             offset: offset,
           );
-          var suggestions = await statistics.runRequestOperation(
-            (performance) async {
-              return await contributor.computeSuggestions(
-                dartRequest,
-                performance,
-              );
-            },
+          var suggestions = await contributor.computeSuggestions(
+            dartRequest,
+            OperationPerformanceImpl('<root>'),
           );
           timer.stop();
 
diff --git a/pkg/analysis_server/test/utils/change_check.dart b/pkg/analysis_server/test/utils/change_check.dart
new file mode 100644
index 0000000..3cd3e2b
--- /dev/null
+++ b/pkg/analysis_server/test/utils/change_check.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
+
+extension SourceChangeExtension on CheckTarget<SourceChange> {
+  @useResult
+  CheckTarget<List<SourceFileEdit>> get edits {
+    return nest(value.edits, (value) => 'has edits ${valueStr(value)}');
+  }
+
+  CheckTarget<SourceFileEdit> hasFileEdit(String path) {
+    return nest(
+      value.edits.singleWhere((e) => e.file == path),
+      (selected) => 'has edit ${valueStr(selected)}',
+    );
+  }
+}
+
+extension SourceFileEditExtension on CheckTarget<SourceFileEdit> {
+  @useResult
+  CheckTarget<String> appliedTo(String applyTo) {
+    var actual = SourceEdit.applySequence(applyTo, value.edits);
+    return nest(
+      actual,
+      (selected) => 'produces ${valueStr(selected)}',
+    );
+  }
+}
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index c7a90fc..a6a9b85 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -10,7 +10,6 @@
 import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/documentation_cache.dart';
 import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
@@ -1227,7 +1226,7 @@
         listener: listener,
       ).computeSuggestions(dartRequest, performance);
 
-      computeIncludedSetList(declarationsTracker, dartRequest.result,
+      computeIncludedSetList(declarationsTracker, dartRequest,
           includedSuggestionSetList, includedElementNames);
 
       var includedSuggestionSetMap = {
@@ -1369,27 +1368,19 @@
             {required MetricsSuggestionListener listener,
             required CompletionMetrics metrics}) async {
           var stopwatch = Stopwatch()..start();
-          var request = DartCompletionRequest(
+          var request = DartCompletionRequest.forResolvedUnit(
             resolvedUnit: resolvedUnitResult,
             offset: expectedCompletion.offset,
             documentationCache: documentationCache,
           );
 
-          late OpType opType;
-          late List<protocol.CompletionSuggestion> suggestions;
-          await CompletionPerformance().runRequestOperation(
-            (performance) async {
-              opType = OpType.forCompletion(request.target, request.offset);
-              suggestions = await _computeCompletionSuggestions(
-                listener,
-                performance,
-                request,
-                metrics.availableSuggestions ? declarationsTracker : null,
-                metrics.availableSuggestions
-                    ? availableSuggestionsParams
-                    : null,
-              );
-            },
+          var opType = OpType.forCompletion(request.target, request.offset);
+          var suggestions = await _computeCompletionSuggestions(
+            listener,
+            OperationPerformanceImpl('<root>'),
+            request,
+            metrics.availableSuggestions ? declarationsTracker : null,
+            metrics.availableSuggestions ? availableSuggestionsParams : null,
           );
           stopwatch.stop();
 
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index cc61b66..ccf6e8a 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -9,10 +9,10 @@
 
 ## Running the Server
 
-The analysis server snapshot is included in the `bin/snapshots` folder of the Dart SDK. Pass the `--lsp` flag to start the server in LSP mode and the `--client-id` and `--client-version` flags to identify your editor/plugin and version:
+Start the language server using the `dart language-server` command. Pass the `--client-id` and `--client-version` flags to identify your editor/plugin and version:
 
 ```
-dart bin/snapshots/analysis_server.dart.snapshot --lsp --client-id my-editor.my-plugin --client-version 1.2
+dart language-server --client-id my-editor.my-plugin --client-version 1.2
 ```
 
 Note: In LSP the client makes the first request so there is no obvious confirmation that the server is working correctly until the client sends an `initialize` request. Unlike standard JSON RPC, [LSP requires that headers are sent](https://microsoft.github.io/language-server-protocol/specification).
@@ -101,8 +101,8 @@
 | codeLens/resolve | | | | | |
 | textDocument/documentLink | | | | | |
 | documentLink/resolve | | | | | |
-| textDocument/documentColor | | | | | |
-| textDocument/colorPresentation | | | | | |
+| textDocument/documentColor | ✅ | ✅ | | ✅ | ✅ |
+| textDocument/colorPresentation | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/formatting | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/rangeFormatting | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/onTypeFormatting | ✅ | ✅ | | ✅ | ✅ |
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index 0339409..d6935bf 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -934,7 +934,8 @@
           case 'bool':
             return FromJsonFunction('jsonDecoder.decodeBool');
           case 'double':
-            return FromJsonFunction('jsonDecoder.decodeDouble');
+            return FromJsonFunction('jsonDecoder.decodeDouble',
+                castType: 'Object');
           case 'int':
           case 'long':
             return FromJsonFunction('jsonDecoder.decodeInt');
@@ -1120,14 +1121,17 @@
   @override
   final String asClosure;
 
-  FromJsonFunction(this.asClosure);
+  final String? castType;
+
+  FromJsonFunction(this.asClosure, {this.castType});
 
   @override
   bool get isIdentity => false;
 
   @override
-  String asSnippet(String jsonPath, String json) =>
-      '$asClosure($jsonPath, $json)';
+  String asSnippet(String jsonPath, String json) => castType == null
+      ? '$asClosure($jsonPath, $json)'
+      : '$asClosure($jsonPath, $json as $castType)';
 }
 
 /// Representation of FromJsonCode for the identity transformation.
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 9f7e268..2108516 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -441,8 +441,12 @@
    * @param offset The offset within the file at which suggestions are to be made.
    * @param maxResults The maximum number of suggestions to return. If the number of suggestions
    *         after filtering is greater than the maxResults, then isIncomplete is set to true.
+   * @param timeout The approximate time in milliseconds that the server should spend. The server
+   *         will perform some steps anyway, even if it takes longer than the specified timeout. This
+   *         field is intended to be used for benchmarking, and usually should not be provided, so
+   *         that the default timeout is used.
    */
-  public void completion_getSuggestions2(String file, int offset, int maxResults, GetSuggestions2Consumer consumer);
+  public void completion_getSuggestions2(String file, int offset, int maxResults, int timeout, GetSuggestions2Consumer consumer);
 
   /**
    * {@code completion.registerLibraryPaths}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index aa08d74..d89a44b 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1482,6 +1482,16 @@
           then <tt>isIncomplete</tt> is set to <tt>true</tt>.
         </p>
       </field>
+      <field name="timeout" experimental="true" optional="true">
+        <ref>int</ref>
+        <p>
+          The approximate time in milliseconds that the server should spend.
+          The server will perform some steps anyway, even if it takes longer
+          than the specified timeout. This field is intended to be used for
+          benchmarking, and usually should not be  provided, so that the
+          default timeout is used.
+        </p>
+      </field>
     </params>
     <result>
       <field name="replacementOffset">
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 2689506..85a4474 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -141,6 +141,7 @@
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_MAX_RESULTS = 'maxResults';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_OFFSET = 'offset';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_TIMEOUT = 'timeout';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_FILE = 'file';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset';
 const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS =
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index 2dcbd32..7bb9c83 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -4698,7 +4698,14 @@
   /// to true.
   int maxResults;
 
-  CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults);
+  /// The approximate time in milliseconds that the server should spend. The
+  /// server will perform some steps anyway, even if it takes longer than the
+  /// specified timeout. This field is intended to be used for benchmarking,
+  /// and usually should not be provided, so that the default timeout is used.
+  int? timeout;
+
+  CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
+      {this.timeout});
 
   factory CompletionGetSuggestions2Params.fromJson(
       JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4723,7 +4730,12 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'maxResults');
       }
-      return CompletionGetSuggestions2Params(file, offset, maxResults);
+      int? timeout;
+      if (json.containsKey('timeout')) {
+        timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
+      }
+      return CompletionGetSuggestions2Params(file, offset, maxResults,
+          timeout: timeout);
     } else {
       throw jsonDecoder.mismatch(
           jsonPath, 'completion.getSuggestions2 params', json);
@@ -4741,6 +4753,10 @@
     result['file'] = file;
     result['offset'] = offset;
     result['maxResults'] = maxResults;
+    var timeout = this.timeout;
+    if (timeout != null) {
+      result['timeout'] = timeout;
+    }
     return result;
   }
 
@@ -4757,7 +4773,8 @@
     if (other is CompletionGetSuggestions2Params) {
       return file == other.file &&
           offset == other.offset &&
-          maxResults == other.maxResults;
+          maxResults == other.maxResults &&
+          timeout == other.timeout;
     }
     return false;
   }
@@ -4767,6 +4784,7 @@
         file,
         offset,
         maxResults,
+        timeout,
       );
 }
 
@@ -11547,7 +11565,7 @@
       double? doubleValue;
       if (json.containsKey('doubleValue')) {
         doubleValue = jsonDecoder.decodeDouble(
-            jsonPath + '.doubleValue', json['doubleValue']);
+            jsonPath + '.doubleValue', json['doubleValue'] as Object);
       }
       int? intValue;
       if (json.containsKey('intValue')) {
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index d672ae5..a0dc0ba 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,7 +1,13 @@
-## 2.8.0-dev
+## 2.8.0
 * Deprecations and renames for `getXyz` methods in `AnalysisDriver`.
 * Removed uppercase named constants from `double` in mock SDK.
 * Deprecated `path` and `uri` from `AnalysisResult`.
+* Deprecated `UriResolver.restoreAbsolute`, use `pathToUri` instead.
+* Deprecated `SourceFactory.restoreAbsolute`, use `pathToUri` instead.
+* Deprecated `UriKind` and `Source.uriKind`.
+* Deprecated `Source.modificationStamp`.
+* Deprecated `Source.isInSystemLibrary`, use `uri.isScheme('dart')` instead.
+* Fixed #47715.
 
 ## 2.7.0
 * Updated `ConstructorElement.displayName` to either `Class` or `Class.constructor`.
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index 9264322..91c3a30 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -23,6 +23,9 @@
   static final control_flow_collections =
       ExperimentalFeatures.control_flow_collections;
 
+  /// Feature information for enhanced enums.
+  static final enhanced_enums = ExperimentalFeatures.enhanced_enums;
+
   /// Feature information for extension methods.
   static final extension_methods = ExperimentalFeatures.extension_methods;
 
@@ -38,6 +41,9 @@
   /// Feature information for set literals.
   static final set_literals = ExperimentalFeatures.set_literals;
 
+  /// Feature information for super parameters.
+  static final super_parameters = ExperimentalFeatures.super_parameters;
+
   /// Feature information for the triple-shift operator.
   static final triple_shift = ExperimentalFeatures.triple_shift;
 
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index ba209b7..a376881 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -570,6 +570,8 @@
 
   R? visitSuperExpression(SuperExpression node);
 
+  R? visitSuperFormalParameter(SuperFormalParameter node);
+
   R? visitSwitchCase(SwitchCase node);
 
   R? visitSwitchDefault(SwitchDefault node);
@@ -1591,6 +1593,9 @@
   /// Return the left curly bracket.
   Token get leftBracket;
 
+  /// Return the members declared by the enumeration.
+  NodeList<ClassMember> get members;
+
   @override
   SimpleIdentifier get name;
 
@@ -2200,6 +2205,7 @@
 ///        [BlockFunctionBody]
 ///      | [EmptyFunctionBody]
 ///      | [ExpressionFunctionBody]
+///      | [NativeFunctionBody]
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionBody implements AstNode {
@@ -4058,6 +4064,48 @@
   Token get superKeyword;
 }
 
+/// A super-initializer formal parameter.
+///
+///    superFormalParameter ::=
+///        ('final' [TypeAnnotation] | 'const' [TypeAnnotation] | 'var' | [TypeAnnotation])?
+///        'super' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SuperFormalParameter implements NormalFormalParameter {
+  @override
+  SimpleIdentifier get identifier;
+
+  /// Return the token representing either the 'final', 'const' or 'var'
+  /// keyword, or `null` if no keyword was used.
+  Token? get keyword;
+
+  /// Return the parameters of the function-typed parameter, or `null` if this
+  /// is not a function-typed field formal parameter.
+  FormalParameterList? get parameters;
+
+  /// Return the token representing the period.
+  Token get period;
+
+  /// If the parameter is function-typed, and has the question mark, then its
+  /// function type is nullable. Having a nullable function type means that the
+  /// parameter can be null.
+  Token? get question;
+
+  /// Return the token representing the 'super' keyword.
+  Token get superKeyword;
+
+  /// Return the declared type of the parameter, or `null` if the parameter does
+  /// not have a declared type.
+  ///
+  /// Note that if this is a function-typed field formal parameter this is the
+  /// return type of the function.
+  TypeAnnotation? get type;
+
+  /// Return the type parameters associated with this method, or `null` if this
+  /// method is not a generic method.
+  TypeParameterList? get typeParameters;
+}
+
 /// A case in a switch statement.
 ///
 ///    switchCase ::=
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index 8a714a8..f4c31cb 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -308,6 +308,7 @@
       SimpleIdentifier name,
       Token leftBracket,
       List<EnumConstantDeclaration> constants,
+      List<ClassMember> members,
       Token rightBracket);
 
   /// Returns a newly created export directive. Either or both of the
@@ -872,6 +873,26 @@
   /// Returns a newly created super expression.
   SuperExpression superExpression(Token superKeyword);
 
+  /// Returns a newly created super-initializer parameter. Either or both of
+  /// the [comment] and [metadata] can be `null` if the parameter does not have
+  /// the corresponding attribute. The [keyword] can be `null` if there is a
+  /// type. The [type] must be `null` if the keyword is 'var'. The [parameters]
+  /// can be `null` if this is not a function-typed super-initializer
+  /// parameter.
+  SuperFormalParameter superFormalParameter(
+      {Comment? comment,
+      List<Annotation>? metadata,
+      Token? covariantKeyword,
+      Token? requiredKeyword,
+      Token? keyword,
+      TypeAnnotation? type,
+      required Token superKeyword,
+      required Token period,
+      required SimpleIdentifier identifier,
+      TypeParameterList? typeParameters,
+      FormalParameterList? parameters,
+      Token? question});
+
   /// Returns a newly created switch case. The list of [labels] can be `null`
   /// if there are no labels.
   SwitchCase switchCase(List<Label> labels, Token keyword,
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 5d3dda9..65551ac 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -561,6 +561,10 @@
   R? visitSuperExpression(SuperExpression node) => visitExpression(node);
 
   @override
+  R? visitSuperFormalParameter(SuperFormalParameter node) =>
+      visitNormalFormalParameter(node);
+
+  @override
   R? visitSwitchCase(SwitchCase node) => visitSwitchMember(node);
 
   @override
@@ -1309,6 +1313,12 @@
   }
 
   @override
+  R? visitSuperFormalParameter(SuperFormalParameter node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R? visitSwitchCase(SwitchCase node) {
     node.visitChildren(this);
     return null;
@@ -1771,6 +1781,9 @@
   R? visitSuperExpression(SuperExpression node) => null;
 
   @override
+  R? visitSuperFormalParameter(SuperFormalParameter node) => null;
+
+  @override
   R? visitSwitchCase(SwitchCase node) => null;
 
   @override
@@ -2184,6 +2197,9 @@
   R? visitSuperExpression(SuperExpression node) => _throw(node);
 
   @override
+  R? visitSuperFormalParameter(SuperFormalParameter node) => _throw(node);
+
+  @override
   R? visitSwitchCase(SwitchCase node) => _throw(node);
 
   @override
@@ -3145,6 +3161,14 @@
   }
 
   @override
+  T? visitSuperFormalParameter(SuperFormalParameter node) {
+    stopwatch.start();
+    T? result = _baseVisitor.visitSuperFormalParameter(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T? visitSwitchCase(SwitchCase node) {
     stopwatch.start();
     T? result = _baseVisitor.visitSwitchCase(node);
@@ -3668,6 +3692,9 @@
   R? visitSuperExpression(SuperExpression node) => visitNode(node);
 
   @override
+  R? visitSuperFormalParameter(SuperFormalParameter node) => visitNode(node);
+
+  @override
   R? visitSwitchCase(SwitchCase node) => visitNode(node);
 
   @override
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 0bc425e..b4924ce 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -256,7 +256,6 @@
   CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
   CompileTimeErrorCode.INVALID_OVERRIDE,
   CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS,
-  CompileTimeErrorCode.INVALID_SUPER_INVOCATION,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
   CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET,
@@ -407,6 +406,7 @@
   CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
   CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
   CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
+  CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST,
   CompileTimeErrorCode.SWITCH_CASE_COMPLETES_NORMALLY,
   CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
   CompileTimeErrorCode.TEAROFF_OF_GENERATIVE_CONSTRUCTOR_OF_ABSTRACT_CLASS,
@@ -475,7 +475,11 @@
   CompileTimeErrorCode.WRONG_TYPE_PARAMETER_VARIANCE_POSITION,
   CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR,
   CompileTimeErrorCode.YIELD_IN_NON_GENERATOR,
+  CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE,
   CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
+  FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_EXTRA,
+  FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_MISSING,
+  FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED,
   FfiCode.ANNOTATION_ON_POINTER_FIELD,
   FfiCode.ARGUMENT_MUST_BE_A_CONSTANT,
   FfiCode.CREATION_OF_STRUCT_OR_UNION,
@@ -1134,8 +1138,7 @@
     return errors.toList();
   }
 
-  static List<Object?>? _translateNamedArguments(
-      Map<String, dynamic> arguments) {
+  static Null _translateNamedArguments(Map<String, dynamic> arguments) {
     // All analyzer errors now use positional arguments, so if this method is
     // being called, either no arguments were provided to the
     // AnalysisError.withNamedArguments constructor, or the client was
diff --git a/pkg/analyzer/lib/error/listener.dart b/pkg/analyzer/lib/error/listener.dart
index ba45f03..6209775 100644
--- a/pkg/analyzer/lib/error/listener.dart
+++ b/pkg/analyzer/lib/error/listener.dart
@@ -165,6 +165,12 @@
         arguments[i] = argument.getDisplayString(
           withNullability: isNonNullableByDefault,
         );
+      } else if (!(argument is String ||
+          argument is DartType ||
+          argument is int ||
+          argument is Uri)) {
+        throw ArgumentError(
+            'Tried to format an error using ${argument.runtimeType}');
       }
     }
   }
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index f6d3b10..ce09cee 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -7,7 +7,7 @@
 import 'dart:typed_data';
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:path/path.dart' as pathos;
 import 'package:watcher/watcher.dart';
diff --git a/pkg/analyzer/lib/file_system/overlay_file_system.dart b/pkg/analyzer/lib/file_system/overlay_file_system.dart
index dbac07b..559d80e 100644
--- a/pkg/analyzer/lib/file_system/overlay_file_system.dart
+++ b/pkg/analyzer/lib/file_system/overlay_file_system.dart
@@ -6,7 +6,7 @@
 import 'dart:typed_data';
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:path/path.dart' as pathos;
 import 'package:watcher/watcher.dart';
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 9824499..3f16df1 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -6,7 +6,7 @@
 import 'dart:typed_data';
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
diff --git a/pkg/analyzer/lib/source/line_info.dart b/pkg/analyzer/lib/source/line_info.dart
index 1867017..b552a35 100644
--- a/pkg/analyzer/lib/source/line_info.dart
+++ b/pkg/analyzer/lib/source/line_info.dart
@@ -17,6 +17,12 @@
   CharacterLocation(this.lineNumber, this.columnNumber);
 
   @override
+  bool operator ==(Object object) =>
+      object is CharacterLocation &&
+      lineNumber == object.lineNumber &&
+      columnNumber == object.columnNumber;
+
+  @override
   String toString() => '$lineNumber:$columnNumber';
 }
 
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
index efb2263..4269e6b 100644
--- a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -35,7 +35,7 @@
   /// Return the analysis options file from which options should be read, or
   /// `null` if there is no analysis options file for code in the given [root].
   ///
-  /// The given [root] directory will be searched first. If no file is found ,
+  /// The given [root] directory will be searched first. If no file is found,
   /// then enclosing directories will be searched.
   File? getOptionsFile(Folder root) {
     for (var current in root.withAncestors) {
@@ -44,6 +44,7 @@
         return file;
       }
     }
+    return null;
   }
 
   /// Provide the options found in [file].
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index 554eb1a..b603111 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
 import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/workspace/package_build.dart';
 
@@ -63,14 +64,6 @@
   }
 
   @override
-  void clearCache() {
-    _absoluteUriToSourceCache.clear();
-    for (var resolver in resolvers) {
-      resolver.clearCache();
-    }
-  }
-
-  @override
   Source? forUri(String absoluteUri) {
     try {
       Uri uri;
@@ -109,6 +102,17 @@
   }
 
   @override
+  Uri? pathToUri(String path) {
+    for (var resolver in resolvers) {
+      var uri = resolver.pathToUri(path);
+      if (uri != null) {
+        return uri;
+      }
+    }
+    return null;
+  }
+
+  @override
   Source? resolveUri(Source? containingSource, String? containedUri) {
     if (containedUri == null) {
       return null;
@@ -135,18 +139,13 @@
     }
   }
 
+  @Deprecated('Use pathToUri() instead')
   @override
   Uri? restoreUri(Source source) {
-    for (UriResolver resolver in resolvers) {
-      // First see if a resolver can restore the URI.
-      Uri? uri = resolver.restoreAbsolute(source);
-
-      if (uri != null) {
-        return uri;
-      }
+    if (source is InSummarySource) {
+      return source.uri;
     }
-
-    return null;
+    return pathToUri(source.fullName);
   }
 
   /// Return a source object representing the URI that results from resolving
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index d8131da..db6b26d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -198,6 +198,7 @@
         return file;
       }
     }
+    return null;
   }
 
   /// Return the analysis options that should be used to analyze code in the
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 38d0316..245db3d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -420,6 +420,7 @@
         return file;
       }
     }
+    return null;
   }
 
   /// Return the analysis options file to be used to analyze files in the given
@@ -432,6 +433,7 @@
         return file;
       }
     }
+    return null;
   }
 
   /// Return the packages file to be used to analyze files in the given
@@ -444,6 +446,7 @@
         return _PackagesFile(current, file);
       }
     }
+    return null;
   }
 
   /// Return a list containing the glob patterns used to exclude files from the
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 32ea11f..f632148 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/exception/exception.dart';
@@ -29,6 +30,7 @@
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/analysis/status.dart';
 import 'package:analyzer/src/dart/analysis/testing_data.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/diagnostic/diagnostic.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/exception/exception.dart';
@@ -42,6 +44,7 @@
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary2/ast_binary_flags.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+import 'package:analyzer/src/util/performance/operation_performance.dart';
 import 'package:meta/meta.dart';
 
 /// This class computes [AnalysisResult]s for Dart files.
@@ -80,7 +83,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 190;
+  static const int DATA_VERSION = 191;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
@@ -686,6 +689,22 @@
     return completer.future;
   }
 
+  /// Return [LibraryElementResult] for the given [file], or `null` if the
+  /// file is a part.
+  LibraryElement? getLibraryByFile(FileState file) {
+    if (file.isPart) {
+      return null;
+    }
+
+    var element = libraryContext.getLibraryElementIfReady(file.uriStr);
+    if (element != null) {
+      return element;
+    }
+
+    libraryContext.load2(file);
+    return libraryContext.getLibraryElement(file.uri);
+  }
+
   /// Return a [Future] that completes with [LibraryElementResult] for the given
   /// [uri], which is either resynthesized from the provided external summary
   /// store, or built for a file to which the given [uri] is resolved.
@@ -1274,6 +1293,7 @@
       return;
     }
     if (file_paths.isDart(resourceProvider.pathContext, path)) {
+      _lastProducedSignatures.remove(path);
       _priorityResults.clear();
       _removePotentiallyAffectedLibraries(path);
       _fileTracker.removeFile(path);
@@ -1281,6 +1301,63 @@
     }
   }
 
+  ResolvedForCompletionResultImpl? resolveForCompletion({
+    required String path,
+    required int offset,
+    required OperationPerformanceImpl performance,
+  }) {
+    if (!_isAbsolutePath(path)) {
+      return null;
+    }
+
+    if (!_fsState.hasUri(path)) {
+      return null;
+    }
+
+    // Process pending changes.
+    while (_fileTracker.verifyChangedFilesIfNeeded()) {}
+
+    var file = _fsState.getFileForPath(path);
+
+    var library = file.isPart ? file.library : file;
+    if (library == null) {
+      return null;
+    }
+
+    libraryContext.load2(library);
+    var unitElement = libraryContext.computeUnitElement(library, file)
+        as CompilationUnitElementImpl;
+
+    var analyzer = LibraryAnalyzer(
+        analysisOptions as AnalysisOptionsImpl,
+        declaredVariables,
+        sourceFactory,
+        libraryContext.analysisContext,
+        libraryContext.elementFactory.libraryOfUri2(library.uriStr),
+        libraryContext.analysisSession.inheritanceManager,
+        library,
+        testingData: testingData);
+
+    var analysisResult = analyzer.analyzeForCompletion(
+      file: file,
+      offset: offset,
+      unitElement: unitElement,
+      performance: performance,
+    );
+
+    return ResolvedForCompletionResultImpl(
+      analysisSession: currentSession,
+      path: path,
+      uri: file.uri,
+      exists: file.exists,
+      content: file.content,
+      lineInfo: file.lineInfo,
+      parsedUnit: analysisResult.parsedUnit,
+      unitElement: unitElement,
+      resolvedNodes: analysisResult.resolvedNodes,
+    );
+  }
+
   void _addDeclaredVariablesToSignature(ApiSignature buffer) {
     var variableNames = declaredVariables.variableNames;
     buffer.addInt(variableNames.length);
@@ -1705,15 +1782,16 @@
   }
 
   void _removePotentiallyAffectedLibraries(String path) {
-    _logger.run('Invalidate affected by $path.', () {
-      _logger.writeln('Work in $name');
-      var affected = <FileState>{};
-      _fsState.collectAffected(path, affected);
-      _logger.writeln('Remove ${affected.length} libraries.');
-      _libraryContext?.elementFactory.removeLibraries(
-        affected.map((e) => e.uriStr).toSet(),
-      );
-    });
+    var affected = <FileState>{};
+    _fsState.collectAffected(path, affected);
+
+    for (var file in affected) {
+      file.invalidateLibraryCycle();
+    }
+
+    _libraryContext?.elementFactory.removeLibraries(
+      affected.map((e) => e.uriStr).toSet(),
+    );
   }
 
   void _reportException(String path, Object exception, StackTrace stackTrace) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index ce99ad0..9d06f65 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -8,7 +8,7 @@
 
 /// The current version of the Dart language (or, for non-stable releases, the
 /// version of the language currently in the process of being developed).
-const _currentVersion = '2.15.0';
+const _currentVersion = '2.16.0';
 
 /// A map containing information about all known experimental flags.
 final _knownFeatures = <String, ExperimentalFeature>{
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index f0f35eb..532447a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -35,6 +35,7 @@
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/util/either.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart';
@@ -94,6 +95,9 @@
   /// The absolute URI of the file.
   final Uri uri;
 
+  /// Properties of the [uri].
+  final FileUriProperties uriProperties;
+
   /// The [Source] of the file with the [uri].
   final Source source;
 
@@ -126,6 +130,9 @@
 
   UnlinkedUnit? _unlinked2;
 
+  /// Files that reference this file.
+  final List<FileState> referencingFiles = [];
+
   List<FileState?>? _importedFiles;
   List<FileState?>? _exportedFiles;
   List<FileState?>? _partedFiles;
@@ -148,7 +155,7 @@
     this.workspacePackage,
     this._contextFeatureSet,
     this.packageLanguageVersion,
-  );
+  ) : uriProperties = FileUriProperties(uri);
 
   /// The unlinked API signature of the file.
   Uint8List get apiSignature => _apiSignature!;
@@ -196,7 +203,10 @@
     return _exportedFiles ??= _unlinked2!.exports.map((directive) {
       var uri = _selectRelativeUri(directive);
       return _fileForRelativeUri(uri).map(
-        (file) => file,
+        (file) {
+          file?.referencingFiles.add(this);
+          return file;
+        },
         (_) => null,
       );
     }).toList();
@@ -210,7 +220,10 @@
     return _importedFiles ??= _unlinked2!.imports.map((directive) {
       var uri = _selectRelativeUri(directive);
       return _fileForRelativeUri(uri).map(
-        (file) => file,
+        (file) {
+          file?.referencingFiles.add(this);
+          return file;
+        },
         (_) => null,
       );
     }).toList();
@@ -276,6 +289,7 @@
       return _fileForRelativeUri(uri).map(
         (file) {
           if (file != null) {
+            file.referencingFiles.add(this);
             _fsState._partToLibraries
                 .putIfAbsent(file, () => <FileState>[])
                 .add(this);
@@ -338,6 +352,11 @@
     _libraryCycle = cycle;
   }
 
+  void invalidateLibraryCycle() {
+    _libraryCycle?.invalidate();
+    _libraryCycle = null;
+  }
+
   /// Return a new parsed unresolved [CompilationUnit].
   CompilationUnitImpl parse([AnalysisErrorListener? errorListener]) {
     errorListener ??= AnalysisErrorListener.NULL_LISTENER;
@@ -420,6 +439,9 @@
       }
     }
 
+    // It is possible that this file does not reference these files.
+    _stopReferencingByThisFile();
+
     // Read imports/exports on demand.
     _importedFiles = null;
     _exportedFiles = null;
@@ -559,6 +581,20 @@
     return directive.uri;
   }
 
+  void _stopReferencingByThisFile() {
+    void removeForOne(List<FileState?>? referencedFiles) {
+      if (referencedFiles != null) {
+        for (var referenced in referencedFiles) {
+          referenced?.referencingFiles.remove(this);
+        }
+      }
+    }
+
+    removeForOne(_importedFiles);
+    removeForOne(_exportedFiles);
+    removeForOne(_partedFiles);
+  }
+
   static UnlinkedUnit serializeAstUnlinked2(CompilationUnit unit) {
     var exports = <UnlinkedNamespaceDirective>[];
     var imports = <UnlinkedNamespaceDirective>[];
@@ -686,11 +722,8 @@
   /// Mapping from a path to the flag whether there is a URI for the path.
   final Map<String, bool> _hasUriForPath = {};
 
-  /// Mapping from a path to the corresponding [FileState]s, canonical or not.
-  final Map<String, List<FileState>> _pathToFiles = {};
-
-  /// Mapping from a path to the corresponding canonical [FileState].
-  final Map<String, FileState> _pathToCanonicalFile = {};
+  /// Mapping from a path to the corresponding [FileState].
+  final Map<String, FileState> _pathToFile = {};
 
   /// We don't read parts until requested, but if we need to know the
   /// library for a file, we need to read parts of every file to know
@@ -737,28 +770,24 @@
   /// Collected files that transitively reference a file with the [path].
   /// These files are potentially affected by the change.
   void collectAffected(String path, Set<FileState> affected) {
-    final knownFiles = this.knownFiles.toList();
-
-    final fileToReferences = <FileState, List<FileState>>{};
-    for (var file in knownFiles) {
-      for (var referenced in file.directReferencedFiles) {
-        var references = fileToReferences[referenced] ??= [];
-        references.add(file);
-      }
+    // TODO(scheglov) This should not be necessary.
+    // We use affected files to remove library elements, and we can only get
+    // these library elements when we link or load them, using library cycles.
+    // And we get library cycles by asking `directReferencedFiles`.
+    for (var file in knownFiles.toList()) {
+      file.directReferencedFiles;
     }
 
     collectAffected(FileState file) {
       if (affected.add(file)) {
-        var references = fileToReferences[file];
-        if (references != null) {
-          for (var other in references) {
-            collectAffected(other);
-          }
+        for (var other in file.referencingFiles) {
+          collectAffected(other);
         }
       }
     }
 
-    for (var file in _pathToFiles[path] ?? <FileState>[]) {
+    var file = _pathToFile[path];
+    if (file != null) {
       collectAffected(file);
     }
   }
@@ -791,36 +820,14 @@
     return featureSetProvider.getLanguageVersion(path, uri);
   }
 
-  /// Return the canonical [FileState] for the given absolute [path]. The
-  /// returned file has the last known state since if was last refreshed.
-  ///
-  /// Here "canonical" means that if the [path] is in a package `lib` then the
-  /// returned file will have the `package:` style URI.
+  /// Return the [FileState] for the given absolute [path]. The returned file
+  /// has the last known state since if was last refreshed.
   FileState getFileForPath(String path) {
-    FileState? file = _pathToCanonicalFile[path];
+    var file = _pathToFile[path];
     if (file == null) {
       File resource = _resourceProvider.getFile(path);
-      Source fileSource = resource.createSource();
-      Uri? uri = _sourceFactory.restoreUri(fileSource);
-      // Try to get the existing instance.
-      file = _uriToFile[uri];
-      // If we have a file, call it the canonical one and return it.
-      if (file != null) {
-        _pathToCanonicalFile[path] = file;
-        return file;
-      }
-      // Create a new file.
-      FileSource uriSource = FileSource(resource, uri!);
-      WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path);
-      FeatureSet featureSet = contextFeatureSet(path, uri, workspacePackage);
-      Version packageLanguageVersion =
-          contextLanguageVersion(path, uri, workspacePackage);
-      file = FileState._(this, path, uri, uriSource, workspacePackage,
-          featureSet, packageLanguageVersion);
-      _uriToFile[uri] = file;
-      _addFileWithPath(path, file);
-      _pathToCanonicalFile[path] = file;
-      file.refresh();
+      Uri uri = _sourceFactory.pathToUri(path)!;
+      file = _newFile(resource, path, uri);
     }
     return file;
   }
@@ -847,7 +854,7 @@
 
     FileState? file = _uriToFile[uri];
     if (file == null) {
-      Source? uriSource = _sourceFactory.resolveUri(null, uri.toString());
+      Source? uriSource = _sourceFactory.forUri2(uri);
 
       // If the URI cannot be resolved, for example because the factory
       // does not understand the scheme, return the unresolved file instance.
@@ -856,34 +863,26 @@
       }
 
       String path = uriSource.fullName;
+
+      // Check if already resolved to this path via different URI.
+      // That different URI must be the canonical one.
+      file = _pathToFile[path];
+      if (file != null) {
+        return Either2.t1(file);
+      }
+
       File resource = _resourceProvider.getFile(path);
-      FileSource source = FileSource(resource, uri);
-      WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path);
-      FeatureSet featureSet = contextFeatureSet(path, uri, workspacePackage);
-      Version packageLanguageVersion =
-          contextLanguageVersion(path, uri, workspacePackage);
-      file = FileState._(this, path, uri, source, workspacePackage, featureSet,
-          packageLanguageVersion);
-      _uriToFile[uri] = file;
-      _addFileWithPath(path, file);
-      file.refresh();
+
+      var rewrittenUri = rewriteFileToPackageUri(_sourceFactory, uri);
+      if (rewrittenUri == null) {
+        return Either2.t1(null);
+      }
+
+      file = _newFile(resource, path, rewrittenUri);
     }
     return Either2.t1(file);
   }
 
-  /// Return the list of all [FileState]s corresponding to the given [path]. The
-  /// list has at least one item, and the first item is the canonical file.
-  List<FileState> getFilesForPath(String path) {
-    FileState canonicalFile = getFileForPath(path);
-    List<FileState> allFiles = _pathToFiles[path]!.toList();
-    if (allFiles.length == 1) {
-      return allFiles;
-    }
-    return allFiles
-      ..remove(canonicalFile)
-      ..insert(0, canonicalFile);
-  }
-
   /// Return files where the given [name] is subtyped, i.e. used in `extends`,
   /// `with` or `implements` clauses.
   Set<FileState>? getFilesSubtypingName(String name) {
@@ -898,10 +897,8 @@
   bool hasUri(String path) {
     bool? flag = _hasUriForPath[path];
     if (flag == null) {
-      File resource = _resourceProvider.getFile(path);
-      Source fileSource = resource.createSource();
-      Uri? uri = _sourceFactory.restoreUri(fileSource);
-      Source? uriSource = _sourceFactory.forUri2(uri!);
+      Uri uri = _sourceFactory.pathToUri(path)!;
+      Source? uriSource = _sourceFactory.forUri2(uri);
       flag = uriSource?.fullName == path;
       _hasUriForPath[path] = flag;
     }
@@ -933,30 +930,34 @@
     _clearFiles();
   }
 
-  void _addFileWithPath(String path, FileState file) {
-    var files = _pathToFiles[path];
-    if (files == null) {
-      knownFilePaths.add(path);
-      knownFiles.add(file);
-      files = <FileState>[];
-      _pathToFiles[path] = files;
-      fileStamp++;
-    }
-    files.add(file);
-  }
-
   /// Clear all [FileState] data - all maps from path or URI, etc.
   void _clearFiles() {
     _uriToFile.clear();
     knownFilePaths.clear();
     knownFiles.clear();
     _hasUriForPath.clear();
-    _pathToFiles.clear();
-    _pathToCanonicalFile.clear();
+    _pathToFile.clear();
     _librariesWithoutPartsRead.clear();
     _partToLibraries.clear();
     _subtypedNameToFiles.clear();
   }
+
+  FileState _newFile(File resource, String path, Uri uri) {
+    FileSource uriSource = FileSource(resource, uri);
+    WorkspacePackage? workspacePackage = _workspace?.findPackageFor(path);
+    FeatureSet featureSet = contextFeatureSet(path, uri, workspacePackage);
+    Version packageLanguageVersion =
+        contextLanguageVersion(path, uri, workspacePackage);
+    var file = FileState._(this, path, uri, uriSource, workspacePackage,
+        featureSet, packageLanguageVersion);
+    _pathToFile[path] = file;
+    _uriToFile[uri] = file;
+    knownFilePaths.add(path);
+    knownFiles.add(file);
+    fileStamp++;
+    file.refresh();
+    return file;
+  }
 }
 
 @visibleForTesting
@@ -971,3 +972,46 @@
         .toSet();
   }
 }
+
+/// Precomputed properties of a file URI, used because [Uri] is relatively
+/// expensive to work with, if we do this thousand times.
+class FileUriProperties {
+  static const int _isDart = 1 << 0;
+  static const int _isSrc = 1 << 1;
+
+  final int _flags;
+  final String? packageName;
+
+  factory FileUriProperties(Uri uri) {
+    if (uri.isScheme('dart')) {
+      return const FileUriProperties._dart();
+    } else if (uri.isScheme('package')) {
+      var segments = uri.pathSegments;
+      if (segments.length >= 2) {
+        return FileUriProperties._package(
+          packageName: segments[0],
+          isSrc: segments[1] == 'src',
+        );
+      }
+    }
+    return const FileUriProperties._unknown();
+  }
+
+  const FileUriProperties._dart()
+      : _flags = _isDart,
+        packageName = null;
+
+  FileUriProperties._package({
+    required String packageName,
+    required bool isSrc,
+  })  : _flags = isSrc ? _isSrc : 0,
+        packageName = packageName;
+
+  const FileUriProperties._unknown()
+      : _flags = 0,
+        packageName = null;
+
+  bool get isDart => (_flags & _isDart) != 0;
+
+  bool get isSrc => (_flags & _isSrc) != 0;
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
index d183ecc..887f450 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
@@ -166,15 +166,9 @@
     return _logger.run('Verify API signature of $path', () {
       _logger.writeln('Work in ${_fsState.contextName}');
 
-      bool anyApiChanged = false;
-      List<FileState> files = _fsState.getFilesForPath(path);
-      for (FileState file in files) {
-        bool apiChanged = file.refresh();
-        if (apiChanged) {
-          anyApiChanged = true;
-        }
-      }
-      if (anyApiChanged) {
+      var file = _fsState.getFileForPath(path);
+      var apiChanged = file.refresh();
+      if (apiChanged) {
         _logger.writeln('API signatures mismatch found.');
         // TODO(scheglov) schedule analysis of only affected files
         var pendingChangedFiles = <String>{};
@@ -190,10 +184,8 @@
         // Add files that directly import the changed file.
         for (String addedPath in addedFiles) {
           FileState addedFile = _fsState.getFileForPath(addedPath);
-          for (FileState changedFile in files) {
-            if (addedFile.importedFiles.contains(changedFile)) {
-              pendingImportFiles.add(addedPath);
-            }
+          if (addedFile.importedFiles.contains(file)) {
+            pendingImportFiles.add(addedPath);
           }
         }
 
@@ -220,7 +212,7 @@
         _pendingErrorFiles = pendingErrorFiles;
         _pendingFiles = pendingFiles;
       }
-      return files[0];
+      return file;
     });
   }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index f6a39e8..beabb03 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -41,6 +41,7 @@
 import 'package:analyzer/src/generated/ffi_verifier.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/hint/sdk_constraint_verifier.dart';
 import 'package:analyzer/src/ignore_comments/ignore_info.dart';
 import 'package:analyzer/src/lint/linter.dart';
@@ -48,6 +49,8 @@
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:pub_semver/pub_semver.dart';
 
 var timerLibraryAnalyzer = Stopwatch();
@@ -57,6 +60,16 @@
 var timerLibraryAnalyzerSplicer = Stopwatch();
 var timerLibraryAnalyzerVerify = Stopwatch();
 
+class AnalysisForCompletionResult {
+  final CompilationUnit parsedUnit;
+  final List<AstNode> resolvedNodes;
+
+  AnalysisForCompletionResult({
+    required this.parsedUnit,
+    required this.resolvedNodes,
+  });
+}
+
 /// Analyzer of a single library.
 class LibraryAnalyzer {
   /// A marker object used to prevent the initialization of
@@ -192,6 +205,84 @@
     return results;
   }
 
+  AnalysisForCompletionResult analyzeForCompletion({
+    required FileState file,
+    required int offset,
+    required CompilationUnitElementImpl unitElement,
+    required OperationPerformanceImpl performance,
+  }) {
+    var parsedUnit = performance.run('parse', (performance) {
+      return _parse(file);
+    });
+
+    var node = NodeLocator(offset).searchWithin(parsedUnit);
+
+    if (_hasEmptyCompletionContext(node)) {
+      return AnalysisForCompletionResult(
+        parsedUnit: parsedUnit,
+        resolvedNodes: [],
+      );
+    }
+
+    var errorListener = RecordingErrorListener();
+
+    return performance.run('resolve', (performance) {
+      // TODO(scheglov) We don't need to do this for the whole unit.
+      parsedUnit.accept(
+        ResolutionVisitor(
+          unitElement: unitElement,
+          errorListener: errorListener,
+          featureSet: _libraryElement.featureSet,
+          nameScope: _libraryElement.scope,
+          elementWalker: ElementWalker.forCompilationUnit(
+            unitElement,
+            libraryFilePath: _library.path,
+            unitFilePath: file.path,
+          ),
+        ),
+      );
+
+      // TODO(scheglov) We don't need to do this for the whole unit.
+      parsedUnit.accept(ScopeResolverVisitor(
+          _libraryElement, file.source, _typeProvider, errorListener,
+          nameScope: _libraryElement.scope));
+
+      FlowAnalysisHelper flowAnalysisHelper = FlowAnalysisHelper(
+          _typeSystem, _testingData != null, _libraryElement.featureSet);
+      _testingData?.recordFlowAnalysisDataForTesting(
+          file.uri, flowAnalysisHelper.dataForTesting!);
+
+      var resolverVisitor = ResolverVisitor(_inheritance, _libraryElement,
+          file.source, _typeProvider, errorListener,
+          featureSet: _libraryElement.featureSet,
+          flowAnalysisHelper: flowAnalysisHelper);
+
+      var nodeToResolve = node?.thisOrAncestorMatching((e) {
+        return e.parent is ClassDeclaration ||
+            e.parent is CompilationUnit ||
+            e.parent is ExtensionDeclaration ||
+            e.parent is MixinDeclaration;
+      });
+      if (nodeToResolve != null) {
+        var can = resolverVisitor.prepareForResolving(nodeToResolve);
+        if (can) {
+          nodeToResolve.accept(resolverVisitor);
+          return AnalysisForCompletionResult(
+            parsedUnit: parsedUnit,
+            resolvedNodes: [nodeToResolve],
+          );
+        }
+      }
+
+      var resolvedUnits = analyze();
+      var resolvedUnit = resolvedUnits[file]!;
+      return AnalysisForCompletionResult(
+        parsedUnit: resolvedUnit.unit,
+        resolvedNodes: [resolvedUnit.unit],
+      );
+    });
+  }
+
   void _checkForInconsistentLanguageVersionOverride(
     Map<FileState, CompilationUnit> units,
   ) {
@@ -244,7 +335,7 @@
   /// Compute [_constants] in all units.
   void _computeConstants() {
     computeConstants(_typeProvider, _typeSystem, _declaredVariables,
-        _constants.toList(), _analysisOptions.experimentStatus);
+        _constants.toList(), _libraryElement.featureSet);
   }
 
   void _computeHints(FileState file, CompilationUnit unit) {
@@ -683,6 +774,18 @@
         featureSet: unit.featureSet, flowAnalysisHelper: flowAnalysisHelper));
   }
 
+  Uri? _resolveRelativeUri(String relativeUriStr) {
+    Uri relativeUri;
+    try {
+      relativeUri = Uri.parse(relativeUriStr);
+    } on FormatException {
+      return null;
+    }
+
+    var absoluteUri = resolveRelativeUri(_library.uri, relativeUri);
+    return rewriteFileToPackageUri(_sourceFactory, absoluteUri);
+  }
+
   /// Return the result of resolve the given [uriContent], reporting errors
   /// against the [uriLiteral].
   Source? _resolveUri(FileState file, bool isImport, StringLiteral uriLiteral,
@@ -724,12 +827,12 @@
         directive.uriSource = defaultSource;
       }
       if (directive is NamespaceDirectiveImpl) {
-        var relativeUri = _selectRelativeUri(directive);
-        directive.selectedUriContent = relativeUri;
-        directive.selectedSource = _sourceFactory.resolveUri(
-          _library.source,
-          relativeUri,
-        );
+        var relativeUriStr = _selectRelativeUri(directive);
+        directive.selectedUriContent = relativeUriStr;
+        var absoluteUri = _resolveRelativeUri(relativeUriStr);
+        if (absoluteUri != null) {
+          directive.selectedSource = _sourceFactory.forUri2(absoluteUri);
+        }
         for (var configuration in directive.configurations) {
           configuration as ConfigurationImpl;
           var uriLiteral = configuration.uri;
@@ -816,6 +919,54 @@
       }
     }
   }
+
+  static bool _hasEmptyCompletionContext(AstNode? node) {
+    if (node is DoubleLiteral || node is IntegerLiteral) {
+      return true;
+    }
+
+    if (node is SimpleIdentifier) {
+      var parent = node.parent;
+
+      if (parent is ConstructorDeclaration && parent.name == node) {
+        return true;
+      }
+
+      if (parent is ConstructorFieldInitializer && parent.fieldName == node) {
+        return true;
+      }
+
+      // We have a contributor that looks at the type, but it is syntactic.
+      if (parent is FormalParameter && parent.identifier == node) {
+        return true;
+      }
+
+      if (parent is FunctionDeclaration && parent.name == node) {
+        return true;
+      }
+
+      if (parent is MethodDeclaration && parent.name == node) {
+        return true;
+      }
+
+      // The name of a NamedType does not provide any context.
+      // So, we don't need to resolve anything.
+      if (parent is NamedType) {
+        return true;
+      }
+
+      if (parent is TypeParameter && parent.name == node) {
+        return true;
+      }
+
+      // We have a contributor that looks at the type, but it is syntactic.
+      if (parent is VariableDeclaration && parent.name == node) {
+        return true;
+      }
+    }
+
+    return false;
+  }
 }
 
 /// Analysis result for single file.
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index dbdb140..4795da1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -81,6 +81,11 @@
     return elementFactory.libraryOfUri2('$uri');
   }
 
+  /// Return [LibraryElement] if it is ready.
+  LibraryElement? getLibraryElementIfReady(String uriStr) {
+    return elementFactory.libraryOfUriIfReady(uriStr);
+  }
+
   /// We are about to discard this context, mark all libraries invalid.
   void invalidAllLibraries() {
     elementFactory.invalidateAllLibraries();
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index 4856a55..a8184db 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -167,6 +167,48 @@
   LineInfo get lineInfo => unit.lineInfo!;
 }
 
+class ResolvedForCompletionResultImpl {
+  final AnalysisSession analysisSession;
+  final String path;
+  final Uri uri;
+  final bool exists;
+  final String content;
+  final LineInfo lineInfo;
+
+  /// The full parsed unit.
+  final CompilationUnit parsedUnit;
+
+  /// The full element for the unit.
+  final CompilationUnitElement unitElement;
+
+  /// Nodes from [parsedUnit] that were resolved to provide enough context
+  /// to perform completion. How much is enough depends on the location
+  /// where resolution for completion was requested, and our knowledge
+  /// how completion contributors work and what information they expect.
+  ///
+  /// This is usually a small subset of the whole unit - a method, a field.
+  /// It could be even empty if the location does not provide any context
+  /// information for any completion contributor, e.g. a type annotation.
+  /// But it could be the whole unit as well, if the location is not something
+  /// we have an optimization for.
+  ///
+  /// If this list is not empty, then the last node contains the requested
+  /// offset. Other nodes are provided mostly FYI.
+  final List<AstNode> resolvedNodes;
+
+  ResolvedForCompletionResultImpl({
+    required this.analysisSession,
+    required this.path,
+    required this.uri,
+    required this.exists,
+    required this.content,
+    required this.lineInfo,
+    required this.parsedUnit,
+    required this.unitElement,
+    required this.resolvedNodes,
+  });
+}
+
 class ResolvedLibraryResultImpl extends AnalysisResultImpl
     implements ResolvedLibraryResult {
   @override
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 4e0449b..651e0f9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
@@ -28,6 +29,102 @@
   return element;
 }
 
+DeclarationKind? _getSearchElementKind(Element element) {
+  if (element is ClassElement) {
+    if (element.isEnum) {
+      return DeclarationKind.ENUM;
+    }
+    if (element.isMixin) return DeclarationKind.MIXIN;
+    if (element.isMixinApplication) return DeclarationKind.CLASS_TYPE_ALIAS;
+    return DeclarationKind.CLASS;
+  }
+
+  if (element is ConstructorElement) {
+    return DeclarationKind.CONSTRUCTOR;
+  }
+
+  if (element is ExtensionElement) {
+    return DeclarationKind.EXTENSION;
+  }
+
+  if (element is FieldElement) {
+    if (element.isEnumConstant) return DeclarationKind.ENUM_CONSTANT;
+    return DeclarationKind.FIELD;
+  }
+
+  if (element is FunctionElement) {
+    return DeclarationKind.FUNCTION;
+  }
+
+  if (element is MethodElement) {
+    return DeclarationKind.METHOD;
+  }
+
+  if (element is PropertyAccessorElement) {
+    return element.isGetter ? DeclarationKind.GETTER : DeclarationKind.SETTER;
+  }
+
+  if (element is TypeAliasElement) {
+    return DeclarationKind.TYPE_ALIAS;
+  }
+
+  if (element is VariableElement) {
+    return DeclarationKind.VARIABLE;
+  }
+
+  return null;
+}
+
+/// An element declaration.
+class Declaration {
+  final int fileIndex;
+  final LineInfo lineInfo;
+  final String name;
+  final DeclarationKind kind;
+  final int offset;
+  final int line;
+  final int column;
+  final int codeOffset;
+  final int codeLength;
+  final String? className;
+  final String? mixinName;
+  final String? parameters;
+
+  Declaration(
+    this.fileIndex,
+    this.lineInfo,
+    this.name,
+    this.kind,
+    this.offset,
+    this.line,
+    this.column,
+    this.codeOffset,
+    this.codeLength,
+    this.className,
+    this.mixinName,
+    this.parameters,
+  );
+}
+
+/// The kind of a [Declaration].
+enum DeclarationKind {
+  CLASS,
+  CLASS_TYPE_ALIAS,
+  CONSTRUCTOR,
+  ENUM,
+  ENUM_CONSTANT,
+  EXTENSION,
+  FIELD,
+  FUNCTION,
+  FUNCTION_TYPE_ALIAS,
+  GETTER,
+  METHOD,
+  MIXIN,
+  SETTER,
+  TYPE_ALIAS,
+  VARIABLE
+}
+
 /// Search support for an [AnalysisDriver].
 class Search {
   final AnalysisDriver _driver;
@@ -64,6 +161,114 @@
     return elements;
   }
 
+  /// Add matching declarations to the [result].
+  Future<void> declarations(
+      WorkspaceSymbols result, RegExp? regExp, int? maxResults,
+      {String? onlyForFile}) async {
+    if (result.hasMoreDeclarationsThan(maxResults)) {
+      return;
+    }
+
+    void addDeclaration(LineInfo lineInfo, Element element) {
+      if (result.hasMoreDeclarationsThan(maxResults)) {
+        throw const _MaxNumberOfDeclarationsError();
+      }
+
+      if (element.isSynthetic) {
+        return;
+      }
+
+      var source = element.source;
+      if (source == null) {
+        return;
+      }
+
+      var path = source.fullName;
+      if (onlyForFile != null && path != onlyForFile) {
+        return;
+      }
+
+      var name = element.name;
+      if (name == null || name.isEmpty) {
+        return;
+      }
+      if (name.endsWith('=')) {
+        name = name.substring(0, name.length - 1);
+      }
+      if (regExp != null && !regExp.hasMatch(name)) {
+        return;
+      }
+
+      var enclosing = element.enclosingElement;
+
+      String? className;
+      String? mixinName;
+      if (enclosing is ClassElement) {
+        if (enclosing.isEnum) {
+          // skip
+        } else if (enclosing.isMixin) {
+          mixinName = enclosing.name;
+        } else {
+          className = enclosing.name;
+        }
+      }
+
+      var kind = _getSearchElementKind(element);
+      if (kind == null) {
+        return;
+      }
+
+      String? parameters;
+      if (element is ExecutableElement) {
+        var displayString = element.getDisplayString(withNullability: true);
+        var parameterIndex = displayString.indexOf('(');
+        if (parameterIndex > 0) {
+          parameters = displayString.substring(parameterIndex);
+        }
+      }
+
+      element as ElementImpl; // to access codeOffset/codeLength
+      var locationOffset = element.nameOffset;
+      var locationStart = lineInfo.getLocation(locationOffset);
+
+      result.declarations.add(
+        Declaration(
+          result._getPathIndex(path),
+          lineInfo,
+          name,
+          kind,
+          locationOffset,
+          locationStart.lineNumber,
+          locationStart.columnNumber,
+          element.codeOffset ?? 0,
+          element.codeLength ?? 0,
+          className,
+          mixinName,
+          parameters,
+        ),
+      );
+    }
+
+    await _driver.discoverAvailableFiles();
+    var knownFiles = _driver.fsState.knownFiles.toList();
+    for (var file in knownFiles) {
+      var libraryElement = _driver.getLibraryByFile(file);
+      if (libraryElement != null) {
+        for (var unitElement in libraryElement.units) {
+          try {
+            unitElement.accept(
+              _FunctionElementVisitor((element) {
+                addDeclaration(unitElement.lineInfo!, element);
+              }),
+            );
+          } on _MaxNumberOfDeclarationsError {
+            return;
+          }
+        }
+      }
+    }
+  }
+
   /// Returns references to the [element].
   Future<List<SearchResult>> references(
       Element? element, SearchedFiles searchedFiles) async {
@@ -604,6 +809,26 @@
   String toString() => id;
 }
 
+class WorkspaceSymbols {
+  final List<Declaration> declarations = [];
+  final List<String> files = [];
+  final Map<String, int> _pathToIndex = {};
+
+  bool hasMoreDeclarationsThan(int? maxResults) {
+    return maxResults != null && declarations.length >= maxResults;
+  }
+
+  int _getPathIndex(String path) {
+    var index = _pathToIndex[path];
+    if (index == null) {
+      index = files.length;
+      files.add(path);
+      _pathToIndex[path] = index;
+    }
+    return index;
+  }
+}
+
 /// A visitor that finds the deep-most [Element] that contains the [offset].
 class _ContainingElementFinder extends GeneralizingElementVisitor<void> {
   final int offset;
@@ -624,6 +849,19 @@
   }
 }
 
+/// A visitor that handles any element with a function.
+class _FunctionElementVisitor extends GeneralizingElementVisitor<void> {
+  final void Function(Element element) process;
+
+  _FunctionElementVisitor(this.process);
+
+  @override
+  void visitElement(Element element) {
+    process(element);
+    super.visitElement(element);
+  }
+}
+
 /// Visitor that adds [SearchResult]s for references to the [importElement].
 class _ImportElementReferencesVisitor extends RecursiveAstVisitor<void> {
   final List<SearchResult> results = <SearchResult>[];
@@ -950,3 +1188,8 @@
         enclosingElement, kind, node.offset, node.length, true, isQualified));
   }
 }
+
+/// The marker class that is thrown to stop adding declarations.
+class _MaxNumberOfDeclarationsError {
+  const _MaxNumberOfDeclarationsError();
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 319ddc6..6376bc1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -221,11 +221,13 @@
 
     _typeSystemLegacy?.updateOptions(
       implicitCasts: analysisOptions.implicitCasts,
+      strictCasts: analysisOptions.strictCasts,
       strictInference: analysisOptions.strictInference,
     );
 
     _typeSystemNonNullableByDefault?.updateOptions(
       implicitCasts: analysisOptions.implicitCasts,
+      strictCasts: analysisOptions.strictCasts,
       strictInference: analysisOptions.strictInference,
     );
   }
@@ -268,6 +270,7 @@
     _typeSystemLegacy = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: false,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: legacy,
     );
@@ -275,6 +278,7 @@
     _typeSystemNonNullableByDefault = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: true,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: nonNullableByDefault,
     );
diff --git a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
index 9e6bf4a..bda06b6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/dart/analysis/uri_converter.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:path/src/context.dart';
 
 /// An implementation of a URI converter based on an analysis driver.
@@ -32,8 +31,7 @@
         }
       }
     }
-    Source source = provider.getFile(path).createSource();
-    return driver.sourceFactory.restoreUri(source);
+    return driver.sourceFactory.pathToUri(path);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 24e1241..3ab0730 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -3301,6 +3301,9 @@
   /// The enumeration constants being declared.
   final NodeListImpl<EnumConstantDeclaration> _constants = NodeListImpl._();
 
+  /// The members defined by the enum.
+  final NodeListImpl<ClassMember> _members = NodeListImpl._();
+
   /// The right curly bracket.
   @override
   Token rightBracket;
@@ -3316,9 +3319,11 @@
       SimpleIdentifierImpl name,
       this.leftBracket,
       List<EnumConstantDeclaration> constants,
+      List<ClassMember> members,
       this.rightBracket)
       : super(comment, metadata, name) {
     _constants._initialize(this, constants);
+    _members._initialize(this, members);
   }
 
   @override
@@ -3328,6 +3333,7 @@
     ..add(_name)
     ..add(leftBracket)
     ..addAll(_constants)
+    ..addAll(_members)
     ..add(rightBracket);
 
   @override
@@ -3343,6 +3349,9 @@
   Token get firstTokenAfterCommentAndMetadata => enumKeyword;
 
   @override
+  NodeListImpl<ClassMember> get members => _members;
+
+  @override
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitEnumDeclaration(this);
 
   @override
@@ -3350,6 +3359,7 @@
     super.visitChildren(visitor);
     _name.accept(visitor);
     _constants.accept(visitor);
+    _members.accept(visitor);
   }
 }
 
@@ -9751,6 +9761,144 @@
   }
 }
 
+/// A super-initializer formal parameter.
+///
+///    fieldFormalParameter ::=
+///        ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?
+///        'super' '.' [SimpleIdentifier]
+///        ([TypeParameterList]? [FormalParameterList])?
+class SuperFormalParameterImpl extends NormalFormalParameterImpl
+    implements SuperFormalParameter {
+  /// The token representing either the 'final', 'const' or 'var' keyword, or
+  /// `null` if no keyword was used.
+  @override
+  Token? keyword;
+
+  /// The name of the declared type of the parameter, or `null` if the parameter
+  /// does not have a declared type.
+  TypeAnnotationImpl? _type;
+
+  /// The token representing the 'super' keyword.
+  @override
+  Token superKeyword;
+
+  /// The token representing the period.
+  @override
+  Token period;
+
+  /// The type parameters associated with the method, or `null` if the method is
+  /// not a generic method.
+  TypeParameterListImpl? _typeParameters;
+
+  /// The parameters of the function-typed parameter, or `null` if this is not a
+  /// function-typed field formal parameter.
+  FormalParameterListImpl? _parameters;
+
+  @override
+  Token? question;
+
+  /// Initialize a newly created formal parameter. Either or both of the
+  /// [comment] and [metadata] can be `null` if the parameter does not have the
+  /// corresponding attribute. The [keyword] can be `null` if there is a type.
+  /// The [type] must be `null` if the keyword is 'var'. The [thisKeyword] and
+  /// [period] can be `null` if the keyword 'this' was not provided.  The
+  /// [parameters] can be `null` if this is not a function-typed field formal
+  /// parameter.
+  SuperFormalParameterImpl(
+      CommentImpl? comment,
+      List<Annotation>? metadata,
+      Token? covariantKeyword,
+      Token? requiredKeyword,
+      this.keyword,
+      this._type,
+      this.superKeyword,
+      this.period,
+      SimpleIdentifierImpl identifier,
+      this._typeParameters,
+      this._parameters,
+      this.question)
+      : super(
+            comment, metadata, covariantKeyword, requiredKeyword, identifier) {
+    _becomeParentOf(_type);
+    _becomeParentOf(_typeParameters);
+    _becomeParentOf(_parameters);
+  }
+
+  @override
+  Token get beginToken {
+    final metadata = this.metadata;
+    if (metadata.isNotEmpty) {
+      return metadata.beginToken!;
+    } else if (requiredKeyword != null) {
+      return requiredKeyword!;
+    } else if (covariantKeyword != null) {
+      return covariantKeyword!;
+    } else if (keyword != null) {
+      return keyword!;
+    } else if (_type != null) {
+      return _type!.beginToken;
+    }
+    return superKeyword;
+  }
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => super._childEntities
+    ..add(keyword)
+    ..add(_type)
+    ..add(superKeyword)
+    ..add(period)
+    ..add(identifier)
+    ..add(_parameters);
+
+  @override
+  Token get endToken {
+    return question ?? _parameters?.endToken ?? identifier.endToken;
+  }
+
+  @override
+  SimpleIdentifierImpl get identifier => super.identifier!;
+
+  @override
+  bool get isConst => keyword?.keyword == Keyword.CONST;
+
+  @override
+  bool get isFinal => keyword?.keyword == Keyword.FINAL;
+
+  @override
+  FormalParameterListImpl? get parameters => _parameters;
+
+  set parameters(FormalParameterList? parameters) {
+    _parameters = _becomeParentOf(parameters as FormalParameterListImpl?);
+  }
+
+  @override
+  TypeAnnotationImpl? get type => _type;
+
+  set type(TypeAnnotation? type) {
+    _type = _becomeParentOf(type as TypeAnnotationImpl);
+  }
+
+  @override
+  TypeParameterListImpl? get typeParameters => _typeParameters;
+
+  set typeParameters(TypeParameterList? typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters as TypeParameterListImpl?);
+  }
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitSuperFormalParameter(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _type?.accept(visitor);
+    identifier.accept(visitor);
+    _typeParameters?.accept(visitor);
+    _parameters?.accept(visitor);
+  }
+}
+
 /// A case in a switch statement.
 ///
 ///    switchCase ::=
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 23b899cdf..b7a9b76 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -391,9 +391,17 @@
           SimpleIdentifier name,
           Token leftBracket,
           List<EnumConstantDeclaration> constants,
+          List<ClassMember> members,
           Token rightBracket) =>
-      EnumDeclarationImpl(comment as CommentImpl?, metadata, enumKeyword,
-          name as SimpleIdentifierImpl, leftBracket, constants, rightBracket);
+      EnumDeclarationImpl(
+          comment as CommentImpl?,
+          metadata,
+          enumKeyword,
+          name as SimpleIdentifierImpl,
+          leftBracket,
+          constants,
+          members,
+          rightBracket);
 
   @override
   ExportDirectiveImpl exportDirective(
@@ -1185,6 +1193,34 @@
       SuperExpressionImpl(superKeyword);
 
   @override
+  SuperFormalParameterImpl superFormalParameter(
+          {Comment? comment,
+          List<Annotation>? metadata,
+          Token? covariantKeyword,
+          Token? requiredKeyword,
+          Token? keyword,
+          TypeAnnotation? type,
+          required Token superKeyword,
+          required Token period,
+          required SimpleIdentifier identifier,
+          TypeParameterList? typeParameters,
+          FormalParameterList? parameters,
+          Token? question}) =>
+      SuperFormalParameterImpl(
+          comment as CommentImpl?,
+          metadata,
+          covariantKeyword,
+          requiredKeyword,
+          keyword,
+          type as TypeAnnotationImpl?,
+          superKeyword,
+          period,
+          identifier as SimpleIdentifierImpl,
+          typeParameters as TypeParameterListImpl?,
+          parameters as FormalParameterListImpl?,
+          question);
+
+  @override
   SwitchCaseImpl switchCase(List<Label> labels, Token keyword,
           Expression expression, Token colon, List<Statement> statements) =>
       SwitchCaseImpl(
diff --git a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
index f9ac572..49dff85 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -953,6 +953,19 @@
   }
 
   @override
+  void visitSuperFormalParameter(SuperFormalParameter node) {
+    _visitNodeList(node.metadata, separator: ' ', suffix: ' ');
+    _visitToken(node.requiredKeyword, suffix: ' ');
+    _visitToken(node.covariantKeyword, suffix: ' ');
+    _visitToken(node.keyword, suffix: ' ');
+    _visitNode(node.type, suffix: ' ');
+    sink.write('super.');
+    _visitNode(node.identifier);
+    _visitNode(node.typeParameters);
+    _visitNode(node.parameters);
+  }
+
+  @override
   void visitSwitchCase(SwitchCase node) {
     _visitNodeList(node.labels, separator: ' ', suffix: ' ');
     sink.write('case ');
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 1b2249a..3bbe4f6 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -1103,6 +1103,19 @@
   }
 
   @override
+  bool visitSuperFormalParameter(SuperFormalParameter node) {
+    SuperFormalParameter other = _other as SuperFormalParameter;
+    return isEqualNodes(
+            node.documentationComment, other.documentationComment) &&
+        _isEqualNodeLists(node.metadata, other.metadata) &&
+        isEqualTokens(node.keyword, other.keyword) &&
+        isEqualNodes(node.type, other.type) &&
+        isEqualTokens(node.superKeyword, other.superKeyword) &&
+        isEqualTokens(node.period, other.period) &&
+        isEqualNodes(node.identifier, other.identifier);
+  }
+
+  @override
   bool visitSwitchCase(SwitchCase node) {
     SwitchCase other = _other as SwitchCase;
     return _isEqualNodeLists(node.labels, other.labels) &&
@@ -1735,6 +1748,9 @@
     } else if (identical(node.stackTraceParameter, _oldNode)) {
       node.stackTraceParameter = _newNode as SimpleIdentifier;
       return true;
+    } else if (identical(node.body, _oldNode)) {
+      node.body = _newNode as Block;
+      return true;
     }
     return visitNode(node);
   }
@@ -2793,6 +2809,21 @@
       visitNode(node);
 
   @override
+  bool visitSuperFormalParameter(covariant SuperFormalParameterImpl node) {
+    if (identical(node.type, _oldNode)) {
+      node.type = _newNode as TypeAnnotation;
+      return true;
+    } else if (identical(node.typeParameters, _oldNode)) {
+      node.typeParameters = _newNode as TypeParameterList;
+      return true;
+    } else if (identical(node.parameters, _oldNode)) {
+      node.parameters = _newNode as FormalParameterList;
+      return true;
+    }
+    return visitNormalFormalParameter(node);
+  }
+
+  @override
   bool visitSwitchCase(covariant SwitchCaseImpl node) {
     if (identical(node.expression, _oldNode)) {
       node.expression = _newNode as Expression;
diff --git a/pkg/analyzer/lib/src/dart/constant/compute.dart b/pkg/analyzer/lib/src/dart/constant/compute.dart
index 295c41c..cb56ffe 100644
--- a/pkg/analyzer/lib/src/dart/constant/compute.dart
+++ b/pkg/analyzer/lib/src/dart/constant/compute.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
@@ -17,8 +17,8 @@
     TypeSystemImpl typeSystem,
     DeclaredVariables declaredVariables,
     List<ConstantEvaluationTarget> constants,
-    ExperimentStatus experimentStatus) {
-  var walker = _ConstantWalker(declaredVariables, experimentStatus);
+    FeatureSet featureSet) {
+  var walker = _ConstantWalker(declaredVariables, featureSet);
 
   for (var constant in constants) {
     var node = walker._getNode(constant);
@@ -47,10 +47,10 @@
 /// [graph.DependencyWalker] for computing constants and detecting cycles.
 class _ConstantWalker extends graph.DependencyWalker<_ConstantNode> {
   final DeclaredVariables declaredVariables;
-  final ExperimentStatus experimentStatus;
+  final FeatureSet featureSet;
   final Map<ConstantEvaluationTarget, _ConstantNode> nodeMap = {};
 
-  _ConstantWalker(this.declaredVariables, this.experimentStatus);
+  _ConstantWalker(this.declaredVariables, this.featureSet);
 
   @override
   void evaluate(_ConstantNode node) {
@@ -79,7 +79,7 @@
   ConstantEvaluationEngine _getEvaluationEngine(_ConstantNode node) {
     return ConstantEvaluationEngine(
       declaredVariables: declaredVariables,
-      isNonNullableByDefault: experimentStatus.non_nullable,
+      isNonNullableByDefault: featureSet.isEnabled(Feature.non_nullable),
     );
   }
 
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index ac9fbb1..3e230c6 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -643,7 +643,7 @@
     TypeAliasElement? viaTypeAlias;
     if (typeElement is TypeAliasElementImpl) {
       if (constructorFunctionType.typeFormals.isNotEmpty &&
-          !typeElement.isProperRename()) {
+          !typeElement.isProperRename) {
         // The type alias is not a proper rename of the aliased class, so
         // the constructor tear-off is distinct from the associated
         // constructor function of the aliased class.
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 094b8b6..313caf6 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -518,6 +518,7 @@
     var typeSystem = TypeSystemImpl(
       implicitCasts: false,
       isNonNullableByDefault: false,
+      strictCasts: false,
       strictInference: false,
       typeProvider: typeProvider,
     );
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d5bc77f..d491590 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -34,8 +34,7 @@
     show Namespace, NamespaceBuilder;
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/generated/element_type_provider.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisContext, AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/source.dart';
@@ -1572,9 +1571,8 @@
   /// of formal parameters, are evaluated.
   void computeConstantDependencies() {
     if (!isConstantEvaluated) {
-      var analysisOptions = context.analysisOptions as AnalysisOptionsImpl;
       computeConstants(library.typeProvider, library.typeSystem,
-          context.declaredVariables, [this], analysisOptions.experimentStatus);
+          context.declaredVariables, [this], library.featureSet);
     }
   }
 }
@@ -1650,9 +1648,8 @@
   /// of this variable could not be computed because of errors.
   DartObject? computeConstantValue() {
     if (evaluationResult == null) {
-      var analysisOptions = context.analysisOptions as AnalysisOptionsImpl;
       computeConstants(library!.typeProvider, library!.typeSystem,
-          context.declaredVariables, [this], analysisOptions.experimentStatus);
+          context.declaredVariables, [this], library!.featureSet);
     }
     return evaluationResult?.value;
   }
@@ -1982,10 +1979,9 @@
   @override
   DartObject? computeConstantValue() {
     if (evaluationResult == null) {
-      var analysisOptions = context.analysisOptions as AnalysisOptionsImpl;
       var library = compilationUnit.library;
       computeConstants(library.typeProvider, library.typeSystem,
-          context.declaredVariables, [this], analysisOptions.experimentStatus);
+          context.declaredVariables, [this], library.featureSet);
     }
     return evaluationResult?.value;
   }
@@ -2033,6 +2029,10 @@
 
 /// A base class for concrete implementations of an [Element].
 abstract class ElementImpl implements Element {
+  static const _metadataFlag_isReady = 1 << 0;
+  static const _metadataFlag_hasDeprecated = 1 << 1;
+  static const _metadataFlag_hasOverride = 1 << 2;
+
   /// An Unicode right arrow.
   @deprecated
   static final String RIGHT_ARROW = " \u2192 ";
@@ -2061,6 +2061,9 @@
   /// A list containing all of the metadata associated with this element.
   List<ElementAnnotation> _metadata = const [];
 
+  /// Cached flags denoting presence of specific annotations in [_metadata].
+  int _metadataFlags = 0;
+
   /// A cached copy of the calculated hashCode for this element.
   int? _cachedHashCode;
 
@@ -2138,14 +2141,7 @@
 
   @override
   bool get hasDeprecated {
-    final metadata = this.metadata;
-    for (var i = 0; i < metadata.length; i++) {
-      var annotation = metadata[i];
-      if (annotation.isDeprecated) {
-        return true;
-      }
-    }
-    return false;
+    return (_getMetadataFlags() & _metadataFlag_hasDeprecated) != 0;
   }
 
   @override
@@ -2277,14 +2273,7 @@
 
   @override
   bool get hasOverride {
-    final metadata = this.metadata;
-    for (var i = 0; i < metadata.length; i++) {
-      var annotation = metadata[i];
-      if (annotation.isOverride) {
-        return true;
-      }
-    }
-    return false;
+    return (_getMetadataFlags() & _metadataFlag_hasOverride) != 0;
   }
 
   /// Return `true` if this element has an annotation of the form
@@ -2587,6 +2576,29 @@
   void visitChildren(ElementVisitor visitor) {
     // There are no children to visit
   }
+
+  /// Return flags that denote presence of a few specific annotations.
+  int _getMetadataFlags() {
+    var result = _metadataFlags;
+
+    // Has at least `_metadataFlag_isReady`.
+    if (result != 0) {
+      return result;
+    }
+
+    final metadata = this.metadata;
+    for (var i = 0; i < metadata.length; i++) {
+      var annotation = metadata[i];
+      if (annotation.isDeprecated) {
+        result |= _metadataFlag_hasDeprecated;
+      } else if (annotation.isOverride) {
+        result |= _metadataFlag_hasOverride;
+      }
+    }
+
+    result |= _metadataFlag_isReady;
+    return _metadataFlags = result;
+  }
 }
 
 /// Abstract base class for elements whose type is guaranteed to be a function
@@ -5482,6 +5494,34 @@
   CompilationUnitElement get enclosingElement =>
       super.enclosingElement as CompilationUnitElement;
 
+  /// Returns whether this alias is a "proper rename" of [aliasedClass], as
+  /// defined in the constructor-tearoffs specification.
+  bool get isProperRename {
+    var aliasedType_ = aliasedType;
+    if (aliasedType_ is! InterfaceType) {
+      return false;
+    }
+    var aliasedClass = aliasedType_.element;
+    var typeArguments = aliasedType_.typeArguments;
+    var typeParameterCount = typeParameters.length;
+    if (typeParameterCount != aliasedClass.typeParameters.length) {
+      return false;
+    }
+    for (var i = 0; i < typeParameterCount; i++) {
+      var bound = typeParameters[i].bound ?? library.typeProvider.dynamicType;
+      var aliasedBound = aliasedClass.typeParameters[i].bound ??
+          library.typeProvider.dynamicType;
+      if (!library.typeSystem.isSubtypeOf(bound, aliasedBound) ||
+          !library.typeSystem.isSubtypeOf(aliasedBound, bound)) {
+        return false;
+      }
+      if (typeParameters[i] != typeArguments[i].element) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   @override
   ElementKind get kind {
     if (isNonFunctionTypeAliasesEnabled) {
@@ -5582,37 +5622,6 @@
     }
   }
 
-  /// Returns whether this alias is a "proper rename" of [aliasedClass], as
-  /// defined in the constructor-tearoffs specification.
-  bool isProperRename() {
-    var aliasedType_ = aliasedType;
-    if (aliasedType_ is! InterfaceType) {
-      return false;
-    }
-    var aliasedClass = aliasedType_.element;
-    var typeArguments = aliasedType_.typeArguments;
-    var typeParameterCount = typeParameters.length;
-    if (typeParameterCount != aliasedClass.typeParameters.length) {
-      return false;
-    }
-    if (typeParameterCount != typeArguments.length) {
-      return false;
-    }
-    for (var i = 0; i < typeParameterCount; i++) {
-      var bound = typeParameters[i].bound ?? library.typeProvider.dynamicType;
-      var aliasedBound = aliasedClass.typeParameters[i].bound ??
-          library.typeProvider.dynamicType;
-      if (!library.typeSystem.isSubtypeOf(bound, aliasedBound) ||
-          !library.typeSystem.isSubtypeOf(aliasedBound, bound)) {
-        return false;
-      }
-      if (typeParameters[i] != typeArguments[i].element) {
-        return false;
-      }
-    }
-    return true;
-  }
-
   void setLinkedData(Reference reference, ElementLinkedData linkedData) {
     this.reference = reference;
     reference.element = this;
diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart
index 6eaa94a..7037407 100644
--- a/pkg/analyzer/lib/src/dart/element/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/element/extensions.dart
@@ -6,6 +6,58 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:meta/meta_meta.dart';
+
+extension ElementAnnotationExtensions on ElementAnnotation {
+  static final Map<String, TargetKind> _targetKindsByName = {
+    for (final kind in TargetKind.values) kind.toString(): kind,
+  };
+
+  /// Return the target kinds defined for this [ElementAnnotation].
+  Set<TargetKind> get targetKinds {
+    final element = this.element;
+    ClassElement? classElement;
+    if (element is PropertyAccessorElement) {
+      if (element.isGetter) {
+        var type = element.returnType;
+        if (type is InterfaceType) {
+          classElement = type.element;
+        }
+      }
+    } else if (element is ConstructorElement) {
+      classElement = element.enclosingElement;
+    }
+    if (classElement == null) {
+      return const <TargetKind>{};
+    }
+    for (var annotation in classElement.metadata) {
+      if (annotation.isTarget) {
+        var value = annotation.computeConstantValue()!;
+        var kinds = <TargetKind>{};
+
+        for (var kindObject in value.getField('kinds')!.toSetValue()!) {
+          // We can't directly translate the index from the analyzed TargetKind
+          // constant to TargetKinds.values because the analyzer from the SDK
+          // may have been compiled with a different version of pkg:meta.
+          var index = kindObject.getField('index')!.toIntValue()!;
+          var targetKindClass =
+              (kindObject.type as InterfaceType).element as EnumElementImpl;
+          // Instead, map constants to their TargetKind by comparing getter
+          // names.
+          var getter = targetKindClass.constants[index];
+          var name = 'TargetKind.${getter.name}';
+
+          var foundTargetKind = _targetKindsByName[name];
+          if (foundTargetKind != null) {
+            kinds.add(foundTargetKind);
+          }
+        }
+        return kinds;
+      }
+    }
+    return const <TargetKind>{};
+  }
+}
 
 extension ElementExtension on Element {
   /// Return `true` if this element is an instance member of a class or mixin.
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index cf52a23..168cc9a 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -401,7 +401,9 @@
       }
     }
 
-    if (getter != null && method != null) {
+    if (getter == null || method == null) {
+      return null;
+    } else {
       return GetterMethodConflict(name: name, getter: getter, method: method);
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 7561115..bb33038 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -20,27 +20,6 @@
 import 'package:analyzer/src/generated/element_type_provider.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
-/// Transforms the given [list] by applying [transform] to all its elements.
-///
-/// If no changes are made (i.e. the return value of [transform] is identical
-/// to its parameter each time it is invoked), the original list is returned.
-List<T> _transformOrShare<T>(List<T> list, T Function(T) transform) {
-  var length = list.length;
-  for (int i = 0; i < length; i++) {
-    var item = list[i];
-    var transformed = transform(item);
-    if (!identical(item, transformed)) {
-      var newList = list.toList();
-      newList[i] = transformed;
-      for (i++; i < length; i++) {
-        newList[i] = transform(list[i]);
-      }
-      return newList;
-    }
-  }
-  return list;
-}
-
 /// The [Type] representing the type `dynamic`.
 class DynamicTypeImpl extends TypeImpl implements DynamicType {
   /// The unique instance of this class.
@@ -247,16 +226,12 @@
 
     var substitution = Substitution.fromPairs(typeFormals, argumentTypes);
 
-    ParameterElement transformParameter(ParameterElement p) {
-      return p.copyWith(
-        type: substitution.substituteType(p.type),
-      );
-    }
-
     return FunctionTypeImpl(
       returnType: substitution.substituteType(returnType),
       typeFormals: const [],
-      parameters: _transformOrShare(parameters, transformParameter),
+      parameters: parameters
+          .map((p) => p.copyWith(type: substitution.substituteType(p.type)))
+          .toList(),
       nullabilitySuffix: nullabilitySuffix,
     );
   }
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index 1ffe3d4..5e1389e 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -567,12 +567,13 @@
   InstantiatedTypeAliasElementImpl? _mapAlias(
     InstantiatedTypeAliasElement? alias,
   ) {
-    if (alias != null) {
-      return InstantiatedTypeAliasElementImpl(
-        element: alias.element,
-        typeArguments: _mapList(alias.typeArguments),
-      );
+    if (alias == null) {
+      return null;
     }
+    return InstantiatedTypeAliasElementImpl(
+      element: alias.element,
+      typeArguments: _mapList(alias.typeArguments),
+    );
   }
 
   List<DartType> _mapList(List<DartType> types) {
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index ef329f4..b38a654 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -45,6 +45,11 @@
   /// This affects the behavior of [isAssignableTo].
   bool implicitCasts;
 
+  /// True if "strict casts" should be enforced.
+  ///
+  /// This affects the behavior of [isAssignableTo].
+  bool strictCasts;
+
   /// A flag indicating whether inference failures are allowed, off by default.
   ///
   /// This option is experimental and subject to change.
@@ -71,6 +76,7 @@
   TypeSystemImpl({
     required this.implicitCasts,
     required this.isNonNullableByDefault,
+    required this.strictCasts,
     required this.strictInference,
     required TypeProvider typeProvider,
   }) : typeProvider = typeProvider as TypeProviderImpl {
@@ -699,9 +705,10 @@
       }
     }
 
-    // First make sure --no-implicit-casts disables all downcasts, including
-    // dynamic casts.
-    if (!implicitCasts) {
+    // First make sure that the static analysis options, `implicit-casts: false`
+    // and `strict-casts: true` disable all downcasts, including casts from
+    // `dynamic`.
+    if (!implicitCasts || strictCasts) {
       return false;
     }
 
@@ -1537,9 +1544,11 @@
 
   void updateOptions({
     required bool implicitCasts,
+    required bool strictCasts,
     required bool strictInference,
   }) {
     this.implicitCasts = implicitCasts;
+    this.strictCasts = strictCasts;
     this.strictInference = strictInference;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
index 4264f45..e794a9b 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
@@ -18,6 +18,34 @@
   /**
    * No parameters.
    */
+  static const FfiCode ABI_SPECIFIC_INTEGER_MAPPING_EXTRA = FfiCode(
+    'ABI_SPECIFIC_INTEGER_MAPPING_EXTRA',
+    "Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a 'NativeType' integer with a fixed size.",
+    correctionMessage: "Try removing the extra annotation.",
+  );
+
+  /**
+   * No parameters.
+   */
+  static const FfiCode ABI_SPECIFIC_INTEGER_MAPPING_MISSING = FfiCode(
+    'ABI_SPECIFIC_INTEGER_MAPPING_MISSING',
+    "Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a 'NativeType' integer with a fixed size.",
+    correctionMessage: "Try adding an annotation.",
+  );
+
+  /**
+   * No parameters.
+   */
+  static const FfiCode ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED = FfiCode(
+    'ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED',
+    "Only mappings to 'Int8', 'Int16', 'Int32', 'Int64', 'Uint8', 'Uint16', 'UInt32', and 'Uint64' are supported.",
+    correctionMessage:
+        "Try changing the value to 'Int8', 'Int16', 'Int32', 'Int64', 'Uint8', 'Uint16', 'UInt32', or 'Uint64'.",
+  );
+
+  /**
+   * No parameters.
+   */
   static const FfiCode ANNOTATION_ON_POINTER_FIELD = FfiCode(
     'ANNOTATION_ON_POINTER_FIELD',
     "Fields in a struct class whose type is 'Pointer' should not have any annotations.",
@@ -302,9 +330,9 @@
    */
   static const FfiCode NON_SIZED_TYPE_ARGUMENT = FfiCode(
     'NON_SIZED_TYPE_ARGUMENT',
-    "Type arguments to '{0}' can't have the type '{1}'. They can only be declared as native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct' or 'Union'.",
+    "Type arguments to '{0}' can't have the type '{1}'. They can only be declared as native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct', 'Union', or 'AbiSpecificInteger'.",
     correctionMessage:
-        "Try using a native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct' or 'Union'.",
+        "Try using a native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct', 'Union', or 'AbiSpecificInteger'.",
   );
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index ecb67b1..fae4e5e 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -3140,7 +3140,7 @@
   // ```
   static const HintCode UNDEFINED_REFERENCED_PARAMETER = HintCode(
     'UNDEFINED_REFERENCED_PARAMETER',
-    "The parameter '{0}' is not defined by '{1}'.",
+    "The parameter '{0}' isn't defined by '{1}'.",
     hasPublishedDocs: true,
   );
 
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index ef663ca..10b3313 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -208,9 +208,7 @@
 
   @override
   Uri? pathToUri(String path, {String? containingPath}) {
-    var fileUri = resourceProvider.pathContext.toUri(path);
-    var fileSource = sourceFactory.forUri2(fileUri)!;
-    return sourceFactory.restoreUri(fileSource);
+    return sourceFactory.pathToUri(path);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
index e904ee0..0b096be 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -197,7 +197,7 @@
   /// Compute [_constants] in all units.
   void _computeConstants() {
     computeConstants(_typeProvider, _typeSystem, _declaredVariables,
-        _constants.toList(), _analysisOptions.experimentStatus);
+        _constants.toList(), _libraryElement.featureSet);
   }
 
   void _computeDiagnostics({
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 7bd4630..80357fb 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -335,10 +335,7 @@
       return file;
     }
 
-    var fileUri = _resourceProvider.pathContext.toUri(path);
-    var uri = _sourceFactory.restoreUri(
-      _FakeSource(path, fileUri),
-    );
+    var uri = _sourceFactory.pathToUri(path);
     if (uri == null) {
       throw StateError('Unable to convert path to URI: $path');
     }
@@ -428,11 +425,7 @@
   }
 
   String? getPathForUri(Uri uri) {
-    var source = _sourceFactory.forUri2(uri);
-    if (source == null) {
-      return null;
-    }
-    return source.fullName;
+    return _sourceFactory.forUri2(uri)?.fullName;
   }
 
   /// Computes the set of [FileState]'s used/not used to analyze the given
@@ -593,19 +586,6 @@
   });
 }
 
-class _FakeSource implements Source {
-  @override
-  final String fullName;
-
-  @override
-  final Uri uri;
-
-  _FakeSource(this.fullName, this.uri);
-
-  @override
-  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
 class _FileStateFiles {
   final List<FileState> imported = [];
   final List<FileState> exported = [];
@@ -712,19 +692,28 @@
     return _fsState._resourceProvider.getFile(path);
   }
 
+  Uri? resolveRelativeUriStr(String relativeUriStr) {
+    if (relativeUriStr.isEmpty) {
+      return null;
+    }
+
+    Uri relativeUri;
+    try {
+      relativeUri = Uri.parse(relativeUriStr);
+    } on FormatException {
+      return null;
+    }
+
+    return resolveRelativeUri(uri, relativeUri);
+  }
+
   FileState? _fileForRelativeUri({
     FileState? containingLibrary,
     required String relativeUri,
     required OperationPerformanceImpl performance,
   }) {
-    if (relativeUri.isEmpty) {
-      return null;
-    }
-
-    Uri absoluteUri;
-    try {
-      absoluteUri = resolveRelativeUri(uri, Uri.parse(relativeUri));
-    } on FormatException {
+    var absoluteUri = resolveRelativeUriStr(relativeUri);
+    if (absoluteUri == null) {
       return null;
     }
 
@@ -760,6 +749,7 @@
         }
       }
     }
+    return null;
   }
 
   _ContentWithDigest _getContent() {
@@ -890,51 +880,46 @@
     }
 
     var libraryUri = unlinked.unit.partOfUri;
-    if (libraryUri != null) {
-      location._fsState.testView.partsDiscoveredLibraries.add(location.path);
-      return _partOfLibrary = location._fileForRelativeUri(
-        relativeUri: libraryUri,
-        performance: performance,
-      );
+    if (libraryUri == null) {
+      return null;
     }
+    location._fsState.testView.partsDiscoveredLibraries.add(location.path);
+    return _partOfLibrary = location._fileForRelativeUri(
+      relativeUri: libraryUri,
+      performance: performance,
+    );
   }
 
   void _prefetchDirectReferences() {
-    if (location._fsState.prefetchFiles == null) {
+    var prefetchFiles = location._fsState.prefetchFiles;
+    if (prefetchFiles == null) {
       return;
     }
 
     var paths = <String>{};
 
-    /// TODO(scheglov) This is duplicate.
-    void findPathForUri(String relativeUri) {
-      if (relativeUri.isEmpty) {
-        return;
-      }
-      Uri absoluteUri;
-      try {
-        absoluteUri = resolveRelativeUri(location.uri, Uri.parse(relativeUri));
-      } on FormatException {
-        return;
-      }
-      var p = location._fsState.getPathForUri(absoluteUri);
-      if (p != null) {
-        paths.add(p);
+    void addRelativeUri(String relativeUri) {
+      var absoluteUri = location.resolveRelativeUriStr(relativeUri);
+      if (absoluteUri != null) {
+        var path = location._fsState.getPathForUri(absoluteUri);
+        if (path != null) {
+          paths.add(path);
+        }
       }
     }
 
     var unlinkedUnit = unlinked.unit;
     for (var directive in unlinkedUnit.imports) {
-      findPathForUri(directive.uri);
+      addRelativeUri(directive.uri);
     }
     for (var directive in unlinkedUnit.exports) {
-      findPathForUri(directive.uri);
+      addRelativeUri(directive.uri);
     }
     for (var uri in unlinkedUnit.parts) {
-      findPathForUri(uri);
+      addRelativeUri(uri);
     }
 
-    location._fsState.prefetchFiles!(paths.toList());
+    prefetchFiles(paths.toList());
   }
 
   static CompilationUnitImpl parse(AnalysisErrorListener errorListener,
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 89c1fe0..e9eec90 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/dart/analysis/context_root.dart';
@@ -17,7 +18,6 @@
 import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/results.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/micro/analysis_context.dart';
 import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/dart/micro/library_analyzer.dart';
@@ -46,19 +46,20 @@
 
 class CiderSearchMatch {
   final String path;
-  final List<int> offsets;
+  final List<CharacterLocation?> startPositions;
 
-  CiderSearchMatch(this.path, this.offsets);
+  CiderSearchMatch(this.path, this.startPositions);
 
   @override
   bool operator ==(Object object) =>
       object is CiderSearchMatch &&
       path == object.path &&
-      const ListEquality<int>().equals(offsets, object.offsets);
+      const ListEquality<CharacterLocation?>()
+          .equals(startPositions, object.startPositions);
 
   @override
   String toString() {
-    return '($path, $offsets)';
+    return '($path, $startPositions)';
   }
 }
 
@@ -184,29 +185,46 @@
     removedCacheIds.addAll(libraryContext!.collectSharedDataIdentifiers());
   }
 
-  /// Looks for references to the Element at the given offset and path. All the
-  /// files currently cached by the resolver are searched, generated files are
-  /// ignored.
-  List<CiderSearchMatch> findReferences(int offset, String path,
+  /// Looks for references to the given Element. All the files currently
+  ///  cached by the resolver are searched, generated files are ignored.
+  List<CiderSearchMatch> findReferences(Element element,
       {OperationPerformanceImpl? performance}) {
-    var references = <CiderSearchMatch>[];
-    var unit = resolve(path: path);
-    var node = NodeLocator(offset).searchWithin(unit.unit);
-    var element = getElementOfNode(node);
-    if (element != null) {
+    return logger.run('findReferences for ${element.name}', () {
+      var references = <CiderSearchMatch>[];
+
+      void collectReferences(
+          String path, OperationPerformanceImpl performance) {
+        performance.run('collectReferences', (_) {
+          var resolved = resolve(path: path);
+          var collector = ReferencesCollector(element);
+          resolved.unit.accept(collector);
+          var offsets = collector.offsets;
+          if (offsets.isNotEmpty) {
+            var lineInfo = resolved.unit.lineInfo;
+            references.add(CiderSearchMatch(
+                path,
+                offsets
+                    .map((offset) => lineInfo?.getLocation(offset))
+                    .toList()));
+          }
+        });
+      }
+
+      performance ??= OperationPerformanceImpl('<default>');
       // TODO(keertip): check if element is named constructor.
-      var result = fsState!.getFilesContaining(element.displayName);
-      result.forEach((filePath) {
-        var resolved = resolve(path: filePath);
-        var collector = ReferencesCollector(element);
-        resolved.unit.accept(collector);
-        var offsets = collector.offsets;
-        if (offsets.isNotEmpty) {
-          references.add(CiderSearchMatch(filePath, offsets));
-        }
-      });
-    }
-    return references;
+      if (element is LocalVariableElement ||
+          (element is ParameterElement && !element.isNamed)) {
+        collectReferences(element.source!.fullName, performance!);
+      } else {
+        var result = performance!.run('getFilesContaining', (performance) {
+          return fsState!.getFilesContaining(element.displayName);
+        });
+        result.forEach((filePath) {
+          collectReferences(filePath, performance!);
+        });
+      }
+      return references;
+    });
   }
 
   ErrorsResult getErrors({
@@ -635,6 +653,7 @@
         return file;
       }
     }
+    return null;
   }
 
   /// Return the analysis options.
diff --git a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
index aa594c5..0391099 100644
--- a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
@@ -263,6 +263,19 @@
     _visitArguments(node, whyNotPromotedList);
   }
 
+  void _localVariable(
+    AnnotationImpl node,
+    VariableElement element,
+    List<WhyNotPromotedGetter> whyNotPromotedList,
+  ) {
+    if (!element.isConst || node.arguments != null) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.INVALID_ANNOTATION, node);
+    }
+
+    _visitArguments(node, whyNotPromotedList);
+  }
+
   void _propertyAccessorElement(
     AnnotationImpl node,
     SimpleIdentifierImpl name,
@@ -393,8 +406,8 @@
       return;
     }
 
-    // TODO(scheglov) Must be const.
     if (element1 is VariableElement) {
+      _localVariable(node, element1, whyNotPromotedList);
       return;
     }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index da8742a..dedb7b5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -40,7 +40,7 @@
 
   ErrorReporter get _errorReporter => _resolver.errorReporter;
 
-  NullabilitySuffix get _nullabilitySuffixForTypeNames =>
+  NullabilitySuffix get _nullabilitySuffix =>
       _isNonNullableByDefault ? NullabilitySuffix.none : NullabilitySuffix.star;
 
   void resolve(FunctionReferenceImpl node) {
@@ -64,7 +64,10 @@
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
           typeArguments,
-          [function.constructorName.type2.name, function.constructorName.name!],
+          [
+            function.constructorName.type2.name.toSource(),
+            function.constructorName.name!.name
+          ],
         );
         _resolve(node: node, rawType: function.staticType);
       }
@@ -310,7 +313,7 @@
     );
     var type = element.instantiate(
       typeArguments: typeArguments,
-      nullabilitySuffix: _nullabilitySuffixForTypeNames,
+      nullabilitySuffix: _nullabilitySuffix,
     );
     _resolveTypeLiteral(node: node, instantiatedType: type, name: name);
   }
@@ -783,8 +786,9 @@
       CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
     );
     var type = element.instantiate(
-        typeArguments: typeArguments,
-        nullabilitySuffix: _nullabilitySuffixForTypeNames);
+      typeArguments: typeArguments,
+      nullabilitySuffix: _nullabilitySuffix,
+    );
     _resolveTypeLiteral(node: node, instantiatedType: type, name: typeAlias);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 36357aa..d7a8fd2 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -129,10 +129,11 @@
       }
     }
 
-    if (typeParameters != null && rawElement != null) {
-      rawElement = _resolver.toLegacyElement(rawElement);
-      return ConstructorElementToInfer(typeParameters, rawElement);
+    if (typeParameters == null || rawElement == null) {
+      return null;
     }
+    rawElement = _resolver.toLegacyElement(rawElement);
+    return ConstructorElementToInfer(typeParameters, rawElement);
   }
 
   FunctionType? inferArgumentTypesForGeneric(AstNode inferenceNode,
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index 157ba4c..d0f35da 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -240,7 +240,7 @@
         node: node,
         requested: writeElementRequested,
         recovery: writeElementRecovery,
-        receiverTypeObject: null,
+        receiverType: null,
       );
     }
 
@@ -469,7 +469,7 @@
           node: propertyName,
           requested: null,
           recovery: result.getter,
-          receiverTypeObject: targetType,
+          receiverType: targetType,
         );
       }
     }
@@ -543,7 +543,7 @@
           node: propertyName,
           requested: null,
           recovery: writeElementRecovery,
-          receiverTypeObject: typeReference.displayName,
+          receiverType: typeReference.thisType,
         );
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 0fb4f74..2e361ad 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -63,7 +63,7 @@
   final bool _isNonNullableByDefault;
   final ErrorReporter _errorReporter;
   final AstRewriter _astRewriter;
-  final NamedTypeResolver _typeNameResolver;
+  final NamedTypeResolver _namedTypeResolver;
 
   /// This index is incremented every time we visit a [LibraryDirective].
   /// There is just one [LibraryElement], so we can support only one node.
@@ -103,7 +103,7 @@
       isNonNullableByDefault: isNonNullableByDefault,
     );
 
-    var typeNameResolver = NamedTypeResolver(
+    var namedTypeResolver = NamedTypeResolver(
       libraryElement,
       typeProvider,
       isNonNullableByDefault,
@@ -117,7 +117,7 @@
       isNonNullableByDefault,
       errorReporter,
       AstRewriter(errorReporter, typeProvider),
-      typeNameResolver,
+      namedTypeResolver,
       nameScope,
       elementWalker,
       ElementHolder(unitElement),
@@ -131,7 +131,7 @@
     this._isNonNullableByDefault,
     this._errorReporter,
     this._astRewriter,
-    this._typeNameResolver,
+    this._namedTypeResolver,
     this._nameScope,
     this._elementWalker,
     this._elementHolder,
@@ -218,7 +218,7 @@
   void visitClassDeclaration(covariant ClassDeclarationImpl node) {
     ClassElementImpl element = _elementWalker!.getClass();
     node.name.staticElement = element;
-    _typeNameResolver.enclosingClass = element;
+    _namedTypeResolver.enclosingClass = element;
 
     node.metadata.accept(this);
     _setElementAnnotations(node.metadata, element.metadata);
@@ -247,14 +247,14 @@
       });
     });
 
-    _typeNameResolver.enclosingClass = null;
+    _namedTypeResolver.enclosingClass = null;
   }
 
   @override
   void visitClassTypeAlias(covariant ClassTypeAliasImpl node) {
     ClassElementImpl element = _elementWalker!.getClass();
     node.name.staticElement = element;
-    _typeNameResolver.enclosingClass = element;
+    _namedTypeResolver.enclosingClass = element;
 
     node.metadata.accept(this);
     _setElementAnnotations(node.metadata, element.metadata);
@@ -275,7 +275,7 @@
       });
     });
 
-    _typeNameResolver.enclosingClass = null;
+    _namedTypeResolver.enclosingClass = null;
   }
 
   @override
@@ -885,11 +885,11 @@
   void visitNamedType(covariant NamedTypeImpl node) {
     node.typeArguments?.accept(this);
 
-    _typeNameResolver.nameScope = _nameScope;
-    _typeNameResolver.resolve(node);
+    _namedTypeResolver.nameScope = _nameScope;
+    _namedTypeResolver.resolve(node);
 
-    if (_typeNameResolver.rewriteResult != null) {
-      _typeNameResolver.rewriteResult!.accept(this);
+    if (_namedTypeResolver.rewriteResult != null) {
+      _namedTypeResolver.rewriteResult!.accept(this);
     }
   }
 
@@ -1242,11 +1242,11 @@
     if (redirectedConstructor == null) return;
 
     var namedType = redirectedConstructor.type2;
-    _typeNameResolver.redirectedConstructor_namedType = namedType;
+    _namedTypeResolver.redirectedConstructor_namedType = namedType;
 
     redirectedConstructor.accept(this);
 
-    _typeNameResolver.redirectedConstructor_namedType = null;
+    _namedTypeResolver.redirectedConstructor_namedType = null;
   }
 
   /// Return the [InterfaceType] of the given [namedType].
@@ -1258,11 +1258,11 @@
   /// classes).
   void _resolveType(NamedTypeImpl namedType, ErrorCode errorCode,
       {bool asClass = false}) {
-    _typeNameResolver.classHierarchy_namedType = namedType;
+    _namedTypeResolver.classHierarchy_namedType = namedType;
     visitNamedType(namedType);
-    _typeNameResolver.classHierarchy_namedType = null;
+    _namedTypeResolver.classHierarchy_namedType = null;
 
-    if (_typeNameResolver.hasErrorReported) {
+    if (_namedTypeResolver.hasErrorReported) {
       return;
     }
 
@@ -1303,12 +1303,12 @@
     if (clause == null) return;
 
     for (var namedType in clause.mixinTypes2) {
-      _typeNameResolver.withClause_namedType = namedType;
+      _namedTypeResolver.withClause_namedType = namedType;
       _resolveType(
         namedType as NamedTypeImpl,
         CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
       );
-      _typeNameResolver.withClause_namedType = null;
+      _namedTypeResolver.withClause_namedType = null;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
index 6e47fa5..0016d66 100644
--- a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
@@ -70,9 +70,9 @@
   /// This method should only be called in generator functions.
   void _checkForYieldOfInvalidType(
     BodyInferenceContext bodyContext,
-    YieldStatement node,
-    bool isYieldEach,
-  ) {
+    YieldStatement node, {
+    required bool isYieldEach,
+  }) {
     var expression = node.expression;
     var expressionType = expression.typeOrThrow;
 
@@ -88,11 +88,27 @@
     var imposedReturnType = bodyContext.imposedType;
     if (imposedReturnType != null &&
         !_typeSystem.isAssignableTo(impliedReturnType, imposedReturnType)) {
-      _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
-        expression,
-        [impliedReturnType, imposedReturnType],
+      if (isYieldEach) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE,
+          expression,
+          [impliedReturnType, imposedReturnType],
+        );
+        return;
+      }
+      var imposedSequenceType = imposedReturnType.asInstanceOf(
+        bodyContext.isSynchronous
+            ? _typeProvider.iterableElement
+            : _typeProvider.streamElement,
       );
+      if (imposedSequenceType != null) {
+        var imposedValueType = imposedSequenceType.typeArguments[0];
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
+          expression,
+          [expressionType, imposedValueType],
+        );
+      }
       return;
     }
 
@@ -109,7 +125,7 @@
 
       if (!_typeSystem.isAssignableTo(impliedReturnType, requiredReturnType)) {
         _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
+          CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE,
           expression,
           [impliedReturnType, requiredReturnType],
         );
@@ -134,7 +150,8 @@
 
     bodyContext.addYield(node);
 
-    _checkForYieldOfInvalidType(bodyContext, node, node.star != null);
+    _checkForYieldOfInvalidType(bodyContext, node,
+        isYieldEach: node.star != null);
     _checkForUseOfVoidResult(node.expression);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 35fb194..60cfa66 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -13,7 +13,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:pub_semver/pub_semver.dart';
 import 'package:yaml/yaml.dart';
 
@@ -46,17 +46,6 @@
   @override
   List<String> get uris => libraryMap.uris;
 
-  /// Add the extensions from one or more sdk extension files to this sdk. The
-  /// [extensions] should be a table mapping the names of extensions to the
-  /// paths where those extensions can be found.
-  void addExtensions(Map<String, String> extensions) {
-    extensions.forEach((String uri, String path) {
-      SdkLibraryImpl library = SdkLibraryImpl(uri);
-      library.path = path;
-      libraryMap.setLibrary(uri, library);
-    });
-  }
-
   /// Return info for debugging https://github.com/dart-lang/sdk/issues/35226.
   Map<String, Object> debugInfo() {
     return <String, Object>{
@@ -139,6 +128,23 @@
     return source;
   }
 
+  @override
+  Uri? pathToUri(String path) {
+    var file = resourceProvider.getFile(path);
+
+    var uriStr = _getPath(file);
+    if (uriStr == null) {
+      return null;
+    }
+
+    try {
+      return Uri.parse(uriStr);
+    } on FormatException {
+      return null;
+    }
+  }
+
+  /// TODO(scheglov) This name is misleading, returns `dart:foo/bar.dart`.
   String? _getPath(File file) {
     List<SdkLibrary> libraries = libraryMap.sdkLibraries;
     int length = libraries.length;
diff --git a/pkg/analyzer/lib/src/error/assignment_verifier.dart b/pkg/analyzer/lib/src/error/assignment_verifier.dart
index a995629..97cbefd 100644
--- a/pkg/analyzer/lib/src/error/assignment_verifier.dart
+++ b/pkg/analyzer/lib/src/error/assignment_verifier.dart
@@ -25,14 +25,14 @@
   /// element, which is definitely not a valid write target. We want to report
   /// a good error about this.
   ///
-  /// The [receiverTypeObject] might be a [DartType] or [String], and when
-  /// it is not `null`, we report [CompileTimeErrorCode.UNDEFINED_SETTER]
-  /// instead of a more generic [CompileTimeErrorCode.UNDEFINED_IDENTIFIER].
+  /// When the [receiverType] is not `null`, we report
+  /// [CompileTimeErrorCode.UNDEFINED_SETTER] instead of a more generic
+  /// [CompileTimeErrorCode.UNDEFINED_IDENTIFIER].
   void verify({
     required SimpleIdentifier node,
     required Element? requested,
     required Element? recovery,
-    required Object? receiverTypeObject,
+    required DartType? receiverType,
   }) {
     if (requested != null) {
       if (requested is VariableElement) {
@@ -106,11 +106,11 @@
       if (node.isSynthetic) {
         return;
       }
-      if (receiverTypeObject != null) {
+      if (receiverType != null) {
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.UNDEFINED_SETTER,
           node,
-          [node.name, receiverTypeObject],
+          [node.name, receiverType],
         );
       } else {
         _errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 85441dc..45dce24 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -42,11 +42,7 @@
 /// Instances of the class `BestPracticesVerifier` traverse an AST structure
 /// looking for violations of Dart best practices.
 class BestPracticesVerifier extends RecursiveAstVisitor<void> {
-  static const String _TO_INT_METHOD_NAME = "toInt";
-
-  static final Map<String, TargetKind> _targetKindsByName = {
-    for (final kind in TargetKind.values) kind.toString(): kind,
-  };
+  static const String toIntMethodName = "toInt";
 
   /// The class containing the AST nodes being visited, or `null` if we are not
   /// in the scope of a class.
@@ -85,7 +81,7 @@
   final WorkspacePackage? _workspacePackage;
 
   /// The [LinterContext] used for possible const calculations.
-  late final LinterContext _linterContext;
+  final LinterContext _linterContext;
 
   /// Is `true` if the library being analyzed is non-nullable by default.
   final bool _isNonNullableByDefault;
@@ -93,9 +89,10 @@
   /// True if inference failures should be reported, otherwise false.
   final bool _strictInference;
 
-  /// Create a new instance of the [BestPracticesVerifier].
-  ///
-  /// @param errorReporter the error reporter
+  /// Whether [_currentLibrary] is part of its containing package's public API.
+  late final bool _inPublicPackageApi = _workspacePackage != null &&
+      _workspacePackage!.sourceIsInPublicApi(_currentLibrary.source);
+
   BestPracticesVerifier(
     this._errorReporter,
     TypeProviderImpl typeProvider,
@@ -121,28 +118,22 @@
         _errorHandlerVerifier =
             ErrorHandlerVerifier(_errorReporter, typeProvider, typeSystem),
         _nullSafeApiVerifier = NullSafeApiVerifier(_errorReporter, typeSystem),
-        _workspacePackage = workspacePackage {
+        _workspacePackage = workspacePackage,
+        _linterContext = LinterContextImpl(
+          [],
+          LinterContextUnit(content, unit),
+          declaredVariables,
+          typeProvider,
+          typeSystem,
+          inheritanceManager,
+          analysisOptions,
+          workspacePackage,
+        ) {
     _deprecatedVerifier.pushInDeprecatedValue(_currentLibrary.hasDeprecated);
     _inDoNotStoreMember = _currentLibrary.hasDoNotStore;
-
-    _linterContext = LinterContextImpl(
-      [],
-      LinterContextUnit(content, unit),
-      declaredVariables,
-      typeProvider,
-      _typeSystem,
-      _inheritanceManager,
-      analysisOptions,
-      _workspacePackage,
-    );
     _invalidAccessVerifier._inTestDirectory = _linterContext.inTestDir(unit);
   }
 
-  bool get _inPublicPackageApi {
-    return _workspacePackage != null &&
-        _workspacePackage!.sourceIsInPublicApi(_currentLibrary.source);
-  }
-
   @override
   void visitAnnotation(Annotation node) {
     var element = node.elementAnnotation;
@@ -305,7 +296,7 @@
       }
     }
 
-    var kinds = _targetKindsFor(element);
+    var kinds = element.targetKinds;
     if (kinds.isNotEmpty) {
       if (!_isValidTarget(parent, kinds)) {
         var invokedElement = element.element!;
@@ -407,7 +398,7 @@
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     var element = node.declaredElement as ConstructorElementImpl;
-    if (!_isNonNullableByDefault && node.declaredElement!.isFactory) {
+    if (!_isNonNullableByDefault && element.isFactory) {
       if (node.body is BlockFunctionBody) {
         // Check the block for a return statement, if not, create the hint.
         if (!ExitDetector.exits(node.body)) {
@@ -482,9 +473,10 @@
           // always named, so we can safely assume
           // `overriddenElement.enclosingElement.name` is non-`null`.
           _errorReporter.reportErrorForNode(
-              HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER,
-              field.name,
-              [field.name, overriddenElement.enclosingElement.name!]);
+              HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, field.name, [
+            field.name.name,
+            overriddenElement.enclosingElement.displayName
+          ]);
         }
         if (!_invalidAccessVerifier._inTestDirectory) {
           _checkForAssignmentOfDoNotStore(field.initializer);
@@ -671,7 +663,7 @@
         _errorReporter.reportErrorForNode(
             HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER,
             node.name,
-            [node.name, overriddenElement.enclosingElement.name!]);
+            [node.name.name, overriddenElement.enclosingElement.displayName]);
       }
 
       super.visitMethodDeclaration(node);
@@ -907,7 +899,7 @@
           _wrapParenthesizedExpression(parent);
       var grandParent = parenthesizedExpression.parent;
       if (grandParent is MethodInvocation) {
-        if (_TO_INT_METHOD_NAME == grandParent.methodName.name &&
+        if (toIntMethodName == grandParent.methodName.name &&
             grandParent.argumentList.arguments.isEmpty) {
           _errorReporter.reportErrorForNode(
               HintCode.DIVISION_OPTIMIZATION, grandParent);
@@ -987,8 +979,6 @@
       return false;
     }
 
-    /// Return `true` if the given class [element] defines a non-final instance
-    /// field.
     Iterable<String> nonFinalInstanceFields(ClassElement element) {
       return element.fields
           .where((FieldElement field) =>
@@ -996,8 +986,6 @@
           .map((FieldElement field) => '${element.name}.${field.name}');
     }
 
-    /// Return `true` if the given class [element] defines or inherits a
-    /// non-final field.
     Iterable<String> definedOrInheritedNonFinalInstanceFields(
         ClassElement element, HashSet<ClassElement> visited) {
       Iterable<String> nonFinalFields = [];
@@ -1716,51 +1704,6 @@
     return false;
   }
 
-  /// Return the target kinds defined for the given [annotation].
-  Set<TargetKind> _targetKindsFor(ElementAnnotation annotation) {
-    var element = annotation.element;
-    ClassElement? classElement;
-    if (element is PropertyAccessorElement) {
-      if (element.isGetter) {
-        var type = element.returnType;
-        if (type is InterfaceType) {
-          classElement = type.element;
-        }
-      }
-    } else if (element is ConstructorElement) {
-      classElement = element.enclosingElement;
-    }
-    if (classElement == null) {
-      return const <TargetKind>{};
-    }
-    for (var annotation in classElement.metadata) {
-      if (annotation.isTarget) {
-        var value = annotation.computeConstantValue()!;
-        var kinds = <TargetKind>{};
-
-        for (var kindObject in value.getField('kinds')!.toSetValue()!) {
-          // We can't directly translate the index from the analyzed TargetKind
-          // constant to TargetKinds.values because the analyzer from the SDK
-          // may have been compiled with a different version of pkg:meta.
-          var index = kindObject.getField('index')!.toIntValue()!;
-          var targetKindClass =
-              (kindObject.type as InterfaceType).element as EnumElementImpl;
-          // Instead, map constants to their TargetKind by comparing getter
-          // names.
-          var getter = targetKindClass.constants[index];
-          var name = 'TargetKind.${getter.name}';
-
-          var foundTargetKind = _targetKindsByName[name];
-          if (foundTargetKind != null) {
-            kinds.add(foundTargetKind);
-          }
-        }
-        return kinds;
-      }
-    }
-    return const <TargetKind>{};
-  }
-
   /// Checks for the passed as expression for the [HintCode.UNNECESSARY_CAST]
   /// hint code.
   ///
@@ -1856,16 +1799,15 @@
   final LibraryElement _library;
   final WorkspacePackage? _workspacePackage;
 
-  late final bool _inTemplateSource;
+  final bool _inTemplateSource;
   late final bool _inTestDirectory;
 
   ClassElement? _enclosingClass;
 
   _InvalidAccessVerifier(
-      this._errorReporter, this._library, this._workspacePackage) {
-    var path = _library.source.fullName;
-    _inTemplateSource = path.contains(_templateExtension);
-  }
+      this._errorReporter, this._library, this._workspacePackage)
+      : _inTemplateSource =
+            _library.source.fullName.contains(_templateExtension);
 
   /// Produces a hint if [identifier] is accessed from an invalid location.
   ///
diff --git a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
index 108cc22..6d06e03 100644
--- a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
+++ b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
@@ -62,6 +62,17 @@
       } else {
         _errorReporter.reportErrorForNode(errorCode, expression, arguments);
       }
+    } else if (!_resolver.definingLibrary.isNonNullableByDefault) {
+      if (expression is InstanceCreationExpression) {
+        // In pre-null safety code, an implicit cast from a supertype is allowed
+        // unless the expression is an explicit instance creation expression,
+        // with the idea that the cast would likely fail at runtime.
+        var constructor = expression.constructorName.staticElement;
+        if (constructor == null || !constructor.isFactory) {
+          _errorReporter.reportErrorForNode(errorCode, expression, arguments);
+          return;
+        }
+      }
     }
   }
 
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index cd94929..be02c3e4 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -7381,51 +7381,6 @@
   );
 
   /**
-   * No parameters.
-   */
-  // #### Description
-  //
-  // The analyzer produces this diagnostic when the initializer list of a
-  // constructor contains an invocation of a constructor in the superclass, but
-  // the invocation isn't the last item in the initializer list.
-  //
-  // #### Example
-  //
-  // The following code produces this diagnostic because the invocation of the
-  // superclass' constructor isn't the last item in the initializer list:
-  //
-  // ```dart
-  // class A {
-  //   A(int x);
-  // }
-  //
-  // class B extends A {
-  //   B(int x) : [!super!](x), assert(x >= 0);
-  // }
-  // ```
-  //
-  // #### Common fixes
-  //
-  // Move the invocation of the superclass' constructor to the end of the
-  // initializer list:
-  //
-  // ```dart
-  // class A {
-  //   A(int x);
-  // }
-  //
-  // class B extends A {
-  //   B(int x) : assert(x >= 0), super(x);
-  // }
-  // ```
-  static const CompileTimeErrorCode INVALID_SUPER_INVOCATION =
-      CompileTimeErrorCode(
-    'INVALID_SUPER_INVOCATION',
-    "The superclass call must be last in an initializer list: '{0}'.",
-    hasPublishedDocs: true,
-  );
-
-  /**
    * Parameters:
    * 0: the name of the type parameter
    */
@@ -12892,6 +12847,52 @@
   );
 
   /**
+   * Parameters:
+   * 0: the superinitializer
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the initializer list of a
+  // constructor contains an invocation of a constructor in the superclass, but
+  // the invocation isn't the last item in the initializer list.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the invocation of the
+  // superclass' constructor isn't the last item in the initializer list:
+  //
+  // ```dart
+  // class A {
+  //   A(int x);
+  // }
+  //
+  // class B extends A {
+  //   B(int x) : [!super!](x), assert(x >= 0);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Move the invocation of the superclass' constructor to the end of the
+  // initializer list:
+  //
+  // ```dart
+  // class A {
+  //   A(int x);
+  // }
+  //
+  // class B extends A {
+  //   B(int x) : assert(x >= 0), super(x);
+  // }
+  // ```
+  static const CompileTimeErrorCode SUPER_INVOCATION_NOT_LAST =
+      CompileTimeErrorCode(
+    'SUPER_INVOCATION_NOT_LAST',
+    "The superconstructor call must be last in an initializer list: '{0}'.",
+    hasPublishedDocs: true,
+  );
+
+  /**
    * No parameters.
    */
   // #### Description
@@ -15614,6 +15615,19 @@
   );
 
   /**
+   * Parameters:
+   * 0: the type of the expression after `yield*`
+   * 1: the return type of the function containing the `yield*`
+   */
+  static const CompileTimeErrorCode YIELD_EACH_OF_INVALID_TYPE =
+      CompileTimeErrorCode(
+    'YIELD_OF_INVALID_TYPE',
+    "The type '{0}' implied by the 'yield*' expression must be assignable to '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'YIELD_EACH_OF_INVALID_TYPE',
+  );
+
+  /**
    * ?? Yield: It is a compile-time error if a yield statement appears in a
    * function that is not a generator function.
    *
@@ -15635,10 +15649,11 @@
    */
   // #### Description
   //
-  // The analyzer produces this diagnostic when the type of object produced by a
-  // `yield` expression doesn't match the type of objects that are to be
-  // returned from the `Iterable` or `Stream` types that are returned from a
-  // generator (a function or method marked with either `sync*` or `async*`).
+  // The analyzer produces this diagnostic when the type of object produced by
+  // a `yield` or `yield*` expression doesn't match the type of objects that
+  // are to be returned from the `Iterable` or `Stream` types that are returned
+  // from a generator (a function or method marked with either `sync*` or
+  // `async*`).
   //
   // #### Example
   //
@@ -15674,7 +15689,7 @@
   static const CompileTimeErrorCode YIELD_OF_INVALID_TYPE =
       CompileTimeErrorCode(
     'YIELD_OF_INVALID_TYPE',
-    "The type '{0}' implied by the 'yield' expression must be assignable to '{1}'.",
+    "A yielded value of type '{0}' must be assignable to '{1}'.",
     hasPublishedDocs: true,
   );
 
@@ -15923,7 +15938,7 @@
   // `isEven` if `s` is `null`. In other words, if `s` is `null`, then neither
   // `length` nor `isEven` will be invoked, and if `s` is non-`null`, then
   // `length` can't return a `null` value. Either way, `isEven` can't be invoked
-  // on a `null` value, so the null-aware operator is not necessary. See
+  // on a `null` value, so the null-aware operator isn't necessary. See
   // [Understanding null safety](/null-safety/understanding-null-safety#smarter-null-aware-methods)
   // for more details.
   //
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index 88d8a87..0ec6f98 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -790,6 +790,6 @@
     if (source2 == null) {
       return false;
     }
-    return !source1.isInSystemLibrary && source2.isInSystemLibrary;
+    return !source1.uri.isScheme('dart') && source2.uri.isScheme('dart');
   }
 }
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 9977e73..b6d1951 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -327,7 +327,7 @@
 
     // The SDK implementation may implement disallowed types. For example,
     // JSNumber in dart2js and _Smi in Dart VM both implement int.
-    if (library.source.isInSystemLibrary) {
+    if (library.source.uri.isScheme('dart')) {
       return false;
     }
 
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index a6962f4..05ee001 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -138,7 +138,15 @@
   /// assigned to the [elementType] of the enclosing collection.
   void _verifySpreadForListOrSet(bool isNullAware, Expression expression) {
     var expressionType = expression.typeOrThrow;
-    if (expressionType.isDynamic) return;
+    if (expressionType.isDynamic) {
+      if (typeSystem.strictCasts) {
+        return errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     if (typeSystem.isNonNullableByDefault) {
       if (typeSystem.isSubtypeOf(expressionType, NeverTypeImpl.instance)) {
@@ -224,7 +232,15 @@
   /// its key and values are assignable to [mapKeyType] and [mapValueType].
   void _verifySpreadForMap(bool isNullAware, Expression expression) {
     var expressionType = expression.typeOrThrow;
-    if (expressionType.isDynamic) return;
+    if (expressionType.isDynamic) {
+      if (typeSystem.strictCasts) {
+        return errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_MAP_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     if (typeSystem.isNonNullableByDefault) {
       if (typeSystem.isSubtypeOf(expressionType, NeverTypeImpl.instance)) {
diff --git a/pkg/analyzer/lib/src/error/return_type_verifier.dart b/pkg/analyzer/lib/src/error/return_type_verifier.dart
index 06ef0ed..2ae92c7 100644
--- a/pkg/analyzer/lib/src/error/return_type_verifier.dart
+++ b/pkg/analyzer/lib/src/error/return_type_verifier.dart
@@ -134,6 +134,12 @@
       return;
     }
 
+    if (enclosingExecutable.isGenerator) {
+      // [CompileTimeErrorCode.RETURN_IN_GENERATOR] has already been reported;
+      // do not report a duplicate error.
+      return;
+    }
+
     if (_typeSystem.isNonNullableByDefault) {
       _checkReturnExpression_nullSafety(expression);
     } else {
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index c2f2f09..9db6af2 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -499,7 +499,8 @@
       NodeList<TypeAnnotation> arguments, ErrorCode errorCode) {
     for (TypeAnnotation type in arguments) {
       if (type is NamedType && type.type is TypeParameterType) {
-        _errorReporter.reportErrorForNode(errorCode, type, [type.name]);
+        _errorReporter
+            .reportErrorForNode(errorCode, type, [type.name.toSource()]);
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 4a50a3c..6cfd05b 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -62,6 +62,8 @@
     show
         ClassDeclarationImpl,
         CompilationUnitImpl,
+        ConstructorNameImpl,
+        EnumDeclarationImpl,
         ExtensionDeclarationImpl,
         ImportDirectiveImpl,
         MethodInvocationImpl,
@@ -104,6 +106,9 @@
   /// The extension currently being parsed, or `null` if none.
   ExtensionDeclarationImpl? extensionDeclaration;
 
+  /// The enum currently being parsed, or `null` if none.
+  EnumDeclarationImpl? enumDeclaration;
+
   /// If true, this is building a full AST. Otherwise, only create method
   /// bodies.
   final bool isFullAst;
@@ -150,6 +155,12 @@
   /// `true` if named arguments anywhere are enabled
   final bool enableNamedArgumentsAnywhere;
 
+  /// `true` if super parameters are enabled
+  final bool enableSuperParameters;
+
+  /// `true` if enhanced enums are enabled
+  final bool enableEnhancedEnums;
+
   final FeatureSet _featureSet;
 
   AstBuilder(ErrorReporter? errorReporter, this.fileUri, this.isFullAst,
@@ -170,6 +181,8 @@
         enableExtensionTypes = _featureSet.isEnabled(Feature.extension_types),
         enableNamedArgumentsAnywhere =
             _featureSet.isEnabled(Feature.named_arguments_anywhere),
+        enableSuperParameters = _featureSet.isEnabled(Feature.super_parameters),
+        enableEnhancedEnums = _featureSet.isEnabled(Feature.enhanced_enums),
         uri = uri ?? fileUri;
 
   NodeList<ClassMember> get currentDeclarationMembers {
@@ -177,8 +190,10 @@
       return classDeclaration!.members;
     } else if (mixinDeclaration != null) {
       return mixinDeclaration!.members;
-    } else {
+    } else if (extensionDeclaration != null) {
       return extensionDeclaration!.members;
+    } else {
+      return enumDeclaration!.members;
     }
   }
 
@@ -187,8 +202,10 @@
       return classDeclaration!.name;
     } else if (mixinDeclaration != null) {
       return mixinDeclaration!.name;
-    } else {
+    } else if (extensionDeclaration != null) {
       return extensionDeclaration!.name;
+    } else {
+      return enumDeclaration!.name;
     }
   }
 
@@ -236,6 +253,9 @@
   }
 
   @override
+  void beginEnum(Token enumKeyword) {}
+
+  @override
   void beginExtensionDeclaration(Token extensionKeyword, Token? nameToken) {
     assert(optional('extension', extensionKeyword));
     assert(classDeclaration == null &&
@@ -330,11 +350,7 @@
     }
     if (staticToken != null) {
       assert(staticToken.isModifier);
-      String? className = classDeclaration != null
-          ? classDeclaration!.name.name
-          : (mixinDeclaration != null
-              ? mixinDeclaration!.name.name
-              : extensionDeclaration!.name?.name);
+      String? className = currentDeclarationName?.name;
       if (name.lexeme != className || getOrSet != null) {
         modifiers.staticKeyword = staticToken;
       }
@@ -1173,17 +1189,18 @@
   }
 
   @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
     assert(optional('enum', enumKeyword));
     assert(optional('{', leftBrace));
     debugEvent("Enum");
+  }
 
-    var constants = popTypedList2<EnumConstantDeclaration>(count);
-    var name = pop() as SimpleIdentifier;
-    var metadata = pop() as List<Annotation>?;
-    var comment = _findComment(metadata, enumKeyword);
-    declarations.add(ast.enumDeclaration(comment, metadata, enumKeyword, name,
-        leftBrace, constants, leftBrace.endGroup!));
+  @override
+  void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    debugEvent("endEnumConstructor");
+    endClassConstructor(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
   }
 
   @override
@@ -1412,18 +1429,32 @@
   @override
   void endFormalParameter(
       Token? thisKeyword,
-      Token? periodAfterThis,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
       Token nameToken,
       Token? initializerStart,
       Token? initializerEnd,
       FormalParameterKind kind,
       MemberKind memberKind) {
     assert(optionalOrNull('this', thisKeyword));
-    assert(thisKeyword == null
-        ? periodAfterThis == null
-        : optional('.', periodAfterThis!));
+    assert(optionalOrNull('super', superKeyword));
+    assert(thisKeyword == null && superKeyword == null
+        ? periodAfterThisOrSuper == null
+        : optional('.', periodAfterThisOrSuper!));
     debugEvent("FormalParameter");
 
+    if (superKeyword != null && !enableSuperParameters) {
+      var feature = ExperimentalFeatures.super_parameters;
+      handleRecoverableError(
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        superKeyword,
+        superKeyword,
+      );
+    }
+
     var defaultValue = pop() as _ParameterDefaultValue?;
     var name = pop() as SimpleIdentifier?;
     var typeOrFunctionTypedParameter = pop() as AstNode?;
@@ -1443,7 +1474,7 @@
       // This is a temporary AST node that was constructed in
       // [endFunctionTypedFormalParameter]. We now deconstruct it and create
       // the final AST node.
-      if (thisKeyword == null) {
+      if (thisKeyword == null && superKeyword == null) {
         node = ast.functionTypedFormalParameter2(
             identifier: name!,
             comment: comment,
@@ -1454,7 +1485,9 @@
             typeParameters: typeOrFunctionTypedParameter.typeParameters,
             parameters: typeOrFunctionTypedParameter.parameters,
             question: typeOrFunctionTypedParameter.question);
-      } else {
+      } else if (thisKeyword != null) {
+        assert(superKeyword == null,
+            "Can't have both 'this' and 'super' in a parameter.");
         node = ast.fieldFormalParameter2(
             identifier: name!,
             comment: comment,
@@ -1463,7 +1496,21 @@
             requiredKeyword: requiredKeyword,
             type: typeOrFunctionTypedParameter.returnType,
             thisKeyword: thisKeyword,
-            period: periodAfterThis!,
+            period: periodAfterThisOrSuper!,
+            typeParameters: typeOrFunctionTypedParameter.typeParameters,
+            parameters: typeOrFunctionTypedParameter.parameters,
+            question: typeOrFunctionTypedParameter.question);
+      } else {
+        assert(superKeyword != null && thisKeyword == null);
+        node = ast.superFormalParameter(
+            identifier: name!,
+            comment: comment,
+            metadata: metadata,
+            covariantKeyword: covariantKeyword,
+            requiredKeyword: requiredKeyword,
+            type: typeOrFunctionTypedParameter.returnType,
+            superKeyword: superKeyword!,
+            period: periodAfterThisOrSuper!,
             typeParameters: typeOrFunctionTypedParameter.typeParameters,
             parameters: typeOrFunctionTypedParameter.parameters,
             question: typeOrFunctionTypedParameter.question);
@@ -2613,20 +2660,6 @@
   }
 
   @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
-    assert(optionalOrNull('implements', implementsKeyword));
-    debugEvent("ClassImplements");
-
-    if (implementsKeyword != null) {
-      var interfaces = popTypedList2<NamedType>(interfacesCount);
-      push(ast.implementsClause(implementsKeyword, interfaces));
-    } else {
-      push(NullValue.IdentifierList);
-    }
-  }
-
-  @override
   void handleClassWithClause(Token withKeyword) {
     assert(optional('with', withKeyword));
     var mixinTypes = pop() as List<NamedType>;
@@ -2702,6 +2735,101 @@
   }
 
   @override
+  void handleEnumElement(Token beginToken) {
+    debugEvent("EnumElement");
+    var arguments = pop() as MethodInvocationImpl?;
+    var constructorName = pop() as ConstructorNameImpl?;
+
+    if (!enableEnhancedEnums &&
+        (arguments != null ||
+            constructorName != null &&
+                (constructorName.type2.typeArguments != null ||
+                    constructorName.name != null))) {
+      Token token = arguments != null
+          ? arguments.argumentList.beginToken
+          : constructorName!.beginToken;
+      var feature = ExperimentalFeatures.enhanced_enums;
+      handleRecoverableError(
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        token,
+        token,
+      );
+    }
+  }
+
+  @override
+  void handleEnumElements(Token elementsEndToken, int elementsCount) {
+    debugEvent("EnumElements");
+
+    var constants = popTypedList2<EnumConstantDeclaration>(elementsCount);
+    enumDeclaration!.constants.addAll(constants);
+
+    if (!enableEnhancedEnums && optional(';', elementsEndToken)) {
+      var feature = ExperimentalFeatures.enhanced_enums;
+      handleRecoverableError(
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        elementsEndToken,
+        elementsEndToken,
+      );
+    }
+  }
+
+  @override
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    assert(optional('enum', enumKeyword));
+    assert(optional('{', leftBrace));
+    debugEvent("EnumHeader");
+
+    var implementsClause = pop(NullValue.IdentifierList) as ImplementsClause?;
+    var withClause = pop(NullValue.WithClause) as WithClause?;
+    var typeParameters = pop() as TypeParameterList?;
+    var name = pop() as SimpleIdentifier;
+    var metadata = pop() as List<Annotation>?;
+    var comment = _findComment(metadata, enumKeyword);
+
+    if (!enableEnhancedEnums &&
+        (withClause != null ||
+            implementsClause != null ||
+            typeParameters != null)) {
+      var token = withClause != null
+          ? withClause.withKeyword
+          : implementsClause != null
+              ? implementsClause.implementsKeyword
+              : typeParameters!.beginToken;
+      var feature = ExperimentalFeatures.enhanced_enums;
+      handleRecoverableError(
+        templateExperimentNotEnabled.withArguments(
+          feature.enableString,
+          _versionAsString(ExperimentStatus.currentVersion),
+        ),
+        token,
+        token,
+      );
+    }
+
+    declarations.add(enumDeclaration = ast.enumDeclaration(comment, metadata,
+        enumKeyword, name, leftBrace, [], [], leftBrace.endGroup!));
+  }
+
+  @override
+  void handleEnumNoWithClause() {
+    push(NullValue.WithClause);
+  }
+
+  @override
+  void handleEnumWithClause(Token withKeyword) {
+    assert(optional('with', withKeyword));
+    var mixinTypes = pop() as List<NamedType>;
+    push(ast.withClause(withKeyword, mixinTypes));
+  }
+
+  @override
   void handleErrorToken(ErrorToken token) {
     translateErrorToken(token, errorReporter.reportScannerError);
   }
@@ -2929,6 +3057,19 @@
   }
 
   @override
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
+    assert(optionalOrNull('implements', implementsKeyword));
+    debugEvent("Implements");
+
+    if (implementsKeyword != null) {
+      var interfaces = popTypedList2<NamedType>(interfacesCount);
+      push(ast.implementsClause(implementsKeyword, interfaces));
+    } else {
+      push(NullValue.IdentifierList);
+    }
+  }
+
+  @override
   void handleImportPrefix(Token? deferredKeyword, Token? asKeyword) {
     assert(optionalOrNull('deferred', deferredKeyword));
     assert(optionalOrNull('as', asKeyword));
@@ -3371,6 +3512,14 @@
   }
 
   @override
+  void handleNoTypeNameInConstructorReference(Token token) {
+    debugEvent("NoTypeNameInConstructorReference");
+    assert(enumDeclaration != null);
+
+    push(ast.simpleIdentifier(enumDeclaration!.name.token));
+  }
+
+  @override
   void handleNoVariableInitializer(Token token) {
     debugEvent("NoVariableInitializer");
   }
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 0159195..6ce8f76 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -191,10 +191,6 @@
         _reportByCode(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, message,
             offset, length);
         return;
-      case "INVALID_SUPER_INVOCATION":
-        errorReporter?.reportErrorForOffset(
-            CompileTimeErrorCode.INVALID_SUPER_INVOCATION, offset, length);
-        return;
       case "MISSING_DIGIT":
         errorReporter?.reportErrorForOffset(
             ScannerErrorCode.MISSING_DIGIT, offset, length);
@@ -265,6 +261,10 @@
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.RETURN_IN_GENERATOR, offset, length);
         return;
+      case "SUPER_INVOCATION_NOT_LAST":
+        errorReporter?.reportErrorForOffset(
+            CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, offset, length);
+        return;
       case "SUPER_IN_REDIRECTING_CONSTRUCTOR":
         errorReporter?.reportErrorForOffset(
             CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
diff --git a/pkg/analyzer/lib/src/file_system/file_system.dart b/pkg/analyzer/lib/src/file_system/file_system.dart
index 16c7b2a..b7b4655 100644
--- a/pkg/analyzer/lib/src/file_system/file_system.dart
+++ b/pkg/analyzer/lib/src/file_system/file_system.dart
@@ -18,6 +18,11 @@
   ResourceProvider get provider => _provider;
 
   @override
+  Uri pathToUri(String path) {
+    return _provider.pathContext.toUri(path);
+  }
+
+  @override
   Source? resolveAbsolute(Uri uri) {
     if (!isFileUri(uri)) {
       return null;
@@ -27,9 +32,9 @@
     return file.createSource(uri);
   }
 
+  @Deprecated('Use pathToUri() instead')
   @override
-  Uri restoreAbsolute(Source source) =>
-      _provider.pathContext.toUri(source.fullName);
+  Uri restoreAbsolute(Source source) => pathToUri(source.fullName);
 
   /// Return `true` if the given [uri] is a `file` URI.
   static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 717940b..e64547d 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -438,7 +438,7 @@
         _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER,
             node,
-            [superType, name]);
+            [superType, name.name]);
       } else {
         _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index c678842..86b03d0 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -285,6 +285,9 @@
   /// re-throwing them)
   bool propagateLinterExceptions = false;
 
+  /// Whether implicit casts should be reported as potential problems.
+  bool strictCasts = false;
+
   /// A flag indicating whether inference failures are allowed, off by default.
   ///
   /// This option is experimental and subject to change.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index b53caa5..115365f 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -260,7 +260,7 @@
         _requiredParametersVerifier = RequiredParametersVerifier(errorReporter),
         _duplicateDefinitionVerifier =
             DuplicateDefinitionVerifier(_currentLibrary, errorReporter) {
-    _isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
+    _isInSystemLibrary = _currentLibrary.source.uri.isScheme('dart');
     _isInCatchClause = false;
     _isInStaticVariableDeclaration = false;
     _isInConstructorInitializer = false;
@@ -517,7 +517,7 @@
       }
       _constructorFieldsVerifier.verify(node);
       _checkForRedirectingConstructorErrorCodes(node);
-      _checkForMultipleSuperInitializers(node);
+      _checkForConflictingInitializerErrorCodes(node);
       _checkForRecursiveConstructorRedirect(node, element);
       if (!_checkForRecursiveFactoryRedirect(node, element)) {
         _checkForAllRedirectConstructorErrorCodes(node);
@@ -795,7 +795,7 @@
         if (parameterType is FunctionType &&
             parameterType.returnType.isDynamic) {
           errorReporter.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_RETURN,
-              node.identifier, [node.identifier]);
+              node.identifier, [node.identifier.name]);
         }
       }
 
@@ -1848,6 +1848,99 @@
     }
   }
 
+  /// Check that the given constructor [declaration] has a valid combination of
+  /// redirecting constructor invocation(s), super constructor invocation(s),
+  /// field initializers, and assert initializers.
+  void _checkForConflictingInitializerErrorCodes(
+      ConstructorDeclaration declaration) {
+    // Count and check each redirecting initializer.
+    var redirectingInitializerCount = 0;
+    var superInitializerCount = 0;
+    late SuperConstructorInvocation superInitializer;
+    for (ConstructorInitializer initializer in declaration.initializers) {
+      if (initializer is RedirectingConstructorInvocation) {
+        if (redirectingInitializerCount > 0) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
+              initializer);
+        }
+        if (declaration.factoryKeyword == null) {
+          RedirectingConstructorInvocation invocation = initializer;
+          var redirectingElement = invocation.staticElement;
+          if (redirectingElement == null) {
+            String enclosingNamedType = _enclosingClass!.displayName;
+            String constructorStrName = enclosingNamedType;
+            if (invocation.constructorName != null) {
+              constructorStrName += ".${invocation.constructorName!.name}";
+            }
+            errorReporter.reportErrorForNode(
+                CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
+                invocation,
+                [constructorStrName, enclosingNamedType]);
+          } else {
+            if (redirectingElement.isFactory) {
+              errorReporter.reportErrorForNode(
+                  CompileTimeErrorCode
+                      .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+                  initializer);
+            }
+          }
+        }
+        // [declaration] is a redirecting constructor via a redirecting
+        // initializer.
+        _checkForRedirectToNonConstConstructor(
+          declaration.declaredElement!,
+          initializer.staticElement,
+          initializer.constructorName ?? initializer.thisKeyword,
+        );
+        redirectingInitializerCount++;
+      } else if (initializer is SuperConstructorInvocation) {
+        if (superInitializerCount == 1) {
+          // Only report the second (first illegal) superinitializer.
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
+        }
+        superInitializer = initializer;
+        superInitializerCount++;
+      }
+    }
+    // Check for initializers which are illegal when alongside a redirecting
+    // initializer.
+    if (redirectingInitializerCount > 0) {
+      for (ConstructorInitializer initializer in declaration.initializers) {
+        if (initializer is SuperConstructorInvocation) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
+              initializer);
+        }
+        if (initializer is ConstructorFieldInitializer) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
+              initializer);
+        }
+        if (initializer is AssertInitializer) {
+          errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
+              initializer);
+        }
+      }
+    }
+    if (redirectingInitializerCount == 0 &&
+        superInitializerCount == 1 &&
+        superInitializer != declaration.initializers.last) {
+      var superNamedType = _enclosingClass!.supertype!.element.displayName;
+      var constructorStrName = superNamedType;
+      var constructorName = superInitializer.constructorName;
+      if (constructorName != null) {
+        constructorStrName += '.${constructorName.name}';
+      }
+      errorReporter.reportErrorForToken(
+          CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST,
+          superInitializer.superKeyword,
+          [constructorStrName]);
+    }
+  }
+
   /// Verify that if the given [constructor] declaration is 'const' then there
   /// are no invocations of non-'const' super constructors, and that there are
   /// no instance variables mixed in.
@@ -2089,12 +2182,12 @@
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
           name,
-          [className, name]);
+          [className.toSource(), name.name]);
     } else {
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
           constructorName,
-          [className]);
+          [className.toSource()]);
     }
   }
 
@@ -2166,6 +2259,26 @@
 
     DartType iterableType = node.iterable.typeOrThrow;
 
+    Token? awaitKeyword;
+    var parent = node.parent;
+    if (parent is ForStatement) {
+      awaitKeyword = parent.awaitKeyword;
+    } else if (parent is ForElement) {
+      awaitKeyword = parent.awaitKeyword;
+    }
+
+    // Use an explicit string instead of [loopType] to remove the "<E>".
+    String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable';
+
+    if (iterableType.isDynamic && typeSystem.strictCasts) {
+      errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE,
+        node.iterable,
+        [iterableType, loopNamedType],
+      );
+      return false;
+    }
+
     // TODO(scheglov) use NullableDereferenceVerifier
     if (_isNonNullableByDefault) {
       if (typeSystem.isNullable(iterableType)) {
@@ -2182,14 +2295,6 @@
       return false;
     }
 
-    Token? awaitKeyword;
-    var parent = node.parent;
-    if (parent is ForStatement) {
-      awaitKeyword = parent.awaitKeyword;
-    } else if (parent is ForElement) {
-      awaitKeyword = parent.awaitKeyword;
-    }
-
     // The object being iterated has to implement Iterable<T> for some T that
     // is assignable to the variable's type.
     // TODO(rnystrom): Move this into mostSpecificTypeArgument()?
@@ -2204,8 +2309,6 @@
     }
 
     if (!typeSystem.isAssignableTo(iterableType, requiredSequenceType)) {
-      // Use an explicit string instead of [loopType] to remove the "<E>".
-      String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable';
       errorReporter.reportErrorForNode(
         CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE,
         node.iterable,
@@ -2403,7 +2506,7 @@
     }
     // The SDK implementation may implement disallowed types. For example,
     // JSNumber in dart2js and _Smi in Dart VM both implement int.
-    if (_currentLibrary.source.isInSystemLibrary) {
+    if (_currentLibrary.source.uri.isScheme('dart')) {
       return false;
     }
     var type = namedType.type;
@@ -2593,7 +2696,7 @@
       }
       // Parameters associated with a variable always have a name, so we can
       // safely rely on [id] being non-`null`.
-      errorReporter.reportErrorForNode(errorCode, node, [id!]);
+      errorReporter.reportErrorForNode(errorCode, node, [id!.toSource()]);
     }
   }
 
@@ -2739,18 +2842,18 @@
         errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
             initializer,
-            [fieldName]);
+            [fieldName.name]);
       } else if (staticElement.isStatic) {
         errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
             initializer,
-            [fieldName]);
+            [fieldName.name]);
       }
     } else {
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
           initializer,
-          [fieldName]);
+          [fieldName.name]);
       return;
     }
   }
@@ -3270,22 +3373,6 @@
     }
   }
 
-  /// Verify that the given [constructor] has at most one 'super' initializer.
-  ///
-  /// See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS].
-  void _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) {
-    bool hasSuperInitializer = false;
-    for (ConstructorInitializer initializer in constructor.initializers) {
-      if (initializer is SuperConstructorInvocation) {
-        if (hasSuperInitializer) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
-        }
-        hasSuperInitializer = true;
-      }
-    }
-  }
-
   /// Checks to ensure that the given native function [body] is in SDK code.
   ///
   /// See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
@@ -3328,12 +3415,12 @@
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR,
           name,
-          [className, name]);
+          [className.toSource(), name.name]);
     } else {
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
           constructorName,
-          [className]);
+          [className.toSource()]);
     }
   }
 
@@ -3651,8 +3738,9 @@
 
       if (treatedAsDouble) {
         // Suggest the nearest valid double (as a BigInt for printing reasons).
-        extraErrorArgs
-            .add(BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme)));
+        extraErrorArgs.add(
+            BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme))
+                .toString());
       }
 
       errorReporter.reportErrorForNode(
@@ -3727,112 +3815,44 @@
     return true;
   }
 
-  /// Check that the given constructor [declaration] has a valid combination of
-  /// redirected constructor invocation(s), super constructor invocations and
-  /// field initializers.
-  ///
-  /// See [CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR],
-  /// [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR],
-  /// [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR],
-  /// [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS],
-  /// [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and
-  /// [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR].
+  /// Check that the given constructor [declaration] has a valid redirected
+  /// constructor.
   void _checkForRedirectingConstructorErrorCodes(
       ConstructorDeclaration declaration) {
-    // Check for default values in the parameters
+    // Check for default values in the parameters.
     var redirectedConstructor = declaration.redirectedConstructor;
-    if (redirectedConstructor != null) {
-      for (FormalParameter parameter in declaration.parameters.parameters) {
-        if (parameter is DefaultFormalParameter &&
-            parameter.defaultValue != null) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode
-                  .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
-              parameter.identifier!);
-        }
-      }
-      var redirectedElement = redirectedConstructor.staticElement;
-      _checkForRedirectToNonConstConstructor(
-        declaration.declaredElement!,
-        redirectedElement,
-        redirectedConstructor,
-      );
-      var redirectedClass = redirectedElement?.enclosingElement;
-      if (redirectedClass is ClassElement &&
-          redirectedClass.isAbstract &&
-          redirectedElement != null &&
-          !redirectedElement.isFactory) {
-        String enclosingNamedType = _enclosingClass!.displayName;
-        String constructorStrName = enclosingNamedType;
-        if (declaration.name != null) {
-          constructorStrName += ".${declaration.name!.name}";
-        }
+    if (redirectedConstructor == null) {
+      return;
+    }
+    for (FormalParameter parameter in declaration.parameters.parameters) {
+      if (parameter is DefaultFormalParameter &&
+          parameter.defaultValue != null) {
         errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
-            redirectedConstructor,
-            [constructorStrName, redirectedClass.name]);
+            CompileTimeErrorCode
+                .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
+            parameter.identifier!);
       }
     }
-    // check if there are redirected invocations
-    int numRedirections = 0;
-    for (ConstructorInitializer initializer in declaration.initializers) {
-      if (initializer is RedirectingConstructorInvocation) {
-        if (numRedirections > 0) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
-              initializer);
-        }
-        if (declaration.factoryKeyword == null) {
-          RedirectingConstructorInvocation invocation = initializer;
-          var redirectingElement = invocation.staticElement;
-          if (redirectingElement == null) {
-            String enclosingNamedType = _enclosingClass!.displayName;
-            String constructorStrName = enclosingNamedType;
-            if (invocation.constructorName != null) {
-              constructorStrName += ".${invocation.constructorName!.name}";
-            }
-            errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
-                invocation,
-                [constructorStrName, enclosingNamedType]);
-          } else {
-            if (redirectingElement.isFactory) {
-              errorReporter.reportErrorForNode(
-                  CompileTimeErrorCode
-                      .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
-                  initializer);
-            }
-          }
-        }
-        // [declaration] is a redirecting constructor via a redirecting
-        // initializer.
-        _checkForRedirectToNonConstConstructor(
-          declaration.declaredElement!,
-          initializer.staticElement,
-          initializer.constructorName ?? initializer.thisKeyword,
-        );
-        numRedirections++;
+    var redirectedElement = redirectedConstructor.staticElement;
+    _checkForRedirectToNonConstConstructor(
+      declaration.declaredElement!,
+      redirectedElement,
+      redirectedConstructor,
+    );
+    var redirectedClass = redirectedElement?.enclosingElement;
+    if (redirectedClass is ClassElement &&
+        redirectedClass.isAbstract &&
+        redirectedElement != null &&
+        !redirectedElement.isFactory) {
+      String enclosingNamedType = _enclosingClass!.displayName;
+      String constructorStrName = enclosingNamedType;
+      if (declaration.name != null) {
+        constructorStrName += ".${declaration.name!.name}";
       }
-    }
-    // check for other initializers
-    if (numRedirections > 0) {
-      for (ConstructorInitializer initializer in declaration.initializers) {
-        if (initializer is SuperConstructorInvocation) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
-              initializer);
-        }
-        if (initializer is ConstructorFieldInitializer) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
-              initializer);
-        }
-        if (initializer is AssertInitializer) {
-          errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
-              initializer);
-        }
-      }
+      errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
+          redirectedConstructor,
+          [constructorStrName, redirectedClass.name]);
     }
   }
 
@@ -4063,7 +4083,7 @@
       errorReporter.reportErrorForNode(
           CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS,
           type,
-          [type.name]);
+          [type.name.toSource()]);
     }
   }
 
@@ -4750,12 +4770,27 @@
 
   void _checkUseOfCovariantInParameters(FormalParameterList node) {
     var parent = node.parent;
-    if (_enclosingClass != null &&
-        parent is MethodDeclaration &&
-        !parent.isStatic) {
+    if (_enclosingClass != null && parent is MethodDeclaration) {
+      // Either [parent] is a static method, in which case `EXTRANEOUS_MODIFIER`
+      // is reported by the parser, or [parent] is an instance method, in which
+      // case any use of `covariant` is legal.
       return;
     }
 
+    if (_enclosingExtension != null) {
+      // `INVALID_USE_OF_COVARIANT_IN_EXTENSION` is reported by the parser.
+      return;
+    }
+
+    if (parent is FunctionExpression) {
+      var parent2 = parent.parent;
+      if (parent2 is FunctionDeclaration && parent2.parent is CompilationUnit) {
+        // `EXTRANEOUS_MODIFIER` is reported by the parser, for library-level
+        // functions.
+        return;
+      }
+    }
+
     NodeList<FormalParameter> parameters = node.parameters;
     int length = parameters.length;
     for (int i = 0; i < length; i++) {
@@ -4765,14 +4800,10 @@
       }
       var keyword = parameter.covariantKeyword;
       if (keyword != null) {
-        if (_enclosingExtension != null) {
-          // Reported by the parser.
-        } else {
-          errorReporter.reportErrorForToken(
-            CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
-            keyword,
-          );
-        }
+        errorReporter.reportErrorForToken(
+          CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
+          keyword,
+        );
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 4d6223c..69b37a5 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -16,6 +16,9 @@
 /// used. See 'pkg/vm/lib/transformations/ffi_checks.md' for the specification
 /// of the desired hints.
 class FfiVerifier extends RecursiveAstVisitor<void> {
+  static const _abiSpecificIntegerClassName = 'AbiSpecificInteger';
+  static const _abiSpecificIntegerMappingClassName =
+      'AbiSpecificIntegerMapping';
   static const _allocatorClassName = 'Allocator';
   static const _allocateExtensionMethodName = 'call';
   static const _allocatorExtensionName = 'AllocatorAlloc';
@@ -25,7 +28,7 @@
   static const _opaqueClassName = 'Opaque';
   static const _ffiNativeName = 'FfiNative';
 
-  static const List<String> _primitiveIntegerNativeTypes = [
+  static const Set<String> _primitiveIntegerNativeTypesFixedSize = {
     'Int8',
     'Int16',
     'Int32',
@@ -34,13 +37,16 @@
     'Uint16',
     'Uint32',
     'Uint64',
+  };
+  static const Set<String> _primitiveIntegerNativeTypes = {
+    ..._primitiveIntegerNativeTypesFixedSize,
     'IntPtr'
-  ];
+  };
 
-  static const List<String> _primitiveDoubleNativeTypes = [
+  static const Set<String> _primitiveDoubleNativeTypes = {
     'Float',
     'Double',
-  ];
+  };
 
   static const _primitiveBoolNativeType = 'Bool';
 
@@ -85,8 +91,12 @@
           if (className == _structClassName) {
             _validatePackedAnnotation(node.metadata);
           }
+        } else if (className == _abiSpecificIntegerClassName) {
+          _validateAbiSpecificIntegerMappingAnnotation(
+              node.name, node.metadata);
         } else if (className != _allocatorClassName &&
-            className != _opaqueClassName) {
+            className != _opaqueClassName &&
+            className != _abiSpecificIntegerClassName) {
           _errorReporter.reportErrorForNode(
               FfiCode.SUBTYPE_OF_FFI_CLASS_IN_EXTENDS,
               superclass.name,
@@ -108,11 +118,11 @@
         return;
       }
       if (typename.ffiClass != null) {
-        _errorReporter.reportErrorForNode(
-            subtypeOfFfiCode, typename, [node.name, typename.name]);
+        _errorReporter.reportErrorForNode(subtypeOfFfiCode, typename,
+            [node.name.name, typename.name.toSource()]);
       } else if (typename.isCompoundSubtype) {
-        _errorReporter.reportErrorForNode(
-            subtypeOfStructCode, typename, [node.name, typename.name]);
+        _errorReporter.reportErrorForNode(subtypeOfStructCode, typename,
+            [node.name.name, typename.name.toSource()]);
       }
     }
 
@@ -133,7 +143,7 @@
 
     if (inCompound && node.declaredElement!.typeParameters.isNotEmpty) {
       _errorReporter.reportErrorForNode(
-          FfiCode.GENERIC_STRUCT_SUBCLASS, node.name, [node.name]);
+          FfiCode.GENERIC_STRUCT_SUBCLASS, node.name, [node.name.name]);
     }
     super.visitClassDeclaration(node);
   }
@@ -452,6 +462,9 @@
     if (nativeType.isArray) {
       return true;
     }
+    if (nativeType.isAbiSpecificIntegerSubtype) {
+      return true;
+    }
     return false;
   }
 
@@ -523,6 +536,9 @@
       if (nativeType.isOpaqueSubtype) {
         return true;
       }
+      if (nativeType.isAbiSpecificIntegerSubtype) {
+        return true;
+      }
       if (allowArray && nativeType.isArray) {
         return _isValidFfiNativeType(nativeType.typeArguments.single,
             allowVoid: false, allowEmptyStruct: false);
@@ -591,10 +607,51 @@
       } else if (_primitiveBoolNativeType == name) {
         return _PrimitiveDartType.bool;
       }
+      if (element.type.returnType.isAbiSpecificIntegerSubtype) {
+        return _PrimitiveDartType.int;
+      }
     }
     return _PrimitiveDartType.none;
   }
 
+  /// Validate that the [annotations] include at most one mapping annotation.
+  void _validateAbiSpecificIntegerMappingAnnotation(
+      AstNode errorNode, NodeList<Annotation> annotations) {
+    final ffiPackedAnnotations = annotations
+        .where((annotation) => annotation.isAbiSpecificIntegerMapping)
+        .toList();
+
+    if (ffiPackedAnnotations.isEmpty) {
+      _errorReporter.reportErrorForNode(
+          FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_MISSING, errorNode);
+      return;
+    }
+
+    if (ffiPackedAnnotations.length > 1) {
+      final extraAnnotations = ffiPackedAnnotations.skip(1);
+      for (final annotation in extraAnnotations) {
+        _errorReporter.reportErrorForNode(
+            FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_EXTRA, annotation.name);
+      }
+    }
+
+    final annotationConstant =
+        ffiPackedAnnotations.first.elementAnnotation?.computeConstantValue();
+    final mappingValues = annotationConstant?.getField('mapping')?.toMapValue();
+    if (mappingValues == null) {
+      return;
+    }
+    for (final nativeType in mappingValues.values) {
+      final nativeTypeName = nativeType?.type?.element?.name;
+      if (nativeTypeName != null &&
+          !_primitiveIntegerNativeTypesFixedSize.contains(nativeTypeName)) {
+        _errorReporter.reportErrorForNode(
+            FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED,
+            ffiPackedAnnotations.first.name);
+      }
+    }
+  }
+
   void _validateAllocate(FunctionExpressionInvocation node) {
     final typeArgumentTypes = node.typeArgumentTypes;
     if (typeArgumentTypes == null || typeArgumentTypes.length != 1) {
@@ -619,7 +676,9 @@
     bool requiredFound = false;
     List<Annotation> extraAnnotations = [];
     for (Annotation annotation in annotations) {
-      if (annotation.element.ffiClass != null) {
+      if (annotation.element.ffiClass != null ||
+          annotation.element?.enclosingElement.isAbiSpecificIntegerSubclass ==
+              true) {
         if (requiredFound) {
           extraAnnotations.add(annotation);
         } else {
@@ -744,7 +803,10 @@
   bool _validateCompatibleNativeType(
       DartType dartType, DartType nativeType, bool checkCovariance) {
     final nativeReturnType = _primitiveNativeType(nativeType);
-    if (nativeReturnType == _PrimitiveDartType.int) {
+    if (nativeReturnType == _PrimitiveDartType.int ||
+        (nativeType is InterfaceType &&
+            nativeType.superclass?.element.name ==
+                _abiSpecificIntegerClassName)) {
       return dartType.isDartCoreInt;
     } else if (nativeReturnType == _PrimitiveDartType.double) {
       return dartType.isDartCoreDouble;
@@ -1197,6 +1259,14 @@
         element.ffiClass != null &&
         element.enclosingElement.name == 'Packed';
   }
+
+  bool get isAbiSpecificIntegerMapping {
+    final element = this.element;
+    return element is ConstructorElement &&
+        element.ffiClass != null &&
+        element.enclosingElement.name ==
+            FfiVerifier._abiSpecificIntegerMappingClassName;
+  }
 }
 
 extension on ElementAnnotation {
@@ -1332,6 +1402,21 @@
     return element is ClassElement && element.supertype.isUnion;
   }
 
+  /// Return `true` if this represents the class `AbiSpecificInteger`.
+  bool get isAbiSpecificInteger {
+    final element = this;
+    return element is ClassElement &&
+        element.name == FfiVerifier._abiSpecificIntegerClassName &&
+        element.isFfiClass;
+  }
+
+  /// Return `true` if this represents a subclass of the class
+  /// `AbiSpecificInteger`.
+  bool get isAbiSpecificIntegerSubclass {
+    final element = this;
+    return element is ClassElement && element.supertype.isAbiSpecificInteger;
+  }
+
   /// If this is a class element from `dart:ffi`, return it.
   ClassElement? get ffiClass {
     var element = this;
@@ -1398,6 +1483,11 @@
     final self = this;
     return self is InterfaceType && self.element.isUnion;
   }
+
+  bool get isAbiSpecificInteger {
+    final self = this;
+    return self is InterfaceType && self.element.isAbiSpecificInteger;
+  }
 }
 
 extension on DartType {
@@ -1467,6 +1557,22 @@
     return false;
   }
 
+  /// Returns `true` iff this is an Abi-specific integer type,
+  /// i.e. a subtype of `AbiSpecificInteger`.
+  bool get isAbiSpecificIntegerSubtype {
+    final self = this;
+    if (self is InterfaceType) {
+      final superType = self.element.supertype;
+      if (superType != null) {
+        final superClassElement = superType.element;
+        return superClassElement.name ==
+                FfiVerifier._abiSpecificIntegerClassName &&
+            superClassElement.isFfiClass;
+      }
+    }
+    return false;
+  }
+
   /// Returns `true` iff this is a opaque type, i.e. a subtype of `Opaque`.
   bool get isOpaqueSubtype {
     final self = this;
@@ -1516,13 +1622,7 @@
   bool get isCompoundSubtype {
     var element = name.staticElement;
     if (element is ClassElement) {
-      bool isCompound(InterfaceType? type) {
-        return type != null && type.isCompound;
-      }
-
-      return isCompound(element.supertype) ||
-          element.interfaces.any(isCompound) ||
-          element.mixins.any(isCompound);
+      return element.allSupertypes.any((e) => e.isCompound);
     }
     return false;
   }
diff --git a/pkg/analyzer/lib/src/generated/java_engine_io.dart b/pkg/analyzer/lib/src/generated/java_engine_io.dart
index 5ee3c34..96e9e51 100644
--- a/pkg/analyzer/lib/src/generated/java_engine_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine_io.dart
@@ -4,14 +4,6 @@
 
 import "dart:io";
 
-import "package:analyzer/src/generated/java_io.dart";
-
-class FileUtilities2 {
-  static JavaFile createFile(String path) {
-    return JavaFile(path).getAbsoluteFile();
-  }
-}
-
 class OSUtilities {
   static String LINE_SEPARATOR = isWindows() ? '\r\n' : '\n';
   static bool isMac() => Platform.operatingSystem == 'macos';
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 3ab4863..4751bc4 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -6,6 +6,7 @@
 
 import 'package:path/path.dart' as path;
 
+@Deprecated('Use ResourceProvider and path context instead.')
 class JavaFile {
   @deprecated
   static path.Context pathContext = path.context;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 5f87d47..80eebe3 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -800,8 +800,10 @@
 
     if (parent is CompilationUnit) {
       return node is ClassDeclaration ||
+          node is Directive ||
           node is ExtensionDeclaration ||
-          node is FunctionDeclaration;
+          node is FunctionDeclaration ||
+          node is TopLevelVariableDeclaration;
     }
 
     void forClassElement(ClassElement parentElement) {
@@ -813,6 +815,11 @@
       return true;
     }
 
+    if (parent is ExtensionDeclaration) {
+      enclosingExtension = parent.declaredElement!;
+      return true;
+    }
+
     if (parent is MixinDeclaration) {
       forClassElement(parent.declaredElement!);
       return true;
@@ -1038,20 +1045,16 @@
     var callerType = InferenceContext.getContext(node);
     NodeList<Expression> arguments = node.arguments;
     if (callerType is FunctionType) {
-      Map<String, DartType> namedParameterTypes =
-          callerType.namedParameterTypes;
-      List<DartType> normalParameterTypes = callerType.normalParameterTypes;
-      List<DartType> optionalParameterTypes = callerType.optionalParameterTypes;
-      int normalCount = normalParameterTypes.length;
-      int optionalCount = optionalParameterTypes.length;
+      var parameters = callerType.parameters;
 
-      Iterable<Expression> positional =
-          arguments.takeWhile((l) => l is! NamedExpression);
-      Iterable<Expression> required = positional.take(normalCount);
-      Iterable<Expression> optional =
-          positional.skip(normalCount).take(optionalCount);
-      Iterable<Expression> named =
-          arguments.skipWhile((l) => l is! NamedExpression);
+      var namedParameters = <String, ParameterElement>{};
+      for (var i = 0; i < parameters.length; i++) {
+        var parameter = parameters[i];
+        if (parameter.isNamed) {
+          namedParameters[parameter.name] = parameter;
+        }
+      }
+
       var parent = node.parent;
       DartType? targetType;
       Element? methodElement;
@@ -1065,28 +1068,29 @@
       //TODO(leafp): Consider using the parameter elements here instead.
       //TODO(leafp): Make sure that the parameter elements are getting
       // setup correctly with inference.
-      int index = 0;
-      for (Expression argument in required) {
-        var parameterType = normalParameterTypes[index++];
-        if (targetType != null) {
-          InferenceContext.setType(
-              argument,
-              typeSystem.refineNumericInvocationContext(
-                  targetType, methodElement, invocationContext, parameterType));
-        } else {
-          InferenceContext.setType(argument, parameterType);
-        }
-      }
-      index = 0;
-      for (Expression argument in optional) {
-        InferenceContext.setType(argument, optionalParameterTypes[index++]);
-      }
-
-      for (Expression argument in named) {
+      var positionalParameterIndex = 0;
+      for (var i = 0; i < arguments.length; i++) {
+        var argument = arguments[i];
+        ParameterElement? parameter;
         if (argument is NamedExpression) {
-          var type = namedParameterTypes[argument.name.label.name];
-          if (type != null) {
-            InferenceContext.setType(argument, type);
+          parameter = namedParameters[argument.name.label.name];
+        } else {
+          while (positionalParameterIndex < parameters.length) {
+            parameter = parameters[positionalParameterIndex++];
+            if (!parameter.isNamed) {
+              break;
+            }
+          }
+        }
+        if (parameter != null) {
+          var parameterType = parameter.type;
+          if (targetType != null) {
+            InferenceContext.setType(
+                argument,
+                typeSystem.refineNumericInvocationContext(targetType,
+                    methodElement, invocationContext, parameterType));
+          } else {
+            InferenceContext.setType(argument, parameterType);
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 1fd1ec8..265ce79 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -59,6 +59,10 @@
   /// Return the source representing the library with the given 'dart:' [uri],
   /// or `null` if the given URI does not denote a library in this SDK.
   Source? mapDartUri(String uri);
+
+  /// Return the `dart` URI representing the given [path] if the file is in
+  /// this SDK, or `null` if the file is not in this SDK.
+  Uri? pathToUri(String path);
 }
 
 /// Manages the DartSdk's that have been created. Clients need to create
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index f134a33..ed375ff 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -6,16 +6,11 @@
 import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
-import 'package:analyzer/src/task/api/model.dart';
 import 'package:path/path.dart' as pathos;
 
 export 'package:analyzer/source/line_info.dart' show LineInfo;
 export 'package:analyzer/source/source_range.dart';
 
-/// A function that is used to visit [ContentCache] entries.
-typedef ContentCacheVisitor = void Function(
-    String fullPath, int stamp, String contents);
-
 /// Base class providing implementations for the methods in [Source] that don't
 /// require filesystem access.
 abstract class BasicSource extends Source {
@@ -24,6 +19,7 @@
 
   BasicSource(this.uri);
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => uri.toString();
 
@@ -33,6 +29,7 @@
   @override
   int get hashCode => uri.hashCode;
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   @override
   bool get isInSystemLibrary => uri.scheme == 'dart';
 
@@ -61,6 +58,11 @@
   DartSdk get dartSdk => _sdk;
 
   @override
+  Uri? pathToUri(String path) {
+    return _sdk.pathToUri(path);
+  }
+
+  @override
   Source? resolveAbsolute(Uri uri) {
     if (!isDartUri(uri)) {
       return null;
@@ -68,12 +70,6 @@
     return _sdk.mapDartUri(uri.toString());
   }
 
-  @override
-  Uri? restoreAbsolute(Source source) {
-    var dartSource = _sdk.fromFileUri(source.uri);
-    return dartSource?.uri;
-  }
-
   /// Return `true` if the given URI is a `dart:` URI.
   ///
   /// @param uri the URI being tested
@@ -84,7 +80,9 @@
 /// An implementation of an non-existing [Source].
 class NonExistingSource extends Source {
   static final unknown = NonExistingSource(
-      '/unknown.dart', pathos.toUri('/unknown.dart'), UriKind.FILE_URI);
+    '/unknown.dart',
+    pathos.toUri('/unknown.dart'),
+  );
 
   @override
   final String fullName;
@@ -92,35 +90,41 @@
   @override
   final Uri uri;
 
-  @override
-  final UriKind uriKind;
-
-  NonExistingSource(this.fullName, this.uri, this.uriKind);
+  NonExistingSource(this.fullName, this.uri);
 
   @override
   TimestampedData<String> get contents {
     throw UnsupportedError('$fullName does not exist.');
   }
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => uri.toString();
 
   @override
   int get hashCode => fullName.hashCode;
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   @override
   bool get isInSystemLibrary => false;
 
+  @Deprecated('Not used anymore')
   @override
   int get modificationStamp => -1;
 
   @override
   String get shortName => pathos.basename(fullName);
 
+  @Deprecated('Use Source.uri instead')
+  @override
+  UriKind get uriKind {
+    return UriKind.FILE_URI;
+  }
+
   @override
   bool operator ==(Object other) {
     if (other is NonExistingSource) {
-      return other.uriKind == uriKind && other.fullName == fullName;
+      return other.uri == uri && other.fullName == fullName;
     }
     return false;
   }
@@ -154,7 +158,7 @@
 /// represent non-existent files must also be retained so that if those files
 /// are created at a later date the long-lived sources representing those files
 /// will know that they now exist.
-abstract class Source implements AnalysisTarget {
+abstract class Source {
   /// Get the contents and timestamp of this source.
   ///
   /// Clients should consider using the method [AnalysisContext.getContents]
@@ -170,7 +174,7 @@
   ///
   /// @return an encoded representation of this source
   /// See [SourceFactory.fromEncoding].
-  @deprecated
+  @Deprecated('Not used anymore')
   String get encoding;
 
   /// Return the full (long) version of the name that can be displayed to the
@@ -190,11 +194,9 @@
   /// Return `true` if this source is in one of the system libraries.
   ///
   /// @return `true` if this is in a system library
+  @Deprecated('Use uri.isScheme("dart") instead')
   bool get isInSystemLibrary;
 
-  @override
-  Source get librarySource => throw UnimplementedError();
-
   /// Return the modification stamp for this source, or a negative value if the
   /// source does not exist. A modification stamp is a non-negative integer with
   /// the property that if the contents of the source have not been modified
@@ -206,6 +208,7 @@
   /// Clients should consider using the method
   /// [AnalysisContext.getModificationStamp] because contexts can have local
   /// overrides of the content of a source that the source is not aware of.
+  @Deprecated('Not used anymore')
   int get modificationStamp;
 
   /// Return a short version of the name that can be displayed to the user to
@@ -215,9 +218,6 @@
   /// @return a name that can be displayed to the user to denote this source
   String get shortName;
 
-  @override
-  Source get source => this;
-
   /// Return the URI from which this source was originally derived.
   ///
   /// @return the URI from which this source was originally derived
@@ -230,6 +230,7 @@
   /// against which the relative URI was resolved.
   ///
   /// @return the kind of URI from which this source was originally derived
+  @Deprecated('Use Source.uri instead')
   UriKind get uriKind;
 
   /// Return `true` if the given object is a source that represents the same
@@ -271,10 +272,6 @@
   /// the package (or [null] if there is no registered package URI resolver).
   Map<String, List<Folder>>? get packageMap;
 
-  /// Clear any cached URI resolution information in the [SourceFactory] itself,
-  /// and also ask each [UriResolver]s to clear its caches.
-  void clearCache();
-
   /// Return a source object representing the given absolute URI, or `null` if
   /// the URI is not a valid URI or if it is not an absolute URI.
   ///
@@ -289,6 +286,13 @@
   /// @return a source object representing the absolute URI
   Source? forUri2(Uri absoluteUri);
 
+  /// Return the URI that should be used to reference the file at the absolute
+  /// [path], or `null` if there is no valid way to reference the file.
+  /// The file at that path is not required to exist.
+  ///
+  /// Throws an [ArgumentError] if the [path] is not a valid path.
+  Uri? pathToUri(String path);
+
   /// Return a source representing the URI that results from resolving the given
   /// (possibly relative) [containedUri] against the URI associated with the
   /// [containingSource], whether or not the resulting source exists, or `null`
@@ -301,6 +305,7 @@
   ///
   /// @param source the source to get URI for
   /// @return the absolute URI representing the given source
+  @Deprecated('Use pathToUri() instead')
   Uri? restoreUri(Source source);
 }
 
@@ -348,6 +353,7 @@
 /// The enumeration `UriKind` defines the different kinds of URI's that are
 /// known to the analysis engine. These are used to keep track of the kind of
 /// URI associated with a given source.
+@Deprecated('Use Source.uri instead')
 class UriKind implements Comparable<UriKind> {
   /// A 'dart:' URI.
   static const UriKind DART_URI = UriKind('DART_URI', 0, 0x64);
@@ -413,15 +419,14 @@
 /// The abstract class `UriResolver` defines the behavior of objects that are
 /// used to resolve URI's for a source factory. Subclasses of this class are
 /// expected to resolve a single scheme of absolute URI.
-///
-/// NOTICE: in a future breaking change release of the analyzer, a method
-/// `void clearCache()` will be added.  Clients that implement, but do not
-/// extend, this class, can prepare for the breaking change by adding an
-/// implementation of this method that clears any cached URI resolution
-/// information.
 abstract class UriResolver {
-  /// Clear any cached URI resolution information.
-  void clearCache() {}
+  /// Return the absolute URI that should be used to reference the file at the
+  /// absolute [path], or `null` if this resolver cannot reference this file.
+  /// The file at that path is not required to exist.
+  ///
+  /// Throws an [ArgumentError] if the [path] is not a valid path.
+  /// ignore: deprecated_member_use_from_same_package
+  Uri? pathToUri(String path) => restoreAbsolute(_FakeSource(path));
 
   /// Resolve the given absolute [uri]. Return a [Source] representing the file
   /// to which it was resolved, whether or not the resulting source exists, or
@@ -432,5 +437,21 @@
   /// valid URI cannot be computed.
   ///
   /// The computation should be based solely on [source.fullName].
-  Uri? restoreAbsolute(Source source) => null;
+  @Deprecated('Use pathToUri() instead')
+  Uri? restoreAbsolute(Source source) {
+    return pathToUri(source.fullName);
+  }
+}
+
+class _FakeSource implements Source {
+  @override
+  final String fullName;
+
+  _FakeSource(this.fullName);
+
+  @override
+  Uri get uri => pathos.toUri(fullName);
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 906a677..1eb71fb 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -2,112 +2,5 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:collection';
-
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/source.dart';
-
+@Deprecated('Import source.dart instead')
 export 'package:analyzer/src/generated/source.dart';
-
-/// Instances of the class `FileBasedSource` implement a source that represents
-/// a file.
-class FileBasedSource extends Source {
-  /// Map from encoded URI/filepath pair to a unique integer identifier.  This
-  /// identifier is used for equality tests and hash codes.
-  ///
-  /// The URI and filepath are joined into a pair by separating them with an '@'
-  /// character.
-  static final Map<String, int> _idTable = HashMap<String, int>();
-
-  /// The URI from which this source was originally derived.
-  @override
-  final Uri uri;
-
-  /// The unique ID associated with this [FileBasedSource].
-  final int id;
-
-  /// The file represented by this source.
-  final JavaFile file;
-
-  /// The cached absolute path of this source.
-  String? _absolutePath;
-
-  /// The cached encoding for this source.
-  String? _encoding;
-
-  /// Initialize a newly created source object to represent the given [file]. If
-  /// a [uri] is given, then it will be used as the URI from which the source
-  /// was derived, otherwise a `file:` URI will be created based on the [file].
-  FileBasedSource(JavaFile file, [Uri? uri])
-      : uri = uri ?? file.toURI(),
-        file = file,
-        id = _idTable.putIfAbsent(
-            '${uri ?? file.toURI()}@${file.getPath()}', () => _idTable.length);
-
-  @override
-  TimestampedData<String> get contents {
-    return contentsFromFile;
-  }
-
-  /// Get the contents and timestamp of the underlying file.
-  ///
-  /// Clients should consider using the method [AnalysisContext.getContents]
-  /// because contexts can have local overrides of the content of a source that
-  /// the source is not aware of.
-  ///
-  /// @return the contents of the source paired with the modification stamp of
-  /// the source
-  /// @throws Exception if the contents of this source could not be accessed
-  /// See [contents].
-  TimestampedData<String> get contentsFromFile {
-    return TimestampedData<String>(
-        file.lastModified(), file.readAsStringSync());
-  }
-
-  @override
-  String get encoding {
-    return _encoding ??= uri.toString();
-  }
-
-  @override
-  String get fullName {
-    return _absolutePath ??= file.getAbsolutePath();
-  }
-
-  @override
-  int get hashCode => uri.hashCode;
-
-  @override
-  bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;
-
-  @override
-  int get modificationStamp => file.lastModified();
-
-  @override
-  String get shortName => file.getName();
-
-  @override
-  UriKind get uriKind {
-    String scheme = uri.scheme;
-    return UriKind.fromScheme(scheme);
-  }
-
-  @override
-  bool operator ==(Object object) {
-    if (object is FileBasedSource) {
-      return id == object.id;
-    } else if (object is Source) {
-      return uri == object.uri;
-    }
-    return false;
-  }
-
-  @override
-  bool exists() => file.isFile();
-
-  @override
-  String toString() {
-    return file.getAbsolutePath();
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/super_context.dart b/pkg/analyzer/lib/src/generated/super_context.dart
index 8902ebb..7068c16 100644
--- a/pkg/analyzer/lib/src/generated/super_context.dart
+++ b/pkg/analyzer/lib/src/generated/super_context.dart
@@ -37,7 +37,7 @@
         return node.factoryKeyword == null
             ? SuperContext.valid
             : SuperContext.static;
-      } else if (node is ConstructorFieldInitializer) {
+      } else if (node is ConstructorInitializer) {
         return SuperContext.static;
       } else if (node is FieldDeclaration) {
         return node.staticKeyword == null && node.fields.lateKeyword != null
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index d722db43..e05cbc0 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -467,6 +467,7 @@
           name,
           TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
           constants,
+          [],
           TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
 
   static EnumDeclarationImpl enumDeclaration2(
@@ -1100,6 +1101,42 @@
               : TokenFactory.tokenFromType(TokenType.COLON),
           expression);
 
+  /// Create a type name whose name has been resolved to the given [element] and
+  /// whose type has been resolved to the type of the given element.
+  ///
+  /// <b>Note:</b> This method does not correctly handle class elements that
+  /// have type parameters.
+  static NamedTypeImpl namedType(ClassElement element,
+      [List<TypeAnnotation>? arguments]) {
+    var name = identifier3(element.name);
+    name.staticElement = element;
+    var typeName = namedType3(name, arguments);
+    typeName.type = element.instantiate(
+      typeArguments: List.filled(
+        element.typeParameters.length,
+        DynamicTypeImpl.instance,
+      ),
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
+    return typeName;
+  }
+
+  static NamedTypeImpl namedType3(Identifier name,
+          [List<TypeAnnotation>? arguments]) =>
+      astFactory.namedType(
+        name: name,
+        typeArguments: typeArgumentList(arguments),
+      );
+
+  static NamedTypeImpl namedType4(String name,
+          [List<TypeAnnotation>? arguments, bool question = false]) =>
+      astFactory.namedType(
+        name: identifier3(name),
+        typeArguments: typeArgumentList(arguments),
+        question:
+            question ? TokenFactory.tokenFromType(TokenType.QUESTION) : null,
+      );
+
   static NativeClauseImpl nativeClause(String nativeCode) =>
       astFactory.nativeClause(
           TokenFactory.tokenFromString("native"), string2(nativeCode));
@@ -1296,6 +1333,21 @@
   static SuperExpressionImpl superExpression() =>
       astFactory.superExpression(TokenFactory.tokenFromKeyword(Keyword.SUPER));
 
+  static SuperFormalParameterImpl superFormalParameter(
+          Keyword? keyword, TypeAnnotation? type, String identifier,
+          [FormalParameterList? parameterList]) =>
+      astFactory.superFormalParameter(
+          keyword:
+              keyword == null ? null : TokenFactory.tokenFromKeyword(keyword),
+          type: type,
+          superKeyword: TokenFactory.tokenFromKeyword(Keyword.SUPER),
+          period: TokenFactory.tokenFromType(TokenType.PERIOD),
+          identifier: identifier3(identifier),
+          parameters: parameterList);
+
+  static SuperFormalParameterImpl superFormalParameter2(String identifier) =>
+      superFormalParameter(null, null, identifier);
+
   static SwitchCaseImpl switchCase(
           Expression expression, List<Statement> statements) =>
       switchCase2(<Label>[], expression, statements);
@@ -1422,42 +1474,6 @@
         types, TokenFactory.tokenFromType(TokenType.GT));
   }
 
-  /// Create a type name whose name has been resolved to the given [element] and
-  /// whose type has been resolved to the type of the given element.
-  ///
-  /// <b>Note:</b> This method does not correctly handle class elements that
-  /// have type parameters.
-  static NamedTypeImpl typeName(ClassElement element,
-      [List<TypeAnnotation>? arguments]) {
-    var name = identifier3(element.name);
-    name.staticElement = element;
-    var typeName = typeName3(name, arguments);
-    typeName.type = element.instantiate(
-      typeArguments: List.filled(
-        element.typeParameters.length,
-        DynamicTypeImpl.instance,
-      ),
-      nullabilitySuffix: NullabilitySuffix.star,
-    );
-    return typeName;
-  }
-
-  static NamedTypeImpl typeName3(Identifier name,
-          [List<TypeAnnotation>? arguments]) =>
-      astFactory.namedType(
-        name: name,
-        typeArguments: typeArgumentList(arguments),
-      );
-
-  static NamedTypeImpl typeName4(String name,
-          [List<TypeAnnotation>? arguments, bool question = false]) =>
-      astFactory.namedType(
-        name: identifier3(name),
-        typeArguments: typeArgumentList(arguments),
-        question:
-            question ? TokenFactory.tokenFromType(TokenType.QUESTION) : null,
-      );
-
   static TypeParameterImpl typeParameter(String name) =>
       astFactory.typeParameter(null, null, identifier3(name), null, null);
 
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index a33890a..cd89eef 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -17,12 +17,14 @@
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:collection/collection.dart';
+import 'package:meta/meta.dart';
 import 'package:path/path.dart';
 
 /// The class `ElementFactory` defines utility methods used to create elements
 /// for testing purposes. The elements that are created are complete in the
 /// sense that as much of the element model as can be created, given the
 /// provided information, has been created.
+@internal
 class ElementFactory {
   /// The element representing the class 'Object'.
   static ClassElementImpl? _objectElement;
@@ -90,8 +92,7 @@
 
   static CompilationUnitElementImpl compilationUnit(String fileName,
       [Source? librarySource]) {
-    Source source =
-        NonExistingSource(fileName, toUri(fileName), UriKind.FILE_URI);
+    Source source = NonExistingSource(fileName, toUri(fileName));
     CompilationUnitElementImpl unit = CompilationUnitElementImpl();
     unit.source = source;
     librarySource ??= source;
@@ -358,7 +359,7 @@
           ConstTopLevelVariableElementImpl(name, -1);
       var typeElement = type.element as ClassElement;
       var initializer = AstTestFactory.instanceCreationExpression2(
-          Keyword.CONST, AstTestFactory.typeName(typeElement));
+          Keyword.CONST, AstTestFactory.namedType(typeElement));
       if (type is InterfaceType) {
         var element = typeElement.unnamedConstructor;
         initializer.constructorName.staticElement = element;
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index f700ddd..9005be7 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -55,6 +55,7 @@
 
   _MockSource(this.uri);
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => '$uri';
 
diff --git a/pkg/analyzer/lib/src/generated/testing/token_factory.dart b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
index 71dabc7..10654de 100644
--- a/pkg/analyzer/lib/src/generated/testing/token_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
@@ -4,8 +4,10 @@
 
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:meta/meta.dart';
 
 /// A set of utility methods that can be used to create tokens.
+@internal
 class TokenFactory {
   static Token tokenFromKeyword(Keyword keyword) => KeywordToken(keyword, 0);
 
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 0c8f774..8b32896 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -28,11 +28,7 @@
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart'
-    show
-        AnalysisErrorInfo,
-        AnalysisErrorInfoImpl,
-        AnalysisOptions,
-        AnalysisOptionsImpl;
+    show AnalysisErrorInfo, AnalysisErrorInfoImpl, AnalysisOptions;
 import 'package:analyzer/src/generated/resolver.dart' show ScopeResolverVisitor;
 import 'package:analyzer/src/generated/source.dart' show LineInfo;
 import 'package:analyzer/src/lint/analysis.dart';
@@ -368,11 +364,26 @@
       isNonNullableByDefault: libraryElement.isNonNullableByDefault,
     );
 
+    var evaluationEngine = ConstantEvaluationEngine(
+      declaredVariables: declaredVariables,
+      isNonNullableByDefault: isEnabled(Feature.non_nullable),
+    );
+
+    var dependencies = <ConstantEvaluationTarget>[];
+    node.accept(
+      ReferenceFinder(dependencies.add),
+    );
+
+    computeConstants(
+      typeProvider,
+      typeSystem,
+      declaredVariables,
+      dependencies,
+      libraryElement.featureSet,
+    );
+
     var visitor = ConstantVisitor(
-      ConstantEvaluationEngine(
-        declaredVariables: declaredVariables,
-        isNonNullableByDefault: isEnabled(Feature.non_nullable),
-      ),
+      evaluationEngine,
       libraryElement,
       errorReporter,
     );
@@ -476,7 +487,7 @@
       typeSystem,
       declaredVariables,
       dependenciesFinder.dependencies.toList(),
-      (analysisOptions as AnalysisOptionsImpl).experimentStatus,
+      libraryElement.featureSet,
     );
 
     var listener = _ConstantAnalysisErrorListener();
diff --git a/pkg/analyzer/lib/src/lint/pub.dart b/pkg/analyzer/lib/src/lint/pub.dart
index d68ecdf..8c11a57 100644
--- a/pkg/analyzer/lib/src/lint/pub.dart
+++ b/pkg/analyzer/lib/src/lint/pub.dart
@@ -52,28 +52,27 @@
 
 PSHost? _processHost(
     YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
-  if (v is! YamlMap) {
-    return null;
+  if (v is YamlScalar) {
+    // dependencies:
+    //   mypkg:
+    //     hosted:  https://some-pub-server.com
+    //     version: ^1.2.3
+    _PSHost host = _PSHost(isShortForm: true);
+    host.token = _PSNode(key, resourceProvider);
+    host.url = _processScalar(key, v, resourceProvider);
+    return host;
   }
-  YamlMap hostMap = v;
-  // name: transmogrify
-  // url: http://your-package-server.com
-  _PSHost host = _PSHost();
-  host.token = _PSNode(key, resourceProvider);
-  host.name = _findEntry(hostMap, 'name', resourceProvider);
-  host.url = _findEntry(hostMap, 'url', resourceProvider);
-  return host;
-}
-
-PSNodeList? _processList(
-    YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
-  if (v is! YamlList) {
-    return null;
+  if (v is YamlMap) {
+    YamlMap hostMap = v;
+    // name: transmogrify
+    // url: http://your-package-server.com
+    _PSHost host = _PSHost(isShortForm: false);
+    host.token = _PSNode(key, resourceProvider);
+    host.name = _findEntry(hostMap, 'name', resourceProvider);
+    host.url = _findEntry(hostMap, 'url', resourceProvider);
+    return host;
   }
-  YamlList nodeList = v;
-
-  return _PSNodeList(_PSNode(key, resourceProvider),
-      nodeList.nodes.map((n) => _PSNode(n, resourceProvider)));
+  return null;
 }
 
 PSEntry? _processScalar(
@@ -86,6 +85,30 @@
       _PSNode(key, resourceProvider), _PSNode(value, resourceProvider));
 }
 
+PSNodeList? _processScalarList(
+    YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
+  if (v is! YamlList) {
+    return null;
+  }
+  YamlList nodeList = v;
+
+  return _PSNodeList(
+      _PSNode(key, resourceProvider),
+      nodeList.nodes
+          .whereType<YamlScalar>()
+          .map((n) => _PSNode(n, resourceProvider)));
+}
+
+/// Representation of a key/value pair a map from package name to
+/// _package description_.
+///
+/// **Example** of a path-dependency:
+/// ```yaml
+/// dependencies:
+///   <name>:
+///     version: <version>
+///     path: <path>
+/// ```
 abstract class PSDependency {
   PSGitRepo? get git;
   PSHost? get host;
@@ -94,6 +117,8 @@
   PSEntry? get version;
 }
 
+/// Representation of the map from package name to _package description_ used
+/// under `dependencies`, `dev_dependencies` and `dependency_overrides`.
 abstract class PSDependencyList with IterableMixin<PSDependency> {}
 
 class PSEntry {
@@ -112,14 +137,54 @@
 }
 
 abstract class PSHost {
+  /// True, if _short-form_ for writing hosted-dependencies was used.
+  ///
+  /// **Example** of a hosted-dependency written in short-form:
+  /// ```yaml
+  /// dependencies:
+  ///   foo:
+  ///     hosted: https://some-pub-server.com
+  ///     version: ^1.2.3
+  /// ```
+  ///
+  /// The _long-form_ for writing the dependency given above is:
+  /// ```yaml
+  /// dependencies:
+  ///   foo:
+  ///     hosted:
+  ///       url: https://some-pub-server.com
+  ///       name: foo
+  ///     version: ^1.2.3
+  /// ```
+  ///
+  /// The short-form was added in Dart 2.15.0 because:
+  ///  * The `name` property just specifies the package name, which can be
+  ///    inferred from the context. So it is unnecessary to write it.
+  ///  * The nested object and `url` key becomes unnecessary when the `name`
+  ///    property is removed.
+  bool get isShortForm;
+
   PSEntry? get name;
   PSNode? get token;
   PSEntry? get url;
 }
 
+/// Representation of a leaf-node from `pubspec.yaml`.
 abstract class PSNode {
   Source get source;
   SourceSpan get span;
+
+  /// String value of the node, or `null` if value in pubspec.yaml is `null` or
+  /// omitted.
+  ///
+  /// **Example**
+  /// ```
+  /// name: foo
+  /// version:
+  /// ```
+  /// In the example above the [PSNode] for `foo` will have [text] "foo", and
+  /// the [PSNode] for `version` will have not have [text] as `null`, as empty
+  /// value or `"null"` is the same in YAML.
   String? get text;
 }
 
@@ -142,7 +207,9 @@
   PSDependencyList? get devDependencies;
   PSEntry? get documentation;
   PSEntry? get homepage;
+  PSEntry? get issueTracker;
   PSEntry? get name;
+  PSEntry? get repository;
   PSEntry? get version;
   void accept(PubspecVisitor visitor);
 }
@@ -159,7 +226,9 @@
   T? visitPackageDevDependency(PSDependency dependency) => null;
   T? visitPackageDocumentation(PSEntry documentation) => null;
   T? visitPackageHomepage(PSEntry homepage) => null;
+  T? visitPackageIssueTracker(PSEntry issueTracker) => null;
   T? visitPackageName(PSEntry name) => null;
+  T? visitPackageRepository(PSEntry repostory) => null;
   T? visitPackageVersion(PSEntry version) => null;
 }
 
@@ -276,11 +345,19 @@
 
 class _PSHost implements PSHost {
   @override
-  PSNode? token;
+  bool isShortForm;
+
   @override
   PSEntry? name;
+
+  @override
+  PSNode? token;
+
   @override
   PSEntry? url;
+
+  _PSHost({required this.isShortForm});
+
   @override
   String toString() => '''
     $token:
@@ -296,7 +373,7 @@
 
   final ResourceProvider? resourceProvider;
 
-  _PSNode(YamlNode node, this.resourceProvider)
+  _PSNode(YamlScalar node, this.resourceProvider)
       : text = node.value?.toString(),
         span = node.span;
 
@@ -337,8 +414,12 @@
   @override
   PSEntry? homepage;
   @override
+  PSEntry? issueTracker;
+  @override
   PSEntry? name;
   @override
+  PSEntry? repository;
+  @override
   PSEntry? version;
   @override
   PSDependencyList? dependencies;
@@ -372,6 +453,12 @@
     if (homepage != null) {
       visitor.visitPackageHomepage(homepage!);
     }
+    if (issueTracker != null) {
+      visitor.visitPackageIssueTracker(issueTracker!);
+    }
+    if (repository != null) {
+      visitor.visitPackageRepository(repository!);
+    }
     if (name != null) {
       visitor.visitPackageName(name!);
     }
@@ -401,6 +488,8 @@
     sb.writelin(authors);
     sb.writelin(description);
     sb.writelin(homepage);
+    sb.writelin(repository);
+    sb.writelin(issueTracker);
     sb.writelin(dependencies);
     sb.writelin(devDependencies);
     sb.writelin(dependencyOverrides);
@@ -424,11 +513,17 @@
           author = _processScalar(key, v, resourceProvider);
           break;
         case 'authors':
-          authors = _processList(key, v, resourceProvider);
+          authors = _processScalarList(key, v, resourceProvider);
           break;
         case 'homepage':
           homepage = _processScalar(key, v, resourceProvider);
           break;
+        case 'repository':
+          repository = _processScalar(key, v, resourceProvider);
+          break;
+        case 'issue_tracker':
+          issueTracker = _processScalar(key, v, resourceProvider);
+          break;
         case 'name':
           name = _processScalar(key, v, resourceProvider);
           break;
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.g.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.g.dart
index d988a94..0e1ee4c 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_warning_code.g.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.g.dart
@@ -76,7 +76,7 @@
   static const ManifestWarningCode UNSUPPORTED_CHROME_OS_FEATURE =
       ManifestWarningCode(
     'UNSUPPORTED_CHROME_OS_FEATURE',
-    "The feature {0} is not supported on Chrome OS, consider making it optional.",
+    "The feature {0} isn't supported on Chrome OS, consider making it optional.",
     correctionMessage:
         "Try changing to `android:required=\"false\"` for this feature.",
   );
@@ -88,7 +88,7 @@
   static const ManifestWarningCode UNSUPPORTED_CHROME_OS_HARDWARE =
       ManifestWarningCode(
     'UNSUPPORTED_CHROME_OS_HARDWARE',
-    "The feature {0} is not supported on Chrome OS, consider making it optional.",
+    "The feature {0} isn't supported on Chrome OS, consider making it optional.",
     correctionMessage:
         "Try adding `android:required=\"false\"` for this feature.",
   );
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.g.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.g.dart
index 689c4ba..88d2f07 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.g.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.g.dart
@@ -291,7 +291,7 @@
   // #### Description
   //
   // The analyzer produces this diagnostic when a package under either
-  // `dependencies` or `dev_dependencies` is not a pub, `git`, or `path` based
+  // `dependencies` or `dev_dependencies` isn't a pub, `git`, or `path` based
   // dependency.
   //
   // See [Package dependencies](https://dart.dev/tools/pub/dependencies) for
@@ -300,7 +300,7 @@
   // #### Example
   //
   // The following code produces this diagnostic because the dependency on the
-  // package `transmogrify` is not a pub, `git`, or `path` based dependency:
+  // package `transmogrify` isn't a pub, `git`, or `path` based dependency:
   //
   // ```yaml
   // %uri="pubspec.yaml"
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 588b150..b5a3097 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -504,6 +504,10 @@
   /// The list of changed file paths.
   final List<String> _changedPaths = [];
 
+  /// While processing [_changedPaths] we accumulate libraries here.
+  /// Then we process all of them at once, and reset to the empty set.
+  Set<_File> _invalidatedLibraries = {};
+
   /// The list of files scheduled for processing.  It may include parts and
   /// libraries, but parts are ignored when we detect them.
   final List<_ScheduledFile> _scheduledFiles = [];
@@ -529,7 +533,9 @@
       _whenKnownFilesPulled = now;
       pullKnownFiles();
     }
-    return _changedPaths.isNotEmpty || _scheduledFiles.isNotEmpty;
+    return _changedPaths.isNotEmpty ||
+        _invalidatedLibraries.isNotEmpty ||
+        _scheduledFiles.isNotEmpty;
   }
 
   /// Add the [analysisContext], so that its libraries are reported via the
@@ -595,6 +601,13 @@
       return;
     }
 
+    // There are no more changes as far as we know.
+    // So, recompute exported declarations for all invalidated libraries.
+    if (_invalidatedLibraries.isNotEmpty) {
+      _processInvalidatedLibraries(_invalidatedLibraries);
+      _invalidatedLibraries = {};
+    }
+
     if (_scheduledFiles.isNotEmpty) {
       var scheduledFile = _scheduledFiles.removeLast();
       var file = _getFileByPath(scheduledFile.context, [], scheduledFile.path)!;
@@ -794,11 +807,33 @@
         _invalidateExportedDeclarations(invalidatedLibraries, newLibrary);
       }
     }
-    _computeExportedDeclarations(invalidatedLibraries);
 
-    var changedLibraries = <Library>[];
+    // Don't compute exported declarations now, there might be more changes.
+    // Instead, accumulate invalidated libraries, and recompute all later.
+    _invalidatedLibraries.addAll(invalidatedLibraries);
+
     var removedLibraries = <int>[];
     for (var libraryFile in invalidatedLibraries) {
+      if (!libraryFile.exists) {
+        _idToLibrary.remove(libraryFile.id);
+        removedLibraries.add(libraryFile.id);
+      }
+    }
+    for (var file in notLibraries) {
+      _idToLibrary.remove(file.id);
+      removedLibraries.add(file.id);
+    }
+    if (removedLibraries.isNotEmpty) {
+      _changesController.add(
+        LibraryChange._([], removedLibraries),
+      );
+    }
+  }
+
+  void _processInvalidatedLibraries(Set<_File> invalidatedLibraries) {
+    _computeExportedDeclarations(invalidatedLibraries);
+    var changedLibraries = <Library>[];
+    for (var libraryFile in invalidatedLibraries) {
       if (libraryFile.exists) {
         var library = Library._(
           libraryFile.id,
@@ -809,17 +844,10 @@
         );
         _idToLibrary[library.id] = library;
         changedLibraries.add(library);
-      } else {
-        _idToLibrary.remove(libraryFile.id);
-        removedLibraries.add(libraryFile.id);
       }
     }
-    for (var file in notLibraries) {
-      _idToLibrary.remove(file.id);
-      removedLibraries.add(file.id);
-    }
     _changesController.add(
-      LibraryChange._(changedLibraries, removedLibraries),
+      LibraryChange._(changedLibraries, []),
     );
   }
 
diff --git a/pkg/analyzer/lib/src/source/package_map_resolver.dart b/pkg/analyzer/lib/src/source/package_map_resolver.dart
index 0feee31..9b96f99 100644
--- a/pkg/analyzer/lib/src/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/src/source/package_map_resolver.dart
@@ -37,6 +37,22 @@
   }
 
   @override
+  Uri? pathToUri(String path) {
+    pathos.Context pathContext = resourceProvider.pathContext;
+    for (String pkgName in packageMap.keys) {
+      Folder pkgFolder = packageMap[pkgName]![0];
+      String pkgFolderPath = pkgFolder.path;
+      if (path.startsWith(pkgFolderPath + pathContext.separator)) {
+        String relPath = path.substring(pkgFolderPath.length + 1);
+        List<String> relPathComponents = pathContext.split(relPath);
+        String relUriPath = pathos.posix.joinAll(relPathComponents);
+        return Uri.parse('$PACKAGE_SCHEME:$pkgName/$relUriPath');
+      }
+    }
+    return null;
+  }
+
+  @override
   Source? resolveAbsolute(Uri uri) {
     if (!isPackageUri(uri)) {
       return null;
@@ -61,23 +77,6 @@
     return null;
   }
 
-  @override
-  Uri? restoreAbsolute(Source source) {
-    String sourcePath = source.fullName;
-    pathos.Context pathContext = resourceProvider.pathContext;
-    for (String pkgName in packageMap.keys) {
-      Folder pkgFolder = packageMap[pkgName]![0];
-      String pkgFolderPath = pkgFolder.path;
-      if (sourcePath.startsWith(pkgFolderPath + pathContext.separator)) {
-        String relPath = sourcePath.substring(pkgFolderPath.length + 1);
-        List<String> relPathComponents = pathContext.split(relPath);
-        String relUriPath = pathos.posix.joinAll(relPathComponents);
-        return Uri.parse('$PACKAGE_SCHEME:$pkgName/$relUriPath');
-      }
-    }
-    return null;
-  }
-
   /// Returns `true` if [uri] is a `package` URI.
   static bool isPackageUri(Uri uri) {
     return uri.scheme == PACKAGE_SCHEME;
diff --git a/pkg/analyzer/lib/src/source/source_resource.dart b/pkg/analyzer/lib/src/source/source_resource.dart
index e9d258a..9334b31 100644
--- a/pkg/analyzer/lib/src/source/source_resource.dart
+++ b/pkg/analyzer/lib/src/source/source_resource.dart
@@ -65,9 +65,10 @@
   /// See [contents].
   TimestampedData<String> get contentsFromFile {
     return TimestampedData<String>(
-        modificationStamp, fileReadMode(file.readAsStringSync()));
+        file.modificationStamp, fileReadMode(file.readAsStringSync()));
   }
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => _encoding ??= uri.toString();
 
@@ -77,9 +78,11 @@
   @override
   int get hashCode => uri.hashCode;
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   @override
   bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;
 
+  @Deprecated('Not used anymore')
   @override
   int get modificationStamp {
     try {
@@ -92,6 +95,7 @@
   @override
   String get shortName => file.shortName;
 
+  @Deprecated('Use Source.uri instead')
   @override
   UriKind get uriKind => UriKind.fromScheme(uri.scheme);
 
diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
index de87280..a8e55db 100644
--- a/pkg/analyzer/lib/src/string_source.dart
+++ b/pkg/analyzer/lib/src/string_source.dart
@@ -29,18 +29,21 @@
   TimestampedData<String> get contents =>
       TimestampedData(modificationStamp, _contents);
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => uri.toString();
 
   @override
   int get hashCode => _contents.hashCode ^ fullName.hashCode;
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   @override
   bool get isInSystemLibrary => false;
 
   @override
   String get shortName => fullName;
 
+  @Deprecated('Use Source.uri instead')
   @override
   UriKind get uriKind => UriKind.FILE_URI;
 
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 03cce04..99372ae 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -72,9 +72,11 @@
   @override
   TimestampedData<String> get contents => TimestampedData<String>(0, '');
 
+  @Deprecated('Not used anymore')
   @override
   int get modificationStamp => 0;
 
+  @Deprecated('Use Source.uri instead')
   @override
   UriKind get uriKind => UriKind.PACKAGE_URI;
 
@@ -95,6 +97,9 @@
   InSummaryUriResolver(this.resourceProvider, this._dataStore);
 
   @override
+  Uri? pathToUri(String path) => null;
+
+  @override
   Source? resolveAbsolute(Uri uri) {
     String uriString = uri.toString();
     String? summaryPath = _dataStore.uriToSummaryPath[uriString];
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 1ad7efe..e53670d 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -90,4 +90,10 @@
     Uri uri = Uri.parse(uriStr);
     return _uriResolver.resolveAbsolute(uri);
   }
+
+  @override
+  Uri? pathToUri(String path) {
+    // Libraries from summaries don't have corresponding Dart files.
+    return null;
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 056696d..e331093 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -1406,6 +1406,8 @@
   List<DartType>? readOptionalTypeList() {
     if (_reader.readBool()) {
       return _readTypeList();
+    } else {
+      return null;
     }
   }
 
@@ -1695,6 +1697,8 @@
   ExpressionImpl? _readOptionalExpression() {
     if (_reader.readBool()) {
       return _readRequiredNode() as ExpressionImpl;
+    } else {
+      return null;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
index ff6e1b8..e72e947 100644
--- a/pkg/analyzer/lib/src/summary2/data_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -57,18 +57,24 @@
   String? readOptionalStringReference() {
     if (readBool()) {
       return readStringReference();
+    } else {
+      return null;
     }
   }
 
   String? readOptionalStringUtf8() {
     if (readBool()) {
       return readStringUtf8();
+    } else {
+      return null;
     }
   }
 
   int? readOptionalUInt30() {
     if (readBool()) {
       return readUInt30();
+    } else {
+      return null;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 5d1e535..8d6599b 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/util/comment.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:collection/collection.dart';
 
 class ElementBuilder extends ThrowingAstVisitor<void> {
@@ -997,16 +998,26 @@
     if (relativeUriStr == null) {
       return null;
     }
-    var relativeUri = Uri.parse(relativeUriStr);
-    return resolveRelativeUri(_libraryBuilder.uri, relativeUri);
+
+    Uri relativeUri;
+    try {
+      relativeUri = Uri.parse(relativeUriStr);
+    } on FormatException {
+      return null;
+    }
+
+    var absoluteUri = resolveRelativeUri(_libraryBuilder.uri, relativeUri);
+
+    var sourceFactory = _linker.analysisContext.sourceFactory;
+    return rewriteFileToPackageUri(sourceFactory, absoluteUri);
   }
 
   LibraryElement? _selectLibrary(NamespaceDirective node) {
-    try {
-      var uri = _selectAbsoluteUri(node);
-      return _linker.elementFactory.libraryOfUri('$uri');
-    } on FormatException {
+    var uri = _selectAbsoluteUri(node);
+    if (uri == null) {
       return null;
+    } else {
+      return _linker.elementFactory.libraryOfUri('$uri');
     }
   }
 
@@ -1261,7 +1272,9 @@
 
   Reference? addParameter(String? name, ParameterElementImpl element) {
     parameters.add(element);
-    if (name != null) {
+    if (name == null) {
+      return null;
+    } else {
       return _bindReference('@parameter', name, element);
     }
   }
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 3833cc9..b91377d 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -180,11 +180,18 @@
   LibraryElementImpl libraryOfUri2(String uriStr) {
     var element = libraryOfUri(uriStr);
     if (element == null) {
+      libraryOfUri(uriStr);
       throw StateError('No library: $uriStr');
     }
     return element;
   }
 
+  /// Return the [LibraryElementImpl] if it is ready.
+  LibraryElementImpl? libraryOfUriIfReady(String uriStr) {
+    var element = rootReference.getChild(uriStr).element;
+    return element is LibraryElementImpl ? element : null;
+  }
+
   /// We have linked the bundle, and need to disconnect its libraries, so
   /// that the client can re-add the bundle, this time read from bytes.
   void removeBundle(Set<String> uriStrSet) {
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 6a393dc..73b4a73 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -139,6 +139,7 @@
   static const String implicitDynamic = 'implicit-dynamic';
 
   // Language options (see AnalysisOptionsImpl for documentation).
+  static const String strictCasts = 'strict-casts';
   static const String strictInference = 'strict-inference';
   static const String strictRawTypes = 'strict-raw-types';
 
@@ -177,7 +178,11 @@
   ];
 
   /// Supported `analyzer` language options.
-  static const List<String> languageOptions = [strictInference, strictRawTypes];
+  static const List<String> languageOptions = [
+    strictCasts,
+    strictInference,
+    strictRawTypes,
+  ];
 
   /// Supported 'analyzer' optional checks options.
   static const List<String> optionalChecksOptions = [
@@ -750,6 +755,9 @@
       AnalysisOptionsImpl options, Object? feature, Object value) {
     var boolValue = toBool(value);
     if (boolValue != null) {
+      if (feature == AnalyzerOptions.strictCasts) {
+        options.strictCasts = boolValue;
+      }
       if (feature == AnalyzerOptions.strictInference) {
         options.strictInference = boolValue;
       }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3d179d7..ef1119a 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -82,21 +82,14 @@
   }
 
   void checkAssignment(Expression expr, DartType to) {
-    checkForCast(expr, from: expr.typeOrThrow, to: to);
+    _checkImplicitCast(expr, from: expr.typeOrThrow, to: to);
   }
 
-  /// Analyzer checks boolean conversions, but we need to check too, because
-  /// it uses the default assignability rules that allow `dynamic` and `Object`
-  /// to be assigned to bool with no message.
-  void checkBoolean(Expression expr) =>
-      checkAssignment(expr, typeProvider.boolType);
-
   void checkCollectionElement(
       CollectionElement? element, DartType expectedType) {
     if (element is ForElement) {
       checkCollectionElement(element.body, expectedType);
     } else if (element is IfElement) {
-      checkBoolean(element.condition);
       checkCollectionElement(element.thenElement, expectedType);
       checkCollectionElement(element.elseElement, expectedType);
     } else if (element is Expression) {
@@ -120,24 +113,11 @@
     }
   }
 
-  void checkForCast(
-    Expression expr, {
-    required DartType from,
-    required DartType to,
-  }) {
-    if (expr is ParenthesizedExpression) {
-      checkForCast(expr.expression, from: from, to: to);
-    } else {
-      _checkImplicitCast(expr, from: from, to: to);
-    }
-  }
-
   void checkMapElement(CollectionElement? element, DartType expectedKeyType,
       DartType expectedValueType) {
     if (element is ForElement) {
       checkMapElement(element.body, expectedKeyType, expectedValueType);
     } else if (element is IfElement) {
-      checkBoolean(element.condition);
       checkMapElement(element.thenElement, expectedKeyType, expectedValueType);
       checkMapElement(element.elseElement, expectedKeyType, expectedValueType);
     } else if (element is MapLiteralEntry) {
@@ -178,17 +158,12 @@
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
-    var left = node.leftHandSide;
-    var right = node.rightHandSide;
     Token operator = node.operator;
     TokenType operatorType = operator.type;
     if (operatorType == TokenType.EQ ||
         operatorType == TokenType.QUESTION_QUESTION_EQ) {
-      checkForCast(right, from: right.typeOrThrow, to: node.writeType!);
-    } else if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
-        operatorType == TokenType.BAR_BAR_EQ) {
-      checkBoolean(left);
-      checkBoolean(right);
+      var right = node.rightHandSide;
+      _checkImplicitCast(right, from: right.typeOrThrow, to: node.writeType!);
     } else {
       _checkCompoundAssignment(node);
     }
@@ -196,28 +171,6 @@
   }
 
   @override
-  void visitBinaryExpression(BinaryExpression node) {
-    var op = node.operator;
-    if (!op.isUserDefinableOperator) {
-      switch (op.type) {
-        case TokenType.AMPERSAND_AMPERSAND:
-        case TokenType.BAR_BAR:
-          checkBoolean(node.leftOperand);
-          checkBoolean(node.rightOperand);
-          break;
-        case TokenType.BANG_EQ:
-        case TokenType.BANG_EQ_EQ:
-        case TokenType.EQ_EQ_EQ:
-        case TokenType.QUESTION_QUESTION:
-          break;
-        default:
-          assert(false);
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  @override
   void visitComment(Comment node) {
     // skip, no need to do typechecking inside comments (they may contain
     // comment references which would require resolution).
@@ -231,31 +184,9 @@
 
   @override
   void visitConditionalExpression(ConditionalExpression node) {
-    checkBoolean(node.condition);
     node.visitChildren(this);
   }
 
-  /// Check constructor declaration to ensure correct super call placement.
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    node.visitChildren(this);
-
-    final init = node.initializers;
-    for (int i = 0, last = init.length - 1; i < last; i++) {
-      final initializer = init[i];
-      if (initializer is SuperConstructorInvocation) {
-        // TODO(srawlins): Don't report this when
-        //  [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR] or
-        //  [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS] is reported for
-        //  this constructor.
-        var source = (node.root as CompilationUnit).declaredElement!.source;
-        var token = initializer.superKeyword;
-        reporter.onError(AnalysisError(source, token.offset, token.length,
-            CompileTimeErrorCode.INVALID_SUPER_INVOCATION, [initializer]));
-      }
-    }
-  }
-
   @override
   void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     var field = node.fieldName;
@@ -281,12 +212,6 @@
   }
 
   @override
-  void visitDoStatement(DoStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitExpressionFunctionBody(ExpressionFunctionBody node) {
     _checkReturnOrYield(node.expression, node);
     node.visitChildren(this);
@@ -305,36 +230,12 @@
   }
 
   @override
-  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
-    var condition = node.condition;
-    if (condition != null) {
-      checkBoolean(condition);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitForPartsWithExpression(ForPartsWithExpression node) {
-    var condition = node.condition;
-    if (condition != null) {
-      checkBoolean(condition);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     _checkFunctionApplication(node);
     node.visitChildren(this);
   }
 
   @override
-  void visitIfStatement(IfStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitIndexExpression(IndexExpression node) {
     var element = node.writeOrReadElement;
     if (element is MethodElement) {
@@ -403,11 +304,7 @@
 
   @override
   void visitPrefixExpression(PrefixExpression node) {
-    if (node.operator.type == TokenType.BANG) {
-      checkBoolean(node.operand);
-    } else {
-      _checkUnary(node, node.operand, node.operator, node.staticElement);
-    }
+    _checkUnary(node, node.operand, node.operator, node.staticElement);
     node.visitChildren(this);
   }
 
@@ -523,7 +420,7 @@
       for (VariableDeclaration variable in node.variables) {
         var initializer = variable.initializer;
         if (initializer != null) {
-          checkForCast(initializer,
+          _checkImplicitCast(initializer,
               from: initializer.typeOrThrow, to: type.typeOrThrow);
         }
       }
@@ -533,12 +430,6 @@
   }
 
   @override
-  void visitWhileStatement(WhileStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitYieldStatement(YieldStatement node) {
     _checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
     node.visitChildren(this);
@@ -591,11 +482,10 @@
     }
   }
 
-  /// Given an expression [expr] of type [fromType], returns true if an implicit
-  /// downcast is required, false if it is not, or null if the types are
-  /// unrelated.
-  bool? _checkFunctionTypeCasts(
-      Expression expr, FunctionType to, DartType fromType) {
+  /// Returns true if an implicit downcast is required to assign an expression
+  /// of type [fromType] to type [to], false if it is not, or null if the
+  /// types are unrelated.
+  bool? _checkFunctionTypeCasts(FunctionType to, DartType fromType) {
     bool callTearoff = false;
     FunctionType? from;
     if (fromType is FunctionType) {
@@ -640,6 +530,7 @@
       return;
     }
 
+    expr = expr.unParenthesized;
     if (_needsImplicitCast(expr, to: to, from: from) == true) {
       _recordImplicitCast(expr, to,
           from: from,
@@ -796,7 +687,7 @@
     if (from.isVoid) return null;
 
     if (to is FunctionType) {
-      var needsCast = _checkFunctionTypeCasts(expr, to, from);
+      var needsCast = _checkFunctionTypeCasts(to, from);
       if (needsCast != null) return needsCast;
     }
 
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 21b51e7..3c22e00 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -344,6 +344,10 @@
     return _node(search, (n) => n is SuperConstructorInvocation);
   }
 
+  SuperFormalParameter superFormalParameter(String search) {
+    return _node(search, (n) => n is SuperFormalParameter);
+  }
+
   SwitchStatement switchStatement(String search) {
     return _node(search, (n) => n is SwitchStatement);
   }
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index a7ecd5a..7693ddd 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -47,7 +47,7 @@
 
   Future<T> whenComplete(action());
 
-  static Future<List<T>> wait<T>(Iterable<Future<T>> futures, 
+  static Future<List<T>> wait<T>(Iterable<Future<T>> futures,
     {void cleanUp(T successValue)?}) => throw 0;
 }
 
@@ -705,6 +705,10 @@
   const Double();
 }
 
+class IntPtr extends NativeType {
+  const IntPtr();
+}
+
 class Pointer<T extends NativeType> extends NativeType {
   external factory Pointer.fromAddress(int ptr);
 
@@ -789,6 +793,50 @@
   final bool isLeaf;
   const FfiNative(this.nativeName, {this.isLeaf: false});
 }
+
+class Abi {
+  static const androidArm = _androidArm;
+  static const androidArm64 = _androidArm64;
+  static const androidIA32 = _androidIA32;
+
+  static const _androidArm = Abi._(_Architecture.arm, _OS.android);
+  static const _androidArm64 = Abi._(_Architecture.arm64, _OS.android);
+  static const _androidIA32 = Abi._(_Architecture.ia32, _OS.android);
+
+  final _OS _os;
+
+  final _Architecture _architecture;
+
+  const Abi._(this._architecture, this._os);
+}
+
+enum _Architecture {
+  arm,
+  arm64,
+  ia32,
+  x64,
+}
+
+enum _OS {
+  android,
+  fuchsia,
+  ios,
+  linux,
+  macos,
+  windows,
+}
+
+
+class AbiSpecificInteger extends NativeType {
+  const AbiSpecificInteger();
+}
+
+class AbiSpecificIntegerMapping {
+  final Map<Abi, NativeType> mapping;
+
+  const AbiSpecificIntegerMapping(this.mapping);
+}
+
 ''',
   )
 ]);
diff --git a/pkg/analyzer/lib/src/util/performance/operation_performance.dart b/pkg/analyzer/lib/src/util/performance/operation_performance.dart
index 3a090d2..3d5ac61b 100644
--- a/pkg/analyzer/lib/src/util/performance/operation_performance.dart
+++ b/pkg/analyzer/lib/src/util/performance/operation_performance.dart
@@ -155,12 +155,9 @@
   ) async {
     var child = _existingOrNewChild(name);
     child._timer.start();
-
-    try {
-      return await operation(child);
-    } finally {
-      child._timer.stop();
-    }
+    var result = await operation(child);
+    child._timer.stop();
+    return result;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/util/uri.dart b/pkg/analyzer/lib/src/util/uri.dart
index 963dafc..08e3008 100644
--- a/pkg/analyzer/lib/src/util/uri.dart
+++ b/pkg/analyzer/lib/src/util/uri.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:path/path.dart';
 
 String fileUriToNormalizedPath(Context context, Uri fileUri) {
@@ -10,3 +12,32 @@
   path = context.normalize(path);
   return path;
 }
+
+/// If the [absoluteUri] is a `file` URI that has corresponding `package` URI,
+/// return it. If the URI is not valid, e.g. has empty path segments, so
+/// does not represent a valid file path, return `null`.
+Uri? rewriteFileToPackageUri(SourceFactory sourceFactory, Uri absoluteUri) {
+  // Only file URIs get rewritten into package URIs.
+  if (!absoluteUri.isScheme('file')) {
+    return absoluteUri;
+  }
+
+  // It must be a valid URI, e.g. `file:///home/` is not.
+  var pathSegments = absoluteUri.pathSegments;
+  if (pathSegments.isEmpty || pathSegments.last.isEmpty) {
+    return null;
+  }
+
+  // We ask for Source only because `restoreUri` needs it.
+  // TODO(scheglov) Add more direct way to convert a path to URI.
+  var source = sourceFactory.forUri2(absoluteUri);
+  if (source == null) {
+    return null;
+  }
+
+  if (source is InSummarySource) {
+    return source.uri;
+  }
+
+  return sourceFactory.pathToUri(source.fullName);
+}
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index aa3aec8..e8f24d5 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -53,9 +53,21 @@
         _context = workspace.provider.pathContext;
 
   @override
-  void clearCache() {
-    _sourceCache.clear();
-    _workspace.clearCache();
+  Uri? pathToUri(String path) {
+    // Search in each root.
+    for (var root in [
+      ..._workspace.binPaths,
+      _workspace.genfiles,
+      _workspace.readonly,
+      _workspace.root
+    ]) {
+      var uriParts = _restoreUriParts(root, path);
+      if (uriParts != null) {
+        return Uri.parse('package:${uriParts[0]}/${uriParts[1]}');
+      }
+    }
+
+    return null;
   }
 
   @override
@@ -70,26 +82,6 @@
     return source;
   }
 
-  @override
-  Uri? restoreAbsolute(Source source) {
-    String filePath = source.fullName;
-
-    // Search in each root.
-    for (var root in [
-      ..._workspace.binPaths,
-      _workspace.genfiles,
-      _workspace.readonly,
-      _workspace.root
-    ]) {
-      var uriParts = _restoreUriParts(root, filePath);
-      if (uriParts != null) {
-        return Uri.parse('package:${uriParts[0]}/${uriParts[1]}');
-      }
-    }
-
-    return null;
-  }
-
   Source? _resolveAbsolute(Uri uri) {
     if (uri.scheme == 'file') {
       var path = fileUriToNormalizedPath(_context, uri);
@@ -148,7 +140,7 @@
         String pathInLib = components.skip(4).join('/');
         return [packageName, pathInLib];
       } else {
-        for (int i = 2; i < components.length - 1; i++) {
+        for (int i = components.length - 2; i >= 2; i--) {
           String component = components[i];
           if (component == 'lib') {
             String packageName = components.getRange(0, i).join('.');
@@ -238,10 +230,6 @@
   @override
   UriResolver get packageUriResolver => BazelPackageUriResolver(this);
 
-  void clearCache() {
-    _directoryToPackage.clear();
-  }
-
   @override
   SourceFactory createSourceFactory(
     DartSdk? sdk,
@@ -370,6 +358,8 @@
         return packageRootedAt(folder);
       }
     }
+
+    return null;
   }
 
   /// In some distributed build environments, BUILD files are not preserved.
@@ -509,10 +499,9 @@
             context.join(root, '$symlinkPrefix-genfiles'),
             lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
       }
-
-      // // Go up the folder.
-      // folder = parent;
     }
+
+    return null;
   }
 
   /// Find the "bin" folder path, by searching for it.
@@ -599,6 +588,8 @@
     for (var match in pattern.allMatches(content)) {
       return Version.parse('${match.group(1)}.0');
     }
+
+    return null;
   }
 }
 
diff --git a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
index b3f09ec..54b96a0 100644
--- a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
@@ -123,6 +123,8 @@
         // folder, so we use a dummy value here. But this shouldn't really
         // matter, since the `symlinkTarget` should detect any modifications.
         return _ModifiedInfo(0, 0, symlinkTarget);
+      } else {
+        return null;
       }
     } on FileSystemException catch (_) {
       // File doesn't exist, so return null.
diff --git a/pkg/analyzer/lib/src/workspace/gn.dart b/pkg/analyzer/lib/src/workspace/gn.dart
index e22ce32..8ebed62 100644
--- a/pkg/analyzer/lib/src/workspace/gn.dart
+++ b/pkg/analyzer/lib/src/workspace/gn.dart
@@ -88,6 +88,7 @@
         return GnWorkspacePackage(folder.path, this);
       }
     }
+    return null;
   }
 
   /// Find the GN workspace that contains the given [filePath].
@@ -123,6 +124,7 @@
         return GnWorkspace._(provider, root, packageMap);
       }
     }
+    return null;
   }
 
   /// For a source at `$root/foo/bar`, the packages files are generated in
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index ba6e15c..4e06f04 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -60,6 +60,18 @@
   Map<String, List<Folder>> get packageMap => _workspace.packageMap;
 
   @override
+  Uri? pathToUri(String path) {
+    if (_context.isWithin(_workspace.root, path)) {
+      var uriParts = _restoreUriParts(path);
+      if (uriParts != null) {
+        return Uri.parse('package:${uriParts[0]}/${uriParts[1]}');
+      }
+    }
+
+    return _normalUriResolver.pathToUri(path);
+  }
+
+  @override
   Source? resolveAbsolute(Uri uri) {
     if (uri.scheme != 'package') {
       return null;
@@ -90,20 +102,6 @@
     return basicResolverSource;
   }
 
-  @override
-  Uri? restoreAbsolute(Source source) {
-    String filePath = source.fullName;
-
-    if (_context.isWithin(_workspace.root, filePath)) {
-      var uriParts = _restoreUriParts(filePath);
-      if (uriParts != null) {
-        return Uri.parse('package:${uriParts[0]}/${uriParts[1]}');
-      }
-    }
-
-    return _normalUriResolver.restoreAbsolute(source);
-  }
-
   List<String>? _restoreUriParts(String filePath) {
     String relative = _context.relative(filePath, from: _workspace.root);
     List<String> components = _context.split(relative);
@@ -330,13 +328,16 @@
         return null;
       }
     }
+    return null;
   }
 
   /// Return the content of the [file], `null` if cannot be read.
   static String? _fileContentOrNull(File file) {
     try {
       return file.readAsStringSync();
-    } catch (_) {}
+    } catch (_) {
+      return null;
+    }
   }
 }
 
diff --git a/pkg/analyzer/lib/src/workspace/pub.dart b/pkg/analyzer/lib/src/workspace/pub.dart
index e5059d7..1d83253 100644
--- a/pkg/analyzer/lib/src/workspace/pub.dart
+++ b/pkg/analyzer/lib/src/workspace/pub.dart
@@ -74,13 +74,16 @@
         return PubWorkspace._(provider, packageMap, root, pubspec);
       }
     }
+    return null;
   }
 
   /// Return the content of the [file], `null` if cannot be read.
   static String? _fileContentOrNull(File file) {
     try {
       return file.readAsStringSync();
-    } catch (_) {}
+    } catch (_) {
+      return null;
+    }
   }
 }
 
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 3aa6e61..7ad997e 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -6524,46 +6524,6 @@
 
       class C {}
       ```
-  INVALID_SUPER_INVOCATION:
-    problemMessage: "The superclass call must be last in an initializer list: '{0}'."
-    hasPublishedDocs: true
-    comment: No parameters.
-    documentation: |-
-      #### Description
-
-      The analyzer produces this diagnostic when the initializer list of a
-      constructor contains an invocation of a constructor in the superclass, but
-      the invocation isn't the last item in the initializer list.
-
-      #### Example
-
-      The following code produces this diagnostic because the invocation of the
-      superclass' constructor isn't the last item in the initializer list:
-
-      ```dart
-      class A {
-        A(int x);
-      }
-
-      class B extends A {
-        B(int x) : [!super!](x), assert(x >= 0);
-      }
-      ```
-
-      #### Common fixes
-
-      Move the invocation of the superclass' constructor to the end of the
-      initializer list:
-
-      ```dart
-      class A {
-        A(int x);
-      }
-
-      class B extends A {
-        B(int x) : assert(x >= 0), super(x);
-      }
-      ```
   INVALID_TYPE_ARGUMENT_IN_CONST_LIST:
     sharedName: INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL
     problemMessage: "Constant list literals can't include a type parameter as a type argument, such as '{0}'."
@@ -11329,6 +11289,49 @@
       7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
       is a compile-time error if a generative constructor of class Object
       includes a superinitializer.
+  SUPER_INVOCATION_NOT_LAST:
+    previousName: INVALID_SUPER_INVOCATION
+    problemMessage: "The superconstructor call must be last in an initializer list: '{0}'."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the superinitializer
+    documentation: |-
+      #### Description
+
+      The analyzer produces this diagnostic when the initializer list of a
+      constructor contains an invocation of a constructor in the superclass, but
+      the invocation isn't the last item in the initializer list.
+
+      #### Example
+
+      The following code produces this diagnostic because the invocation of the
+      superclass' constructor isn't the last item in the initializer list:
+
+      ```dart
+      class A {
+        A(int x);
+      }
+
+      class B extends A {
+        B(int x) : [!super!](x), assert(x >= 0);
+      }
+      ```
+
+      #### Common fixes
+
+      Move the invocation of the superclass' constructor to the end of the
+      initializer list:
+
+      ```dart
+      class A {
+        A(int x);
+      }
+
+      class B extends A {
+        B(int x) : assert(x >= 0), super(x);
+      }
+      ```
   SUPER_IN_EXTENSION:
     problemMessage: "The 'super' keyword can't be used in an extension because an extension doesn't have a superclass."
     hasPublishedDocs: true
@@ -12936,6 +12939,7 @@
       1: the name of the enclosing type where the getter is being looked for
   UNDEFINED_SUPER_METHOD:
     sharedName: UNDEFINED_SUPER_MEMBER
+    previousName: UNDEFINED_SUPER_METHOD
     problemMessage: "The method '{0}' isn't defined in a superclass of '{1}'."
     correctionMessage: "Try correcting the name to the name of an existing method, or defining a method named '{0}' in a superclass."
     hasPublishedDocs: true
@@ -13715,8 +13719,16 @@
       function that is not a generator function.
 
       No parameters.
+  YIELD_EACH_OF_INVALID_TYPE:
+    sharedName: YIELD_OF_INVALID_TYPE
+    problemMessage: "The type '{0}' implied by the 'yield*' expression must be assignable to '{1}'."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the type of the expression after `yield*`
+      1: the return type of the function containing the `yield*`
   YIELD_OF_INVALID_TYPE:
-    problemMessage: "The type '{0}' implied by the 'yield' expression must be assignable to '{1}'."
+    problemMessage: "A yielded value of type '{0}' must be assignable to '{1}'."
     hasPublishedDocs: true
     comment: |-
       Parameters:
@@ -13725,10 +13737,11 @@
     documentation: |-
       #### Description
 
-      The analyzer produces this diagnostic when the type of object produced by a
-      `yield` expression doesn't match the type of objects that are to be
-      returned from the `Iterable` or `Stream` types that are returned from a
-      generator (a function or method marked with either `sync*` or `async*`).
+      The analyzer produces this diagnostic when the type of object produced by
+      a `yield` or `yield*` expression doesn't match the type of objects that
+      are to be returned from the `Iterable` or `Stream` types that are returned
+      from a generator (a function or method marked with either `sync*` or
+      `async*`).
 
       #### Example
 
@@ -13762,6 +13775,18 @@
       }
       ```
 FfiCode:
+  ABI_SPECIFIC_INTEGER_MAPPING_EXTRA:
+    problemMessage: "Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a 'NativeType' integer with a fixed size."
+    correctionMessage: Try removing the extra annotation.
+    comment: No parameters.
+  ABI_SPECIFIC_INTEGER_MAPPING_MISSING:
+    problemMessage: "Classes extending 'AbiSpecificInteger' must have exactly one 'AbiSpecificIntegerMapping' annotation specifying the mapping from ABI to a 'NativeType' integer with a fixed size."
+    correctionMessage: Try adding an annotation.
+    comment: No parameters.
+  ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED:
+    problemMessage: "Only mappings to 'Int8', 'Int16', 'Int32', 'Int64', 'Uint8', 'Uint16', 'UInt32', and 'Uint64' are supported."
+    correctionMessage: Try changing the value to 'Int8', 'Int16', 'Int32', 'Int64', 'Uint8', 'Uint16', 'UInt32', or 'Uint64'.
+    comment: No parameters.
   ANNOTATION_ON_POINTER_FIELD:
     problemMessage: "Fields in a struct class whose type is 'Pointer' should not have any annotations."
     correctionMessage: Try removing the annotation.
@@ -13903,8 +13928,8 @@
     correctionMessage: Try changing the input to a positive number.
     comment: No parameters.
   NON_SIZED_TYPE_ARGUMENT:
-    problemMessage: "Type arguments to '{0}' can't have the type '{1}'. They can only be declared as native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct' or 'Union'."
-    correctionMessage: "Try using a native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct' or 'Union'."
+    problemMessage: "Type arguments to '{0}' can't have the type '{1}'. They can only be declared as native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct', 'Union', or 'AbiSpecificInteger'."
+    correctionMessage: "Try using a native integer, 'Float', 'Double', 'Pointer', or subtype of 'Struct', 'Union', or 'AbiSpecificInteger'."
     comment: |-
       Parameters:
       0: the type of the field
@@ -16620,7 +16645,7 @@
       var x = min(0, 1);
       ```
   UNDEFINED_REFERENCED_PARAMETER:
-    problemMessage: "The parameter '{0}' is not defined by '{1}'."
+    problemMessage: "The parameter '{0}' isn't defined by '{1}'."
     hasPublishedDocs: true
     comment: |-
       Parameters:
@@ -17444,11 +17469,11 @@
     correctionMessage: Consider declaring the corresponding activity element with `screenOrientation="unspecified"` or `"fullSensor"` attribute.
     comment: A code indicating that the activity is locked to an orientation.
   UNSUPPORTED_CHROME_OS_FEATURE:
-    problemMessage: "The feature {0} is not supported on Chrome OS, consider making it optional."
+    problemMessage: "The feature {0} isn't supported on Chrome OS, consider making it optional."
     correctionMessage: "Try changing to `android:required=\"false\"` for this feature."
     comment: A code indicating that a specified feature is not supported on Chrome OS.
   UNSUPPORTED_CHROME_OS_HARDWARE:
-    problemMessage: "The feature {0} is not supported on Chrome OS, consider making it optional."
+    problemMessage: "The feature {0} isn't supported on Chrome OS, consider making it optional."
     correctionMessage: "Try adding `android:required=\"false\"` for this feature."
     comment: |-
       A code indicating that a specified hardware feature is not supported on
@@ -18015,7 +18040,7 @@
       #### Description
 
       The analyzer produces this diagnostic when a package under either
-      `dependencies` or `dev_dependencies` is not a pub, `git`, or `path` based
+      `dependencies` or `dev_dependencies` isn't a pub, `git`, or `path` based
       dependency.
 
       See [Package dependencies](https://dart.dev/tools/pub/dependencies) for
@@ -18024,7 +18049,7 @@
       #### Example
 
       The following code produces this diagnostic because the dependency on the
-      package `transmogrify` is not a pub, `git`, or `path` based dependency:
+      package `transmogrify` isn't a pub, `git`, or `path` based dependency:
 
       ```yaml
       %uri="pubspec.yaml"
@@ -18384,7 +18409,7 @@
       `isEven` if `s` is `null`. In other words, if `s` is `null`, then neither
       `length` nor `isEven` will be invoked, and if `s` is non-`null`, then
       `length` can't return a `null` value. Either way, `isEven` can't be invoked
-      on a `null` value, so the null-aware operator is not necessary. See
+      on a `null` value, so the null-aware operator isn't necessary. See
       [Understanding null safety](/null-safety/understanding-null-safety#smarter-null-aware-methods)
       for more details.
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 76dc2d2..14a27f7 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 2.8.0-dev
+version: 2.8.0
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer
 
@@ -7,7 +7,7 @@
   sdk: '>=2.14.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^30.0.0
+  _fe_analyzer_shared: ^31.0.0
   cli_util: ^0.3.0
   collection: ^1.15.0
   convert: ^3.0.0
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 4718ea0..12d892c 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -122,8 +122,8 @@
                 "A",
                 null,
                 null,
-                AstTestFactory.typeName4('B'),
-                AstTestFactory.withClause([AstTestFactory.typeName4('M')]),
+                AstTestFactory.namedType4('B'),
+                AstTestFactory.withClause([AstTestFactory.namedType4('M')]),
                 null)
             .isAbstract,
         isFalse);
@@ -132,8 +132,8 @@
                 "B",
                 null,
                 Keyword.ABSTRACT,
-                AstTestFactory.typeName4('A'),
-                AstTestFactory.withClause([AstTestFactory.typeName4('M')]),
+                AstTestFactory.namedType4('A'),
+                AstTestFactory.withClause([AstTestFactory.namedType4('M')]),
                 null)
             .isAbstract,
         isTrue);
@@ -1142,7 +1142,7 @@
 
   void test_isQualified_inConstructorName() {
     ConstructorName constructor = AstTestFactory.constructorName(
-        AstTestFactory.typeName4('MyClass'), "test");
+        AstTestFactory.namedType4('MyClass'), "test");
     SimpleIdentifier name = constructor.name!;
     expect(name.isQualified, isTrue);
   }
@@ -1688,6 +1688,21 @@
 }
 
 @reflectiveTest
+class SuperFormalParameterTest {
+  void test_endToken_noParameters() {
+    SuperFormalParameter parameter =
+        AstTestFactory.superFormalParameter2('field');
+    expect(parameter.endToken, parameter.identifier.endToken);
+  }
+
+  void test_endToken_parameters() {
+    SuperFormalParameter parameter = AstTestFactory.superFormalParameter(
+        null, null, 'field', AstTestFactory.formalParameterList([]));
+    expect(parameter.endToken, parameter.parameters!.endToken);
+  }
+}
+
+@reflectiveTest
 class VariableDeclarationTest extends ParserTestCase {
   void test_getDocumentationComment_onGrandParent() {
     VariableDeclaration varDecl = AstTestFactory.variableDeclaration("a");
diff --git a/pkg/analyzer/test/file_system/file_system_test_support.dart b/pkg/analyzer/test/file_system/file_system_test_support.dart
index 722474a..0550aa1 100644
--- a/pkg/analyzer/test/file_system/file_system_test_support.dart
+++ b/pkg/analyzer/test/file_system/file_system_test_support.dart
@@ -103,7 +103,6 @@
     Source source = file.createSource();
     expect(source, isNotNull);
     expect(source.fullName, defaultFilePath);
-    expect(source.uriKind, UriKind.FILE_URI);
     expect(source.uri, Uri.file(defaultFilePath));
     expect(source.exists(), isTrue);
     expect(source.contents.data, defaultFileContent);
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index 9eecb33..873dc18 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -216,6 +216,7 @@
     expect(source.fullName, sourcePath);
   }
 
+  @Deprecated('Not used anymore')
   test_modificationStamp() {
     expect(source.modificationStamp, -1);
   }
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index c6192fb..61f06df 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -29,6 +29,12 @@
     expect(resolver, isNotNull);
   }
 
+  void test_pathToUri() {
+    var path = convertPath('/test.dart');
+    var uri = toUri(path);
+    expect(resolver.pathToUri(path), uri);
+  }
+
   void test_resolveAbsolute_file() {
     var uri = toUri('/test.dart');
 
@@ -59,14 +65,15 @@
     expect(source, isNull);
   }
 
+  @Deprecated('Use pathToUri() instead')
   void test_restoreAbsolute() {
     var uri = toUri('/test.dart');
 
     var source = resolver.resolveAbsolute(uri)!;
     expect(resolver.restoreAbsolute(source), uri);
     expect(
-        resolver.restoreAbsolute(NonExistingSource(
-            source.fullName, Uri.parse('dart:math'), UriKind.DART_URI)),
+        resolver.restoreAbsolute(
+            NonExistingSource(source.fullName, Uri.parse('dart:math'))),
         uri);
   }
 }
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 2fd5fff..532fa53 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -5,10 +5,8 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart' hide SdkLibrariesReader;
-import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:test/test.dart';
@@ -18,7 +16,6 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(DartUriResolverTest);
     defineReflectiveTests(ErrorSeverityTest);
-    defineReflectiveTests(FileBasedSourceTest);
     defineReflectiveTests(ResolveRelativeUriTest);
     defineReflectiveTests(UriKindTest);
   });
@@ -44,6 +41,18 @@
     expect(DartUriResolver.isDartUri(uri), isFalse);
   }
 
+  void test_pathToUri_library() {
+    var path = convertPath('/sdk/lib/core/core.dart');
+    var dartUri = resolver.pathToUri(path);
+    expect(dartUri.toString(), 'dart:core');
+  }
+
+  void test_pathToUri_part() {
+    var path = convertPath('/sdk/lib/core/int.dart');
+    var dartUri = resolver.pathToUri(path);
+    expect(dartUri.toString(), 'dart:core/int.dart');
+  }
+
   void test_resolve_dart_library() {
     var source = resolver.resolveAbsolute(Uri.parse('dart:core'));
     expect(source, isNotNull);
@@ -64,16 +73,18 @@
     expect(result, isNull);
   }
 
+  @Deprecated('Use pathToUri() instead')
   void test_restoreAbsolute_library() {
     _SourceMock source = _SourceMock();
-    source.uri = toUri('/sdk/lib/core/core.dart');
+    source.fullName = convertPath('/sdk/lib/core/core.dart');
     var dartUri = resolver.restoreAbsolute(source);
     expect(dartUri.toString(), 'dart:core');
   }
 
+  @Deprecated('Use pathToUri() instead')
   void test_restoreAbsolute_part() {
     _SourceMock source = _SourceMock();
-    source.uri = toUri('/sdk/lib/core/int.dart');
+    source.fullName = convertPath('/sdk/lib/core/int.dart');
     var dartUri = resolver.restoreAbsolute(source);
     expect(dartUri.toString(), 'dart:core/int.dart');
   }
@@ -128,134 +139,6 @@
 }
 
 @reflectiveTest
-class FileBasedSourceTest {
-  test_equals_false_differentFiles() async {
-    JavaFile file1 = FileUtilities2.createFile("/does/not/exist1.dart");
-    JavaFile file2 = FileUtilities2.createFile("/does/not/exist2.dart");
-    FileBasedSource source1 = FileBasedSource(file1);
-    FileBasedSource source2 = FileBasedSource(file2);
-    expect(source1 == source2, isFalse);
-  }
-
-  test_equals_false_null() async {
-    JavaFile file = FileUtilities2.createFile("/does/not/exist1.dart");
-    FileBasedSource source1 = FileBasedSource(file);
-    expect(source1, isNotNull);
-  }
-
-  test_equals_true() async {
-    JavaFile file1 = FileUtilities2.createFile("/does/not/exist.dart");
-    JavaFile file2 = FileUtilities2.createFile("/does/not/exist.dart");
-    FileBasedSource source1 = FileBasedSource(file1);
-    FileBasedSource source2 = FileBasedSource(file2);
-    expect(source1 == source2, isTrue);
-  }
-
-  test_getFullName() async {
-    String fullPath = "/does/not/exist.dart";
-    JavaFile file = FileUtilities2.createFile(fullPath);
-    FileBasedSource source = FileBasedSource(file);
-    expect(source.fullName, file.getAbsolutePath());
-  }
-
-  test_getShortName() async {
-    JavaFile file = FileUtilities2.createFile("/does/not/exist.dart");
-    FileBasedSource source = FileBasedSource(file);
-    expect(source.shortName, "exist.dart");
-  }
-
-  test_hashCode() async {
-    JavaFile file1 = FileUtilities2.createFile("/does/not/exist.dart");
-    JavaFile file2 = FileUtilities2.createFile("/does/not/exist.dart");
-    FileBasedSource source1 = FileBasedSource(file1);
-    FileBasedSource source2 = FileBasedSource(file2);
-    expect(source2.hashCode, source1.hashCode);
-  }
-
-  test_isInSystemLibrary_contagious() async {
-    DartSdk sdk = (_SimpleDartSdkTest()..setUp()).sdk;
-    UriResolver resolver = DartUriResolver(sdk);
-    SourceFactory factory = SourceFactory([resolver]);
-    // resolve dart:core
-    var result = resolver.resolveAbsolute(Uri.parse("dart:core"));
-    expect(result, isNotNull);
-    expect(result!.isInSystemLibrary, isTrue);
-    // system libraries reference only other system libraries
-    var partSource = factory.resolveUri(result, "num.dart");
-    expect(partSource, isNotNull);
-    expect(partSource!.isInSystemLibrary, isTrue);
-  }
-
-  test_isInSystemLibrary_false() async {
-    JavaFile file = FileUtilities2.createFile("/does/not/exist.dart");
-    FileBasedSource source = FileBasedSource(file);
-    expect(source, isNotNull);
-    expect(source.fullName, file.getAbsolutePath());
-    expect(source.isInSystemLibrary, isFalse);
-  }
-
-  test_issue14500() async {
-    // see https://code.google.com/p/dart/issues/detail?id=14500
-    FileBasedSource source = FileBasedSource(
-        FileUtilities2.createFile("/some/packages/foo:bar.dart"));
-    expect(source, isNotNull);
-    expect(source.exists(), isFalse);
-  }
-
-  test_resolveRelative_file_fileName() async {
-    if (OSUtilities.isWindows()) {
-      // On Windows, the URI that is produced includes a drive letter,
-      // which I believe is not consistent across all machines that might run
-      // this test.
-      return;
-    }
-    JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
-    FileBasedSource source = FileBasedSource(file);
-    expect(source, isNotNull);
-    Uri relative = resolveRelativeUri(source.uri, Uri.parse("lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "file:///a/b/lib.dart");
-  }
-
-  test_resolveRelative_file_filePath() async {
-    if (OSUtilities.isWindows()) {
-      // On Windows, the URI that is produced includes a drive letter,
-      // which I believe is not consistent across all machines that might run
-      // this test.
-      return;
-    }
-    JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
-    FileBasedSource source = FileBasedSource(file);
-    expect(source, isNotNull);
-    Uri relative = resolveRelativeUri(source.uri, Uri.parse("c/lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "file:///a/b/c/lib.dart");
-  }
-
-  test_resolveRelative_file_filePathWithParent() async {
-    if (OSUtilities.isWindows()) {
-      // On Windows, the URI that is produced includes a drive letter, which I
-      // believe is not consistent across all machines that might run this test.
-      return;
-    }
-    JavaFile file = FileUtilities2.createFile("/a/b/test.dart");
-    FileBasedSource source = FileBasedSource(file);
-    expect(source, isNotNull);
-    Uri relative = resolveRelativeUri(source.uri, Uri.parse("../c/lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "file:///a/c/lib.dart");
-  }
-
-  test_system() async {
-    JavaFile file = FileUtilities2.createFile("/does/not/exist.dart");
-    FileBasedSource source = FileBasedSource(file, Uri.parse("dart:core"));
-    expect(source, isNotNull);
-    expect(source.fullName, file.getAbsolutePath());
-    expect(source.isInSystemLibrary, isTrue);
-  }
-}
-
-@reflectiveTest
 class ResolveRelativeUriTest {
   test_resolveRelative_dart_dartUri() async {
     _assertResolve('dart:foo', 'dart:bar', 'dart:bar');
@@ -310,6 +193,7 @@
 
 @reflectiveTest
 class UriKindTest {
+  @deprecated
   test_fromEncoding() async {
     expect(UriKind.fromEncoding(0x64), same(UriKind.DART_URI));
     expect(UriKind.fromEncoding(0x66), same(UriKind.FILE_URI));
@@ -317,6 +201,7 @@
     expect(UriKind.fromEncoding(0x58), isNull);
   }
 
+  @deprecated
   test_getEncoding() async {
     expect(UriKind.DART_URI.encoding, 0x64);
     expect(UriKind.FILE_URI.encoding, 0x66);
@@ -351,6 +236,9 @@
 
 class _SourceMock implements Source {
   @override
+  late final String fullName;
+
+  @override
   late final Uri uri;
 
   @override
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index a82b0a3..a018a3e 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -444,7 +444,7 @@
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
     ConstructorName name = AstTestFactory.constructorName(
-        AstTestFactory.typeName(classA), constructorName);
+        AstTestFactory.namedType(classA), constructorName);
     _resolveNode(name);
     expect(name.staticElement, same(constructor));
     _listener.assertNoErrors();
@@ -458,7 +458,7 @@
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
     ConstructorName name = AstTestFactory.constructorName(
-        AstTestFactory.typeName(classA), constructorName);
+        AstTestFactory.namedType(classA), constructorName);
     _resolveNode(name);
     expect(name.staticElement, same(constructor));
     _listener.assertNoErrors();
@@ -573,7 +573,7 @@
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
     var name = AstTestFactory.constructorName(
-        AstTestFactory.typeName(classA), constructorName);
+        AstTestFactory.namedType(classA), constructorName);
     name.staticElement = constructor;
     InstanceCreationExpression creation =
         AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
@@ -588,7 +588,7 @@
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
     var name = AstTestFactory.constructorName(
-        AstTestFactory.typeName(classA), constructorName);
+        AstTestFactory.namedType(classA), constructorName);
     name.staticElement = constructor;
     InstanceCreationExpression creation =
         AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
@@ -607,7 +607,7 @@
     constructor.parameters = <ParameterElement>[parameter];
     classA.constructors = <ConstructorElement>[constructor];
     var name = AstTestFactory.constructorName(
-        AstTestFactory.typeName(classA), constructorName);
+        AstTestFactory.namedType(classA), constructorName);
     name.staticElement = constructor;
     InstanceCreationExpression creation =
         AstTestFactory.instanceCreationExpression(Keyword.NEW, name, [
diff --git a/pkg/analyzer/test/generated/java_io_test.dart b/pkg/analyzer/test/generated/java_io_test.dart
index 561b53a..35bfdeb 100644
--- a/pkg/analyzer/test/generated/java_io_test.dart
+++ b/pkg/analyzer/test/generated/java_io_test.dart
@@ -16,6 +16,7 @@
         expect(path.context.isAbsolute(absolutePath), isTrue,
             reason: '"$absolutePath" is not absolute');
         // test that toURI() returns an absolute URI
+        // ignore: deprecated_member_use_from_same_package
         Uri uri = JavaFile(absolutePath).toURI();
         expect(uri.isAbsolute, isTrue);
         expect(uri.scheme, 'file');
@@ -30,6 +31,7 @@
         // it may be not on Windows, if "temp" is on other disk.
         String relPath = path.context.relative(absolutePath);
         // test that toURI() returns an absolute URI
+        // ignore: deprecated_member_use_from_same_package
         Uri uri = JavaFile(relPath).toURI();
         expect(uri.isAbsolute, isTrue);
         expect(uri.scheme, 'file');
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index 6cdd3b6..f40c8da 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -732,9 +732,56 @@
   }
 
   @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
     end('Enum');
-    super.endEnum(enumKeyword, leftBrace, count);
+    super.endEnum(enumKeyword, leftBrace, memberCount);
+  }
+
+  @override
+  void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    end('Method');
+    super.endEnumConstructor(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
+  }
+
+  @override
+  void endEnumFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    end('FactoryMethod');
+    super.endEnumFactoryMethod(beginToken, factoryKeyword, endToken);
+  }
+
+  @override
+  void endEnumFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    expectIn('Member');
+    super.endEnumFields(
+        abstractToken,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        count,
+        beginToken,
+        endToken);
+  }
+
+  @override
+  void endEnumMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    end('Method');
+    super.endEnumMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
   }
 
   @override
@@ -838,15 +885,16 @@
   @override
   void endFormalParameter(
       Token? thisKeyword,
-      Token? periodAfterThis,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
       Token nameToken,
       Token? initializerStart,
       Token? initializerEnd,
       FormalParameterKind kind,
       MemberKind memberKind) {
     end('FormalParameter');
-    super.endFormalParameter(thisKeyword, periodAfterThis, nameToken,
-        initializerStart, initializerEnd, kind, memberKind);
+    super.endFormalParameter(thisKeyword, superKeyword, periodAfterThisOrSuper,
+        nameToken, initializerStart, initializerEnd, kind, memberKind);
   }
 
   @override
@@ -1283,25 +1331,54 @@
   }
 
   @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
-    expectInOneOf(['ClassDeclaration', 'MixinDeclaration']);
-    listener?.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
-  }
-
-  @override
   void handleDottedName(int count, Token firstIdentifier) {
     expectIn('ConditionalUri');
     super.handleDottedName(count, firstIdentifier);
   }
 
   @override
+  void handleEnumElement(Token beginToken) {
+    expectIn('Enum');
+    super.handleEnumElement(beginToken);
+  }
+
+  @override
+  void handleEnumElements(Token elementsEndToken, int elementsCount) {
+    expectIn('Enum');
+    super.handleEnumElements(elementsEndToken, elementsCount);
+  }
+
+  @override
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    expectIn('Enum');
+    super.handleEnumHeader(enumKeyword, leftBrace);
+  }
+
+  @override
+  void handleEnumNoWithClause() {
+    expectIn('Enum');
+    super.handleEnumNoWithClause();
+  }
+
+  @override
+  void handleEnumWithClause(Token withKeyword) {
+    expectIn('Enum');
+    super.handleEnumWithClause(withKeyword);
+  }
+
+  @override
   void handleIdentifierList(int count) {
     expectInOneOf(['Hide', 'Show']);
     super.handleIdentifierList(count);
   }
 
   @override
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
+    expectInOneOf(['ClassDeclaration', 'MixinDeclaration', 'Enum']);
+    listener?.handleImplements(implementsKeyword, interfacesCount);
+  }
+
+  @override
   void handleImportPrefix(Token? deferredKeyword, Token? asKeyword) {
     // This event normally happens within "Import",
     // but happens within "CompilationUnit" during recovery.
@@ -1346,6 +1423,12 @@
   }
 
   @override
+  void handleNoTypeNameInConstructorReference(Token token) {
+    expectIn('Enum');
+    super.handleNoTypeNameInConstructorReference(token);
+  }
+
+  @override
   void handleRecoverClassHeader() {
     expectIn('ClassDeclaration');
     listener?.handleRecoverClassHeader();
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index 98e3f04..f13f48d 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -39,6 +39,16 @@
     expect(SourceFactory([]), isNotNull);
   }
 
+  void test_pathToUri() {
+    File file1 = getFile("/some/file1.dart");
+    File file2 = getFile("/some/file2.dart");
+    Uri expected1 = Uri.parse("file:///my_file.dart");
+    SourceFactory factory =
+        SourceFactory([UriResolver_restoreUri(file1.path, expected1)]);
+    expect(factory.pathToUri(file1.path), expected1);
+    expect(factory.pathToUri(file2.path), isNull);
+  }
+
   void test_resolveUri_absolute() {
     UriResolver_absolute resolver = UriResolver_absolute();
     SourceFactory factory = SourceFactory([resolver]);
@@ -95,6 +105,7 @@
     expect(result.uri.toString(), 'package:package/dir/second.dart');
   }
 
+  @Deprecated('Use pathToUri() instead')
   void test_restoreUri() {
     File file1 = getFile("/some/file1.dart");
     File file2 = getFile("/some/file2.dart");
@@ -102,7 +113,7 @@
     Source source2 = FileSource(file2);
     Uri expected1 = Uri.parse("file:///my_file.dart");
     SourceFactory factory =
-        SourceFactory([UriResolver_restoreUri(source1, expected1)]);
+        SourceFactory([UriResolver_restoreUri(file1.path, expected1)]);
     expect(factory.restoreUri(source1), same(expected1));
     expect(factory.restoreUri(source2), isNull);
   }
@@ -121,20 +132,20 @@
 }
 
 class UriResolver_restoreUri extends UriResolver {
-  Source source1;
+  String path1;
   Uri expected1;
-  UriResolver_restoreUri(this.source1, this.expected1);
+  UriResolver_restoreUri(this.path1, this.expected1);
 
   @override
-  Source? resolveAbsolute(Uri uri) => null;
-
-  @override
-  Uri? restoreAbsolute(Source source) {
-    if (identical(source, source1)) {
+  Uri? pathToUri(String path) {
+    if (path == path1) {
       return expected1;
     }
     return null;
   }
+
+  @override
+  Source? resolveAbsolute(Uri uri) => null;
 }
 
 class UriResolver_SourceFactoryTest_test_fromEncoding_valid
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index affcebc..6d3741a 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -230,7 +230,7 @@
     InterfaceType superclassType = interfaceTypeStar(superclass);
     ClassElement subclass = ElementFactory.classElement("B", superclassType);
     Expression node = AstTestFactory.asExpression(
-        AstTestFactory.thisExpression(), AstTestFactory.typeName(subclass));
+        AstTestFactory.thisExpression(), AstTestFactory.namedType(subclass));
     expect(_analyze(node, superclassType), interfaceTypeStar(subclass));
     _listener.assertNoErrors();
   }
@@ -315,7 +315,7 @@
     InstanceCreationExpression node =
         AstTestFactory.instanceCreationExpression2(
             null,
-            AstTestFactory.typeName(classElement),
+            AstTestFactory.namedType(classElement),
             [AstTestFactory.identifier3(constructorName)]);
     expect(_analyze(node), interfaceTypeStar(classElement));
     _listener.assertNoErrors();
@@ -328,8 +328,8 @@
     ConstructorElementImpl constructor =
         ElementFactory.constructorElement2(elementC, null);
     elementC.constructors = <ConstructorElement>[constructor];
-    var typeName =
-        AstTestFactory.typeName(elementC, [AstTestFactory.typeName(elementI)]);
+    var typeName = AstTestFactory.namedType(
+        elementC, [AstTestFactory.namedType(elementI)]);
     typeName.type = interfaceTypeStar(elementC,
         typeArguments: [interfaceTypeStar(elementI)]);
     InstanceCreationExpression node =
@@ -349,7 +349,7 @@
     classElement.constructors = <ConstructorElement>[constructor];
     InstanceCreationExpression node =
         AstTestFactory.instanceCreationExpression2(
-            null, AstTestFactory.typeName(classElement));
+            null, AstTestFactory.namedType(classElement));
     expect(_analyze(node), interfaceTypeStar(classElement));
     _listener.assertNoErrors();
   }
@@ -365,7 +365,7 @@
   void test_visitIsExpression_negated() {
     // a is! String
     Expression node = AstTestFactory.isExpression(
-        _resolvedString("a"), true, AstTestFactory.typeName4("String"));
+        _resolvedString("a"), true, AstTestFactory.namedType4("String"));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
@@ -373,7 +373,7 @@
   void test_visitIsExpression_notNegated() {
     // a is String
     Expression node = AstTestFactory.isExpression(
-        _resolvedString("a"), false, AstTestFactory.typeName4("String"));
+        _resolvedString("a"), false, AstTestFactory.namedType4("String"));
     expect(_analyze(node), same(_typeProvider.boolType));
     _listener.assertNoErrors();
   }
diff --git a/pkg/analyzer/test/generated/test_analysis_context.dart b/pkg/analyzer/test/generated/test_analysis_context.dart
index 840d225..7d5eae6 100644
--- a/pkg/analyzer/test/generated/test_analysis_context.dart
+++ b/pkg/analyzer/test/generated/test_analysis_context.dart
@@ -9,7 +9,7 @@
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk_elements.dart';
 
 class TestAnalysisContext implements AnalysisContext {
@@ -43,6 +43,7 @@
     _typeSystemLegacy = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: false,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: _typeProviderLegacy,
     );
@@ -50,6 +51,7 @@
     _typeSystemNonNullableByDefault = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: true,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: _typeProviderNonNullableByDefault,
     );
@@ -105,6 +107,7 @@
 
   _MockSource(this.uri);
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => '$uri';
 
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index be7a535..927a542 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -454,6 +454,7 @@
     return TimestampedData<String>(0, _contents);
   }
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => _name;
 
@@ -465,11 +466,13 @@
   @override
   int get hashCode => 0;
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   @override
   bool get isInSystemLibrary {
     return false;
   }
 
+  @Deprecated('Not used anymore')
   @override
   int get modificationStamp =>
       generateExceptionOnRead ? -1 : _modificationStamp;
@@ -482,6 +485,7 @@
   @override
   Uri get uri => Uri.file(_name);
 
+  @Deprecated('Use Source.uri instead')
   @override
   UriKind get uriKind {
     throw UnsupportedError('uriKind');
@@ -519,9 +523,11 @@
   TestSourceWithUri(String path, this.uri, [String content = ''])
       : super(path, content);
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => uri.toString();
 
+  @Deprecated('Use Source.uri instead')
   @override
   UriKind get uriKind {
     if (uri.scheme == 'dart') {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 95aa6050..20115cd 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,15 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -209,24 +212,6 @@
   Expression get(CascadeExpression node) => node.target;
 }
 
-class Getter_NodeReplacerTest_test_catchClause
-    implements NodeReplacerTest_Getter<CatchClause, SimpleIdentifier> {
-  @override
-  SimpleIdentifier? get(CatchClause node) => node.stackTraceParameter;
-}
-
-class Getter_NodeReplacerTest_test_catchClause_2
-    implements NodeReplacerTest_Getter<CatchClause, SimpleIdentifier> {
-  @override
-  SimpleIdentifier? get(CatchClause node) => node.exceptionParameter;
-}
-
-class Getter_NodeReplacerTest_test_catchClause_3
-    implements NodeReplacerTest_Getter<CatchClause, TypeAnnotation> {
-  @override
-  TypeAnnotation? get(CatchClause node) => node.exceptionType;
-}
-
 class Getter_NodeReplacerTest_test_classDeclaration
     implements NodeReplacerTest_Getter<ClassDeclaration, ImplementsClause> {
   @override
@@ -1399,7 +1384,7 @@
         AstTestFactory.identifier3("c"),
         AstTestFactory.argumentList([AstTestFactory.integer(0)]),
         typeArguments:
-            AstTestFactory.typeArgumentList2([AstTestFactory.typeName4('T')]));
+            AstTestFactory.typeArgumentList2([AstTestFactory.namedType4('T')]));
     _assertReplace(node, Getter_NodeReplacerTest_test_annotation());
     _assertReplace(node, Getter_NodeReplacerTest_test_annotation_3());
     _assertReplace(node, Getter_NodeReplacerTest_test_annotation_2());
@@ -1414,8 +1399,8 @@
   void test_asExpression() {
     AsExpression node = AstTestFactory.asExpression(
         AstTestFactory.integer(0),
-        AstTestFactory.typeName3(
-            AstTestFactory.identifier3("a"), [AstTestFactory.typeName4("C")]));
+        AstTestFactory.namedType3(
+            AstTestFactory.identifier3("a"), [AstTestFactory.namedType4("C")]));
     _assertReplace(node, Getter_NodeReplacerTest_test_asExpression_2());
     _assertReplace(node, Getter_NodeReplacerTest_test_asExpression());
   }
@@ -1475,14 +1460,22 @@
   }
 
   void test_catchClause() {
-    CatchClause node = AstTestFactory.catchClause5(
-        AstTestFactory.typeName4("E"),
-        "e",
-        "s",
-        [AstTestFactory.emptyStatement()]);
-    _assertReplace(node, Getter_NodeReplacerTest_test_catchClause_3());
-    _assertReplace(node, Getter_NodeReplacerTest_test_catchClause_2());
-    _assertReplace(node, Getter_NodeReplacerTest_test_catchClause());
+    var findNode = _parseStringToFindNode(r'''
+void f() {
+  try {} on E catch (e, st) {}
+  try {} on E2 catch (e2, st2) {}
+}
+''');
+    _assertReplace2<CatchClause>(
+      destination: findNode.catchClause('(e,'),
+      source: findNode.catchClause('(e2,'),
+      getters: [
+        (node) => node.exceptionType!,
+        (node) => node.exceptionParameter!,
+        (node) => node.stackTraceParameter!,
+        (node) => node.body,
+      ],
+    );
   }
 
   void test_classDeclaration() {
@@ -1490,9 +1483,9 @@
         null,
         "A",
         AstTestFactory.typeParameterList(["E"]),
-        AstTestFactory.extendsClause(AstTestFactory.typeName4("B")),
-        AstTestFactory.withClause([AstTestFactory.typeName4("C")]),
-        AstTestFactory.implementsClause([AstTestFactory.typeName4("D")]), [
+        AstTestFactory.extendsClause(AstTestFactory.namedType4("B")),
+        AstTestFactory.withClause([AstTestFactory.namedType4("C")]),
+        AstTestFactory.implementsClause([AstTestFactory.namedType4("D")]), [
       AstTestFactory.fieldDeclaration2(
           false, null, [AstTestFactory.variableDeclaration("f")])
     ]);
@@ -1515,9 +1508,9 @@
         "A",
         AstTestFactory.typeParameterList(["E"]),
         null,
-        AstTestFactory.typeName4("B"),
-        AstTestFactory.withClause([AstTestFactory.typeName4("C")]),
-        AstTestFactory.implementsClause([AstTestFactory.typeName4("D")]));
+        AstTestFactory.namedType4("B"),
+        AstTestFactory.withClause([AstTestFactory.namedType4("C")]),
+        AstTestFactory.implementsClause([AstTestFactory.namedType4("D")]));
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
     node.metadata
         .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
@@ -1582,7 +1575,7 @@
     node.metadata
         .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
     node.redirectedConstructor =
-        AstTestFactory.constructorName(AstTestFactory.typeName4("B"), "a");
+        AstTestFactory.constructorName(AstTestFactory.namedType4("B"), "a");
     _assertReplace(
         node, Getter_NodeReplacerTest_test_constructorDeclaration_3());
     _assertReplace(
@@ -1609,7 +1602,7 @@
 
   void test_constructorName() {
     ConstructorName node =
-        AstTestFactory.constructorName(AstTestFactory.typeName4("C"), "n");
+        AstTestFactory.constructorName(AstTestFactory.namedType4("C"), "n");
     _assertReplace(node, Getter_NodeReplacerTest_test_constructorName());
     _assertReplace(node, Getter_NodeReplacerTest_test_constructorName_2());
   }
@@ -1621,7 +1614,7 @@
 
   void test_declaredIdentifier() {
     var node =
-        AstTestFactory.declaredIdentifier4(AstTestFactory.typeName4("C"), "i");
+        AstTestFactory.declaredIdentifier4(AstTestFactory.namedType4("C"), "i");
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
     node.metadata
         .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
@@ -1688,7 +1681,7 @@
 
   void test_extendsClause() {
     ExtendsClause node =
-        AstTestFactory.extendsClause(AstTestFactory.typeName4("S"));
+        AstTestFactory.extendsClause(AstTestFactory.namedType4("S"));
     _assertReplace(node, Getter_NodeReplacerTest_test_extendsClause());
   }
 
@@ -1696,7 +1689,7 @@
     var node = AstTestFactory.fieldDeclaration(
         false,
         null,
-        AstTestFactory.typeName4("C"),
+        AstTestFactory.namedType4("C"),
         [AstTestFactory.variableDeclaration("c")]);
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
     node.metadata
@@ -1708,7 +1701,7 @@
   void test_fieldFormalParameter() {
     var node = AstTestFactory.fieldFormalParameter(
         null,
-        AstTestFactory.typeName4("C"),
+        AstTestFactory.namedType4("C"),
         "f",
         AstTestFactory.formalParameterList());
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
@@ -1789,7 +1782,7 @@
 
   void test_functionDeclaration() {
     var node = AstTestFactory.functionDeclaration(
-        AstTestFactory.typeName4("R"),
+        AstTestFactory.namedType4("R"),
         null,
         "f",
         AstTestFactory.functionExpression2(AstTestFactory.formalParameterList(),
@@ -1806,7 +1799,7 @@
   void test_functionDeclarationStatement() {
     FunctionDeclarationStatement node =
         AstTestFactory.functionDeclarationStatement(
-            AstTestFactory.typeName4("R"),
+            AstTestFactory.namedType4("R"),
             null,
             "f",
             AstTestFactory.functionExpression2(
@@ -1836,7 +1829,7 @@
 
   void test_functionTypeAlias() {
     var node = AstTestFactory.typeAlias(
-        AstTestFactory.typeName4("R"),
+        AstTestFactory.namedType4("R"),
         "F",
         AstTestFactory.typeParameterList(["E"]),
         AstTestFactory.formalParameterList());
@@ -1852,7 +1845,7 @@
 
   void test_functionTypedFormalParameter() {
     var node = AstTestFactory.functionTypedFormalParameter(
-        AstTestFactory.typeName4("R"),
+        AstTestFactory.namedType4("R"),
         "f",
         [AstTestFactory.simpleFormalParameter3("p")]);
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
@@ -1883,7 +1876,7 @@
 
   void test_implementsClause() {
     ImplementsClause node = AstTestFactory.implementsClause(
-        [AstTestFactory.typeName4("I"), AstTestFactory.typeName4("J")]);
+        [AstTestFactory.namedType4("I"), AstTestFactory.namedType4("J")]);
     _assertReplace(node, ListGetter_NodeReplacerTest_test_implementsClause(0));
   }
 
@@ -1911,7 +1904,7 @@
   void test_instanceCreationExpression() {
     InstanceCreationExpression node =
         AstTestFactory.instanceCreationExpression3(null,
-            AstTestFactory.typeName4("C"), "c", [AstTestFactory.integer(2)]);
+            AstTestFactory.namedType4("C"), "c", [AstTestFactory.integer(2)]);
     _assertReplace(
         node, Getter_NodeReplacerTest_test_instanceCreationExpression_2());
     _assertReplace(
@@ -1926,7 +1919,7 @@
 
   void test_isExpression() {
     IsExpression node = AstTestFactory.isExpression(
-        AstTestFactory.identifier3("v"), false, AstTestFactory.typeName4("T"));
+        AstTestFactory.identifier3("v"), false, AstTestFactory.namedType4("T"));
     _assertReplace(node, Getter_NodeReplacerTest_test_isExpression());
     _assertReplace(node, Getter_NodeReplacerTest_test_isExpression_2());
   }
@@ -1960,7 +1953,7 @@
   void test_listLiteral() {
     ListLiteral node = AstTestFactory.listLiteral2(
         null,
-        AstTestFactory.typeArgumentList([AstTestFactory.typeName4("E")]),
+        AstTestFactory.typeArgumentList([AstTestFactory.namedType4("E")]),
         [AstTestFactory.identifier3("e")]);
     _assertReplace(node, ListGetter_NodeReplacerTest_test_listLiteral(0));
     _testTypedLiteral(node);
@@ -1969,7 +1962,7 @@
   void test_mapLiteral() {
     SetOrMapLiteral node = AstTestFactory.setOrMapLiteral(
         null,
-        AstTestFactory.typeArgumentList([AstTestFactory.typeName4("E")]),
+        AstTestFactory.typeArgumentList([AstTestFactory.namedType4("E")]),
         [AstTestFactory.mapLiteralEntry("k", AstTestFactory.identifier3("v"))]);
     _assertReplace(node, ListGetter_NodeReplacerTest_test_mapLiteral(0));
     _testTypedLiteral(node);
@@ -1985,7 +1978,7 @@
   void test_methodDeclaration() {
     var node = AstTestFactory.methodDeclaration2(
         null,
-        AstTestFactory.typeName4("A"),
+        AstTestFactory.namedType4("A"),
         null,
         null,
         AstTestFactory.identifier3("m"),
@@ -2099,7 +2092,7 @@
 
   void test_simpleFormalParameter() {
     var node = AstTestFactory.simpleFormalParameter4(
-        AstTestFactory.typeName4("T"), "p");
+        AstTestFactory.namedType4("T"), "p");
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
     node.metadata = [
       AstTestFactory.annotation(AstTestFactory.identifier3("a"))
@@ -2127,6 +2120,30 @@
         node, Getter_NodeReplacerTest_test_superConstructorInvocation_2());
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/47741')
+  void test_superFormalParameter() {
+    var findNode = _parseStringToFindNode(r'''
+class A {
+  A(int foo<T>(int a));
+}
+
+class B extends A {
+  B.sub1(double super.bar1<T1>(int a1),);
+  B.sub2(double super.bar2<T2>(int a2),);
+}
+''');
+    _assertReplace2<SuperFormalParameter>(
+      destination: findNode.superFormalParameter('bar1'),
+      source: findNode.superFormalParameter('bar2'),
+      getters: [
+        (node) => node.type!,
+        (node) => node.identifier,
+        (node) => node.typeParameters!,
+        (node) => node.parameters!,
+      ],
+    );
+  }
+
   void test_switchCase() {
     SwitchCase node = AstTestFactory.switchCase2([AstTestFactory.label2("l")],
         AstTestFactory.integer(0), [AstTestFactory.block()]);
@@ -2161,7 +2178,7 @@
   void test_topLevelVariableDeclaration() {
     var node = AstTestFactory.topLevelVariableDeclaration(
         null,
-        AstTestFactory.typeName4("T"),
+        AstTestFactory.namedType4("T"),
         [AstTestFactory.variableDeclaration("t")]);
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
     node.metadata
@@ -2185,20 +2202,20 @@
 
   void test_typeArgumentList() {
     TypeArgumentList node =
-        AstTestFactory.typeArgumentList2([AstTestFactory.typeName4("A")]);
+        AstTestFactory.typeArgumentList2([AstTestFactory.namedType4("A")]);
     _assertReplace(node, ListGetter_NodeReplacerTest_test_typeArgumentList(0));
   }
 
   void test_typeName() {
-    NamedType node = AstTestFactory.typeName4(
-        "T", [AstTestFactory.typeName4("E"), AstTestFactory.typeName4("F")]);
+    NamedType node = AstTestFactory.namedType4(
+        "T", [AstTestFactory.namedType4("E"), AstTestFactory.namedType4("F")]);
     _assertReplace(node, Getter_NodeReplacerTest_test_typeName_2());
     _assertReplace(node, Getter_NodeReplacerTest_test_typeName());
   }
 
   void test_typeParameter() {
     TypeParameter node =
-        AstTestFactory.typeParameter2("E", AstTestFactory.typeName4("B"));
+        AstTestFactory.typeParameter2("E", AstTestFactory.namedType4("B"));
     _assertReplace(node, Getter_NodeReplacerTest_test_typeParameter_2());
     _assertReplace(node, Getter_NodeReplacerTest_test_typeParameter());
   }
@@ -2222,7 +2239,7 @@
   void test_variableDeclarationList() {
     var node = AstTestFactory.variableDeclarationList(
         null,
-        AstTestFactory.typeName4("T"),
+        AstTestFactory.namedType4("T"),
         [AstTestFactory.variableDeclaration("a")]);
     node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
     node.metadata
@@ -2238,7 +2255,7 @@
     VariableDeclarationStatement node =
         AstTestFactory.variableDeclarationStatement(
             null,
-            AstTestFactory.typeName4("T"),
+            AstTestFactory.namedType4("T"),
             [AstTestFactory.variableDeclaration("a")]);
     _assertReplace(
         node, Getter_NodeReplacerTest_test_variableDeclarationStatement());
@@ -2253,7 +2270,7 @@
 
   void test_withClause() {
     WithClause node =
-        AstTestFactory.withClause([AstTestFactory.typeName4("M")]);
+        AstTestFactory.withClause([AstTestFactory.namedType4("M")]);
     _assertReplace(node, ListGetter_NodeReplacerTest_test_withClause(0));
   }
 
@@ -2271,6 +2288,35 @@
     }
   }
 
+  void _assertReplace2<T extends AstNode>({
+    required T destination,
+    required T source,
+    required List<AstNode Function(T node)> getters,
+  }) {
+    for (var getter in getters) {
+      var child = getter(destination);
+      expect(child.parent, destination);
+
+      var replacement = getter(source);
+      NodeReplacer.replace(child, replacement);
+      expect(getter(destination), replacement);
+      expect(replacement.parent, destination);
+    }
+  }
+
+  FindNode _parseStringToFindNode(String content) {
+    var parseResult = parseString(
+      content: content,
+      featureSet: FeatureSet.fromEnableFlags2(
+        sdkLanguageVersion: ExperimentStatus.currentVersion,
+        flags: [
+          Feature.super_parameters.enableString,
+        ],
+      ),
+    );
+    return FindNode(parseResult.content, parseResult.unit);
+  }
+
   void _testAnnotatedNode(AnnotatedNode node) {
     _assertReplace(node, Getter_NodeReplacerTest_testAnnotatedNode());
     _assertReplace(node, ListGetter_NodeReplacerTest_testAnnotatedNode(0));
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index 19aee6d..27d7a9c 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -39,6 +39,33 @@
     expect(PackageMapUriResolver.isPackageUri(uri), isFalse);
   }
 
+  void test_pathToUri() {
+    String pkgFileA = provider.convertPath('/pkgA/lib/libA.dart');
+    String pkgFileB = provider.convertPath('/pkgB/lib/src/libB.dart');
+    provider.newFile(pkgFileA, 'library lib_a;');
+    provider.newFile(pkgFileB, 'library lib_b;');
+    PackageMapUriResolver resolver =
+        PackageMapUriResolver(provider, <String, List<Folder>>{
+      'pkgA': <Folder>[provider.getFolder(provider.convertPath('/pkgA/lib'))],
+      'pkgB': <Folder>[provider.getFolder(provider.convertPath('/pkgB/lib'))]
+    });
+    {
+      var path = provider.convertPath('/pkgA/lib/libA.dart');
+      var uri = resolver.pathToUri(path);
+      expect(uri, Uri.parse('package:pkgA/libA.dart'));
+    }
+    {
+      var path = provider.convertPath('/pkgB/lib/src/libB.dart');
+      var uri = resolver.pathToUri(path);
+      expect(uri, Uri.parse('package:pkgB/src/libB.dart'));
+    }
+    {
+      var path = provider.convertPath('/no/such/file');
+      var uri = resolver.pathToUri(path);
+      expect(uri, isNull);
+    }
+  }
+
   void test_resolve_multiple_folders() {
     var a = provider.newFile(provider.convertPath('/aaa/a.dart'), '');
     var b = provider.newFile(provider.convertPath('/bbb/b.dart'), '');
@@ -70,14 +97,14 @@
       Uri uri = Uri.parse('package:pkgA/libA.dart');
       var result = resolver.resolveAbsolute(uri)!;
       expect(result.exists(), isTrue);
-      expect(result.uriKind, UriKind.PACKAGE_URI);
+      expect(result.uri, uri);
       expect(result.fullName, pkgFileA);
     }
     {
       Uri uri = Uri.parse('package:pkgB/libB.dart');
       var result = resolver.resolveAbsolute(uri)!;
       expect(result.exists(), isTrue);
-      expect(result.uriKind, UriKind.PACKAGE_URI);
+      expect(result.uri, uri);
       expect(result.fullName, pkgFileB);
     }
   }
@@ -144,6 +171,7 @@
     expect(result, isNull);
   }
 
+  @Deprecated('Use pathToUri() instead')
   void test_restoreAbsolute() {
     String pkgFileA = provider.convertPath('/pkgA/lib/libA.dart');
     String pkgFileB = provider.convertPath('/pkgB/lib/src/libB.dart');
@@ -173,7 +201,8 @@
     }
   }
 
+  @Deprecated('Use pathToUri() instead')
   Source _createFileSource(String path) {
-    return NonExistingSource(path, toUri(path), UriKind.FILE_URI);
+    return NonExistingSource(path, toUri(path));
   }
 }
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 7f3d1cb..b6c9542 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -153,13 +153,10 @@
   void tearDown() {}
 }
 
-class _GeneratedUriResolverMock implements UriResolver {
+class _GeneratedUriResolverMock extends UriResolver {
   Source? Function(Uri)? resolveAbsoluteFunction;
 
-  Uri? Function(Source)? restoreAbsoluteFunction;
-
-  @override
-  void clearCache() {}
+  Uri? Function(String)? pathToUriFunction;
 
   @override
   noSuchMethod(Invocation invocation) {
@@ -167,17 +164,14 @@
   }
 
   @override
-  Source? resolveAbsolute(Uri uri) {
-    if (resolveAbsoluteFunction != null) {
-      return resolveAbsoluteFunction!(uri);
-    }
-    return null;
+  Uri? pathToUri(String path) {
+    return pathToUriFunction?.call(path);
   }
 
   @override
-  Uri? restoreAbsolute(Source source) {
-    if (restoreAbsoluteFunction != null) {
-      return restoreAbsoluteFunction!(source);
+  Source? resolveAbsolute(Uri uri) {
+    if (resolveAbsoluteFunction != null) {
+      return resolveAbsoluteFunction!(uri);
     }
     return null;
   }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 65e9392..d9bdc60 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -51,7 +51,7 @@
       TypeArgumentList argumentList, List<DartType> expectedTypes) {
     expect(argumentList.arguments, hasLength(expectedTypes.length));
     for (int i = 0; i < expectedTypes.length; i++) {
-      _assertTypeNameSimple(argumentList.arguments[i], expectedTypes[i]);
+      _assertNamedTypeSimple(argumentList.arguments[i], expectedTypes[i]);
     }
   }
 
@@ -1804,11 +1804,11 @@
       expect(type.parameters[0].type, typeProvider.intType);
     }
 
-    _assertTypeNameSimple(p.returnType!, typeProvider.stringType);
+    _assertNamedTypeSimple(p.returnType!, typeProvider.stringType);
 
     {
       var a = p.parameters.parameters[0] as SimpleFormalParameter;
-      _assertTypeNameSimple(a.type!, typeProvider.intType);
+      _assertNamedTypeSimple(a.type!, typeProvider.intType);
       expect(a.identifier!.staticType, isNull);
     }
   }
@@ -1850,11 +1850,11 @@
       expect(type.parameters[0].type, typeProvider.intType);
     }
 
-    _assertTypeNameSimple(p.type!, typeProvider.stringType);
+    _assertNamedTypeSimple(p.type!, typeProvider.stringType);
 
     {
       var a = p.parameters!.parameters[0] as SimpleFormalParameter;
-      _assertTypeNameSimple(a.type!, typeProvider.intType);
+      _assertNamedTypeSimple(a.type!, typeProvider.intType);
       expect(a.identifier!.staticType, isNull);
     }
   }
@@ -1912,7 +1912,7 @@
     expect(parameterElement.field, same(fElement));
 
     var parameterNode = parameters[0] as FieldFormalParameter;
-    _assertTypeNameSimple(parameterNode.type!, typeProvider.intType);
+    _assertNamedTypeSimple(parameterNode.type!, typeProvider.intType);
     expect(parameterNode.declaredElement, same(parameterElement));
 
     expect(parameterNode.identifier.staticElement, same(parameterElement));
@@ -1980,7 +1980,7 @@
 
     List<TypeAnnotation> typeArguments = invocation.typeArguments!.arguments;
     expect(typeArguments, hasLength(1));
-    _assertTypeNameSimple(typeArguments[0], typeProvider.stringType);
+    _assertNamedTypeSimple(typeArguments[0], typeProvider.stringType);
   }
 
   test_functionExpressionInvocation_namedArgument() async {
@@ -2307,7 +2307,7 @@
 
       NamedType namedType = constructorName.type2;
       expect(namedType.typeArguments!.arguments, hasLength(1));
-      _assertTypeNameSimple(
+      _assertNamedTypeSimple(
           namedType.typeArguments!.arguments[0], typeProvider.boolType);
 
       var typeIdentifier = namedType.name as PrefixedIdentifier;
@@ -2384,7 +2384,7 @@
 
       NamedType namedType = constructorName.type2;
       expect(namedType.typeArguments!.arguments, hasLength(1));
-      _assertTypeNameSimple(
+      _assertNamedTypeSimple(
           namedType.typeArguments!.arguments[0], typeProvider.boolType);
 
       var typeIdentifier = namedType.name as SimpleIdentifier;
@@ -2432,7 +2432,7 @@
 
       NamedType namedType = constructorName.type2;
       expect(namedType.typeArguments!.arguments, hasLength(1));
-      _assertTypeNameSimple(
+      _assertNamedTypeSimple(
           namedType.typeArguments!.arguments[0], typeProvider.boolType);
 
       var typeIdentifier = namedType.name as SimpleIdentifier;
@@ -4906,10 +4906,10 @@
     LocalVariableElement vElement = vNode.declaredElement!;
     expect(vElement.type, typeProvider.numType);
 
-    var vTypeName = vNode.type as NamedType;
-    expect(vTypeName.type, typeProvider.numType);
+    var vNamedType = vNode.type as NamedType;
+    expect(vNamedType.type, typeProvider.numType);
 
-    var vTypeIdentifier = vTypeName.name as SimpleIdentifier;
+    var vTypeIdentifier = vNamedType.name as SimpleIdentifier;
     expect(vTypeIdentifier.staticElement, typeProvider.numType.element);
     expect(vTypeIdentifier.staticType, isNull);
 
@@ -7439,7 +7439,7 @@
       expect(bElement.type, typeProvider.doubleType);
 
       var namedType = bDeclaration.variables.type as NamedType;
-      _assertTypeNameSimple(namedType, typeProvider.doubleType);
+      _assertNamedTypeSimple(namedType, typeProvider.doubleType);
 
       expect(bNode.name.staticElement, same(bElement));
       expect(bNode.name.staticType, isNull);
@@ -7579,7 +7579,7 @@
     expect(aliasElement, same(findElement.typeAlias('F')));
     expect(function.returnType, typeProvider.intType);
 
-    _assertTypeNameSimple(alias.returnType as NamedType, typeProvider.intType);
+    _assertNamedTypeSimple(alias.returnType as NamedType, typeProvider.intType);
 
     _assertSimpleParameter(
         alias.parameters.parameters[0] as SimpleFormalParameter,
@@ -7645,10 +7645,10 @@
       expect(listIdentifier.staticElement, same(listElement));
       expect(listIdentifier.staticType, isNull);
 
-      var aTypeName = bound.typeArguments!.arguments[0] as NamedType;
-      expect(aTypeName.type, interfaceTypeNone(aElement));
+      var aNamedType = bound.typeArguments!.arguments[0] as NamedType;
+      expect(aNamedType.type, interfaceTypeNone(aElement));
 
-      var aIdentifier = aTypeName.name as SimpleIdentifier;
+      var aIdentifier = aNamedType.name as SimpleIdentifier;
       expect(aIdentifier.staticElement, same(aElement));
       expect(aIdentifier.staticType, isNull);
     }
@@ -7717,7 +7717,7 @@
     {
       var statement = statements[1] as TryStatement;
       CatchClause catchClause = statement.catchClauses[0];
-      _assertTypeNameSimple(
+      _assertNamedTypeSimple(
           catchClause.exceptionType as NamedType, typeProvider.intType);
 
       var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
@@ -7760,7 +7760,7 @@
     {
       var statement = statements[3] as TryStatement;
       CatchClause catchClause = statement.catchClauses[0];
-      _assertTypeNameSimple(catchClause.exceptionType!, typeProvider.intType);
+      _assertNamedTypeSimple(catchClause.exceptionType!, typeProvider.intType);
       expect(catchClause.stackTraceParameter, isNull);
 
       var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
@@ -7773,7 +7773,7 @@
     {
       var statement = statements[4] as TryStatement;
       CatchClause catchClause = statement.catchClauses[0];
-      _assertTypeNameSimple(
+      _assertNamedTypeSimple(
           catchClause.exceptionType as NamedType, typeProvider.intType);
       expect(catchClause.exceptionParameter, isNull);
       expect(catchClause.stackTraceParameter, isNull);
@@ -7821,7 +7821,7 @@
 
     List<TypeAnnotation> typeArguments = namedType.typeArguments!.arguments;
     expect(typeArguments, hasLength(1));
-    _assertTypeNameSimple(typeArguments[0], typeProvider.intType);
+    _assertNamedTypeSimple(typeArguments[0], typeProvider.intType);
   }
 
   test_type_void() async {
@@ -8657,6 +8657,15 @@
     }
   }
 
+  void _assertNamedTypeSimple(TypeAnnotation namedType, DartType type) {
+    namedType as NamedType;
+    expect(namedType.type, type);
+
+    var identifier = namedType.name as SimpleIdentifier;
+    expect(identifier.staticElement, same(type.element));
+    expect(identifier.staticType, isNull);
+  }
+
   void _assertParameterElement(ParameterElement element,
       {String? name, int? offset, ParameterKind? kind, DartType? type}) {
     expect(element, isNotNull);
@@ -8688,15 +8697,6 @@
     }
   }
 
-  void _assertTypeNameSimple(TypeAnnotation namedType, DartType type) {
-    namedType as NamedType;
-    expect(namedType.type, type);
-
-    var identifier = namedType.name as SimpleIdentifier;
-    expect(identifier.staticElement, same(type.element));
-    expect(identifier.staticType, isNull);
-  }
-
   List<Statement> _getMainStatements(ResolvedUnitResult result) {
     for (var declaration in result.unit.declarations) {
       if (declaration is FunctionDeclaration &&
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index de37c97..252bab2 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1246,8 +1246,7 @@
     Source generatedSource = _SourceMock(generatedPath, uri);
 
     generatedUriResolver.resolveAbsoluteFunction = (uri) => generatedSource;
-    generatedUriResolver.restoreAbsoluteFunction = (Source source) {
-      String path = source.fullName;
+    generatedUriResolver.pathToUriFunction = (path) {
       if (path == templatePath || path == generatedPath) {
         return uri;
       } else {
@@ -1952,16 +1951,13 @@
       expect(result.errors, isEmpty);
     }
 
-    // Analysis of my_pkg/bin/b.dart produces the error "A value of type
-    // 'String' can't be assigned to a variable of type 'int'", because
-    // file:///my_pkg/bin/b.dart imports file:///my_pkg/lib/c.dart, which
-    // successfully imports file:///my_pkg/test/d.dart, causing y to have an
-    // inferred type of String.
+    // Analysis of my_pkg/bin/a.dart produces no error because
+    // the import `../lib/c.dart` is resolved to package:my_pkg/c.dart, and
+    // package:my_pkg/c.dart's import is erroneous, causing y's reference to z
+    // to be unresolved (and therefore have type dynamic).
     {
       ResolvedUnitResult result = await driver.getResultValid(b);
-      List<AnalysisError> errors = result.errors;
-      expect(errors, hasLength(1));
-      expect(errors[0].errorCode, CompileTimeErrorCode.INVALID_ASSIGNMENT);
+      expect(result.errors, isEmpty);
     }
   }
 
@@ -2028,8 +2024,10 @@
 
     {
       ResolvedUnitResult result = await driver.getResultValid(b);
-      expect(_getImportSource(result.unit, 0).uri.toString(),
-          'package:test/a.dart');
+      expect(
+        _getImportSource(result.unit, 0).uri,
+        Uri.parse('package:test/a.dart'),
+      );
       _assertTopLevelVarType(result.unit, 'VB', 'A<int>');
     }
 
@@ -2037,7 +2035,7 @@
       ResolvedUnitResult result = await driver.getResultValid(c);
       expect(
         _getImportSource(result.unit, 0).uri,
-        toUri('/test/lib/a.dart'),
+        Uri.parse('package:test/a.dart'),
       );
       _assertTopLevelVarType(result.unit, 'VC', 'A<double>');
     }
@@ -2924,6 +2922,24 @@
     expect(result.unit, isNotNull);
   }
 
+  test_removeFile_addFile_results() async {
+    var a = convertPath('/test/lib/a.dart');
+    newFile(a, content: 'class A {}');
+
+    driver.addFile(a);
+
+    await waitForIdleWithoutExceptions();
+    expect(allResults.map((e) => e.path).toSet(), {a});
+    allResults.clear();
+
+    driver.removeFile(a);
+    driver.addFile(a);
+
+    // a.dart should be produced again
+    await waitForIdleWithoutExceptions();
+    expect(allResults.map((e) => e.path).toSet(), {a});
+  }
+
   test_removeFile_changeFile_implicitlyAnalyzed() async {
     var a = convertPath('/test/lib/a.dart');
     var b = convertPath('/test/lib/b.dart');
diff --git a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
index dfcbe51..0f485b1 100644
--- a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
@@ -446,9 +446,7 @@
 
   FeatureSet _getPathFeatureSet(String path) {
     path = convertPath(path);
-    var fileUri = toUri(path);
-    var fileSource = sourceFactory.forUri2(fileUri)!;
-    var uri = sourceFactory.restoreUri(fileSource)!;
+    var uri = sourceFactory.pathToUri(path)!;
     return provider.getFeatureSet(path, uri);
   }
 
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index b298989..f0a3e1f 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -30,13 +30,71 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../resolution/context_collection_resolution.dart';
+
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(FileSystemStateTest);
+    defineReflectiveTests(FileSystemState_BazelWorkspaceTest);
   });
 }
 
 @reflectiveTest
+class FileSystemState_BazelWorkspaceTest extends BazelWorkspaceResolutionTest {
+  void test_getFileForUri_hasGenerated_askGeneratedFirst() async {
+    var relPath = 'dart/my/test/a.dart';
+    var writablePath = convertPath('$workspaceRootPath/$relPath');
+    var generatedPath = convertPath('$workspaceRootPath/bazel-bin/$relPath');
+
+    // This generated file should be used instead of the writable.
+    newFile(generatedPath);
+
+    var analysisDriver = driverFor(convertPath(testFilePath));
+
+    var fsState = analysisDriver.fsState;
+
+    // The file is the generated file.
+    var generatedUri = toUri(generatedPath);
+    var generatedFile = fsState.getFileForUri(generatedUri).t1!;
+    expect(generatedFile.uri, generatedUri);
+    expect(generatedFile.path, generatedPath);
+
+    // The file is cached under the requested URI.
+    var writableUri = toUri(writablePath);
+    var writableFile1 = fsState.getFileForUri(writableUri).t1!;
+    var writableFile2 = fsState.getFileForUri(writableUri).t1!;
+    expect(writableFile1, same(generatedFile));
+    expect(writableFile2, same(generatedFile));
+  }
+
+  void test_getFileForUri_hasGenerated_askWritableFirst() async {
+    var relPath = 'dart/my/test/a.dart';
+    var writablePath = convertPath('$workspaceRootPath/$relPath');
+    var generatedPath = convertPath('$workspaceRootPath/bazel-bin/$relPath');
+
+    // This generated file should be used instead of the writable.
+    newFile(generatedPath);
+
+    var analysisDriver = driverFor(convertPath(testFilePath));
+
+    var fsState = analysisDriver.fsState;
+
+    // The file is cached under the requested URI.
+    var writableUri = toUri(writablePath);
+    var writableFile1 = fsState.getFileForUri(writableUri).t1!;
+    var writableFile2 = fsState.getFileForUri(writableUri).t1!;
+    expect(writableFile2, same(writableFile1));
+
+    // The file is the generated file.
+    var generatedUri = toUri(generatedPath);
+    var generatedFile = fsState.getFileForUri(generatedUri).t1!;
+    expect(generatedFile.uri, generatedUri);
+    expect(generatedFile.path, generatedPath);
+    expect(writableFile2, same(generatedFile));
+  }
+}
+
+@reflectiveTest
 class FileSystemStateTest with ResourceProviderMixin {
   final ByteStore byteStore = MemoryByteStore();
   final FileContentOverlay contentOverlay = FileContentOverlay();
@@ -268,8 +326,6 @@
     expect(file.libraryFiles, [file, file.partedFiles[0]]);
 
     expect(_excludeSdk(file.directReferencedFiles), hasLength(5));
-
-    expect(fileSystemState.getFilesForPath(a1), [file]);
   }
 
   test_getFileForPath_onlyDartFiles() {
@@ -363,27 +419,6 @@
     );
   }
 
-  test_getFileForUri_packageVsFileUri() {
-    String path = convertPath('/aaa/lib/a.dart');
-    var packageUri = Uri.parse('package:aaa/a.dart');
-    var fileUri = toUri(path);
-
-    // The files with `package:` and `file:` URIs are different.
-    var filePackageUri = fileSystemState.getFileForUri(packageUri).asFileState;
-    var fileFileUri = fileSystemState.getFileForUri(fileUri).asFileState;
-    expect(filePackageUri, isNot(same(fileFileUri)));
-
-    expect(filePackageUri.path, path);
-    expect(filePackageUri.uri, packageUri);
-
-    expect(fileFileUri.path, path);
-    expect(fileFileUri.uri, fileUri);
-
-    // The file with the `package:` style URI is canonical, and is the first.
-    var files = fileSystemState.getFilesForPath(path);
-    expect(files, [filePackageUri, fileFileUri]);
-  }
-
   test_getFilesSubtypingName() {
     String a = convertPath('/a.dart');
     String b = convertPath('/b.dart');
@@ -742,10 +777,10 @@
   }
 }
 
-class _GeneratedUriResolverMock implements UriResolver {
+class _GeneratedUriResolverMock extends UriResolver {
   Source? Function(Uri)? resolveAbsoluteFunction;
 
-  Uri? Function(Source)? restoreAbsoluteFunction;
+  Uri? Function(String)? pathToUriFunction;
 
   @override
   noSuchMethod(Invocation invocation) {
@@ -753,17 +788,14 @@
   }
 
   @override
-  Source? resolveAbsolute(Uri uri) {
-    if (resolveAbsoluteFunction != null) {
-      return resolveAbsoluteFunction!(uri);
-    }
-    return null;
+  Uri? pathToUri(String path) {
+    return pathToUriFunction?.call(path);
   }
 
   @override
-  Uri? restoreAbsolute(Source source) {
-    if (restoreAbsoluteFunction != null) {
-      return restoreAbsoluteFunction!(source);
+  Source? resolveAbsolute(Uri uri) {
+    if (resolveAbsoluteFunction != null) {
+      return resolveAbsoluteFunction!(uri);
     }
     return null;
   }
@@ -784,11 +816,13 @@
   }
 }
 
-extension on Either2<FileState?, ExternalLibrary> {
-  FileState get asFileState {
-    return map(
-      (file) => file!,
-      (_) => fail('Expected a file'),
+extension _Either2Extension<T1, T2> on Either2<T1, T2> {
+  T1 get t1 {
+    late T1 result;
+    map(
+      (t1) => result = t1,
+      (_) => throw 'Expected T1',
     );
+    return result;
   }
 }
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index cecd83d..29798f2 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -1155,6 +1155,18 @@
     assertThat(element)..isReferencedAt('test: 0', true);
   }
 
+  test_isReferencedBy_ParameterElement_optionalNamed_ofTopFunction_anywhere() async {
+    await _indexTestUnit('''
+void foo(int a, int b, {int? test}) {}
+
+void() {
+  foo(1, test: 0, 2);
+}
+''');
+    Element element = findElement.parameter('test');
+    assertThat(element)..isReferencedAt('test: 0', true);
+  }
+
   test_isReferencedBy_ParameterElement_optionalPositional() async {
     await _indexTestUnit('''
 foo([p]) {
diff --git a/pkg/analyzer/test/src/dart/analysis/resolve_for_completion_test.dart b/pkg/analyzer/test/src/dart/analysis/resolve_for_completion_test.dart
new file mode 100644
index 0000000..e241371
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/resolve_for_completion_test.dart
@@ -0,0 +1,546 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/results.dart';
+import 'package:analyzer/src/util/performance/operation_performance.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ResolveForCompletionTest);
+  });
+}
+
+@reflectiveTest
+class ResolveForCompletionTest extends PubPackageResolutionTest {
+  AnalysisDriver get testDriver {
+    return driverFor(testFilePathPlatform);
+  }
+
+  String get testFilePathPlatform => convertPath(testFilePath);
+
+  test_class__fieldDeclaration_type_namedType_name() async {
+    var result = _resolveTestCode(r'''
+class A {
+  var f1 = 0;
+  doub^ f2 = null;
+  var f3 = 1;
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_class__fieldDeclaration_type_namedType_typeArgument_name() async {
+    var result = _resolveTestCode(r'''
+class A {
+  var f1 = 0;
+  List<doub^>? f2 = null;
+  var f3 = 1;
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_class_extends_name() async {
+    var result = _resolveTestCode(r'''
+class A extends foo^ {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_class_fieldDeclaration_initializer() async {
+    var result = _resolveTestCode(r'''
+class A {
+  var f1 = 0;
+  var f2 = foo^;
+  var f3 = 1;
+}
+''');
+
+    result.assertResolvedNodes([
+      'var f2 = foo;',
+    ]);
+  }
+
+  test_class_implements_name() async {
+    var result = _resolveTestCode(r'''
+class A implements foo^ {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_class_methodDeclaration_body() async {
+    var result = _resolveTestCode(r'''
+class A {}
+
+class B {
+  void foo1() {}
+
+  void foo2() {
+    print(0);
+    bar^;
+    print(1);
+  }
+
+  void foo3() {}
+}
+''');
+
+    result.assertResolvedNodes([
+      'void foo2() {print(0); bar; print(1);}',
+    ]);
+  }
+
+  test_class_methodDeclaration_name() async {
+    var result = _resolveTestCode(r'''
+class A {
+  void foo^() {
+    print(0);
+  }
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_class_methodDeclaration_returnType_name() async {
+    var result = _resolveTestCode(r'''
+class A {
+  doub^ foo() {}
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_class_with_name() async {
+    var result = _resolveTestCode(r'''
+class A with foo^ {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_constructorDeclaration_body() async {
+    var result = _resolveTestCode(r'''
+class A {}
+
+class B {
+  void foo1() {}
+
+  B() {
+    print(0);
+    bar^;
+    print(1);
+  }
+
+  void foo2() {}
+}
+''');
+
+    result.assertResolvedNodes([
+      'B() {print(0); bar; print(1);}',
+    ]);
+  }
+
+  test_constructorDeclaration_fieldInitializer_name() async {
+    var result = _resolveTestCode(r'''
+class A {}
+
+class B {
+  var f;
+
+  void foo1() {}
+
+  B(int a) : bar^ = 0 {
+    print(0);
+  }
+
+  void foo2() {}
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_constructorDeclaration_fieldInitializer_value() async {
+    var result = _resolveTestCode(r'''
+class A {
+  var f;
+
+  A(int a) : f = a + bar^ {
+    print(0);
+  }
+}
+''');
+
+    // TODO(scheglov) Resolve only the initializer.
+    result.assertResolvedNodes([
+      'A(int a) : f = a + bar {print(0);}',
+    ]);
+  }
+
+  test_constructorDeclaration_name() async {
+    var result = _resolveTestCode(r'''
+class A {
+  A.foo^() {
+    print(0);
+  }
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_doubleLiteral() async {
+    var result = _resolveTestCode(r'''
+var v = 1.2^;
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_extension_methodDeclaration_body() async {
+    var result = _resolveTestCode(r'''
+extension E on int {
+  void foo1() {}
+
+  void foo2() {
+    print(0);
+    bar^;
+    print(1);
+  }
+
+  void foo3() {}
+}
+''');
+
+    result.assertResolvedNodes([
+      'void foo2() {print(0); bar; print(1);}',
+    ]);
+  }
+
+  test_extension_methodDeclaration_name() async {
+    var result = _resolveTestCode(r'''
+extension E on int {
+  void foo^() {
+    print(0);
+  }
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_extension_methodDeclaration_returnType_name() async {
+    var result = _resolveTestCode(r'''
+extension E on int {
+  doub^ foo() {}
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_extension_on_name() async {
+    var result = _resolveTestCode(r'''
+extension E on int^ {
+  void foo() {}
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_functionDeclaration_body() async {
+    var result = _resolveTestCode(r'''
+void foo1() {}
+
+void foo2() {
+  print(0);
+  bar^;
+  print(1);
+}
+
+void foo3() {}
+''');
+
+    result.assertResolvedNodes([
+      'void foo2() {print(0); bar; print(1);}',
+    ]);
+  }
+
+  test_functionDeclaration_name() async {
+    var result = _resolveTestCode(r'''
+void foo^() {
+  print(0);
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_functionDeclaration_returnType_name() async {
+    var result = _resolveTestCode(r'''
+doub^ f() {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_importDirective_show_name() async {
+    var result = _resolveTestCode(r'''
+import 'dart:async';
+import 'dart:math' show ^;
+import 'dart:io';
+''');
+
+    result.assertResolvedNodes([
+      "import 'dart:math' show ;",
+    ]);
+  }
+
+  test_importDirective_uri() async {
+    var result = _resolveTestCode(r'''
+import 'dart:async';
+import 'dart:ma^'
+import 'dart:io';
+''');
+
+    result.assertResolvedNodes([
+      "import 'dart:ma';",
+    ]);
+  }
+
+  test_integerLiteral() async {
+    var result = _resolveTestCode(r'''
+var v = 0^;
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_localVariableDeclaration_name() async {
+    var result = _resolveTestCode(r'''
+void f() {
+  var foo^
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_localVariableDeclaration_type_name() async {
+    var result = _resolveTestCode(r'''
+void f() {
+  doub^ a;
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_mixin_implements_name() async {
+    var result = _resolveTestCode(r'''
+mixin M implements foo^ {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_mixin_methodDeclaration_body() async {
+    var result = _resolveTestCode(r'''
+class A {}
+
+mixin M {
+  void foo1() {}
+
+  void foo2() {
+    print(0);
+    bar^;
+    print(1);
+  }
+
+  void foo3() {}
+}
+''');
+
+    result.assertResolvedNodes([
+      'void foo2() {print(0); bar; print(1);}',
+    ]);
+  }
+
+  test_mixin_methodDeclaration_name() async {
+    var result = _resolveTestCode(r'''
+mixin M {
+  void foo^() {
+    print(0);
+  }
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_mixin_methodDeclaration_returnType_name() async {
+    var result = _resolveTestCode(r'''
+mixin M {
+  doub^ foo() {}
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_mixin_on_name() async {
+    var result = _resolveTestCode(r'''
+mixin M on foo^ {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_processPendingChanges() async {
+    newFile(testFilePath, content: 'class A {}');
+
+    // Read the file.
+    testDriver.getFileSync(testFilePathPlatform);
+
+    // Should call `changeFile()`, and the driver must re-read the file.
+    var result = _resolveTestCode(r'''
+var v1 = 0;
+var v2 = v1.^;
+''');
+
+    result.assertResolvedNodes([
+      'var v2 = v1.;',
+    ]);
+  }
+
+  test_simpleFormalParameter_name() async {
+    var result = _resolveTestCode(r'''
+void f(doub^) {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_simpleFormalParameter_type_name() async {
+    var result = _resolveTestCode(r'''
+void f(doub^ a) {}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_topLevelVariable_initializer() async {
+    var result = _resolveTestCode(r'''
+var v1 = 0;
+var v2 = foo^;
+var v3 = 1;
+''');
+
+    result.assertResolvedNodes([
+      'var v2 = foo;',
+    ]);
+  }
+
+  test_topLevelVariable_name() async {
+    var result = _resolveTestCode(r'''
+var v1 = 0;
+var v2^
+var v3 = 0;
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_topLevelVariable_type_namedType_name() async {
+    var result = _resolveTestCode(r'''
+var v1 = 0;
+doub^ v2 = null;
+var v3 = 1;
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_topLevelVariable_type_namedType_typeArgument_name() async {
+    var result = _resolveTestCode(r'''
+var v1 = 0;
+List<doub^>? v2 = null;
+var v3 = 1;
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  test_typedef_name_nothing() async {
+    var result = _resolveTestCode(r'''
+typedef F^
+''');
+
+    _assertWholeUnitResolved(result);
+  }
+
+  test_typeParameter_name() async {
+    var result = _resolveTestCode(r'''
+void f<T^>() {
+  print(0);
+}
+''');
+
+    result.assertResolvedNodes([]);
+  }
+
+  int _newFileWithOffset(String path, String content) {
+    var offset = content.indexOf('^');
+    expect(offset, isNot(equals(-1)), reason: 'missing ^');
+
+    var nextOffset = content.indexOf('^', offset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+
+    var before = content.substring(0, offset);
+    var after = content.substring(offset + 1);
+    newFile(path, content: before + after);
+
+    return offset;
+  }
+
+  ResolvedForCompletionResultImpl _resolveTestCode(String content) {
+    var path = testFilePathPlatform;
+    var offset = _newFileWithOffset(path, content);
+    testDriver.changeFile(path);
+
+    var performance = OperationPerformanceImpl('<root>');
+    var result = testDriver.resolveForCompletion(
+      path: path,
+      offset: offset,
+      performance: performance,
+    );
+    return result!;
+  }
+
+  static void _assertWholeUnitResolved(
+    ResolvedForCompletionResultImpl result,
+  ) {
+    expect(result.resolvedNodes, [result.parsedUnit]);
+  }
+}
+
+extension ResolvedForCompletionResultImplExtension
+    on ResolvedForCompletionResultImpl {
+  void assertResolvedNodes(List<String> expected) {
+    var actual = resolvedNodes.map((e) => '$e').toList();
+    expect(actual, expected);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 700ec3d..612ac02 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -114,6 +114,259 @@
         unorderedEquals([a.methods[0], b.fields[0]]));
   }
 
+  test_declarations_class() async {
+    await resolveTestCode('''
+class C {
+  int f;
+  C();
+  C.named();
+  int get g => 0;
+  void set s(_) {}
+  void m() {}
+}
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+    declarations.assertHas('C', DeclarationKind.CLASS,
+        offset: 6, codeOffset: 0, codeLength: 91);
+    declarations.assertHas('f', DeclarationKind.FIELD,
+        offset: 16, codeOffset: 12, codeLength: 5, className: 'C');
+    declarations.assertHas('named', DeclarationKind.CONSTRUCTOR,
+        offset: 30, codeOffset: 28, codeLength: 10, className: 'C');
+    declarations.assertHas('g', DeclarationKind.GETTER,
+        offset: 49, codeOffset: 41, codeLength: 15, className: 'C');
+    declarations.assertHas('s', DeclarationKind.SETTER,
+        offset: 68, codeOffset: 59, codeLength: 16, className: 'C');
+    declarations.assertHas('m', DeclarationKind.METHOD,
+        offset: 83, codeOffset: 78, codeLength: 11, className: 'C');
+  }
+
+  test_declarations_discover() async {
+    var aaaPackageRootPath = '$packagesRootPath/aaa';
+    var bbbPackageRootPath = '$packagesRootPath/bbb';
+    var cccPackageRootPath = '$packagesRootPath/ccc';
+    var aaaFilePath = convertPath('$aaaPackageRootPath/lib/a.dart');
+    var bbbFilePath = convertPath('$bbbPackageRootPath/lib/b.dart');
+    var cccFilePath = convertPath('$cccPackageRootPath/lib/c.dart');
+
+    writeTestPackageConfig(
+      PackageConfigFileBuilder()
+        ..add(name: 'aaa', rootPath: aaaPackageRootPath)
+        ..add(name: 'bbb', rootPath: bbbPackageRootPath),
+    );
+
+    newFile(aaaFilePath, content: 'class A {}');
+    newFile(bbbFilePath, content: 'class B {}');
+    newFile(cccFilePath, content: 'class C {}');
+
+    await resolveTestCode('class T {}');
+
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+
+    declarations.assertHas('T', DeclarationKind.CLASS);
+    declarations.assertHas('A', DeclarationKind.CLASS);
+    declarations.assertHas('B', DeclarationKind.CLASS);
+    declarations.assertNo('C');
+  }
+
+  test_declarations_enum() async {
+    await resolveTestCode('''
+enum E {
+  a, bb, ccc
+}
+''');
+
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+
+    declarations.assertHas('E', DeclarationKind.ENUM,
+        offset: 5, codeOffset: 0, codeLength: 23);
+    declarations.assertHas('a', DeclarationKind.ENUM_CONSTANT,
+        offset: 11, codeOffset: 11, codeLength: 1);
+    declarations.assertHas('bb', DeclarationKind.ENUM_CONSTANT,
+        offset: 14, codeOffset: 14, codeLength: 2);
+    declarations.assertHas('ccc', DeclarationKind.ENUM_CONSTANT,
+        offset: 18, codeOffset: 18, codeLength: 3);
+  }
+
+  test_declarations_maxResults() async {
+    await resolveTestCode('''
+class A {}
+class B {}
+class C {}
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, 2);
+    expect(results.declarations, hasLength(2));
+  }
+
+  test_declarations_mixin() async {
+    await resolveTestCode('''
+mixin M {
+  int f;
+  int get g => 0;
+  void set s(_) {}
+  void m() {}
+}
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+    declarations.assertHas('M', DeclarationKind.MIXIN,
+        offset: 6, codeOffset: 0, codeLength: 71);
+    declarations.assertHas('f', DeclarationKind.FIELD,
+        offset: 16, codeOffset: 12, codeLength: 5, mixinName: 'M');
+    declarations.assertHas('g', DeclarationKind.GETTER,
+        offset: 29, codeOffset: 21, codeLength: 15, mixinName: 'M');
+    declarations.assertHas('s', DeclarationKind.SETTER,
+        offset: 48, codeOffset: 39, codeLength: 16, mixinName: 'M');
+    declarations.assertHas('m', DeclarationKind.METHOD,
+        offset: 63, codeOffset: 58, codeLength: 11, mixinName: 'M');
+  }
+
+  test_declarations_onlyForFile() async {
+    newFile('$testPackageLibPath/a.dart', content: 'class A {}');
+    var b = newFile('$testPackageLibPath/b.dart', content: 'class B {}').path;
+
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null, onlyForFile: b);
+    var declarations = results.declarations;
+
+    expect(results.files, [b]);
+
+    declarations.assertNo('A');
+    declarations.assertHas('B', DeclarationKind.CLASS);
+  }
+
+  test_declarations_parameters() async {
+    await resolveTestCode('''
+class C {
+  int get g => 0;
+  void m(int a, double b) {}
+}
+void f(bool a, String b) {}
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+
+    var declaration = declarations.assertHas('C', DeclarationKind.CLASS);
+    expect(declaration.parameters, isNull);
+
+    declaration =
+        declarations.assertHas('g', DeclarationKind.GETTER, className: 'C');
+    expect(declaration.parameters, isNull);
+
+    declaration =
+        declarations.assertHas('m', DeclarationKind.METHOD, className: 'C');
+    expect(declaration.parameters, '(int a, double b)');
+
+    declaration = declarations.assertHas('f', DeclarationKind.FUNCTION);
+    expect(declaration.parameters, '(bool a, String b)');
+  }
+
+  test_declarations_parameters_functionTyped() async {
+    await resolveTestCode('''
+void f1(bool a(int b, String c)) {}
+void f2(a(b, c)) {}
+void f3(bool Function(int a, String b) c) {}
+void f4(bool Function(int, String) a) {}
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+
+    var declaration = declarations.assertHas('f1', DeclarationKind.FUNCTION);
+    expect(declaration.parameters, '(bool Function(int, String) a)');
+
+    declaration = declarations.assertHas('f2', DeclarationKind.FUNCTION);
+    expect(declaration.parameters, '(dynamic Function(dynamic, dynamic) a)');
+
+    declaration = declarations.assertHas('f3', DeclarationKind.FUNCTION);
+    expect(declaration.parameters, '(bool Function(int, String) c)');
+
+    declaration = declarations.assertHas('f4', DeclarationKind.FUNCTION);
+    expect(declaration.parameters, '(bool Function(int, String) a)');
+  }
+
+  test_declarations_parameters_typeArguments() async {
+    await resolveTestCode('''
+class A<T, T2> {
+  void m1(Map<int, String> a) {}
+  void m2<U>(Map<T, U> a) {}
+  void m3<U1, U2>(Map<Map<T2, U2>, Map<U1, T>> a) {}
+}
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+
+    var declaration =
+        declarations.assertHas('m1', DeclarationKind.METHOD, className: 'A');
+    expect(declaration.parameters, '(Map<int, String> a)');
+
+    declaration =
+        declarations.assertHas('m2', DeclarationKind.METHOD, className: 'A');
+    expect(declaration.parameters, '(Map<T, U> a)');
+
+    declaration =
+        declarations.assertHas('m3', DeclarationKind.METHOD, className: 'A');
+    expect(declaration.parameters, '(Map<Map<T2, U2>, Map<U1, T>> a)');
+  }
+
+  test_declarations_regExp() async {
+    await resolveTestCode('''
+class A {}
+class B {}
+class C {}
+class D {}
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, RegExp(r'[A-C]'), null);
+    var declarations = results.declarations;
+
+    declarations.assertHas('A', DeclarationKind.CLASS);
+    declarations.assertHas('B', DeclarationKind.CLASS);
+    declarations.assertHas('C', DeclarationKind.CLASS);
+    declarations.assertNo('D');
+  }
+
+  test_declarations_top() async {
+    await resolveTestCode('''
+int get g => 0;
+void set s(_) {}
+void f(int p) {}
+int v;
+typedef void tf1();
+typedef tf2<T> = int Function<S>(T tp, S sp);
+''');
+    var results = WorkspaceSymbols();
+    await driver.search.declarations(results, null, null);
+    var declarations = results.declarations;
+
+    declarations.assertHas('g', DeclarationKind.GETTER,
+        offset: 8, codeOffset: 0, codeLength: 15);
+    declarations.assertHas('s', DeclarationKind.SETTER,
+        offset: 25, codeOffset: 16, codeLength: 16);
+    declarations.assertHas(
+      'f',
+      DeclarationKind.FUNCTION,
+      offset: 38,
+      codeOffset: 33,
+      codeLength: 16,
+    );
+    declarations.assertHas('v', DeclarationKind.VARIABLE,
+        offset: 54, codeOffset: 50, codeLength: 5);
+    declarations.assertHas('tf1', DeclarationKind.TYPE_ALIAS,
+        offset: 70, codeOffset: 57, codeLength: 19);
+    declarations.assertHas('tf2', DeclarationKind.TYPE_ALIAS,
+        offset: 85, codeOffset: 77, codeLength: 45);
+  }
+
   test_searchMemberReferences_qualified_resolved() async {
     await resolveTestCode('''
 class C {
@@ -1164,6 +1417,25 @@
     await _verifyReferences(element, expected);
   }
 
+  test_searchReferences_ParameterElement_optionalNamed_anywhere() async {
+    await resolveTestCode('''
+foo(int a, int b, {p}) {
+  p;
+}
+main() {
+  foo(0, p: 1, 2);
+}
+''');
+    var element = findElement.parameter('p');
+    var foo = findElement.function('foo');
+    var main = findElement.function('main');
+    var expected = [
+      _expectId(foo, SearchResultKind.READ, 'p;'),
+      _expectIdQ(main, SearchResultKind.REFERENCE, 'p: 1')
+    ];
+    await _verifyReferences(element, expected);
+  }
+
   test_searchReferences_ParameterElement_optionalPositional() async {
     await resolveTestCode('''
 foo([p]) {
@@ -2126,3 +2398,38 @@
     expect(matches, unorderedEquals(expectedMatches));
   }
 }
+
+extension on List<Declaration> {
+  void assertNo(String name) {
+    for (var declaration in this) {
+      if (declaration.name == name) {
+        fail('Unexpected declaration $name');
+      }
+    }
+  }
+
+  Declaration assertHas(String name, DeclarationKind kind,
+      {int? offset,
+      int? codeOffset,
+      int? codeLength,
+      String? className,
+      String? mixinName}) {
+    for (var declaration in this) {
+      if (declaration.name == name &&
+          declaration.kind == kind &&
+          (offset == null || declaration.offset == offset) &&
+          (codeOffset == null || declaration.codeOffset == codeOffset) &&
+          (codeLength == null || declaration.codeLength == codeLength) &&
+          declaration.className == className &&
+          declaration.mixinName == mixinName) {
+        return declaration;
+      }
+    }
+    var actual =
+        map((d) => '(name=${d.name}, kind=${d.kind}, offset=${d.offset}, '
+            'codeOffset=${d.codeOffset}, codeLength=${d.codeLength}, '
+            'className=${d.className}, mixinName=${d.mixinName})').join('\n');
+    fail('Expected to find (name=$name, kind=$kind, offset=$offset, '
+        'codeOffset=$codeOffset, codeLength=$codeLength) in\n$actual');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/test_all.dart b/pkg/analyzer/test/src/dart/analysis/test_all.dart
index fbbd8d5..2c5030d 100644
--- a/pkg/analyzer/test/src/dart/analysis/test_all.dart
+++ b/pkg/analyzer/test/src/dart/analysis/test_all.dart
@@ -24,6 +24,7 @@
 import 'index_test.dart' as index;
 import 'mutex_test.dart' as mutex;
 import 'referenced_names_test.dart' as referenced_names;
+import 'resolve_for_completion_test.dart' as resolve_for_completion;
 import 'results/test_all.dart' as results;
 import 'search_test.dart' as search;
 import 'session_helper_test.dart' as session_helper;
@@ -53,6 +54,7 @@
     index.main();
     mutex.main();
     referenced_names.main();
+    resolve_for_completion.main();
     results.main();
     search.main();
     session.main();
diff --git a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
index 70b153a..9914458 100644
--- a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
@@ -46,7 +46,7 @@
         AstTestFactory.annotation2(AstTestFactory.identifier3("A"),
             AstTestFactory.identifier3("c"), AstTestFactory.argumentList(),
             typeArguments: AstTestFactory.typeArgumentList2(
-                [AstTestFactory.typeName4('T')])));
+                [AstTestFactory.namedType4('T')])));
   }
 
   void test_visitArgumentList() {
@@ -62,7 +62,7 @@
     _assertSource(
         "e as T",
         AstTestFactory.asExpression(
-            AstTestFactory.identifier3("e"), AstTestFactory.typeName4("T")));
+            AstTestFactory.identifier3("e"), AstTestFactory.namedType4("T")));
   }
 
   void test_visitAssertStatement() {
@@ -193,12 +193,12 @@
 
   void test_visitCatchClause_on() {
     _assertSource(
-        "on E {}", AstTestFactory.catchClause3(AstTestFactory.typeName4("E")));
+        "on E {}", AstTestFactory.catchClause3(AstTestFactory.namedType4("E")));
   }
 
   void test_visitCatchClause_on_catch() {
     _assertSource("on E catch (e) {}",
-        AstTestFactory.catchClause4(AstTestFactory.typeName4("E"), "e"));
+        AstTestFactory.catchClause4(AstTestFactory.namedType4("E"), "e"));
   }
 
   void test_visitClassDeclaration_abstract() {
@@ -220,7 +220,7 @@
             null,
             "C",
             null,
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
             null,
             null));
   }
@@ -232,9 +232,9 @@
             null,
             "C",
             null,
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
             null,
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
   }
 
   void test_visitClassDeclaration_extends_with() {
@@ -244,8 +244,8 @@
             null,
             "C",
             null,
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
             null));
   }
 
@@ -256,16 +256,16 @@
             null,
             "C",
             null,
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
   }
 
   void test_visitClassDeclaration_implements() {
     _assertSource(
         "class C implements B {}",
         AstTestFactory.classDeclaration(null, "C", null, null, null,
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
   }
 
   void test_visitClassDeclaration_multipleMember() {
@@ -293,7 +293,7 @@
             null,
             "C",
             AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
             null,
             null));
   }
@@ -305,9 +305,9 @@
             null,
             "C",
             AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
             null,
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
   }
 
   void test_visitClassDeclaration_parameters_extends_with() {
@@ -317,8 +317,8 @@
             null,
             "C",
             AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
             null));
   }
 
@@ -329,9 +329,9 @@
             null,
             "C",
             AstTestFactory.typeParameterList(["E"]),
-            AstTestFactory.extendsClause(AstTestFactory.typeName4("A")),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M")]),
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
+            AstTestFactory.extendsClause(AstTestFactory.namedType4("A")),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M")]),
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
   }
 
   void test_visitClassDeclaration_parameters_implements() {
@@ -343,7 +343,7 @@
             AstTestFactory.typeParameterList(["E"]),
             null,
             null,
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("B")])));
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("B")])));
   }
 
   void test_visitClassDeclaration_singleMember() {
@@ -370,8 +370,8 @@
             "C",
             null,
             Keyword.ABSTRACT,
-            AstTestFactory.typeName4("S"),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.namedType4("S"),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
             null));
   }
 
@@ -382,9 +382,9 @@
             "C",
             null,
             Keyword.ABSTRACT,
-            AstTestFactory.typeName4("S"),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
+            AstTestFactory.namedType4("S"),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
   }
 
   void test_visitClassTypeAlias_generic() {
@@ -394,9 +394,9 @@
             "C",
             AstTestFactory.typeParameterList(["E"]),
             null,
-            AstTestFactory.typeName4("S", [AstTestFactory.typeName4("E")]),
+            AstTestFactory.namedType4("S", [AstTestFactory.namedType4("E")]),
             AstTestFactory.withClause([
-              AstTestFactory.typeName4("M1", [AstTestFactory.typeName4("E")])
+              AstTestFactory.namedType4("M1", [AstTestFactory.namedType4("E")])
             ]),
             null));
   }
@@ -408,9 +408,9 @@
             "C",
             null,
             null,
-            AstTestFactory.typeName4("S"),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
+            AstTestFactory.namedType4("S"),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
   }
 
   void test_visitClassTypeAlias_minimal() {
@@ -420,8 +420,8 @@
             "C",
             null,
             null,
-            AstTestFactory.typeName4("S"),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.namedType4("S"),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
             null));
   }
 
@@ -432,8 +432,8 @@
             "C",
             AstTestFactory.typeParameterList(["E"]),
             Keyword.ABSTRACT,
-            AstTestFactory.typeName4("S"),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+            AstTestFactory.namedType4("S"),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
             null));
   }
 
@@ -444,9 +444,9 @@
             "C",
             AstTestFactory.typeParameterList(["E"]),
             Keyword.ABSTRACT,
-            AstTestFactory.typeName4("S"),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
+            AstTestFactory.namedType4("S"),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
   }
 
   void test_visitClassTypeAlias_parameters_implements() {
@@ -456,9 +456,9 @@
             "C",
             AstTestFactory.typeParameterList(["E"]),
             null,
-            AstTestFactory.typeName4("S"),
-            AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
-            AstTestFactory.implementsClause([AstTestFactory.typeName4("I")])));
+            AstTestFactory.namedType4("S"),
+            AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
+            AstTestFactory.implementsClause([AstTestFactory.namedType4("I")])));
   }
 
   void test_visitClassTypeAlias_withMetadata() {
@@ -466,8 +466,8 @@
         "C",
         null,
         null,
-        AstTestFactory.typeName4("S"),
-        AstTestFactory.withClause([AstTestFactory.typeName4("M1")]),
+        AstTestFactory.namedType4("S"),
+        AstTestFactory.withClause([AstTestFactory.namedType4("M1")]),
         null);
     declaration.metadata.add(
         AstTestFactory.annotation(AstTestFactory.identifier3("deprecated")));
@@ -684,19 +684,19 @@
     _assertSource(
         "p.C.n",
         AstTestFactory.constructorName(
-            AstTestFactory.typeName4("p.C.n"), null));
+            AstTestFactory.namedType4("p.C.n"), null));
   }
 
   void test_visitConstructorName_unnamed_noPrefix() {
     _assertSource("C",
-        AstTestFactory.constructorName(AstTestFactory.typeName4("C"), null));
+        AstTestFactory.constructorName(AstTestFactory.namedType4("C"), null));
   }
 
   void test_visitConstructorName_unnamed_prefix() {
     _assertSource(
         "p.C",
         AstTestFactory.constructorName(
-            AstTestFactory.typeName3(AstTestFactory.identifier5("p", "C")),
+            AstTestFactory.namedType3(AstTestFactory.identifier5("p", "C")),
             null));
   }
 
@@ -845,7 +845,7 @@
 
   void test_visitExtendsClause() {
     _assertSource("extends C",
-        AstTestFactory.extendsClause(AstTestFactory.typeName4("C")));
+        AstTestFactory.extendsClause(AstTestFactory.namedType4("C")));
   }
 
   void test_visitExtensionDeclaration_empty() {
@@ -853,7 +853,7 @@
         'extension E on C {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             isExtensionTypeDeclaration: false));
   }
 
@@ -862,7 +862,7 @@
         'extension E on C {var a; var b;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
                   [AstTestFactory.variableDeclaration('a')]),
@@ -878,7 +878,7 @@
         AstTestFactory.extensionDeclaration(
             name: 'E',
             typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             isExtensionTypeDeclaration: false));
   }
 
@@ -887,7 +887,7 @@
         'extension E on C {var a;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(
                   false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
@@ -900,9 +900,9 @@
         'extension type E on C hide B {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             hideClause:
-                AstTestFactory.hideClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -911,7 +911,7 @@
         'extension type E on C hide B {var a; var b;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
                   [AstTestFactory.variableDeclaration('a')]),
@@ -919,7 +919,7 @@
                   false, Keyword.VAR, [AstTestFactory.variableDeclaration('b')])
             ],
             hideClause:
-                AstTestFactory.hideClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -929,9 +929,9 @@
         AstTestFactory.extensionDeclaration(
             name: 'E',
             typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             hideClause:
-                AstTestFactory.hideClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -940,13 +940,13 @@
         'extension type E on C hide B {var a;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(
                   false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
             ],
             hideClause:
-                AstTestFactory.hideClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.hideClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -955,7 +955,7 @@
         'extension type E on C show foo {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause: AstTestFactory.showClause(
                 [AstTestFactory.showHideElement("foo")]),
             isExtensionTypeDeclaration: true));
@@ -966,9 +966,9 @@
         'extension type E on C show B {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause:
-                AstTestFactory.showClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -977,7 +977,7 @@
         'extension type E on C show get foo {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause: AstTestFactory.showClause(
                 [AstTestFactory.showHideElementGetter("foo")]),
             isExtensionTypeDeclaration: true));
@@ -988,7 +988,7 @@
         'extension type E on C show B {var a; var b;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
                   [AstTestFactory.variableDeclaration('a')]),
@@ -996,7 +996,7 @@
                   false, Keyword.VAR, [AstTestFactory.variableDeclaration('b')])
             ],
             showClause:
-                AstTestFactory.showClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -1005,7 +1005,7 @@
         'extension type E on C show operator * {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause: AstTestFactory.showClause(
                 [AstTestFactory.showHideElementOperator("*")]),
             isExtensionTypeDeclaration: true));
@@ -1017,9 +1017,9 @@
         AstTestFactory.extensionDeclaration(
             name: 'E',
             typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause:
-                AstTestFactory.showClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -1028,9 +1028,9 @@
         'extension type E on C show prefix.B {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause: AstTestFactory.showClause([
-              AstTestFactory.typeName3(
+              AstTestFactory.namedType3(
                   AstTestFactory.identifier5('prefix', 'B'))
             ]),
             isExtensionTypeDeclaration: true));
@@ -1041,7 +1041,7 @@
         'extension type E on C show set foo {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause: AstTestFactory.showClause(
                 [AstTestFactory.showHideElementSetter("foo")]),
             isExtensionTypeDeclaration: true));
@@ -1052,13 +1052,13 @@
         'extension type E on C show B {var a;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(
                   false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
             ],
             showClause:
-                AstTestFactory.showClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
             isExtensionTypeDeclaration: true));
   }
 
@@ -1067,11 +1067,11 @@
         'extension type E on C show B<int, String> {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause: AstTestFactory.showClause([
-              AstTestFactory.typeName3(AstTestFactory.identifier3('B'), [
-                AstTestFactory.typeName4('int'),
-                AstTestFactory.typeName4('String')
+              AstTestFactory.namedType3(AstTestFactory.identifier3('B'), [
+                AstTestFactory.namedType4('int'),
+                AstTestFactory.namedType4('String')
               ])
             ]),
             isExtensionTypeDeclaration: true));
@@ -1082,9 +1082,9 @@
         'extension type E on C show B hide foo {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             showClause:
-                AstTestFactory.showClause([AstTestFactory.typeName4("B")]),
+                AstTestFactory.showClause([AstTestFactory.namedType4("B")]),
             hideClause: AstTestFactory.hideClause(
                 [AstTestFactory.showHideElement("foo")]),
             isExtensionTypeDeclaration: true));
@@ -1105,7 +1105,7 @@
         AstTestFactory.extensionOverride(
             extensionName: AstTestFactory.identifier5('p', 'E'),
             typeArguments: AstTestFactory.typeArgumentList(
-                [AstTestFactory.typeName4('A')]),
+                [AstTestFactory.namedType4('A')]),
             argumentList: AstTestFactory.argumentList(
                 [AstTestFactory.identifier3('o')])));
   }
@@ -1125,7 +1125,7 @@
         AstTestFactory.extensionOverride(
             extensionName: AstTestFactory.identifier3('E'),
             typeArguments: AstTestFactory.typeArgumentList(
-                [AstTestFactory.typeName4('A')]),
+                [AstTestFactory.namedType4('A')]),
             argumentList: AstTestFactory.argumentList(
                 [AstTestFactory.identifier3('o')])));
   }
@@ -1135,7 +1135,7 @@
         'extension type E on C {}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             isExtensionTypeDeclaration: true));
   }
 
@@ -1144,7 +1144,7 @@
         'extension type E on C {var a; var b;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(false, Keyword.VAR,
                   [AstTestFactory.variableDeclaration('a')]),
@@ -1160,7 +1160,7 @@
         AstTestFactory.extensionDeclaration(
             name: 'E',
             typeParameters: AstTestFactory.typeParameterList(['T']),
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             isExtensionTypeDeclaration: true));
   }
 
@@ -1169,7 +1169,7 @@
         'extension type E on C {var a;}',
         AstTestFactory.extensionDeclaration(
             name: 'E',
-            extendedType: AstTestFactory.typeName4('C'),
+            extendedType: AstTestFactory.namedType4('C'),
             members: [
               AstTestFactory.fieldDeclaration2(
                   false, Keyword.VAR, [AstTestFactory.variableDeclaration('a')])
@@ -1227,7 +1227,7 @@
         "A this.a(b)",
         AstTestFactory.fieldFormalParameter(
             null,
-            AstTestFactory.typeName4("A"),
+            AstTestFactory.namedType4("A"),
             "a",
             AstTestFactory.formalParameterList(
                 [AstTestFactory.simpleFormalParameter3("b")])));
@@ -1237,7 +1237,7 @@
     _assertSource(
         "A this.a<E, F>(b)",
         astFactory.fieldFormalParameter2(
-            type: AstTestFactory.typeName4('A'),
+            type: AstTestFactory.namedType4('A'),
             thisKeyword: TokenFactory.tokenFromKeyword(Keyword.THIS),
             period: TokenFactory.tokenFromType(TokenType.PERIOD),
             identifier: AstTestFactory.identifier3('a'),
@@ -1255,19 +1255,19 @@
     _assertSource(
         "final A this.a",
         AstTestFactory.fieldFormalParameter(
-            Keyword.FINAL, AstTestFactory.typeName4("A"), "a"));
+            Keyword.FINAL, AstTestFactory.namedType4("A"), "a"));
   }
 
   void test_visitFieldFormalParameter_type() {
     _assertSource(
         "A this.a",
         AstTestFactory.fieldFormalParameter(
-            null, AstTestFactory.typeName4("A"), "a"));
+            null, AstTestFactory.namedType4("A"), "a"));
   }
 
   void test_visitFieldFormalParameter_type_covariant() {
     var expected = AstTestFactory.fieldFormalParameter(
-        null, AstTestFactory.typeName4("A"), "a");
+        null, AstTestFactory.namedType4("A"), "a");
     expected.covariantKeyword =
         TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
     _assertSource("covariant A this.a", expected);
@@ -1370,7 +1370,7 @@
               null),
           AstTestFactory.namedFormalParameter(
               AstTestFactory.simpleFormalParameter2(
-                  null, AstTestFactory.typeName4('A'), "b")
+                  null, AstTestFactory.namedType4('A'), "b")
                 ..requiredKeyword =
                     TokenFactory.tokenFromKeyword(Keyword.REQUIRED),
               null),
@@ -1819,14 +1819,14 @@
         "f<A>()",
         AstTestFactory.functionExpressionInvocation2(
             AstTestFactory.identifier3("f"),
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')])));
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('A')])));
   }
 
   void test_visitFunctionTypeAlias_generic() {
     _assertSource(
         "typedef A F<B>();",
         AstTestFactory.typeAlias(
-            AstTestFactory.typeName4("A"),
+            AstTestFactory.namedType4("A"),
             "F",
             AstTestFactory.typeParameterList(["B"]),
             AstTestFactory.formalParameterList()));
@@ -1835,13 +1835,13 @@
   void test_visitFunctionTypeAlias_nonGeneric() {
     _assertSource(
         "typedef A F();",
-        AstTestFactory.typeAlias(AstTestFactory.typeName4("A"), "F", null,
+        AstTestFactory.typeAlias(AstTestFactory.namedType4("A"), "F", null,
             AstTestFactory.formalParameterList()));
   }
 
   void test_visitFunctionTypeAlias_withMetadata() {
     FunctionTypeAlias declaration = AstTestFactory.typeAlias(
-        AstTestFactory.typeName4("A"),
+        AstTestFactory.namedType4("A"),
         "F",
         null,
         AstTestFactory.formalParameterList());
@@ -1867,7 +1867,7 @@
     _assertSource(
         "T f()?",
         astFactory.functionTypedFormalParameter2(
-            returnType: AstTestFactory.typeName4("T"),
+            returnType: AstTestFactory.namedType4("T"),
             identifier: AstTestFactory.identifier3('f'),
             parameters: AstTestFactory.formalParameterList([]),
             question: TokenFactory.tokenFromType(TokenType.QUESTION)));
@@ -1877,12 +1877,12 @@
     _assertSource(
         "T f()",
         AstTestFactory.functionTypedFormalParameter(
-            AstTestFactory.typeName4("T"), "f"));
+            AstTestFactory.namedType4("T"), "f"));
   }
 
   void test_visitFunctionTypedFormalParameter_type_covariant() {
     var expected = AstTestFactory.functionTypedFormalParameter(
-        AstTestFactory.typeName4("T"), "f");
+        AstTestFactory.namedType4("T"), "f");
     expected.covariantKeyword =
         TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
     _assertSource("covariant T f()", expected);
@@ -1892,7 +1892,7 @@
     _assertSource(
         "T f<E>()",
         astFactory.functionTypedFormalParameter2(
-            returnType: AstTestFactory.typeName4("T"),
+            returnType: AstTestFactory.namedType4("T"),
             identifier: AstTestFactory.identifier3('f'),
             typeParameters: AstTestFactory.typeParameterList(['E']),
             parameters: AstTestFactory.formalParameterList([])));
@@ -1902,11 +1902,11 @@
     _assertSource(
         "int Function<T>(T)",
         AstTestFactory.genericFunctionType(
-            AstTestFactory.typeName4("int"),
+            AstTestFactory.namedType4("int"),
             AstTestFactory.typeParameterList2(['T']),
             AstTestFactory.formalParameterList([
               AstTestFactory.simpleFormalParameter4(
-                  AstTestFactory.typeName4("T"), null)
+                  AstTestFactory.namedType4("T"), null)
             ])));
   }
 
@@ -1914,11 +1914,11 @@
     _assertSource(
         "int Function<T>(T)?",
         AstTestFactory.genericFunctionType(
-            AstTestFactory.typeName4("int"),
+            AstTestFactory.namedType4("int"),
             AstTestFactory.typeParameterList2(['T']),
             AstTestFactory.formalParameterList([
               AstTestFactory.simpleFormalParameter4(
-                  AstTestFactory.typeName4("T"), null)
+                  AstTestFactory.namedType4("T"), null)
             ]),
             question: true));
   }
@@ -1930,11 +1930,11 @@
             'X',
             AstTestFactory.typeParameterList2(['S']),
             AstTestFactory.genericFunctionType(
-                AstTestFactory.typeName4("S"),
+                AstTestFactory.namedType4("S"),
                 AstTestFactory.typeParameterList2(['T']),
                 AstTestFactory.formalParameterList([
                   AstTestFactory.simpleFormalParameter4(
-                      AstTestFactory.typeName4("T"), null)
+                      AstTestFactory.namedType4("T"), null)
                 ]))));
   }
 
@@ -1980,12 +1980,12 @@
     _assertSource(
         "implements A, B",
         AstTestFactory.implementsClause(
-            [AstTestFactory.typeName4("A"), AstTestFactory.typeName4("B")]));
+            [AstTestFactory.namedType4("A"), AstTestFactory.namedType4("B")]));
   }
 
   void test_visitImplementsClause_single() {
     _assertSource("implements A",
-        AstTestFactory.implementsClause([AstTestFactory.typeName4("A")]));
+        AstTestFactory.implementsClause([AstTestFactory.namedType4("A")]));
   }
 
   void test_visitImportDirective_combinator() {
@@ -2101,21 +2101,21 @@
     _assertSource(
         "const C()",
         AstTestFactory.instanceCreationExpression2(
-            Keyword.CONST, AstTestFactory.typeName4("C")));
+            Keyword.CONST, AstTestFactory.namedType4("C")));
   }
 
   void test_visitInstanceCreationExpression_named() {
     _assertSource(
         "new C.c()",
         AstTestFactory.instanceCreationExpression3(
-            Keyword.NEW, AstTestFactory.typeName4("C"), "c"));
+            Keyword.NEW, AstTestFactory.namedType4("C"), "c"));
   }
 
   void test_visitInstanceCreationExpression_unnamed() {
     _assertSource(
         "new C()",
         AstTestFactory.instanceCreationExpression2(
-            Keyword.NEW, AstTestFactory.typeName4("C")));
+            Keyword.NEW, AstTestFactory.namedType4("C")));
   }
 
   void test_visitIntegerLiteral() {
@@ -2141,14 +2141,14 @@
     _assertSource(
         "a is! C",
         AstTestFactory.isExpression(AstTestFactory.identifier3("a"), true,
-            AstTestFactory.typeName4("C")));
+            AstTestFactory.namedType4("C")));
   }
 
   void test_visitIsExpression_normal() {
     _assertSource(
         "a is C",
         AstTestFactory.isExpression(AstTestFactory.identifier3("a"), false,
-            AstTestFactory.typeName4("C")));
+            AstTestFactory.namedType4("C")));
   }
 
   void test_visitLabel() {
@@ -2201,7 +2201,7 @@
         '<int>[0, for (e in l) 0, if (b) 1, ...[0]]',
         astFactory.listLiteral(
             null,
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('int')]),
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
             Tokens.openSquareBracket(),
             [
               AstTestFactory.integer(0),
@@ -2267,7 +2267,7 @@
         'const <int>[0]',
         astFactory.listLiteral(
             TokenFactory.tokenFromKeyword(Keyword.CONST),
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('int')]),
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
             Tokens.openSquareBracket(),
             [AstTestFactory.integer(0)],
             Tokens.closeSquareBracket()));
@@ -2285,7 +2285,7 @@
         '<int>[0]',
         astFactory.listLiteral(
             null,
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('int')]),
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
             Tokens.openSquareBracket(),
             [AstTestFactory.integer(0)],
             Tokens.closeSquareBracket()));
@@ -2332,7 +2332,7 @@
         "external T m();",
         AstTestFactory.methodDeclaration(
             null,
-            AstTestFactory.typeName4("T"),
+            AstTestFactory.namedType4("T"),
             null,
             null,
             AstTestFactory.identifier3("m"),
@@ -2357,7 +2357,7 @@
         "T get m {}",
         AstTestFactory.methodDeclaration2(
             null,
-            AstTestFactory.typeName4("T"),
+            AstTestFactory.namedType4("T"),
             Keyword.GET,
             null,
             AstTestFactory.identifier3("m"),
@@ -2370,7 +2370,7 @@
         "T set m(var v) {}",
         AstTestFactory.methodDeclaration2(
             null,
-            AstTestFactory.typeName4("T"),
+            AstTestFactory.namedType4("T"),
             Keyword.SET,
             null,
             AstTestFactory.identifier3("m"),
@@ -2426,7 +2426,7 @@
         "T operator +() {}",
         AstTestFactory.methodDeclaration2(
             null,
-            AstTestFactory.typeName4("T"),
+            AstTestFactory.namedType4("T"),
             null,
             Keyword.OPERATOR,
             AstTestFactory.identifier3("+"),
@@ -2439,7 +2439,7 @@
         "T m() {}",
         AstTestFactory.methodDeclaration2(
             null,
-            AstTestFactory.typeName4("T"),
+            AstTestFactory.namedType4("T"),
             null,
             null,
             AstTestFactory.identifier3("m"),
@@ -2479,7 +2479,7 @@
         "static T m() {}",
         AstTestFactory.methodDeclaration2(
             Keyword.STATIC,
-            AstTestFactory.typeName4("T"),
+            AstTestFactory.namedType4("T"),
             null,
             null,
             AstTestFactory.identifier3("m"),
@@ -2535,7 +2535,7 @@
     _assertSource(
         "m<A>()",
         AstTestFactory.methodInvocation3(null, "m",
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')])));
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('A')])));
   }
 
   void test_visitNamedExpression() {
@@ -2681,8 +2681,8 @@
       astFactory.setOrMapLiteral(
         leftBracket: Tokens.openCurlyBracket(),
         typeArguments: AstTestFactory.typeArgumentList([
-          AstTestFactory.typeName4('String'),
-          AstTestFactory.typeName4('String')
+          AstTestFactory.namedType4('String'),
+          AstTestFactory.namedType4('String')
         ]),
         elements: [
           AstTestFactory.mapLiteralEntry3('a', 'b'),
@@ -2736,8 +2736,8 @@
       astFactory.setOrMapLiteral(
         constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
         typeArguments: AstTestFactory.typeArgumentList([
-          AstTestFactory.typeName4('String'),
-          AstTestFactory.typeName4('String')
+          AstTestFactory.namedType4('String'),
+          AstTestFactory.namedType4('String')
         ]),
         leftBracket: Tokens.openCurlyBracket(),
         elements: [AstTestFactory.mapLiteralEntry3('a', 'b')],
@@ -2762,8 +2762,8 @@
       "<String, String>{'a' : 'b'}",
       astFactory.setOrMapLiteral(
         typeArguments: AstTestFactory.typeArgumentList([
-          AstTestFactory.typeName4('String'),
-          AstTestFactory.typeName4('String')
+          AstTestFactory.namedType4('String'),
+          AstTestFactory.namedType4('String')
         ]),
         leftBracket: Tokens.openCurlyBracket(),
         elements: [AstTestFactory.mapLiteralEntry3('a', 'b')],
@@ -2777,7 +2777,7 @@
       '<int>{0, for (e in l) 0, if (b) 1, ...[0]}',
       astFactory.setOrMapLiteral(
         typeArguments:
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('int')]),
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
         leftBracket: Tokens.openCurlyBracket(),
         elements: [
           AstTestFactory.integer(0),
@@ -2833,7 +2833,7 @@
       astFactory.setOrMapLiteral(
         constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
         typeArguments:
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('int')]),
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
         leftBracket: Tokens.openCurlyBracket(),
         elements: [AstTestFactory.integer(0)],
         rightBracket: Tokens.closeCurlyBracket(),
@@ -2857,7 +2857,7 @@
       '<int>{0}',
       astFactory.setOrMapLiteral(
         typeArguments:
-            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('int')]),
+            AstTestFactory.typeArgumentList([AstTestFactory.namedType4('int')]),
         leftBracket: Tokens.openCurlyBracket(),
         elements: [AstTestFactory.integer(0)],
         rightBracket: Tokens.closeCurlyBracket(),
@@ -2882,19 +2882,19 @@
     _assertSource(
         "final A a",
         AstTestFactory.simpleFormalParameter2(
-            Keyword.FINAL, AstTestFactory.typeName4("A"), "a"));
+            Keyword.FINAL, AstTestFactory.namedType4("A"), "a"));
   }
 
   void test_visitSimpleFormalParameter_type() {
     _assertSource(
         "A a",
         AstTestFactory.simpleFormalParameter4(
-            AstTestFactory.typeName4("A"), "a"));
+            AstTestFactory.namedType4("A"), "a"));
   }
 
   void test_visitSimpleFormalParameter_type_covariant() {
     var expected = AstTestFactory.simpleFormalParameter4(
-        AstTestFactory.typeName4("A"), "a");
+        AstTestFactory.namedType4("A"), "a");
     expected.covariantKeyword =
         TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
     _assertSource("covariant A a", expected);
@@ -2962,6 +2962,64 @@
     _assertSource("super", AstTestFactory.superExpression());
   }
 
+  void test_visitSuperFormalParameter_annotation() {
+    SuperFormalParameter parameter = AstTestFactory.superFormalParameter2('f');
+    parameter.metadata
+        .add(AstTestFactory.annotation(AstTestFactory.identifier3("A")));
+    _assertSource('@A super.f', parameter);
+  }
+
+  void test_visitSuperFormalParameter_functionTyped() {
+    _assertSource(
+        "A super.a(b)",
+        AstTestFactory.superFormalParameter(
+            null,
+            AstTestFactory.namedType4("A"),
+            "a",
+            AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter3("b")])));
+  }
+
+  void test_visitSuperFormalParameter_functionTyped_typeParameters() {
+    _assertSource(
+        "A super.a<E, F>(b)",
+        astFactory.superFormalParameter(
+            type: AstTestFactory.namedType4('A'),
+            superKeyword: TokenFactory.tokenFromKeyword(Keyword.SUPER),
+            period: TokenFactory.tokenFromType(TokenType.PERIOD),
+            identifier: AstTestFactory.identifier3('a'),
+            typeParameters: AstTestFactory.typeParameterList(['E', 'F']),
+            parameters: AstTestFactory.formalParameterList(
+                [AstTestFactory.simpleFormalParameter3("b")])));
+  }
+
+  void test_visitSuperFormalParameter_keyword() {
+    _assertSource("var super.a",
+        AstTestFactory.superFormalParameter(Keyword.VAR, null, "a"));
+  }
+
+  void test_visitSuperFormalParameter_keywordAndType() {
+    _assertSource(
+        "final A super.a",
+        AstTestFactory.superFormalParameter(
+            Keyword.FINAL, AstTestFactory.namedType4("A"), "a"));
+  }
+
+  void test_visitSuperFormalParameter_type() {
+    _assertSource(
+        "A super.a",
+        AstTestFactory.superFormalParameter(
+            null, AstTestFactory.namedType4("A"), "a"));
+  }
+
+  void test_visitSuperFormalParameter_type_covariant() {
+    var expected = AstTestFactory.superFormalParameter(
+        null, AstTestFactory.namedType4("A"), "a");
+    expected.covariantKeyword =
+        TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
+    _assertSource("covariant A super.a", expected);
+  }
+
   void test_visitSwitchCase_multipleLabels() {
     _assertSource(
         "l1: l2: case a: {}",
@@ -3074,15 +3132,15 @@
     _assertSource(
         "try {} on E {}",
         AstTestFactory.tryStatement2(AstTestFactory.block(),
-            [AstTestFactory.catchClause3(AstTestFactory.typeName4("E"))]));
+            [AstTestFactory.catchClause3(AstTestFactory.namedType4("E"))]));
   }
 
   void test_visitTryStatement_catches() {
     _assertSource(
         "try {} on E {} on F {}",
         AstTestFactory.tryStatement2(AstTestFactory.block(), [
-          AstTestFactory.catchClause3(AstTestFactory.typeName4("E")),
-          AstTestFactory.catchClause3(AstTestFactory.typeName4("F"))
+          AstTestFactory.catchClause3(AstTestFactory.namedType4("E")),
+          AstTestFactory.catchClause3(AstTestFactory.namedType4("F"))
         ]));
   }
 
@@ -3091,7 +3149,7 @@
         "try {} on E {} finally {}",
         AstTestFactory.tryStatement3(
             AstTestFactory.block(),
-            [AstTestFactory.catchClause3(AstTestFactory.typeName4("E"))],
+            [AstTestFactory.catchClause3(AstTestFactory.namedType4("E"))],
             AstTestFactory.block()));
   }
 
@@ -3106,45 +3164,45 @@
     _assertSource(
         "<E, F>",
         AstTestFactory.typeArgumentList2(
-            [AstTestFactory.typeName4("E"), AstTestFactory.typeName4("F")]));
+            [AstTestFactory.namedType4("E"), AstTestFactory.namedType4("F")]));
   }
 
   void test_visitTypeArgumentList_single() {
     _assertSource("<E>",
-        AstTestFactory.typeArgumentList2([AstTestFactory.typeName4("E")]));
+        AstTestFactory.typeArgumentList2([AstTestFactory.namedType4("E")]));
   }
 
   void test_visitTypeName_multipleArgs() {
     _assertSource(
         "C<D, E>",
-        AstTestFactory.typeName4("C",
-            [AstTestFactory.typeName4("D"), AstTestFactory.typeName4("E")]));
+        AstTestFactory.namedType4("C",
+            [AstTestFactory.namedType4("D"), AstTestFactory.namedType4("E")]));
   }
 
   void test_visitTypeName_nestedArg() {
     _assertSource(
         "C<D<E>>",
-        AstTestFactory.typeName4("C", [
-          AstTestFactory.typeName4("D", [AstTestFactory.typeName4("E")])
+        AstTestFactory.namedType4("C", [
+          AstTestFactory.namedType4("D", [AstTestFactory.namedType4("E")])
         ]));
   }
 
   void test_visitTypeName_noArgs() {
-    _assertSource("C", AstTestFactory.typeName4("C"));
+    _assertSource("C", AstTestFactory.namedType4("C"));
   }
 
   void test_visitTypeName_noArgs_withQuestion() {
-    _assertSource("C?", AstTestFactory.typeName4("C", null, true));
+    _assertSource("C?", AstTestFactory.namedType4("C", null, true));
   }
 
   void test_visitTypeName_singleArg() {
-    _assertSource(
-        "C<D>", AstTestFactory.typeName4("C", [AstTestFactory.typeName4("D")]));
+    _assertSource("C<D>",
+        AstTestFactory.namedType4("C", [AstTestFactory.namedType4("D")]));
   }
 
   void test_visitTypeName_singleArg_withQuestion() {
     _assertSource("C<D>?",
-        AstTestFactory.typeName4("C", [AstTestFactory.typeName4("D")], true));
+        AstTestFactory.namedType4("C", [AstTestFactory.namedType4("D")], true));
   }
 
   void test_visitTypeParameter_variance_contravariant() {
@@ -3161,7 +3219,7 @@
 
   void test_visitTypeParameter_withExtends() {
     _assertSource("E extends C",
-        AstTestFactory.typeParameter2("E", AstTestFactory.typeName4("C")));
+        AstTestFactory.typeParameter2("E", AstTestFactory.namedType4("C")));
   }
 
   void test_visitTypeParameter_withMetadata() {
@@ -3205,7 +3263,7 @@
     _assertSource(
         "const C a, b",
         AstTestFactory.variableDeclarationList(
-            Keyword.CONST, AstTestFactory.typeName4("C"), [
+            Keyword.CONST, AstTestFactory.namedType4("C"), [
           AstTestFactory.variableDeclaration("a"),
           AstTestFactory.variableDeclaration("b")
         ]));
@@ -3235,7 +3293,7 @@
     _assertSource(
         "C a, b",
         AstTestFactory.variableDeclarationList(
-            null, AstTestFactory.typeName4("C"), [
+            null, AstTestFactory.namedType4("C"), [
           AstTestFactory.variableDeclaration("a"),
           AstTestFactory.variableDeclaration("b")
         ]));
@@ -3255,7 +3313,7 @@
         "C c;",
         AstTestFactory.variableDeclarationStatement(
             null,
-            AstTestFactory.typeName4("C"),
+            AstTestFactory.namedType4("C"),
             [AstTestFactory.variableDeclaration("c")]));
   }
 
@@ -3270,15 +3328,15 @@
     _assertSource(
         "with A, B, C",
         AstTestFactory.withClause([
-          AstTestFactory.typeName4("A"),
-          AstTestFactory.typeName4("B"),
-          AstTestFactory.typeName4("C")
+          AstTestFactory.namedType4("A"),
+          AstTestFactory.namedType4("B"),
+          AstTestFactory.namedType4("C")
         ]));
   }
 
   void test_visitWithClause_single() {
     _assertSource(
-        "with A", AstTestFactory.withClause([AstTestFactory.typeName4("A")]));
+        "with A", AstTestFactory.withClause([AstTestFactory.namedType4("A")]));
   }
 
   void test_visitYieldStatement() {
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 26f0785..09360c4 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -64,6 +64,18 @@
     );
   }
 
+  test_identical_constructorReference_aliasIsNotProperRename_differentCount2() async {
+    await resolveTestCode('''
+class C<T, U> {}
+typedef MyC<T> = C;
+const a = identical(MyC.new, C.new);
+''');
+    expect(
+      _evaluateConstant('a'),
+      _boolValue(false),
+    );
+  }
+
   test_identical_constructorReference_aliasIsNotProperRename_differentOrder() async {
     await resolveTestCode('''
 class C<T, U> {}
@@ -124,7 +136,7 @@
     );
   }
 
-  test_identical_constructorReference_aliasIsProperRename_mutualSubtypes() async {
+  test_identical_constructorReference_aliasIsProperRename_mutualSubtypes_dynamic() async {
     await resolveTestCode('''
 class C<T> {}
 typedef MyC<T extends Object?> = C<T>;
@@ -136,6 +148,18 @@
     );
   }
 
+  test_identical_constructorReference_aliasIsProperRename_mutualSubtypes_futureOr() async {
+    await resolveTestCode('''
+class C<T extends num> {}
+typedef MyC<T extends FutureOr<num>> = C<T>;
+const a = identical(MyC<int>.new, MyC<int>.new);
+''');
+    expect(
+      _evaluateConstant('a'),
+      _boolValue(true),
+    );
+  }
+
   test_identical_constructorReference_aliasIsProperRename_uninstantiated() async {
     await resolveTestCode('''
 class C<T> {}
@@ -1500,11 +1524,7 @@
       'c',
       errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
     );
-    if (analysisOptions.experimentStatus.constant_update_2018) {
-      expect(result.toIntValue(), 1);
-    } else {
-      expect(result, isNull);
-    }
+    expect(result.toIntValue(), 1);
   }
 
   test_visitConditionalExpression_eager_true_invalid_int() async {
diff --git a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
index 853eb50..82433a76 100644
--- a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
@@ -642,7 +642,7 @@
 
     var reporter = ErrorReporter(
       listener,
-      NonExistingSource('/test.dart', toUri('/test.dart'), UriKind.FILE_URI),
+      NonExistingSource('/test.dart', toUri('/test.dart')),
       isNonNullableByDefault: false,
     );
 
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 7a04577..0b35e99 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -2,10 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/dart/micro/library_graph.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/dart/micro/utils.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:test/test.dart';
@@ -390,10 +394,10 @@
 ''');
 
     await resolveFile(bPath);
-    var result = fileResolver.findReferences(6, aPath);
+    var result = fileResolver.findReferences(_findElement(6, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [6]),
-      CiderSearchMatch(bPath, [42])
+      CiderSearchMatch(bPath, [CharacterLocation(4, 11)]),
+      CiderSearchMatch(aPath, [CharacterLocation(1, 7)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -411,9 +415,10 @@
 ''');
 
     await resolveFile(aPath);
-    var result = fileResolver.findReferences(16, aPath);
+    var result = fileResolver.findReferences(_findElement(16, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [16, 53])
+      CiderSearchMatch(
+          aPath, [CharacterLocation(2, 7), CharacterLocation(5, 5)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -429,9 +434,10 @@
 ''');
 
     await resolveFile(aPath);
-    var result = fileResolver.findReferences(11, aPath);
+    var result = fileResolver.findReferences(_findElement(11, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [11, 28])
+      CiderSearchMatch(
+          aPath, [CharacterLocation(2, 3), CharacterLocation(5, 1)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -454,10 +460,10 @@
 ''');
 
     await resolveFile(bPath);
-    var result = fileResolver.findReferences(20, aPath);
+    var result = fileResolver.findReferences(_findElement(20, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [20]),
-      CiderSearchMatch(bPath, [56])
+      CiderSearchMatch(bPath, [CharacterLocation(5, 15)]),
+      CiderSearchMatch(aPath, [CharacterLocation(2, 11)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -473,9 +479,10 @@
 }
 ''');
     await resolveFile(aPath);
-    var result = fileResolver.findReferences(39, aPath);
+    var result = fileResolver.findReferences(_findElement(39, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [39, 62])
+      CiderSearchMatch(
+          aPath, [CharacterLocation(3, 9), CharacterLocation(4, 11)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -505,10 +512,11 @@
 ''');
 
     await resolveFile(bPath);
-    var result = fileResolver.findReferences(17, aPath);
+    var result = fileResolver.findReferences(_findElement(17, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [17, 68]),
-      CiderSearchMatch(bPath, [46])
+      CiderSearchMatch(bPath, [CharacterLocation(5, 5)]),
+      CiderSearchMatch(
+          aPath, [CharacterLocation(2, 8), CharacterLocation(7, 4)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -531,10 +539,10 @@
 ''');
 
     await resolveFile(bPath);
-    var result = fileResolver.findReferences(21, aPath);
+    var result = fileResolver.findReferences(_findElement(21, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [21]),
-      CiderSearchMatch(bPath, [46])
+      CiderSearchMatch(bPath, [CharacterLocation(5, 5)]),
+      CiderSearchMatch(aPath, [CharacterLocation(2, 12)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -558,10 +566,10 @@
 ''');
 
     await resolveFile(bPath);
-    var result = fileResolver.findReferences(19, aPath);
+    var result = fileResolver.findReferences(_findElement(19, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [19]),
-      CiderSearchMatch(bPath, [39])
+      CiderSearchMatch(bPath, [CharacterLocation(4, 13)]),
+      CiderSearchMatch(aPath, [CharacterLocation(3, 9)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -585,10 +593,10 @@
 ''');
 
     await resolveFile(bPath);
-    var result = fileResolver.findReferences(20, aPath);
+    var result = fileResolver.findReferences(_findElement(20, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [20]),
-      CiderSearchMatch(bPath, [29])
+      CiderSearchMatch(bPath, [CharacterLocation(4, 3)]),
+      CiderSearchMatch(aPath, [CharacterLocation(3, 10)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -605,9 +613,10 @@
 ''');
 
     await resolveFile(aPath);
-    var result = fileResolver.findReferences(10, aPath);
+    var result = fileResolver.findReferences(_findElement(10, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [10, 43])
+      CiderSearchMatch(
+          aPath, [CharacterLocation(1, 11), CharacterLocation(4, 11)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -622,14 +631,18 @@
 }
 ''');
     await resolveFile(aPath);
-    var result = fileResolver.findReferences(10, aPath);
+    var result = fileResolver.findReferences(_findElement(10, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [10, 22, 40])
+      CiderSearchMatch(aPath, [
+        CharacterLocation(1, 11),
+        CharacterLocation(2, 8),
+        CharacterLocation(4, 12)
+      ])
     ];
     expect(result.map((e) => e.path),
         unorderedEquals(expected.map((e) => e.path)));
-    expect(result.map((e) => e.offsets),
-        unorderedEquals(expected.map((e) => e.offsets)));
+    expect(result.map((e) => e.startPositions),
+        unorderedEquals(expected.map((e) => e.startPositions)));
   }
 
   test_findReferences_typedef() async {
@@ -646,10 +659,10 @@
 ''');
 
     await resolveFile(bPath);
-    var result = fileResolver.findReferences(8, aPath);
+    var result = fileResolver.findReferences(_findElement(8, aPath));
     var expected = <CiderSearchMatch>[
-      CiderSearchMatch(aPath, [8]),
-      CiderSearchMatch(bPath, [25])
+      CiderSearchMatch(bPath, [CharacterLocation(3, 8)]),
+      CiderSearchMatch(aPath, [CharacterLocation(1, 9)])
     ];
     expect(result, unorderedEquals(expected));
   }
@@ -1266,4 +1279,11 @@
   void _assertRemovedPaths(Matcher matcher) {
     expect(fileResolver.fsState!.testView.removedPaths, matcher);
   }
+
+  Element _findElement(int offset, String filePath) {
+    var resolvedUnit = fileResolver.resolve(path: filePath);
+    var node = NodeLocator(offset).searchWithin(resolvedUnit.unit);
+    var element = getElementOfNode(node);
+    return element!;
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
index 3d386b9..7735e22 100644
--- a/pkg/analyzer/test/src/dart/resolution/comment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -15,359 +15,7 @@
 
 @reflectiveTest
 class CommentDriverResolutionTest extends PubPackageResolutionTest {
-  test_error_unqualifiedReferenceToNonLocalStaticMember() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  static void foo() {}
-}
-
-/// [foo]
-class B extends A {}
-''');
-
-    assertElement(
-      findNode.simple('foo]'),
-      findElement.method('foo', of: 'A'),
-    );
-  }
-
-  test_identifier_beforeClass() async {
-    await assertNoErrorsInCode(r'''
-/// [foo]
-class A {
-  foo() {}
-}
-''');
-
-    assertElement(
-      findNode.simple('foo]'),
-      findElement.method('foo'),
-    );
-  }
-
-  test_identifier_beforeConstructor() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  /// [p]
-  A(int p);
-}''');
-
-    assertElement(
-      findNode.simple('p]'),
-      findElement.parameter('p'),
-    );
-  }
-
-  test_identifier_beforeEnum() async {
-    await assertNoErrorsInCode(r'''
-/// This is the [Samurai] kind.
-enum Samurai {
-  /// Use [int].
-  WITH_SWORD,
-  /// Like [WITH_SWORD], but only without one.
-  WITHOUT_SWORD
-}''');
-
-    assertElement(
-      findNode.simple('Samurai]'),
-      findElement.enum_('Samurai'),
-    );
-    assertElement(
-      findNode.simple('int]'),
-      intElement,
-    );
-    assertElement(
-      findNode.simple('WITH_SWORD]'),
-      findElement.getter('WITH_SWORD'),
-    );
-  }
-
-  test_identifier_beforeFunction_blockBody() async {
-    await assertNoErrorsInCode(r'''
-/// [p]
-foo(int p) {}
-''');
-
-    assertElement(
-      findNode.simple('p]'),
-      findElement.parameter('p'),
-    );
-  }
-
-  test_identifier_beforeFunction_expressionBody() async {
-    await assertNoErrorsInCode(r'''
-/// [p]
-foo(int p) => null;
-''');
-
-    assertElement(
-      findNode.simple('p]'),
-      findElement.parameter('p'),
-    );
-  }
-
-  test_identifier_beforeFunctionTypeAlias() async {
-    await assertNoErrorsInCode(r'''
-/// [p]
-typedef Foo(int p);
-''');
-
-    assertElement(
-      findNode.simple('p]'),
-      findElement.parameter('p'),
-    );
-  }
-
-  test_identifier_beforeGenericTypeAlias() async {
-    await assertNoErrorsInCode(r'''
-/// Can resolve [T], [S], and [p].
-typedef Foo<T> = Function<S>(int p);
-''');
-
-    assertElement(
-      findNode.simple('T]'),
-      findElement.typeParameter('T'),
-    );
-    assertElement(findNode.simple('S]'), findElement.typeParameter('S'));
-    assertElement(
-      findNode.simple('p]'),
-      findElement.parameter('p'),
-    );
-  }
-
-  test_identifier_beforeGetter() async {
-    await assertNoErrorsInCode(r'''
-/// [int]
-get g => null;
-''');
-
-    assertElement(findNode.simple('int]'), intElement);
-  }
-
-  test_identifier_beforeMethod() async {
-    await assertNoErrorsInCode(r'''
-abstract class A {
-  /// [p1]
-  ma(int p1);
-
-  /// [p2]
-  mb(int p2);
-
-  /// [p3] and [p4]
-  mc(int p3, p4());
-
-  /// [p5]
-  md(int p5, {int p6});
-}
-''');
-
-    assertElement(findNode.simple('p1]'), findElement.parameter('p1'));
-    assertElement(findNode.simple('p2]'), findElement.parameter('p2'));
-    assertElement(findNode.simple('p3]'), findElement.parameter('p3'));
-    assertElement(findNode.simple('p4]'), findElement.parameter('p4'));
-    assertElement(findNode.simple('p5]'), findElement.parameter('p5'));
-  }
-
-  test_identifier_class_instanceGetter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  int get foo => 0;
-}
-
-/// [A.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
-    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
-  }
-
-  test_identifier_class_instanceMethod() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  void foo() {}
-}
-
-/// [A.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
-    assertElement(findNode.simple('foo]'), findElement.method('foo'));
-  }
-
-  test_identifier_class_instanceSetter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  set foo(int _) {}
-}
-
-/// [A.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
-    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
-  }
-
-  test_identifier_class_staticGetter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  static int get foo => 0;
-}
-
-/// [A.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
-    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
-  }
-
-  test_identifier_class_staticMethod() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  static void foo() {}
-}
-
-/// [A.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
-    assertElement(findNode.simple('foo]'), findElement.method('foo'));
-  }
-
-  test_identifier_class_staticSetter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  static set foo(int _) {}
-}
-
-/// [A.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
-    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
-  }
-
-  test_identifier_extension_instanceGetter() async {
-    await assertNoErrorsInCode(r'''
-extension E on int {
-  int get foo => 0;
-}
-
-/// [E.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
-    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
-  }
-
-  test_identifier_extension_instanceMethod() async {
-    await assertNoErrorsInCode(r'''
-extension E on int {
-  void foo() {}
-}
-
-/// [E.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
-    assertElement(findNode.simple('foo]'), findElement.method('foo'));
-  }
-
-  test_identifier_extension_instanceSetter() async {
-    await assertNoErrorsInCode(r'''
-extension E on int {
-  set foo(int _) {}
-}
-
-/// [E.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
-    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
-  }
-
-  test_identifier_extension_staticGetter() async {
-    await assertNoErrorsInCode(r'''
-extension E on int {
-  static int get foo => 0;
-}
-
-/// [E.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
-    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
-  }
-
-  test_identifier_extension_staticMethod() async {
-    await assertNoErrorsInCode(r'''
-extension E on int {
-  static void foo() {}
-}
-
-/// [E.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
-    assertElement(findNode.simple('foo]'), findElement.method('foo'));
-  }
-
-  test_identifier_extension_staticSetter() async {
-    await assertNoErrorsInCode(r'''
-extension E on int {
-  static set foo(int _) {}
-}
-
-/// [E.foo]
-void f() {}
-''');
-
-    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
-    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
-  }
-
-  test_identifier_parameter_functionTyped() async {
-    await assertNoErrorsInCode(r'''
-/// [bar]
-foo(int bar()) {}
-''');
-
-    assertElement(
-      findNode.simple('bar]'),
-      findElement.parameter('bar'),
-    );
-  }
-
-  test_identifier_setter() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  /// [x] in A
-  mA() {}
-  set x(value) {}
-}
-
-class B extends A {
-  /// [x] in B
-  mB() {}
-}
-''');
-
-    var x = findElement.setter('x', of: 'A');
-    assertElement(findNode.simple('x] in A'), x);
-    assertElement(findNode.simple('x] in B'), x);
-  }
-
-  test_new() async {
+  test_newKeyword() async {
     await assertErrorsInCode('''
 class A {
   A();
@@ -394,4 +42,356 @@
       findElement.constructor('named', of: 'A'),
     );
   }
+
+  test_prefixedIdentifier_class_instanceGetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  int get foo => 0;
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_prefixedIdentifier_class_instanceMethod() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  void foo() {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_prefixedIdentifier_class_instanceSetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  set foo(int _) {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
+  test_prefixedIdentifier_class_staticGetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static int get foo => 0;
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_prefixedIdentifier_class_staticMethod() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static void foo() {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_prefixedIdentifier_class_staticSetter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static set foo(int _) {}
+}
+
+/// [A.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('A.foo'), findElement.class_('A'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
+  test_prefixedIdentifier_extension_instanceGetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  int get foo => 0;
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_prefixedIdentifier_extension_instanceMethod() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  void foo() {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_prefixedIdentifier_extension_instanceSetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  set foo(int _) {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
+  test_prefixedIdentifier_extension_staticGetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  static int get foo => 0;
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.getter('foo'));
+  }
+
+  test_prefixedIdentifier_extension_staticMethod() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  static void foo() {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.method('foo'));
+  }
+
+  test_prefixedIdentifier_extension_staticSetter() async {
+    await assertNoErrorsInCode(r'''
+extension E on int {
+  static set foo(int _) {}
+}
+
+/// [E.foo]
+void f() {}
+''');
+
+    assertElement(findNode.simple('E.foo'), findElement.extension_('E'));
+    assertElement(findNode.simple('foo]'), findElement.setter('foo'));
+  }
+
+  test_simpleIdentifier_beforeClass() async {
+    await assertNoErrorsInCode(r'''
+/// [foo]
+class A {
+  foo() {}
+}
+''');
+
+    assertElement(
+      findNode.simple('foo]'),
+      findElement.method('foo'),
+    );
+  }
+
+  test_simpleIdentifier_beforeConstructor() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  /// [p]
+  A(int p);
+}''');
+
+    assertElement(
+      findNode.simple('p]'),
+      findElement.parameter('p'),
+    );
+  }
+
+  test_simpleIdentifier_beforeEnum() async {
+    await assertNoErrorsInCode(r'''
+/// This is the [Samurai] kind.
+enum Samurai {
+  /// Use [int].
+  WITH_SWORD,
+  /// Like [WITH_SWORD], but only without one.
+  WITHOUT_SWORD
+}''');
+
+    assertElement(
+      findNode.simple('Samurai]'),
+      findElement.enum_('Samurai'),
+    );
+    assertElement(
+      findNode.simple('int]'),
+      intElement,
+    );
+    assertElement(
+      findNode.simple('WITH_SWORD]'),
+      findElement.getter('WITH_SWORD'),
+    );
+  }
+
+  test_simpleIdentifier_beforeFunction_blockBody() async {
+    await assertNoErrorsInCode(r'''
+/// [p]
+foo(int p) {}
+''');
+
+    assertElement(
+      findNode.simple('p]'),
+      findElement.parameter('p'),
+    );
+  }
+
+  test_simpleIdentifier_beforeFunction_expressionBody() async {
+    await assertNoErrorsInCode(r'''
+/// [p]
+foo(int p) => null;
+''');
+
+    assertElement(
+      findNode.simple('p]'),
+      findElement.parameter('p'),
+    );
+  }
+
+  test_simpleIdentifier_beforeFunctionTypeAlias() async {
+    await assertNoErrorsInCode(r'''
+/// [p]
+typedef Foo(int p);
+''');
+
+    assertElement(
+      findNode.simple('p]'),
+      findElement.parameter('p'),
+    );
+  }
+
+  test_simpleIdentifier_beforeGenericTypeAlias() async {
+    await assertNoErrorsInCode(r'''
+/// Can resolve [T], [S], and [p].
+typedef Foo<T> = Function<S>(int p);
+''');
+
+    assertElement(
+      findNode.simple('T]'),
+      findElement.typeParameter('T'),
+    );
+    assertElement(findNode.simple('S]'), findElement.typeParameter('S'));
+    assertElement(
+      findNode.simple('p]'),
+      findElement.parameter('p'),
+    );
+  }
+
+  test_simpleIdentifier_beforeGetter() async {
+    await assertNoErrorsInCode(r'''
+/// [int]
+get g => null;
+''');
+
+    assertElement(findNode.simple('int]'), intElement);
+  }
+
+  test_simpleIdentifier_beforeMethod() async {
+    await assertNoErrorsInCode(r'''
+abstract class A {
+  /// [p1]
+  ma(int p1);
+
+  /// [p2]
+  mb(int p2);
+
+  /// [p3] and [p4]
+  mc(int p3, p4());
+
+  /// [p5]
+  md(int p5, {int p6});
+}
+''');
+
+    assertElement(findNode.simple('p1]'), findElement.parameter('p1'));
+    assertElement(findNode.simple('p2]'), findElement.parameter('p2'));
+    assertElement(findNode.simple('p3]'), findElement.parameter('p3'));
+    assertElement(findNode.simple('p4]'), findElement.parameter('p4'));
+    assertElement(findNode.simple('p5]'), findElement.parameter('p5'));
+  }
+
+  test_simpleIdentifier_parameter_functionTyped() async {
+    await assertNoErrorsInCode(r'''
+/// [bar]
+foo(int bar()) {}
+''');
+
+    assertElement(
+      findNode.simple('bar]'),
+      findElement.parameter('bar'),
+    );
+  }
+
+  test_simpleIdentifier_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  /// [x] in A
+  mA() {}
+  set x(value) {}
+}
+
+class B extends A {
+  /// [x] in B
+  mB() {}
+}
+''');
+
+    var x = findElement.setter('x', of: 'A');
+    assertElement(findNode.simple('x] in A'), x);
+    assertElement(findNode.simple('x] in B'), x);
+  }
+
+  test_simpleIdentifier_unqualifiedReferenceToNonLocalStaticMember() async {
+    await assertNoErrorsInCode('''
+class A {
+  static void foo() {}
+}
+
+/// [foo]
+class B extends A {}
+''');
+
+    assertElement(
+      findNode.simple('foo]'),
+      findElement.method('foo', of: 'A'),
+    );
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index 148433e..1b491ac 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -36,6 +36,7 @@
   final bool implicitCasts;
   final bool implicitDynamic;
   final List<String> lints;
+  final bool strictCasts;
   final bool strictInference;
   final bool strictRawTypes;
   final List<String> unignorableNames;
@@ -45,6 +46,7 @@
     this.implicitCasts = true,
     this.implicitDynamic = true,
     this.lints = const [],
+    this.strictCasts = false,
     this.strictInference = false,
     this.strictRawTypes = false,
     this.unignorableNames = const [],
@@ -59,8 +61,9 @@
       buffer.writeln('    - $experiment');
     }
     buffer.writeln('  language:');
-    buffer.writeln('    strict-raw-types: $strictRawTypes');
+    buffer.writeln('    strict-casts: $strictCasts');
     buffer.writeln('    strict-inference: $strictInference');
+    buffer.writeln('    strict-raw-types: $strictRawTypes');
     buffer.writeln('  strong-mode:');
     buffer.writeln('    implicit-casts: $implicitCasts');
     buffer.writeln('    implicit-dynamic: $implicitDynamic');
@@ -393,13 +396,14 @@
 }
 
 mixin WithNoImplicitCastsMixin on PubPackageResolutionTest {
+  /// Asserts that no errors are reported in [code] when implicit casts are
+  /// allowed, and that [expectedErrors] are reported for the same [code] when
+  /// implicit casts are not allowed.
   Future<void> assertErrorsWithNoImplicitCasts(
     String code,
-    List<ExpectedError> expectedErrorsWhenImplicitCastsDisabled,
+    List<ExpectedError> expectedErrors,
   ) async {
-    newFile(testFilePath, content: code);
-
-    await resolveTestFile();
+    await resolveTestCode(code);
     assertNoErrorsInResult();
 
     disposeAnalysisContextCollection();
@@ -411,8 +415,13 @@
     );
 
     await resolveTestFile();
-    assertErrorsInResult(expectedErrorsWhenImplicitCastsDisabled);
+    assertErrorsInResult(expectedErrors);
   }
+
+  /// Asserts that no errors are reported in [code], both when implicit casts
+  /// are allowed and when implicit casts are not allowed.
+  Future<void> assertNoErrorsWithNoImplicitCasts(String code) async =>
+      assertErrorsWithNoImplicitCasts(code, []);
 }
 
 mixin WithoutConstructorTearoffsMixin on PubPackageResolutionTest {
@@ -427,3 +436,32 @@
   @override
   bool get typeToStringWithNullability => false;
 }
+
+mixin WithStrictCastsMixin on PubPackageResolutionTest {
+  /// Asserts that no errors are reported in [code] when implicit casts are
+  /// allowed, and that [expectedErrors] are reported for the same [code] when
+  /// implicit casts are not allowed.
+  Future<void> assertErrorsWithStrictCasts(
+    String code,
+    List<ExpectedError> expectedErrors,
+  ) async {
+    await resolveTestCode(code);
+    assertNoErrorsInResult();
+
+    disposeAnalysisContextCollection();
+
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(
+        strictCasts: true,
+      ),
+    );
+
+    await resolveTestFile();
+    assertErrorsInResult(expectedErrors);
+  }
+
+  /// Asserts that no errors are reported in [code], both when implicit casts
+  /// are allowed and when implicit casts are not allowed.
+  Future<void> assertNoErrorsWithStrictCasts(String code) async =>
+      assertErrorsWithStrictCasts(code, []);
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index fc226d1..a2dab45 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -311,13 +311,33 @@
 var x = A.foo<int>;
 ''', [
       error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 42,
-          5),
+          5,
+          messageContains: ["'A.foo'"]),
     ]);
 
     assertFunctionReference(findNode.functionReference('A.foo<int>;'),
         findElement.constructor('foo'), 'dynamic');
   }
 
+  test_constructorReference_prefixed() async {
+    await assertErrorsInCode('''
+import 'dart:async' as a;
+var x = a.Future.delayed<int>;
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 50,
+          5,
+          messageContains: ["'a.Future.delayed'"]),
+    ]);
+    assertFunctionReference(
+        findNode.functionReference('a.Future.delayed<int>;'),
+        findElement
+            .import('dart:async')
+            .importedLibrary!
+            .getType('Future')!
+            .getNamedConstructor('delayed'),
+        'dynamic');
+  }
+
   test_dynamicTyped() async {
     await assertErrorsInCode('''
 dynamic i = 1;
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index feac804..5175800 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -305,42 +305,48 @@
 
   test_namedArgument_anywhere() async {
     await assertNoErrorsInCode('''
-class A {
-  A(int a, double b, {bool? c, bool? d});
+class A {}
+class B {}
+class C {}
+class D {}
+
+class X {
+  X(A a, B b, {C? c, D? d});
 }
 
+T g1<T>() => throw 0;
+T g2<T>() => throw 0;
+T g3<T>() => throw 0;
+T g4<T>() => throw 0;
+
 void f() {
-  A(0, c: true, 1.2, d: true);
+  X(g1(), c: g3(), g2(), d: g4());
 }
 ''');
 
     assertInstanceCreation(
-      findNode.instanceCreation('A(0'),
-      findElement.class_('A'),
-      'A',
+      findNode.instanceCreation('X(g'),
+      findElement.class_('X'),
+      'X',
     );
 
-    assertParameterElement(
-      findNode.integerLiteral('0'),
-      findElement.parameter('a'),
-    );
+    var g1 = findNode.methodInvocation('g1()');
+    assertType(g1, 'A');
+    assertParameterElement(g1, findElement.parameter('a'));
 
-    assertParameterElement(
-      findNode.doubleLiteral('1.2'),
-      findElement.parameter('b'),
-    );
+    var g2 = findNode.methodInvocation('g2()');
+    assertType(g2, 'B');
+    assertParameterElement(g2, findElement.parameter('b'));
 
-    assertParameterElement(
-      findNode.namedExpression('c: true'),
-      findElement.parameter('c'),
-    );
-    assertNamedParameterRef('c: true', 'c');
+    var named_g3 = findNode.namedExpression('c: g3()');
+    assertType(named_g3.expression, 'C?');
+    assertParameterElement(named_g3, findElement.parameter('c'));
+    assertNamedParameterRef('c:', 'c');
 
-    assertParameterElement(
-      findNode.namedExpression('d: true'),
-      findElement.parameter('d'),
-    );
-    assertNamedParameterRef('d: true', 'd');
+    var named_g4 = findNode.namedExpression('d: g4()');
+    assertType(named_g4.expression, 'D?');
+    assertParameterElement(named_g4, findElement.parameter('d'));
+    assertNamedParameterRef('d:', 'd');
   }
 
   test_typeAlias_generic_class_generic_named_infer_all() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index 7c96192..b17dc6f 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -128,7 +128,7 @@
           rightParenthesis: )
         constructorName: ConstructorName
           staticElement: self::@class::A::@constructor::•
-          type: TypeName
+          type: NamedType
             name: SimpleIdentifier
               staticElement: self::@class::A
               staticType: null
@@ -804,7 +804,7 @@
     token: A
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -855,7 +855,7 @@
     token: A
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -1202,7 +1202,7 @@
     token: B
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -1515,7 +1515,7 @@
     staticType: null
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -1580,7 +1580,7 @@
     staticType: null
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -1679,7 +1679,7 @@
     token: B
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -1744,7 +1744,7 @@
     token: B
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -1911,7 +1911,7 @@
     token: B
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
@@ -1965,7 +1965,7 @@
     token: B
   typeArguments: TypeArgumentList
     arguments
-      TypeName
+      NamedType
         name: SimpleIdentifier
           staticElement: dart:core::@class::int
           staticType: null
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 32d8c5d..c564c0c 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -2865,40 +2865,46 @@
 
   test_namedArgument_anywhere() async {
     await assertNoErrorsInCode('''
-void foo(int a, double b, {bool? c, bool? d}) {}
+class A {}
+class B {}
+class C {}
+class D {}
+
+void foo(A a, B b, {C? c, D? d}) {}
+
+T g1<T>() => throw 0;
+T g2<T>() => throw 0;
+T g3<T>() => throw 0;
+T g4<T>() => throw 0;
 
 void f() {
-  foo(0, c: true, 1.2, d: true);
+  foo(g1(), c: g3(), g2(), d: g4());
 }
 ''');
 
     assertMethodInvocation(
-      findNode.methodInvocation('foo(0'),
+      findNode.methodInvocation('foo(g'),
       findElement.topFunction('foo'),
-      'void Function(int, double, {bool? c, bool? d})',
+      'void Function(A, B, {C? c, D? d})',
     );
 
-    assertParameterElement(
-      findNode.integerLiteral('0'),
-      findElement.parameter('a'),
-    );
+    var g1 = findNode.methodInvocation('g1()');
+    assertType(g1, 'A');
+    assertParameterElement(g1, findElement.parameter('a'));
 
-    assertParameterElement(
-      findNode.doubleLiteral('1.2'),
-      findElement.parameter('b'),
-    );
+    var g2 = findNode.methodInvocation('g2()');
+    assertType(g2, 'B');
+    assertParameterElement(g2, findElement.parameter('b'));
 
-    assertParameterElement(
-      findNode.namedExpression('c: true'),
-      findElement.parameter('c'),
-    );
-    assertNamedParameterRef('c: true', 'c');
+    var named_g3 = findNode.namedExpression('c: g3()');
+    assertType(named_g3.expression, 'C?');
+    assertParameterElement(named_g3, findElement.parameter('c'));
+    assertNamedParameterRef('c:', 'c');
 
-    assertParameterElement(
-      findNode.namedExpression('d: true'),
-      findElement.parameter('d'),
-    );
-    assertNamedParameterRef('d: true', 'd');
+    var named_g4 = findNode.namedExpression('d: g4()');
+    assertType(named_g4.expression, 'D?');
+    assertParameterElement(named_g4, findElement.parameter('d'));
+    assertNamedParameterRef('d:', 'd');
   }
 
   test_nullShorting_cascade_firstMethodInvocation() async {
diff --git a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
index 6af1989..6e9b9ef 100644
--- a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
+++ b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
@@ -122,17 +122,6 @@
 
 @reflectiveTest
 class FolderBasedDartSdkTest with ResourceProviderMixin {
-  void test_addExtensions() {
-    FolderBasedDartSdk sdk = _createDartSdk();
-    String uri = 'dart:my.internal';
-    sdk.addExtensions({uri: '/Users/user/dart/my.dart'});
-    expect(sdk.mapDartUri(uri), isNotNull);
-    // The `shortName` property must include the `dart:` prefix.
-    expect(sdk.sdkLibraries, contains(predicate((SdkLibrary library) {
-      return library.shortName == uri;
-    })));
-  }
-
   void test_creation() {
     FolderBasedDartSdk sdk = _createDartSdk();
     expect(sdk, isNotNull);
@@ -150,7 +139,6 @@
         .getChildAssumingFile("core.dart")
         .toUri())!;
     expect(source, isNotNull);
-    expect(source.isInSystemLibrary, isTrue);
     expect(source.uri.toString(), "dart:core");
   }
 
@@ -161,7 +149,6 @@
     File file = dirDartium.getChildAssumingFile("html_dart2js.dart");
     var source = sdk.fromFileUri(file.toUri())!;
     expect(source, isNotNull);
-    expect(source.isInSystemLibrary, isTrue);
     expect(source.uri.toString(), "dart:html");
   }
 
@@ -172,7 +159,6 @@
     File file = dirCommon.getChildAssumingFile("html_common_dart2js.dart");
     var source = sdk.fromFileUri(file.toUri())!;
     expect(source, isNotNull);
-    expect(source.isInSystemLibrary, isTrue);
     expect(source.uri.toString(), "dart:html_common");
   }
 
@@ -183,7 +169,6 @@
         .getChildAssumingFile("num.dart")
         .toUri())!;
     expect(source, isNotNull);
-    expect(source.isInSystemLibrary, isTrue);
     expect(source.uri.toString(), "dart:core/num.dart");
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/abi_specific_integer_mapping_test.dart b/pkg/analyzer/test/src/diagnostics/abi_specific_integer_mapping_test.dart
new file mode 100644
index 0000000..746ce71
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/abi_specific_integer_mapping_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/ffi_code.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AbiSpecificIntegerMappingTest);
+  });
+}
+
+@reflectiveTest
+class AbiSpecificIntegerMappingTest extends PubPackageResolutionTest {
+  test_doubleMapping() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+@AbiSpecificIntegerMapping({})
+@AbiSpecificIntegerMapping({})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+''', [
+      error(FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_EXTRA, 51, 25),
+    ]);
+  }
+
+  test_invalidMapping() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: IntPtr(),
+  Abi.androidIA32: UintPtr(),
+})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+''', [
+      error(FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_UNSUPPORTED, 20, 25),
+    ]);
+  }
+
+  test_noMapping() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+''', [
+      error(FfiCode.ABI_SPECIFIC_INTEGER_MAPPING_MISSING, 25, 7),
+    ]);
+  }
+
+  test_singleMapping() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+@AbiSpecificIntegerMapping({})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+''');
+  }
+
+  test_validMapping() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+})
+class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
index 60ca6a0..226eafa 100644
--- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
@@ -11,8 +11,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ArgumentTypeNotAssignableTest);
-    defineReflectiveTests(ArgumentTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        ArgumentTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(ArgumentTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(ArgumentTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -656,7 +658,7 @@
 }
 
 @reflectiveTest
-class ArgumentTypeNotAssignableWithNoImplicitCastsTest
+class ArgumentTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_functionCall() async {
@@ -708,3 +710,28 @@
     ]);
   }
 }
+
+@reflectiveTest
+class ArgumentTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_functionCall() async {
+    await assertErrorsWithStrictCasts('''
+void f(int i) {}
+void foo(dynamic a) {
+  f(a);
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 43, 1),
+    ]);
+  }
+
+  test_operator() async {
+    await assertErrorsWithStrictCasts('''
+void foo(int i, dynamic a) {
+  i + a;
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 35, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_type_bool_num_string_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_type_bool_num_string_test.dart
index 8acf4e9..b4bcb41 100644
--- a/pkg/analyzer/test/src/diagnostics/const_eval_type_bool_num_string_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_eval_type_bool_num_string_test.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -17,21 +16,14 @@
 @reflectiveTest
 class ConstEvalTypeBoolNumStringTest extends PubPackageResolutionTest {
   test_equal() async {
-    await assertErrorsInCode(
-        r'''
+    await assertNoErrorsInCode(r'''
 class A {
   const A();
 }
 
 const num a = 0;
 const b = a == const A();
-''',
-        IsEnabledByDefault.constant_update_2018
-            ? []
-            : [
-                error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 53,
-                    14),
-              ]);
+''');
   }
 
   test_notEqual() async {
diff --git a/pkg/analyzer/test/src/diagnostics/const_with_undefined_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/const_with_undefined_constructor_test.dart
index ee5737d..90bd671 100644
--- a/pkg/analyzer/test/src/diagnostics/const_with_undefined_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_with_undefined_constructor_test.dart
@@ -24,7 +24,23 @@
   return const A.noSuchConstructor();
 }
 ''', [
-      error(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, 48, 17),
+      error(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, 48, 17,
+          messageContains: ["class 'A'", "constructor 'noSuchConstructor'"]),
+    ]);
+  }
+
+  test_named_prefixed() async {
+    await assertErrorsInCode(r'''
+import 'dart:async' as a;
+f() {
+  return const a.Future.noSuchConstructor();
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, 56, 17,
+          messageContains: [
+            "class 'a.Future'",
+            "constructor 'noSuchConstructor'"
+          ]),
     ]);
   }
 
@@ -53,7 +69,26 @@
 }
 ''', [
       error(
-          CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 51, 1),
+          CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 51, 1,
+          messageContains: ["'A'"]),
+    ]);
+  }
+
+  test_unnamed_prefixed() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+class A {
+  const A.name();
+}
+''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' as lib1;
+f() {
+  return const lib1.A();
+}
+''', [
+      error(
+          CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 49, 6,
+          messageContains: ["'lib1.A'"]),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart
index 07abbcd..767bfa9 100644
--- a/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart
@@ -10,7 +10,9 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(FieldInitializerNotAssignableTest);
-    defineReflectiveTests(FieldInitializerNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        FieldInitializerNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
+    defineReflectiveTests(FieldInitializerNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -53,14 +55,34 @@
 }
 
 @reflectiveTest
-class FieldInitializerNotAssignableWithNoImplicitCastsTest
+class FieldInitializerNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_constructorInitializer() async {
-    await assertErrorsWithNoImplicitCasts(
-      'class A { int i; A(num n) : i = n; }',
+    await assertErrorsWithNoImplicitCasts('''
+class A {
+  int i;
+  A(num n) : i = n;
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 36, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class FieldInitializerNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_constructorInitializer() async {
+    await assertErrorsWithStrictCasts(
+      '''
+class A {
+  int i;
+  A(dynamic a) : i = a;
+}
+''',
       [
-        error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 32, 1),
+        error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 40, 1),
       ],
     );
   }
diff --git a/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
index c75dd89..31ecd85 100644
--- a/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(ForInOfInvalidTypeTest);
     defineReflectiveTests(ForInOfInvalidTypeWithoutNullSafetyTest);
+    defineReflectiveTests(ForInOfInvalidTypeWithStrictCastsTest);
   });
 }
 
@@ -183,3 +184,19 @@
 ''');
   }
 }
+
+@reflectiveTest
+class ForInOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_forIn() async {
+    await assertErrorsWithStrictCasts('''
+f(dynamic e) {
+  for (var id in e) {
+    id;
+  }
+}
+''', [
+      error(CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE, 32, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart b/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart
index 68e338d..f154d5d 100644
--- a/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/generic_struct_subclass_test.dart
@@ -22,7 +22,7 @@
   external Pointer notEmpty;
 }
 ''', [
-      error(FfiCode.GENERIC_STRUCT_SUBCLASS, 25, 1),
+      error(FfiCode.GENERIC_STRUCT_SUBCLASS, 25, 1, messageContains: ["'S'"]),
     ]);
   }
 
@@ -33,7 +33,7 @@
   external Pointer notEmpty;
 }
 ''', [
-      error(FfiCode.GENERIC_STRUCT_SUBCLASS, 25, 1),
+      error(FfiCode.GENERIC_STRUCT_SUBCLASS, 25, 1, messageContains: ["'S'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/implicit_dynamic_field_test.dart b/pkg/analyzer/test/src/diagnostics/implicit_dynamic_field_test.dart
index fd002a6..1bfd680 100644
--- a/pkg/analyzer/test/src/diagnostics/implicit_dynamic_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implicit_dynamic_field_test.dart
@@ -49,7 +49,8 @@
   final f = (<dynamic>[])[0];
 }
 ''', [
-      error(LanguageCode.IMPLICIT_DYNAMIC_FIELD, 18, 20),
+      error(LanguageCode.IMPLICIT_DYNAMIC_FIELD, 18, 20,
+          messageContains: ["'f'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/initializer_for_non_existent_field_test.dart b/pkg/analyzer/test/src/diagnostics/initializer_for_non_existent_field_test.dart
index 43361f5..e2b6231 100644
--- a/pkg/analyzer/test/src/diagnostics/initializer_for_non_existent_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/initializer_for_non_existent_field_test.dart
@@ -24,7 +24,20 @@
 }
 A a = const A();
 ''', [
-      error(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, 24, 9),
+      error(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, 24, 9,
+          messageContains: ["'x'"]),
+    ]);
+  }
+
+  test_getter() async {
+    await assertErrorsInCode('''
+class A {
+  int get x => 0;
+  A() : x = 0;
+}
+''', [
+      error(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, 36, 5,
+          messageContains: ["'x'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/initializer_for_static_field_test.dart b/pkg/analyzer/test/src/diagnostics/initializer_for_static_field_test.dart
index 6acd087..d556c0b 100644
--- a/pkg/analyzer/test/src/diagnostics/initializer_for_static_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/initializer_for_static_field_test.dart
@@ -33,7 +33,8 @@
   A() : x = 0 {}
 }
 ''', [
-      error(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, 38, 5),
+      error(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, 38, 5,
+          messageContains: ["'x'"]),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
index a72d21b..00abc76 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
@@ -110,6 +110,40 @@
     ]);
   }
 
+  test_localVariable_const() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  const a = 0;
+  @a
+  var b; // ignore:unused_local_variable
+}
+''');
+  }
+
+  test_localVariable_const_withArguments() async {
+    await assertErrorsInCode(r'''
+void f() {
+  const a = 0;
+  @a(0)
+  var b; // ignore:unused_local_variable
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_ANNOTATION, 28, 5),
+    ]);
+  }
+
+  test_localVariable_final() async {
+    await assertErrorsInCode(r'''
+void f() {
+  final a = 0;
+  @a
+  var b; // ignore:unused_local_variable
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_ANNOTATION, 28, 2),
+    ]);
+  }
+
   test_notClass_importWithPrefix() async {
     newFile('$testPackageLibPath/annotations.dart', content: r'''
 class Property {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
index a303efd..726f456 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
@@ -11,8 +11,10 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(InvalidAssignment_ImplicitCallReferenceTest);
     defineReflectiveTests(InvalidAssignmentTest);
-    defineReflectiveTests(InvalidAssignmentWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        InvalidAssignmentWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(InvalidAssignmentWithoutNullSafetyTest);
+    defineReflectiveTests(InvalidAssignmentWithStrictCastsTest);
   });
 }
 
@@ -962,24 +964,27 @@
 }
 
 @reflectiveTest
-class InvalidAssignmentWithNoImplicitCastsTest extends PubPackageResolutionTest
+class InvalidAssignmentWithoutNullSafetyAndNoImplicitCastsTest
+    extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_assignment() async {
-    await assertErrorsWithNoImplicitCasts(
-      'void f(num n, int i) { i = n;}',
-      [
-        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 27, 1),
-      ],
-    );
+    await assertErrorsWithNoImplicitCasts('''
+void f(num n, int i) {
+  i = n;
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 29, 1),
+    ]);
   }
 
   test_compoundAssignment() async {
-    await assertErrorsWithNoImplicitCasts(
-      'void f(num n, int i) { i += n; }',
-      [
-        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 28, 1),
-      ],
-    );
+    await assertErrorsWithNoImplicitCasts('''
+void f(num n, int i) {
+  i += n;
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 30, 1),
+    ]);
   }
 
   @failingTest
@@ -1008,11 +1013,11 @@
 
   test_numericOps() async {
     // Regression test for https://github.com/dart-lang/sdk/issues/26912
-    await assertErrorsWithNoImplicitCasts(r'''
+    await assertNoErrorsWithNoImplicitCasts('''
 void f(int x, int y) {
   x += y;
 }
-''', []);
+''');
   }
 
   @failingTest
@@ -1088,3 +1093,16 @@
     ]);
   }
 }
+
+@reflectiveTest
+class InvalidAssignmentWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_assignment() async {
+    await assertErrorsWithStrictCasts('''
+dynamic a;
+int b = a;
+''', [
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 19, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_of_non_virtual_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_of_non_virtual_member_test.dart
index 10a52f8..7c31b18 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_of_non_virtual_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_of_non_virtual_member_test.dart
@@ -35,7 +35,8 @@
   int g = 0;
 }
 ''', [
-      error(HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, 113, 1),
+      error(HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, 113, 1,
+          messageContains: ["member 'g'", "in 'C'"]),
     ]);
   }
 
@@ -70,7 +71,8 @@
   int get g => 0;
 }
 ''', [
-      error(HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, 117, 1),
+      error(HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, 117, 1,
+          messageContains: ["member 'g'", "in 'C'"]),
     ]);
   }
 
@@ -228,7 +230,8 @@
   void f() {}
 }
 ''', [
-      error(HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, 111, 1),
+      error(HintCode.INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER, 111, 1,
+          messageContains: ["member 'f'", "in 'M'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_list_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_list_test.dart
index a47fffd..85db5dc 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_list_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_list_test.dart
@@ -23,7 +23,8 @@
   }
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST, 39, 1),
+      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST, 39, 1,
+          messageContains: ["'E'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_map_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_map_test.dart
index 3c75e1d..d12b1e8 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_map_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_map_test.dart
@@ -23,7 +23,8 @@
   }
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP, 39, 1),
+      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP, 39, 1,
+          messageContains: ["'E'"]),
     ]);
   }
 
@@ -45,7 +46,8 @@
   }
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP, 47, 1),
+      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP, 47, 1,
+          messageContains: ["'E'"]),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_set_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_set_test.dart
index fe0c076..69d6881 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_set_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_type_argument_in_const_set_test.dart
@@ -23,7 +23,8 @@
   }
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET, 39, 1),
+      error(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET, 39, 1,
+          messageContains: ["'E'"]),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_covariant_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_covariant_test.dart
new file mode 100644
index 0000000..20b7d5c
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_covariant_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.g.dart';
+import 'package:analyzer/src/error/codes.g.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidUseOfCovariantTest);
+  });
+}
+
+@reflectiveTest
+class InvalidUseOfCovariantTest extends PubPackageResolutionTest {
+  test_functionExpression() async {
+    await assertErrorsInCode('''
+Function f = (covariant int x) {};
+''', [
+      error(CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, 14, 9),
+    ]);
+  }
+
+  test_functionType_inFunctionTypedParameterOfInstanceMethod() async {
+    await assertErrorsInCode('''
+class C {
+  void m(void p(covariant int)) {}
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, 26, 9),
+    ]);
+  }
+
+  test_functionType_inParameterOfInstanceMethod() async {
+    await assertErrorsInCode('''
+class C {
+  void m(void Function(covariant int) p) {}
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, 33, 9),
+    ]);
+  }
+
+  test_functionType_inTypeAlias() async {
+    await assertErrorsInCode('''
+typedef F = void Function(covariant int);
+''', [
+      error(CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, 26, 9),
+    ]);
+  }
+
+  test_functionType_inTypeArgument() async {
+    await assertErrorsInCode('''
+List<void Function(covariant int)> a = [];
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, 19, 9),
+      // TODO(srawlins): Recover better from this situation (`covariant` in
+      // parameter in type argument).
+      error(ParserErrorCode.EXPECTED_EXECUTABLE, 43, 1),
+    ]);
+  }
+
+  test_functionType_inTypeParameterBound() async {
+    await assertErrorsInCode('''
+void foo<T extends void Function(covariant int)>() {}
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, 33, 9),
+      // TODO(srawlins): Recover better from this situation (`covariant` in
+      // parameter in bound).
+      error(ParserErrorCode.EXPECTED_EXECUTABLE, 54, 1),
+    ]);
+  }
+
+  test_localFunction() async {
+    await assertErrorsInCode('''
+void foo() {
+  void f(covariant int x) {}
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 20, 1),
+      error(CompileTimeErrorCode.INVALID_USE_OF_COVARIANT, 22, 9),
+    ]);
+  }
+
+  test_staticFunction() async {
+    await assertErrorsInCode('''
+class C {
+  static void m(covariant int x) {}
+}
+''', [
+      // INVALID_USE_OF_COVARIANT is not reported here; it would be redundant.
+      error(ParserErrorCode.EXTRANEOUS_MODIFIER, 26, 9),
+    ]);
+  }
+
+  test_staticFunction_onMixin() async {
+    await assertErrorsInCode('''
+mixin M {
+  static void m(covariant int x) {}
+}
+''', [
+      // INVALID_USE_OF_COVARIANT is not reported here; it would be redundant.
+      error(ParserErrorCode.EXTRANEOUS_MODIFIER, 26, 9),
+    ]);
+  }
+
+  test_topLevelFunction() async {
+    await assertErrorsInCode('''
+void f(covariant int x) {}
+''', [
+      // INVALID_USE_OF_COVARIANT is not reported here; it would be redundant.
+      error(ParserErrorCode.EXTRANEOUS_MODIFIER, 7, 9),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
index 8d45f28..6a85dc3 100644
--- a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ListElementTypeNotAssignableTest);
-    defineReflectiveTests(ListElementTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        ListElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(ListElementTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(ListElementTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -233,7 +235,7 @@
 }
 
 @reflectiveTest
-class ListElementTypeNotAssignableWithNoImplicitCastsTest
+class ListElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_dynamic() async {
@@ -291,3 +293,37 @@
 class ListElementTypeNotAssignableWithoutNullSafetyTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, ListElementTypeNotAssignableTestCases {}
+
+@reflectiveTest
+class ListElementTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>[if (c) 0 else a];
+}
+''', [
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 50, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>[if (c) a];
+}
+''', [
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 43, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Iterable<dynamic> a) {
+  <int>[...a];
+}
+''', [
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 41, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
index 1216de7..ca3c915 100644
--- a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MapKeyTypeNotAssignableTest);
-    defineReflectiveTests(MapKeyTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        MapKeyTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(MapKeyTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(MapKeyTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -238,7 +240,7 @@
 }
 
 @reflectiveTest
-class MapKeyTypeNotAssignableWithNoImplicitCastsTest
+class MapKeyTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_key_dynamic() async {
@@ -302,3 +304,37 @@
 ''');
   }
 }
+
+@reflectiveTest
+class MapKeyTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) 0: 0 else a: 0};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 58, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) a: 0 };
+}
+''', [
+      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 48, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Map<dynamic, int> a) {
+  <int, int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 46, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
index 212b70b..4cebc25 100644
--- a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MapValueTypeNotAssignableTest);
-    defineReflectiveTests(MapValueTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        MapValueTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(MapValueTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(MapValueTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -232,7 +234,7 @@
 }
 
 @reflectiveTest
-class MapValueTypeNotAssignableWithNoImplicitCastsTest
+class MapValueTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_value_dynamic() async {
@@ -296,3 +298,37 @@
 ''');
   }
 }
+
+@reflectiveTest
+class MapValueTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) 0: 0 else 0: a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 61, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) 0: a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 51, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Map<int, dynamic> a) {
+  <int, int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 46, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart b/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
index 8147f29..ef8d48e 100644
--- a/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
@@ -15,14 +15,22 @@
 
 @reflectiveTest
 class MultipleSuperInitializersTest extends PubPackageResolutionTest {
+  test_oneSuperInitializer() async {
+    await assertNoErrorsInCode('''
+class A {}
+class B extends A {
+  B() : super() {}
+}
+''');
+  }
+
   test_twoSuperInitializers() async {
-    await assertErrorsInCode(r'''
+    await assertErrorsInCode('''
 class A {}
 class B extends A {
   B() : super(), super() {}
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 39, 5),
       error(CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, 48, 7),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart
index 4ebf06c..4a7c777 100644
--- a/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart
@@ -30,7 +30,8 @@
   new A();
 }
 ''', [
-      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 38, 1),
+      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 38, 1,
+          messageContains: ["'A'"]),
     ]);
   }
 
@@ -47,6 +48,24 @@
     ]);
   }
 
+  test_default_prefixed() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+class A {
+  A.name() {}
+}
+''');
+    await assertErrorsInCode('''
+import 'lib1.dart' as lib1;
+
+f() {
+  new lib1.A();
+}
+''', [
+      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, 41, 6,
+          messageContains: ["'lib1.A'"]),
+    ]);
+  }
+
   test_default_unnamedViaNew() async {
     await assertErrorsInCode('''
 class A {
@@ -102,7 +121,25 @@
   new A.name();
 }
 ''', [
-      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 35, 4),
+      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 35, 4,
+          messageContains: ["class 'A'", "named 'name'"]),
+    ]);
+  }
+
+  test_named_prefixed() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+class A {
+  A() {}
+}
+''');
+    await assertErrorsInCode('''
+import 'lib1.dart' as lib1;
+f() {
+  new lib1.A.name();
+}
+''', [
+      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 47, 4,
+          messageContains: ["class 'lib1.A'", "named 'name'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
index 0e9e5de..3f99747 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolConditionTest);
-    defineReflectiveTests(NonBoolConditionWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        NonBoolConditionWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(NonBoolConditionWithNullSafetyTest);
+    defineReflectiveTests(NonBoolConditionWithStrictCastsTest);
   });
 }
 
@@ -26,6 +28,21 @@
     ]);
   }
 
+  test_conditional_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() { return [1, 2, 3] ? 2 : 1; }
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 13, 9),
+    ]);
+  }
+
+  test_conditional_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+f() { return o ? 2 : 1; }
+''');
+  }
+
   test_do() async {
     await assertErrorsInCode(r'''
 f() {
@@ -36,6 +53,26 @@
     ]);
   }
 
+  test_do_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+Object o;
+f() {
+  do {} while ([1, 2, 3]);
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 31, 9),
+    ]);
+  }
+
+  test_do_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+f() {
+  do {} while (o);
+}
+''');
+  }
+
   test_for() async {
     // https://github.com/dart-lang/sdk/issues/24713
     await assertErrorsInCode(r'''
@@ -71,6 +108,25 @@
     ]);
   }
 
+  test_for_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  for (;[1, 2, 3];) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 14, 9),
+    ]);
+  }
+
+  test_for_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+f() {
+  for (;o;) {}
+}
+''');
+  }
+
   test_forElement() async {
     await assertErrorsInCode('''
 var v = [for (; 0;) 1];
@@ -89,6 +145,24 @@
     ]);
   }
 
+  test_if_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  if ([1, 2, 3]) return 2; else return 1;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 12, 9),
+    ]);
+  }
+
+  test_if_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+f(Object o) {
+  if (o) return 2; else return 1;
+}
+''');
+  }
+
   test_ifElement() async {
     await assertErrorsInCode('''
 var v = [if (3) 1];
@@ -97,6 +171,21 @@
     ]);
   }
 
+  test_ifElement_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+var v = [if ([1, 2, 3]) 'x'];
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 13, 9),
+    ]);
+  }
+
+  test_ifElement_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+Object o;
+var v = [if (o) 'x'];
+''');
+  }
+
   test_while() async {
     await assertErrorsInCode(r'''
 f() {
@@ -106,10 +195,52 @@
       error(CompileTimeErrorCode.NON_BOOL_CONDITION, 15, 1),
     ]);
   }
+
+  test_while_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  while ([1, 2, 3]) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 15, 9),
+    ]);
+  }
+
+  test_while_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+f(Object o) {
+  while (o) {}
+}
+''');
+  }
 }
 
 @reflectiveTest
-class NonBoolConditionWithNoImplicitCastsTest extends PubPackageResolutionTest
+class NonBoolConditionWithNullSafetyTest extends PubPackageResolutionTest {
+  test_if_null() async {
+    await assertErrorsInCode(r'''
+void f(Null a) {
+  if (a) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 23, 1),
+    ]);
+  }
+
+  test_ternary_condition_null() async {
+    await assertErrorsInCode(r'''
+void f(Null a) {
+  a ? 0 : 1;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 19, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class NonBoolConditionWithoutNullSafetyAndNoImplicitCastsTest
+    extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_map_ifElement_condition_dynamic() async {
     await assertErrorsWithNoImplicitCasts(r'''
@@ -153,26 +284,25 @@
 }
 
 @reflectiveTest
-class NonBoolConditionWithNullSafetyTest extends PubPackageResolutionTest {
-  test_if_null() async {
-    await assertErrorsInCode(r'''
-m() {
-  Null x;
-  if (x) {}
+class NonBoolConditionWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_map_ifElement_condition() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic c) {
+  <int, int>{if (c) 0: 0};
 }
 ''', [
-      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 22, 1),
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 37, 1),
     ]);
   }
 
-  test_ternary_condition_null() async {
-    await assertErrorsInCode(r'''
-m() {
-  Null x;
-  x ? 0 : 1;
+  test_set_ifElement_condition() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic c) {
+  <int>{if (c) 0};
 }
 ''', [
-      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 18, 1),
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 32, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart
index 0a12cfb..1305b0d 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart
@@ -10,6 +10,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolExpressionTest);
+    defineReflectiveTests(NonBoolExpressionWithStrictCastsTest);
   });
 }
 
@@ -47,3 +48,17 @@
     ]);
   }
 }
+
+@reflectiveTest
+class NonBoolExpressionWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_assert() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  assert(a);
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_EXPRESSION, 29, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
index 2d2c516..f0578ad 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolNegationExpressionTest);
     defineReflectiveTests(NonBoolNegationExpressionWithNullSafetyTest);
+    defineReflectiveTests(NonBoolNegationExpressionWithStrictCastsTest);
   });
 }
 
@@ -26,20 +27,50 @@
       error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 9, 2),
     ]);
   }
+
+  test_nonBool_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+f() {
+  ![1, 2, 3];
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 9, 9),
+    ]);
+  }
+
+  test_nonBool_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+f(Object o) {
+  !o;
+}
+''');
+  }
 }
 
 @reflectiveTest
 class NonBoolNegationExpressionWithNullSafetyTest
     extends PubPackageResolutionTest {
   test_null() async {
-    await assertErrorsInCode(r'''
-m() {
-  Null x;
+    await assertErrorsInCode('''
+void m(Null x) {
   !x;
 }
 ''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
-      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 19, 1),
+      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 20, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class NonBoolNegationExpressionWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_negation() async {
+    await assertErrorsWithStrictCasts(r'''
+void f(dynamic a) {
+  !a;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 23, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
index f3d16b1..1b25120 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolOperandTest);
     defineReflectiveTests(NonBoolOperandWithNullSafetyTest);
+    defineReflectiveTests(NonBoolOperandWithStrictCastsTest);
   });
 }
 
@@ -27,6 +28,34 @@
     ]);
   }
 
+  test_and_left_implicitCast_fromInstanceCreationExpression() async {
+    await assertErrorsInCode('''
+main() {
+  new Object() && true;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_OPERAND, 11, 12),
+    ]);
+  }
+
+  test_and_left_implicitCast_fromLiteral() async {
+    await assertErrorsInCode('''
+bool f(List<int> left, bool right) {
+  return left && right;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_OPERAND, 46, 4),
+    ]);
+  }
+
+  test_and_left_implicitCast_fromSupertype() async {
+    await assertNoErrorsInCode('''
+bool f(Object left, bool right) {
+  return left && right;
+}
+''');
+  }
+
   test_and_right() async {
     await assertErrorsInCode(r'''
 bool f(bool left, String right) {
@@ -82,3 +111,17 @@
     ]);
   }
 }
+
+@reflectiveTest
+class NonBoolOperandWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_and() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  if(a && true) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_OPERAND, 25, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
index d81a21a..d968410 100644
--- a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NotIterableSpreadTest);
     defineReflectiveTests(NotIterableSpreadWithoutNullSafetyTest);
+    defineReflectiveTests(NotIterableSpreadWithStrictCastsTest);
   });
 }
 
@@ -112,3 +113,27 @@
 @reflectiveTest
 class NotIterableSpreadWithoutNullSafetyTest extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, NotIterableSpreadTestCases {}
+
+@reflectiveTest
+class NotIterableSpreadWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_list() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  [...a];
+}
+''', [
+      error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 26, 1),
+    ]);
+  }
+
+  test_set() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  <int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 31, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
index 3c008f9..aa8cf06 100644
--- a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NotMapSpreadTest);
     defineReflectiveTests(NotMapSpreadWithoutNullSafetyTest);
+    defineReflectiveTests(NotMapSpreadWithStrictCastsTest);
   });
 }
 
@@ -102,3 +103,17 @@
 @reflectiveTest
 class NotMapSpreadWithoutNullSafetyTest extends PubPackageResolutionTest
     with NotMapSpreadTestCases, WithoutNullSafetyMixin {}
+
+@reflectiveTest
+class NotMapSpreadWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_map() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  <int, String>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.NOT_MAP_SPREAD, 39, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
index 89bab3f..1a11708 100644
--- a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ReturnOfInvalidTypeTest);
-    defineReflectiveTests(ReturnOfInvalidTypeWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        ReturnOfInvalidTypeWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(ReturnOfInvalidTypeWithoutNullSafetyTest);
+    defineReflectiveTests(ReturnOfInvalidTypeWithStrictCastsTest);
   });
 }
 
@@ -234,6 +236,15 @@
 ''');
   }
 
+  test_function_asyncStar() async {
+    await assertErrorsInCode('''
+Stream<int> f() async* => 3;
+''', [
+      // RETURN_OF_INVALID_TYPE shouldn't be reported in addition to this error.
+      error(CompileTimeErrorCode.RETURN_IN_GENERATOR, 23, 2),
+    ]);
+  }
+
   test_function_sync_block__to_dynamic() async {
     await assertNoErrorsInCode(r'''
 f() {
@@ -430,6 +441,15 @@
     ]);
   }
 
+  test_function_syncStar() async {
+    await assertErrorsInCode('''
+Iterable<int> f() sync* => 3;
+''', [
+      // RETURN_OF_INVALID_TYPE shouldn't be reported in addition to this error.
+      error(CompileTimeErrorCode.RETURN_IN_GENERATOR, 24, 2),
+    ]);
+  }
+
   test_getter_sync_block_String__to_int() async {
     await assertErrorsInCode('''
 int get g {
@@ -529,7 +549,7 @@
 }
 
 @reflectiveTest
-class ReturnOfInvalidTypeWithNoImplicitCastsTest
+class ReturnOfInvalidTypeWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_return() async {
@@ -553,3 +573,25 @@
 @reflectiveTest
 class ReturnOfInvalidTypeWithoutNullSafetyTest extends PubPackageResolutionTest
     with ReturnOfInvalidTypeTestCases, WithoutNullSafetyMixin {}
+
+@reflectiveTest
+class ReturnOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_return() async {
+    await assertErrorsWithStrictCasts('''
+int f(dynamic a) => a;
+''', [
+      error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 20, 1),
+    ]);
+  }
+
+  test_return_async() async {
+    await assertErrorsWithStrictCasts('''
+Future<int> f(dynamic a) async {
+  return a;
+}
+''', [
+      error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 42, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
index a74f2cc..d5cb62b 100644
--- a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(SetElementTypeNotAssignableTest);
-    defineReflectiveTests(SetElementTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        SetElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(SetElementTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(SetElementTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -198,7 +200,7 @@
 }
 
 @reflectiveTest
-class SetElementTypeNotAssignableWithNoImplicitCastsTest
+class SetElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_dynamic() async {
@@ -256,3 +258,37 @@
 class SetElementTypeNotAssignableWithoutNullSafetyTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, SetElementTypeNotAssignableTestCases {}
+
+@reflectiveTest
+class SetElementTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>{if (c) 0 else a};
+}
+''', [
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 50, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>{if (c) a};
+}
+''', [
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 43, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Iterable<dynamic> a) {
+  <int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 41, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
index 6e19801..63d6735 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
@@ -154,7 +154,18 @@
 import 'dart:ffi';
 class C implements Double {}
 ''', [
-      error(FfiCode.SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS, 38, 6),
+      error(FfiCode.SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS, 38, 6,
+          messageContains: ["class 'C'", "implement 'Double'"]),
+    ]);
+  }
+
+  test_Double_prefixed() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi' as ffi;
+class C implements ffi.Double {}
+''', [
+      error(FfiCode.SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS, 45, 10,
+          messageContains: ["class 'C'", "implement 'ffi.Double'"]),
     ]);
   }
 
@@ -285,7 +296,20 @@
 ''', [
       error(CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR, 32, 6),
       error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 32, 6),
-      error(FfiCode.SUBTYPE_OF_FFI_CLASS_IN_WITH, 32, 6),
+      error(FfiCode.SUBTYPE_OF_FFI_CLASS_IN_WITH, 32, 6,
+          messageContains: ["class 'C'", "mix in 'Double'"]),
+    ]);
+  }
+
+  test_Double_prefixed() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi' as ffi;
+class C with ffi.Double {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR, 39, 10),
+      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 39, 10),
+      error(FfiCode.SUBTYPE_OF_FFI_CLASS_IN_WITH, 39, 10,
+          messageContains: ["class 'C'", "mix in 'ffi.Double'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
index 026be64..969c1be 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
@@ -52,7 +52,22 @@
 class C implements S {}
 ''', [
       error(FfiCode.EMPTY_STRUCT, 25, 1),
-      error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 64, 1),
+      error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 64, 1,
+          messageContains: ["class 'C'", "implement 'S'"]),
+    ]);
+  }
+
+  test_implements_struct_prefixed() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+import 'dart:ffi';
+class S extends Struct {}
+''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' as lib1;
+class C implements lib1.S {}
+''', [
+      error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 47, 6,
+          messageContains: ["class 'C'", "implement 'lib1.S'"]),
     ]);
   }
 
@@ -78,7 +93,24 @@
 ''', [
       error(FfiCode.EMPTY_STRUCT, 25, 1),
       error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 58, 1),
-      error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_WITH, 58, 1),
+      error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_WITH, 58, 1,
+          messageContains: ["class 'C'", "mix in 'S'"]),
+    ]);
+  }
+
+  test_with_struct_prefixed() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+import 'dart:ffi';
+class S extends Struct {}
+''');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' as lib1;
+
+class C with lib1.S {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 42, 6),
+      error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_WITH, 42, 6,
+          messageContains: ["class 'C'", "mix in 'lib1.S'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart b/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart
index 321b5e8..ca2e979 100644
--- a/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_in_invalid_context_test.dart
@@ -77,7 +77,7 @@
     ]);
   }
 
-  test_constructorFieldInitializer() async {
+  test_constructorInitializer_field() async {
     await assertErrorsInCode(r'''
 class A {
   m() {}
@@ -91,6 +91,37 @@
     ]);
   }
 
+  test_constructorInitializer_super() async {
+    await assertErrorsInCode(r'''
+class S {
+  final int f;
+  S(this.f);
+}
+
+class C extends S {
+  C() : super(super.f);
+}
+''', [
+      error(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, 75, 5),
+    ]);
+  }
+
+  test_constructorInitializer_this() async {
+    await assertErrorsInCode(r'''
+class S {
+  final int f;
+  S(this.f);
+}
+
+class C extends S {
+  C() : this.other(super.f);
+  C.other(int a) : super(a);
+}
+''', [
+      error(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, 80, 5),
+    ]);
+  }
+
   test_extension_field_static() async {
     await assertErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
index 9fafaa1..c58d414 100644
--- a/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
@@ -33,7 +33,6 @@
   A.name() {}
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 18, 5),
       error(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, 18, 7),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart b/pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
similarity index 66%
rename from pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart
rename to pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
index 078fecf..6924087 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
@@ -9,19 +9,19 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(InvalidSuperInvocationTest);
+    defineReflectiveTests(SuperInvocationNotLastTest);
   });
 }
 
 @reflectiveTest
-class InvalidSuperInvocationTest extends PubPackageResolutionTest {
+class SuperInvocationNotLastTest extends PubPackageResolutionTest {
   test_superBeforeAssert() async {
     await assertErrorsInCode(r'''
 class A {
   A(int? x) : super(), assert(x != null);
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 24, 5),
+      error(CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, 24, 5),
     ]);
   }
 
@@ -32,7 +32,16 @@
   A() : super(), x = 1;
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 33, 5),
+      error(CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, 33, 5),
     ]);
   }
+
+  test_superIsLast() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final int x;
+  A() : x = 1, super();
+}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 0331a23..4456cef 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -4,6 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'abi_specific_integer_mapping_test.dart' as abi_specific_integer_mapping;
 import 'abstract_class_member_test.dart' as abstract_class_member;
 import 'abstract_field_constructor_initializer_test.dart'
     as abstract_field_constructor_initializer;
@@ -344,7 +345,6 @@
     as invalid_required_positional_param;
 import 'invalid_sealed_annotation_test.dart' as invalid_sealed_annotation;
 import 'invalid_super_in_initializer_test.dart' as invalid_super_in_initializer;
-import 'invalid_super_invocation_test.dart' as invalid_super_invocation;
 import 'invalid_type_argument_in_const_list_test.dart'
     as invalid_type_argument_in_const_list;
 import 'invalid_type_argument_in_const_map_test.dart'
@@ -354,6 +354,7 @@
 import 'invalid_uri_test.dart' as invalid_uri;
 import 'invalid_use_of_covariant_in_extension_test.dart'
     as invalid_use_of_covariant_in_extension;
+import 'invalid_use_of_covariant_test.dart' as invalid_use_of_covariant;
 import 'invalid_use_of_internal_member_test.dart'
     as invalid_use_of_internal_member;
 import 'invalid_use_of_protected_member_test.dart'
@@ -624,6 +625,7 @@
 import 'super_in_redirecting_constructor_test.dart'
     as super_in_redirecting_constructor;
 import 'super_initializer_in_object_test.dart' as super_initializer_in_object;
+import 'super_invocation_not_last_test.dart' as super_invocation_not_last;
 import 'switch_case_completes_normally_test.dart'
     as switch_case_completes_normally;
 import 'switch_expression_not_assignable_test.dart'
@@ -720,6 +722,7 @@
 
 main() {
   defineReflectiveSuite(() {
+    abi_specific_integer_mapping.main();
     abstract_class_member.main();
     abstract_field_constructor_initializer.main();
     abstract_field_initializer.main();
@@ -947,11 +950,11 @@
     invalid_required_positional_param.main();
     invalid_sealed_annotation.main();
     invalid_super_in_initializer.main();
-    invalid_super_invocation.main();
     invalid_type_argument_in_const_list.main();
     invalid_type_argument_in_const_map.main();
     invalid_type_argument_in_const_set.main();
     invalid_uri.main();
+    invalid_use_of_covariant.main();
     invalid_use_of_covariant_in_extension.main();
     invalid_use_of_internal_member.main();
     invalid_use_of_protected_member.main();
@@ -1130,6 +1133,7 @@
     super_in_invalid_context.main();
     super_in_redirecting_constructor.main();
     super_initializer_in_object.main();
+    super_invocation_not_last.main();
     switch_case_completes_normally.main();
     switch_expression_not_assignable.main();
     tearoff_of_generative_constructor_of_abstract_class.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart b/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
index c622fb0..b432e45 100644
--- a/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
@@ -25,7 +25,8 @@
 class C<T> { const C(); }
 @C<a.D>() main () {}
 ''', [
-      error(CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS, 77, 3),
+      error(CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS, 77, 3,
+          messageContains: ["'a.D'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_constructor_in_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_constructor_in_initializer_test.dart
index b951089..daee2e5 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_constructor_in_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_constructor_in_initializer_test.dart
@@ -22,7 +22,8 @@
   B() : super.named();
 }
 ''', [
-      error(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, 39, 13),
+      error(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, 39, 13,
+          messageContains: ["class 'A'", "named 'named'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index d97a894..a577c7f 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -36,7 +36,8 @@
 class T {}
 f(T e1) { e1.m = 0; }
 ''', [
-      error(CompileTimeErrorCode.UNDEFINED_SETTER, 24, 1),
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 24, 1,
+          messageContains: ["the type 'T'"]),
     ]);
   }
 
@@ -99,7 +100,8 @@
 f(var p) {
   f(C.s = 1);
 }''', [
-      error(CompileTimeErrorCode.UNDEFINED_SETTER, 75, 1),
+      error(CompileTimeErrorCode.UNDEFINED_SETTER, 75, 1,
+          messageContains: ["type 'C'"]),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
index 8eec4b2..44ea839 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
@@ -1651,7 +1651,7 @@
   yield* x;
 }
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 37, 1),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 37, 1),
       error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE_IN_YIELD_EACH,
           37, 1),
     ]);
diff --git a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
index ddb8c9c..e064365 100644
--- a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(YieldOfInvalidTypeTest);
     defineReflectiveTests(YieldOfInvalidTypeWithoutNullSafetyTest);
+    defineReflectiveTests(YieldOfInvalidTypeWithStrictCastsTest);
   });
 }
 
@@ -39,7 +40,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, 0, 3),
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 25, 1),
     ]);
   }
 
@@ -58,7 +58,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, 0, 13),
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 35, 1),
     ]);
   }
 
@@ -140,7 +139,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, 0, 3),
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 24, 1),
     ]);
   }
 
@@ -198,7 +196,6 @@
 }
 ''', [
       error(CompileTimeErrorCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, 0, 11),
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 32, 1),
     ]);
   }
 
@@ -246,7 +243,7 @@
   yield* 0;
 }
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 22, 1),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 22, 1),
     ]);
   }
 
@@ -257,7 +254,7 @@
   yield* a;
 }
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 41, 1),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 41, 1),
     ]);
   }
 
@@ -268,7 +265,7 @@
   yield* a;
 }
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 53, 1),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 53, 1),
     ]);
   }
 
@@ -279,7 +276,7 @@
   yield* a;
 }
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 56, 1),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 56, 1),
     ]);
   }
 
@@ -303,7 +300,7 @@
 Stream g() => throw 0;
 ''',
         expectedErrorsByNullability(nullable: [
-          error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 34, 3),
+          error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 34, 3),
         ], legacy: []));
   }
 
@@ -335,7 +332,7 @@
 
 Stream<String> g() => throw 0;
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 34, 3),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 34, 3),
     ]);
   }
 
@@ -375,7 +372,7 @@
   yield* 0;
 }
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 21, 1),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 21, 1),
     ]);
   }
 
@@ -388,7 +385,7 @@
   f;
 }
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 41, 1),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 41, 1),
     ]);
   }
 
@@ -412,7 +409,7 @@
 Iterable g() => throw 0;
 ''',
         expectedErrorsByNullability(nullable: [
-          error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 35, 3),
+          error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 35, 3),
         ], legacy: []));
   }
 
@@ -444,7 +441,7 @@
 
 Iterable<String> g() => throw 0;
 ''', [
-      error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 35, 3),
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 35, 3),
     ]);
   }
 }
@@ -452,3 +449,27 @@
 @reflectiveTest
 class YieldOfInvalidTypeWithoutNullSafetyTest extends PubPackageResolutionTest
     with YieldOfInvalidTypeTestCases, WithoutNullSafetyMixin {}
+
+@reflectiveTest
+class YieldOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_yieldEach_asyncStar() async {
+    await assertErrorsWithStrictCasts('''
+f(dynamic a) async* {
+  yield* a;
+}
+''', [
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 31, 1),
+    ]);
+  }
+
+  test_yieldEach_syncStar() async {
+    await assertErrorsWithStrictCasts('''
+f(dynamic a) sync* {
+  yield* a;
+}
+''', [
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 30, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
index 4212464..5beaead 100644
--- a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
+++ b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
@@ -488,6 +488,29 @@
     expect(result.value!.toIntValue(), 3);
   }
 
+  test_hasValue_constantReference() async {
+    await resolve('''
+const a = 42;
+var x = a;
+''');
+    var result = _evaluateX();
+    expect(result.errors, isEmpty);
+    expect(result.value!.toIntValue(), 42);
+  }
+
+  test_hasValue_constantReference_imported() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+const a = 42;
+''');
+    await resolve('''
+import 'a.dart';
+var x = a;
+''');
+    var result = _evaluateX();
+    expect(result.errors, isEmpty);
+    expect(result.value!.toIntValue(), 42);
+  }
+
   test_hasValue_intLiteral() async {
     await resolve('''
 var x = 42;
diff --git a/pkg/analyzer/test/src/lint/pub_test.dart b/pkg/analyzer/test/src/lint/pub_test.dart
index 4e71879..db3a2d0 100644
--- a/pkg/analyzer/test/src/lint/pub_test.dart
+++ b/pkg/analyzer/test/src/lint/pub_test.dart
@@ -27,6 +27,13 @@
       name: transmogrify
       url: http://your-package-server.com
     version: '>=0.4.0 <1.0.0'
+  transmogrify_optional_name:
+    hosted:
+      url: http://your-package-server.com
+    version: '>=0.4.0 <1.0.0'
+  transmogrify_short_form:
+    hosted: http://your-package-server.com
+    version: '>=0.4.0 <1.0.0'
   analyzer: '0.24.0-dev.1'
   cli_util: '>=0.0.1 <0.1.0'
   semver: '>=0.2.0 <0.3.0'
@@ -43,6 +50,8 @@
   unittest: '>=0.11.0 <0.12.0'
 dependency_overrides:
   foo: 1.2.0
+repository: https://github.com/dart-lang/linter
+issue_tracker: https://github.com/dart-lang/linter/issues
 """;
 
   Pubspec ps = Pubspec.parse(src);
@@ -65,6 +74,10 @@
       });
       testValue('homepage', ps.homepage,
           equals('https://github.com/dart-lang/linter'));
+      testValue('repository', ps.repository,
+          equals('https://github.com/dart-lang/linter'));
+      testValue('issue_tracker', ps.issueTracker,
+          equals('https://github.com/dart-lang/linter/issues'));
       testValue(
           'description', ps.description, equals('Style linter for Dart.'));
       testValue('version', ps.version, equals('0.0.1'));
@@ -108,6 +121,26 @@
         testValueSpan('name', host.name, startOffset: 243, endOffset: 255);
       });
 
+      group('hosted (optional name)', () {
+        PSDependency dep =
+            findDependency(ps.dependencies, name: 'transmogrify_optional_name');
+        PSHost host = dep.host!;
+        test('name', () => expect(host.name, isNull));
+        testValue('url', host.url, equals('http://your-package-server.com'));
+        testKeySpan('url', host.url, startOffset: 376, endOffset: 379);
+        testValueSpan('url', host.url, startOffset: 381, endOffset: 411);
+      });
+
+      group('hosted (short-form)', () {
+        PSDependency dep =
+            findDependency(ps.dependencies, name: 'transmogrify_short_form');
+        PSHost host = dep.host!;
+        test('name', () => expect(host.name, isNull));
+        testValue('url', host.url, equals('http://your-package-server.com'));
+        testKeySpan('url', host.url, startOffset: 473, endOffset: 479);
+        testValueSpan('url', host.url, startOffset: 481, endOffset: 511);
+      });
+
       group('git', () {
         PSDependency dep = findDependency(ps.dependencies, name: 'kittens');
         PSGitRepo git = dep.git!;
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart
index 17908dd..357ca89 100644
--- a/pkg/analyzer/test/src/services/available_declarations_test.dart
+++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -914,6 +914,75 @@
     ]);
   }
 
+  /// https://github.com/dart-lang/sdk/issues/47804
+  test_updated_exported2() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+
+    newFile(a, content: r'''
+class A {}
+''');
+    newFile(b, content: r'''
+class B {}
+''');
+    newFile(c, content: r'''
+export 'a.dart';
+export 'b.dart';
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+    ]);
+
+    changes.clear();
+
+    newFile(a, content: r'''
+class A2 {}
+''');
+    newFile(b, content: r'''
+class B2 {}
+''');
+    tracker.changeFile(a);
+    tracker.changeFile(b);
+    await _doAllTrackerWork();
+
+    // In general it is OK to get duplicate libraries.
+    // But here we notified about both `a.dart` and `b.dart` changes before
+    // performing any work. So, there is no reason do handle `c.dart` twice.
+    var uniquePathSet = <String>{};
+    for (var change in changes) {
+      for (var library in change.changed) {
+        if (!uniquePathSet.add(library.path)) {
+          fail('Not unique path: ${library.path}');
+        }
+      }
+    }
+
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('A2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+    ]);
+  }
+
   test_updated_library() async {
     var a = convertPath('/home/test/lib/a.dart');
     var b = convertPath('/home/test/lib/b.dart');
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
index fb3b7b8a..901d10f 100644
--- a/pkg/analyzer/test/src/source/source_resource_test.dart
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -83,6 +83,7 @@
     expect(source2.hashCode, source1.hashCode);
   }
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   void test_isInSystemLibrary_contagious() {
     DartSdk sdk = _createSdk();
     UriResolver resolver = DartUriResolver(sdk);
@@ -95,6 +96,7 @@
     expect(partSource.isInSystemLibrary, isTrue);
   }
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   void test_isInSystemLibrary_false() {
     File file = getFile("/does/not/exist.dart");
     FileSource source = FileSource(file);
@@ -159,7 +161,7 @@
     FileSource source = FileSource(file, Uri.parse("dart:core"));
     expect(source, isNotNull);
     expect(source.fullName, file.path);
-    expect(source.isInSystemLibrary, isTrue);
+    expect(source.uri.toString(), 'dart:core');
   }
 
   DartSdk _createSdk() {
diff --git a/pkg/analyzer/test/src/summary/in_summary_source_test.dart b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
index 570ebce..2e8ef04 100644
--- a/pkg/analyzer/test/src/summary/in_summary_source_test.dart
+++ b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 11f3116..3f5806f 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -1036,8 +1036,7 @@
   @override
   void visitNamedType(NamedType node) {
     _writeNextCodeLine(node);
-    // TODO(scheglov) Change to NamedType.
-    _writeln('TypeName');
+    _writeln('NamedType');
     _withIndent(() {
       _writeNode('name', node.name);
       _writeType('type', node.type);
@@ -1439,8 +1438,7 @@
     _writeln('TypeLiteral');
     _withIndent(() {
       var properties = _Properties();
-      // TODO(scheglov) Change to 'type'.
-      properties.addNode('typeName', node.type);
+      properties.addNode('type', node.type);
       _addExpression(properties, node);
       _writeProperties(properties);
     });
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index b1f2a75..6378283 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -13,11 +13,13 @@
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/util/uri.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'element_text.dart';
@@ -60,7 +62,7 @@
     for (var sdkLibrary in sdk.sdkLibraries) {
       var source = sourceFactory.resolveUri(null, sdkLibrary.shortName)!;
       var text = getFile(source.fullName).readAsStringSync();
-      var unit = parseText(text, featureSet);
+      var unit = parseText(source, text, featureSet);
 
       var inputUnits = <LinkInputUnit>[];
       _addLibraryUnits(source, unit, inputUnits, featureSet);
@@ -143,7 +145,7 @@
       );
     }
 
-    return elementFactory.libraryOfUri('${source.uri}')!;
+    return elementFactory.libraryOfUri2('${source.uri}');
   }
 
   void setUp() {
@@ -178,7 +180,7 @@
 
         if (partSource != null) {
           var text = _readSafely(partSource.fullName);
-          var unit = parseText(text, featureSet);
+          var unit = parseText(partSource, text, featureSet);
           units.add(
             LinkInputUnit(
               partDirectiveIndex: partDirectiveIndex,
@@ -196,16 +198,14 @@
   void _addNonDartLibraries(
     Set<Source> addedLibraries,
     List<LinkInputLibrary> libraries,
-    Source? source,
+    Source source,
   ) {
-    if (source == null ||
-        source.uri.isScheme('dart') ||
-        !addedLibraries.add(source)) {
+    if (source.uri.isScheme('dart') || !addedLibraries.add(source)) {
       return;
     }
 
     var text = _readSafely(source.fullName);
-    var unit = parseText(text, featureSet);
+    var unit = parseText(source, text, featureSet);
 
     var units = <LinkInputUnit>[];
     _addLibraryUnits(source, unit, units, featureSet);
@@ -217,8 +217,29 @@
     );
 
     void addRelativeUriStr(StringLiteral uriNode) {
-      var uriStr = uriNode.stringValue;
-      var uriSource = sourceFactory.resolveUri(source, uriStr);
+      var relativeUriStr = uriNode.stringValue;
+      if (relativeUriStr == null) {
+        return;
+      }
+
+      Uri relativeUri;
+      try {
+        relativeUri = Uri.parse(relativeUriStr);
+      } on FormatException {
+        return;
+      }
+
+      var absoluteUri = resolveRelativeUri(source.uri, relativeUri);
+      var rewrittenUri = rewriteFileToPackageUri(sourceFactory, absoluteUri);
+      if (rewrittenUri == null) {
+        return;
+      }
+
+      var uriSource = sourceFactory.forUri2(rewrittenUri);
+      if (uriSource == null) {
+        return;
+      }
+
       _addNonDartLibraries(addedLibraries, libraries, uriSource);
     }
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 25f182d..bdfa95c 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -72,8 +72,7 @@
 
   Source addSource(String path, String contents) {
     var file = newFile(path, content: contents);
-    var fileSource = file.createSource();
-    var uri = sourceFactory.restoreUri(fileSource)!;
+    var uri = sourceFactory.pathToUri(file.path)!;
     return sourceFactory.forUri2(uri)!;
   }
 
@@ -6187,7 +6186,7 @@
               staticType: num
               token: a @27
             staticType: int
-            type: TypeName
+            type: NamedType
               name: SimpleIdentifier
                 staticElement: dart:core::@class::int
                 staticType: null
@@ -6399,7 +6398,7 @@
               staticElement: ConstructorMember
                 base: self::@class::C::@constructor::•
                 substitution: {T: int}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -6429,7 +6428,7 @@
               staticElement: ConstructorMember
                 base: self::@class::C::@constructor::named
                 substitution: {T: int}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -6486,7 +6485,7 @@
                 token: named @37
               period: . @36
               staticElement: self::@class::A::@constructor::named
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::A
                   staticType: null
@@ -6583,7 +6582,7 @@
               int
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -6717,7 +6716,7 @@
                   staticElement: ConstructorMember
                     base: self::@class::P1::@constructor::•
                     substitution: {T: dynamic}
-                  type: TypeName
+                  type: NamedType
                     name: SimpleIdentifier
                       staticElement: self::@class::P1
                       staticType: null
@@ -6732,7 +6731,7 @@
                   staticElement: ConstructorMember
                     base: self::@class::P2::@constructor::•
                     substitution: {T: int}
-                  type: TypeName
+                  type: NamedType
                     name: SimpleIdentifier
                       staticElement: self::@class::P2
                       staticType: null
@@ -6740,7 +6739,7 @@
                     type: P2<int>
                     typeArguments: TypeArgumentList
                       arguments
-                        TypeName
+                        NamedType
                           name: SimpleIdentifier
                             staticElement: dart:core::@class::int
                             staticType: null
@@ -7029,7 +7028,7 @@
               staticElement: ConstructorMember
                 base: self::@class::C::@constructor::named
                 substitution: {K: int, V: String}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -7037,13 +7036,13 @@
                 type: C<int, String>
                 typeArguments: TypeArgumentList
                   arguments
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::int
                         staticType: null
                         token: int @63
                       type: int
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::String
                         staticType: null
@@ -7099,7 +7098,7 @@
               staticElement: ConstructorMember
                 base: a.dart::@class::C::@constructor::named
                 substitution: {K: int, V: String}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: a.dart::@class::C
                   staticType: null
@@ -7107,13 +7106,13 @@
                 type: C<int, String>
                 typeArguments: TypeArgumentList
                   arguments
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::int
                         staticType: null
                         token: int @35
                       type: int
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::String
                         staticType: null
@@ -7169,7 +7168,7 @@
               staticElement: ConstructorMember
                 base: a.dart::@class::C::@constructor::named
                 substitution: {K: int, V: String}
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: a.dart::@class::C
@@ -7185,13 +7184,13 @@
                 type: C<int, String>
                 typeArguments: TypeArgumentList
                   arguments
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::int
                         staticType: null
                         token: int @42
                       type: int
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::String
                         staticType: null
@@ -7238,7 +7237,7 @@
               staticElement: ConstructorMember
                 base: self::@class::C::@constructor::•
                 substitution: {K: dynamic, V: dynamic}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -7283,7 +7282,7 @@
               staticElement: ConstructorMember
                 base: self::@class::C::@constructor::•
                 substitution: {K: int, V: String}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -7291,13 +7290,13 @@
                 type: C<int, String>
                 typeArguments: TypeArgumentList
                   arguments
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::int
                         staticType: null
                         token: int @49
                       type: int
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::String
                         staticType: null
@@ -7340,7 +7339,7 @@
               staticElement: ConstructorMember
                 base: a.dart::@class::C::@constructor::•
                 substitution: {K: int, V: String}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: a.dart::@class::C
                   staticType: null
@@ -7348,13 +7347,13 @@
                 type: C<int, String>
                 typeArguments: TypeArgumentList
                   arguments
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::int
                         staticType: null
                         token: int @35
                       type: int
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::String
                         staticType: null
@@ -7397,7 +7396,7 @@
               staticElement: ConstructorMember
                 base: a.dart::@class::C::@constructor::•
                 substitution: {K: int, V: String}
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: a.dart::@class::C
@@ -7413,13 +7412,13 @@
                 type: C<int, String>
                 typeArguments: TypeArgumentList
                   arguments
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::int
                         staticType: null
                         token: int @42
                       type: int
-                    TypeName
+                    NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::String
                         staticType: null
@@ -7504,7 +7503,7 @@
                 token: named @91
               period: . @90
               staticElement: self::@class::C::@constructor::named
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -7548,7 +7547,7 @@
                 token: named @35
               period: . @34
               staticElement: a.dart::@class::C::@constructor::named
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: a.dart::@class::C
                   staticType: null
@@ -7592,7 +7591,7 @@
                 token: named @42
               period: . @41
               staticElement: a.dart::@class::C::@constructor::named
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: a.dart::@class::C
@@ -7641,7 +7640,7 @@
                 token: named @29
               period: . @28
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -7672,7 +7671,7 @@
               rightParenthesis: ) @24
             constructorName: ConstructorName
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: <null>
@@ -7723,7 +7722,7 @@
                 token: named @42
               period: . @41
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: a.dart::@class::C
@@ -7771,7 +7770,7 @@
                 token: named @42
               period: . @41
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: <null>
@@ -7815,7 +7814,7 @@
                 token: named @20
               period: . @19
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: <null>
@@ -7867,7 +7866,7 @@
                 token: named @32
               period: . @31
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -7905,7 +7904,7 @@
               rightParenthesis: ) @43
             constructorName: ConstructorName
               staticElement: self::@class::C::@constructor::•
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -7944,7 +7943,7 @@
               rightParenthesis: ) @35
             constructorName: ConstructorName
               staticElement: a.dart::@class::C::@constructor::•
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: a.dart::@class::C
                   staticType: null
@@ -7983,7 +7982,7 @@
               rightParenthesis: ) @42
             constructorName: ConstructorName
               staticElement: a.dart::@class::C::@constructor::•
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: a.dart::@class::C
@@ -8022,7 +8021,7 @@
               rightParenthesis: ) @18
             constructorName: ConstructorName
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: <null>
                   staticType: null
@@ -8057,7 +8056,7 @@
               rightParenthesis: ) @42
             constructorName: ConstructorName
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: <null>
@@ -8096,7 +8095,7 @@
               rightParenthesis: ) @20
             constructorName: ConstructorName
               staticElement: <null>
-              type: TypeName
+              type: NamedType
                 name: PrefixedIdentifier
                   identifier: SimpleIdentifier
                     staticElement: <null>
@@ -8143,7 +8142,7 @@
               token: a @23
             isOperator: is @25
             staticType: bool
-            type: TypeName
+            type: NamedType
               name: SimpleIdentifier
                 staticElement: dart:core::@class::int
                 staticType: null
@@ -8509,7 +8508,7 @@
             staticType: List<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -8552,7 +8551,7 @@
             staticType: List<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -8620,7 +8619,7 @@
                   staticType: List<int>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
@@ -8634,7 +8633,7 @@
             staticType: List<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -8673,7 +8672,7 @@
                   staticType: List<int>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
@@ -8687,7 +8686,7 @@
             staticType: List<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -8732,13 +8731,13 @@
             staticType: Map<int, int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
                     token: int @24
                   type: int
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -8828,13 +8827,13 @@
                   staticType: Map<int, int>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
                           token: int @38
                         type: int
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
@@ -8849,13 +8848,13 @@
             staticType: Map<int, int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
                     token: int @24
                   type: int
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -8899,13 +8898,13 @@
                   staticType: Map<int, int>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
                           token: int @39
                         type: int
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
@@ -8920,13 +8919,13 @@
             staticType: Map<int, int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
                     token: int @24
                   type: int
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -8970,7 +8969,7 @@
               int
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -10345,7 +10344,7 @@
             staticType: Set<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -10426,7 +10425,7 @@
                   staticType: Set<int>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
@@ -10441,7 +10440,7 @@
             staticType: Set<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -10481,7 +10480,7 @@
                   staticType: Set<int>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
@@ -10496,7 +10495,7 @@
             staticType: Set<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -11495,7 +11494,7 @@
             staticType: List<Null>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::Null
                     staticType: null
@@ -11523,7 +11522,7 @@
             staticType: List<dynamic>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dynamic@-1
                     staticType: null
@@ -11551,7 +11550,7 @@
             staticType: List<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -11569,7 +11568,7 @@
             staticType: List<List<dynamic>>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::List
                     staticType: null
@@ -11587,7 +11586,7 @@
             staticType: List<List<String>>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::List
                     staticType: null
@@ -11595,7 +11594,7 @@
                   type: List<String>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::String
                           staticType: null
@@ -11615,7 +11614,7 @@
             staticType: List<Map<int, List<String>>>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::Map
                     staticType: null
@@ -11623,13 +11622,13 @@
                   type: Map<int, List<String>>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::int
                           staticType: null
                           token: int @288
                         type: int
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::List
                           staticType: null
@@ -11637,7 +11636,7 @@
                         type: List<String>
                         typeArguments: TypeArgumentList
                           arguments
-                            TypeName
+                            NamedType
                               name: SimpleIdentifier
                                 staticElement: dart:core::@class::String
                                 staticType: null
@@ -11687,7 +11686,7 @@
             staticType: List<C>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: a.dart::@class::C
                     staticType: null
@@ -11723,7 +11722,7 @@
             staticType: List<C>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: PrefixedIdentifier
                     identifier: SimpleIdentifier
                       staticElement: a.dart::@class::C
@@ -11772,7 +11771,7 @@
             staticType: List<int Function(String)>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: self::@typeAlias::F
                     staticType: null
@@ -11808,13 +11807,13 @@
             staticType: Map<dynamic, int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dynamic@-1
                     staticType: null
                     token: dynamic @25
                   type: dynamic
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -11833,13 +11832,13 @@
             staticType: Map<int, dynamic>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
                     token: int @67
                   type: int
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dynamic@-1
                     staticType: null
@@ -11858,13 +11857,13 @@
             staticType: Map<int, String>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
                     token: int @110
                   type: int
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::String
                     staticType: null
@@ -11883,13 +11882,13 @@
             staticType: Map<int, List<String>>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
                     token: int @169
                   type: int
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::List
                     staticType: null
@@ -11897,7 +11896,7 @@
                   type: List<String>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::String
                           staticType: null
@@ -11940,7 +11939,7 @@
             staticType: Set<dynamic>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dynamic@-1
                     staticType: null
@@ -11959,7 +11958,7 @@
             staticType: Set<int>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -11978,7 +11977,7 @@
             staticType: Set<List<String>>
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::List
                     staticType: null
@@ -11986,7 +11985,7 @@
                   type: List<String>
                   typeArguments: TypeArgumentList
                     arguments
-                      TypeName
+                      NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::String
                           staticType: null
@@ -12126,7 +12125,7 @@
         constantInitializer
           TypeLiteral
             staticType: Type
-            typeName: TypeName
+            type: NamedType
               name: SimpleIdentifier
                 staticElement: dart:core::@class::List
                 staticType: List<int>
@@ -12134,7 +12133,7 @@
               type: List<int>
               typeArguments: TypeArgumentList
                 arguments
-                  TypeName
+                  NamedType
                     name: SimpleIdentifier
                       staticElement: dart:core::@class::int
                       staticType: null
@@ -12608,7 +12607,7 @@
                         staticElement: ConstructorMember
                           base: self::@class::A::@constructor::•
                           substitution: {T: dynamic Function()}
-                        type: TypeName
+                        type: NamedType
                           name: SimpleIdentifier
                             staticElement: self::@class::A
                             staticType: null
@@ -13889,7 +13888,7 @@
                     rightParenthesis: ) @47
                   constructorName: ConstructorName
                     staticElement: self::@class::D::@constructor::•
-                    type: TypeName
+                    type: NamedType
                       name: SimpleIdentifier
                         staticElement: self::@class::D
                         staticType: null
@@ -13919,7 +13918,7 @@
                     rightParenthesis: ) @99
                   constructorName: ConstructorName
                     staticElement: self::@class::C::@constructor::•
-                    type: TypeName
+                    type: NamedType
                       name: SimpleIdentifier
                         staticElement: self::@class::C
                         staticType: null
@@ -14139,7 +14138,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::A::@constructor::•
                         substitution: {T: dynamic Function()}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::A
                           staticType: null
@@ -14187,7 +14186,7 @@
                       staticType: int
                     isOperator: is @16
                     staticType: bool
-                    type: TypeName
+                    type: NamedType
                       name: SimpleIdentifier
                         staticElement: dart:core::@class::int
                         staticType: null
@@ -14306,7 +14305,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T1: int, T2: double}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -14355,7 +14354,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T: Never}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -14414,7 +14413,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T: Never}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -14474,7 +14473,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T: Null*}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -14523,7 +14522,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T: Null*}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -14567,7 +14566,7 @@
                   staticElement: ConstructorMember
                     base: self::@class::B::@constructor::•
                     substitution: {T: Never}
-                  type: TypeName
+                  type: NamedType
                     name: SimpleIdentifier
                       staticElement: self::@class::B
                       staticType: null
@@ -14617,7 +14616,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T: Never}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -14672,7 +14671,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T1: Never, T2: Never}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -14723,7 +14722,7 @@
                       staticElement: ConstructorMember
                         base: self::@class::B::@constructor::•
                         substitution: {T: Never}
-                      type: TypeName
+                      type: NamedType
                         name: SimpleIdentifier
                           staticElement: self::@class::B
                           staticType: null
@@ -16135,7 +16134,7 @@
                   staticElement: ConstructorMember
                     base: self::@class::A::@constructor::•
                     substitution: {T: int Function(double)}
-                  type: TypeName
+                  type: NamedType
                     name: SimpleIdentifier
                       staticElement: self::@class::A
                       staticType: null
@@ -16162,14 +16161,14 @@
                                   staticElement: a@78
                                   staticType: null
                                   token: a @78
-                                type: TypeName
+                                type: NamedType
                                   name: SimpleIdentifier
                                     staticElement: dart:core::@class::double
                                     staticType: null
                                     token: double @71
                                   type: double
                             rightParenthesis: ) @79
-                          returnType: TypeName
+                          returnType: NamedType
                             name: SimpleIdentifier
                               staticElement: dart:core::@class::int
                               staticType: null
@@ -17774,14 +17773,14 @@
                           staticElement: a@52
                           staticType: null
                           token: a @52
-                        type: TypeName
+                        type: NamedType
                           name: SimpleIdentifier
                             staticElement: dart:core::@class::String
                             staticType: null
                             token: String @45
                           type: String
                     rightParenthesis: ) @53
-                  returnType: TypeName
+                  returnType: NamedType
                     name: SimpleIdentifier
                       staticElement: dart:core::@class::int
                       staticType: null
@@ -17850,14 +17849,14 @@
                           staticElement: a@52
                           staticType: null
                           token: a @52
-                        type: TypeName
+                        type: NamedType
                           name: SimpleIdentifier
                             staticElement: dart:core::@class::String
                             staticType: null
                             token: String @45
                           type: String
                     rightParenthesis: ) @53
-                  returnType: TypeName
+                  returnType: NamedType
                     name: SimpleIdentifier
                       staticElement: dart:core::@class::int
                       staticType: null
@@ -17908,7 +17907,7 @@
               staticElement: ConstructorMember
                 base: self::@class::A::@constructor::•
                 substitution: {T: String Function({int? a})}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::A
                   staticType: null
@@ -17942,14 +17941,14 @@
                                 staticElement: a@63
                                 staticType: null
                                 token: a @63
-                              type: TypeName
+                              type: NamedType
                                 name: SimpleIdentifier
                                   staticElement: dart:core::@class::int
                                   staticType: null
                                   token: int @58
                                 type: int?
                         rightParenthesis: ) @65
-                      returnType: TypeName
+                      returnType: NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::String
                           staticType: null
@@ -17995,7 +17994,7 @@
               staticElement: ConstructorMember
                 base: self::@class::A::@constructor::•
                 substitution: {T: String Function([int?])}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::A
                   staticType: null
@@ -18029,14 +18028,14 @@
                                 staticElement: a@63
                                 staticType: null
                                 token: a @63
-                              type: TypeName
+                              type: NamedType
                                 name: SimpleIdentifier
                                   staticElement: dart:core::@class::int
                                   staticType: null
                                   token: int @58
                                 type: int?
                         rightParenthesis: ) @65
-                      returnType: TypeName
+                      returnType: NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::String
                           staticType: null
@@ -18082,7 +18081,7 @@
               staticElement: ConstructorMember
                 base: self::@class::A::@constructor::•
                 substitution: {T: String Function({required int a})}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::A
                   staticType: null
@@ -18117,14 +18116,14 @@
                                 staticType: null
                                 token: a @71
                               requiredKeyword: required @58
-                              type: TypeName
+                              type: NamedType
                                 name: SimpleIdentifier
                                   staticElement: dart:core::@class::int
                                   staticType: null
                                   token: int @67
                                 type: int
                         rightParenthesis: ) @73
-                      returnType: TypeName
+                      returnType: NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::String
                           staticType: null
@@ -18170,7 +18169,7 @@
               staticElement: ConstructorMember
                 base: self::@class::A::@constructor::•
                 substitution: {T: String Function(int)}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::A
                   staticType: null
@@ -18197,14 +18196,14 @@
                               staticElement: a@61
                               staticType: null
                               token: a @61
-                            type: TypeName
+                            type: NamedType
                               name: SimpleIdentifier
                                 staticElement: dart:core::@class::int
                                 staticType: null
                                 token: int @57
                               type: int
                         rightParenthesis: ) @62
-                      returnType: TypeName
+                      returnType: NamedType
                         name: SimpleIdentifier
                           staticElement: dart:core::@class::String
                           staticType: null
@@ -18533,7 +18532,7 @@
                 token: named @67
               period: . @66
               staticElement: self::@class::C::@constructor::named
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -18936,8 +18935,7 @@
   test_import_short_absolute() async {
     testFile = '/my/project/bin/test.dart';
     // Note: "/a.dart" resolves differently on Windows vs. Posix.
-    var destinationPath =
-        resourceProvider.pathContext.fromUri(Uri.parse('/a.dart'));
+    var destinationPath = convertPath('/a.dart');
     addLibrarySource(destinationPath, 'class C {}');
     var library = await checkLibrary('import "/a.dart"; C c;');
     checkElementText(library, r'''
@@ -19108,7 +19106,7 @@
               staticElement: ConstructorMember
                 base: self::@class::C::@constructor::•
                 substitution: {V: int}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -19176,7 +19174,7 @@
               rightParenthesis: ) @114
             constructorName: ConstructorName
               staticElement: self::@class::C::@constructor::•
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::C
                   staticType: null
@@ -22218,7 +22216,7 @@
               token: A @36
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -22274,7 +22272,7 @@
               token: A @36
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -22441,7 +22439,7 @@
               staticType: null
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -22654,7 +22652,7 @@
               token: A @30
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -22798,7 +22796,7 @@
               staticType: null
             typeArguments: TypeArgumentList
               arguments
-                TypeName
+                NamedType
                   name: SimpleIdentifier
                     staticElement: dart:core::@class::int
                     staticType: null
@@ -33883,7 +33881,7 @@
               staticElement: ConstructorMember
                 base: self::@class::A::@constructor::•
                 substitution: {T: int}
-              type: TypeName
+              type: NamedType
                 name: SimpleIdentifier
                   staticElement: self::@class::A
                   staticType: null
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 5632a0a..8d21be1 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -14,22 +14,22 @@
 import 'package:analyzer/src/generated/source.dart';
 
 CompilationUnit parseText(
+  Source source,
   String text,
   FeatureSet featureSet,
 ) {
   CharSequenceReader reader = CharSequenceReader(text);
-  Scanner scanner =
-      Scanner(_SourceMock.instance, reader, AnalysisErrorListener.NULL_LISTENER)
-        ..configureFeatures(
-          featureSetForOverriding: featureSet,
-          featureSet: featureSet,
-        );
+  Scanner scanner = Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER)
+    ..configureFeatures(
+      featureSetForOverriding: featureSet,
+      featureSet: featureSet,
+    );
   Token token = scanner.tokenize();
   // Pass the feature set from the scanner to the parser
   // because the scanner may have detected a language version comment
   // and downgraded the feature set it holds.
   Parser parser = Parser(
-    NonExistingSource.unknown,
+    source,
     AnalysisErrorListener.NULL_LISTENER,
     featureSet: scanner.featureSet,
   );
@@ -43,10 +43,3 @@
 
   return unit;
 }
-
-class _SourceMock implements Source {
-  static final Source instance = _SourceMock();
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index a25a5ac..5a33bcb 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -1906,13 +1906,18 @@
 var fe0 = (int x) => x as dynamic;
 var fe1 = (int x) => x;
 ''', [
-      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 12, 2),
-      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 96, 2),
+      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 12, 2,
+          messageContains: ["'f0'"]),
+      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 96, 2,
+          messageContains: ["'g0'"]),
       error(HintCode.UNUSED_ELEMENT, 96, 2),
       error(HintCode.UNUSED_ELEMENT, 126, 2),
-      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 212, 12),
-      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 304, 2),
-      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 373, 1),
+      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 212, 12,
+          messageContains: ["'m0'"]),
+      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 304, 2,
+          messageContains: ["'y0'"]),
+      error(LanguageCode.IMPLICIT_DYNAMIC_RETURN, 373, 1,
+          messageContains: ["'f'"]),
     ]);
   }
 
@@ -3026,33 +3031,6 @@
     ]);
   }
 
-  test_superCallPlacement() async {
-    await assertErrorsInCode('''
-class Base {
-  var x;
-  Base() : x = 1;
-}
-
-class Derived extends Base {
-  var y, z;
-  Derived() : y = 1, super(), z = 2;
-}
-
-class Valid extends Base {
-  var y, z;
-  Valid(): y = 1, z = 2, super();
-}
-
-class AlsoValid extends Base {
-  AlsoValid() : super();
-}
-
-main() => new Derived();
-''', [
-      error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 105, 5),
-    ]);
-  }
-
   test_superclassOverrideOfGrandInterface_interfaceOfAbstractSuperclass() async {
     await assertErrorsInCode('''
 class A {}
@@ -3411,62 +3389,6 @@
     ]);
   }
 
-  test_unaryOperators() async {
-    await assertErrorsInCode('''
-class A {
-  A operator ~() => null;
-  A operator +(int x) => null;
-  A operator -(int x) => null;
-  A operator -() => null;
-}
-class B extends A {}
-class C extends B {}
-
-foo() => new A();
-
-test() {
-  A a = new A();
-  B b = new B();
-  var c = foo();
-  dynamic d;
-
-  ~a;
-  (~d);
-
-  !a;
-  !d;
-
-  -a;
-  (-d);
-
-  ++a;
-  --a;
-  (++d);
-  (--d);
-
-  a++;
-  a--;
-  (d++);
-  (d--);
-
-  ++b;
-  --b;
-  b++;
-  b--;
-
-  takesC(C c) => null;
-  takesC(++b);
-  takesC(--b);
-  takesC(b++);
-  takesC(b--);
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 201, 1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 237, 1),
-      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 280, 1),
-    ]);
-  }
-
   test_unboundTypeName() async {
     await assertErrorsInCode('''
 void main() {
diff --git a/pkg/analyzer/test/src/workspace/bazel_test.dart b/pkg/analyzer/test/src/workspace/bazel_test.dart
index 88e983e..bdfa730 100644
--- a/pkg/analyzer/test/src/workspace/bazel_test.dart
+++ b/pkg/analyzer/test/src/workspace/bazel_test.dart
@@ -38,6 +38,12 @@
     expect(workspace.isBazel, isTrue);
   }
 
+  void test_pathToUri() {
+    Uri uri = toUri('/workspace/test.dart');
+    var source = resolver.resolveAbsolute(uri)!;
+    expect(resolver.pathToUri(source.fullName), uri);
+  }
+
   void test_resolveAbsolute_doesNotExist() {
     var source = _resolvePath('/workspace/foo.dart')!;
     expect(source.exists(), isFalse);
@@ -79,14 +85,15 @@
     expect(source, isNull);
   }
 
+  @Deprecated('Use pathToUri() instead')
   void test_restoreAbsolute() {
     Uri uri =
         resourceProvider.pathContext.toUri(convertPath('/workspace/test.dart'));
     var source = resolver.resolveAbsolute(uri)!;
     expect(resolver.restoreAbsolute(source), uri);
     expect(
-        resolver.restoreAbsolute(NonExistingSource(source.fullName,
-            Uri.parse('package:test/test.dart'), UriKind.PACKAGE_URI)),
+        resolver.restoreAbsolute(NonExistingSource(
+            source.fullName, Uri.parse('package:test/test.dart'))),
         uri);
   }
 
@@ -538,6 +545,15 @@
         'package:third_party.something/foo.dart');
   }
 
+  void test_restoreAbsolute_workspace_nestedLib() {
+    _addResources([
+      '/workspace/WORKSPACE',
+      '/workspace/my/components/lib/src/foo/lib/foo.dart',
+    ]);
+    _assertRestore('/workspace/my/components/lib/src/foo/lib/foo.dart',
+        'package:my.components.lib.src.foo/foo.dart');
+  }
+
   void _addResources(List<String> paths,
       {String workspacePath = '/workspace'}) {
     for (String path in paths) {
@@ -561,21 +577,25 @@
       {bool exists = true, bool restore = true}) {
     Uri uri = Uri.parse(uriStr);
     var source = resolver.resolveAbsolute(uri)!;
-    expect(source.fullName, convertPath(posixPath));
+    var path = source.fullName;
+    expect(path, convertPath(posixPath));
     expect(source.uri, uri);
     expect(source.exists(), exists);
     // If enabled, test also "restoreAbsolute".
     if (restore) {
-      var uri = resolver.restoreAbsolute(source);
-      expect(uri.toString(), uriStr);
+      expect(resolver.pathToUri(path), uri);
+      // ignore: deprecated_member_use_from_same_package
+      expect(resolver.restoreAbsolute(source), uri);
     }
   }
 
-  void _assertRestore(String posixPath, String? expectedUri) {
+  void _assertRestore(String posixPath, String? expectedUriStr) {
+    var expectedUri = expectedUriStr != null ? Uri.parse(expectedUriStr) : null;
     String path = convertPath(posixPath);
     _MockSource source = _MockSource(path);
-    var uri = resolver.restoreAbsolute(source);
-    expect(uri?.toString(), expectedUri);
+    expect(resolver.pathToUri(path), expectedUri);
+    // ignore: deprecated_member_use_from_same_package
+    expect(resolver.restoreAbsolute(source), expectedUri);
   }
 }
 
diff --git a/pkg/analyzer/test/src/workspace/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
index b7a9650..f262445 100644
--- a/pkg/analyzer/test/src/workspace/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -20,23 +20,25 @@
 
 class MockUriResolver implements UriResolver {
   Map<Uri, File> uriToFile = {};
-  Map<String, Uri> pathToUri = {};
+  Map<String, Uri> pathToUriMap = {};
 
   void add(Uri uri, File file) {
     uriToFile[uri] = file;
-    pathToUri[file.path] = uri;
+    pathToUriMap[file.path] = uri;
   }
 
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
   @override
-  Source? resolveAbsolute(Uri uri) {
-    return uriToFile[uri]?.createSource(uri);
+  Uri? pathToUri(String path) {
+    return pathToUriMap[path];
   }
 
   @override
-  Uri? restoreAbsolute(Source source) => pathToUri[source.fullName];
+  Source? resolveAbsolute(Uri uri) {
+    return uriToFile[uri]?.createSource(uri);
+  }
 }
 
 @reflectiveTest
@@ -61,6 +63,12 @@
     expect(workspace.isBazel, isFalse);
   }
 
+  void test_pathToUri() {
+    var uri = toUri('/workspace/test.dart');
+    var source = resolver.resolveAbsolute(uri)!;
+    expect(resolver.pathToUri(source.fullName), uri);
+  }
+
   void test_resolveAbsolute_doesNotExist() {
     var source = _resolvePath('/workspace/foo.dart')!;
     expect(source, isNotNull);
@@ -98,6 +106,7 @@
     expect(source, isNull);
   }
 
+  @Deprecated('Use pathToUri() instead')
   void test_restoreAbsolute() {
     Uri uri =
         resourceProvider.pathContext.toUri(convertPath('/workspace/test.dart'));
@@ -105,8 +114,8 @@
     expect(source, isNotNull);
     expect(resolver.restoreAbsolute(source), uri);
     expect(
-        resolver.restoreAbsolute(NonExistingSource(source.fullName,
-            Uri.parse('package:test/test.dart'), UriKind.PACKAGE_URI)),
+        resolver.restoreAbsolute(NonExistingSource(
+            source.fullName, Uri.parse('package:test/test.dart'))),
         uri);
   }
 
@@ -207,13 +216,15 @@
   Source _assertResolveUri(Uri uri, String posixPath,
       {bool exists = true, bool restore = true}) {
     var source = resolver.resolveAbsolute(uri)!;
-    expect(source.fullName, convertPath(posixPath));
+    var path = source.fullName;
+    expect(path, convertPath(posixPath));
     expect(source.uri, uri);
     expect(source.exists(), exists);
     // If enabled, test also "restoreAbsolute".
     if (restore) {
-      var restoredUri = resolver.restoreAbsolute(source);
-      expect(restoredUri.toString(), uri.toString());
+      expect(resolver.pathToUri(path), uri);
+      // ignore: deprecated_member_use_from_same_package
+      expect(resolver.restoreAbsolute(source), uri);
     }
     return source;
   }
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index d00d0d5..97d64c9 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -6518,7 +6518,7 @@
 #### Description
 
 The analyzer produces this diagnostic when a package under either
-`dependencies` or `dev_dependencies` is not a pub, `git`, or `path` based
+`dependencies` or `dev_dependencies` isn't a pub, `git`, or `path` based
 dependency.
 
 See [Package dependencies](https://dart.dev/tools/pub/dependencies) for
@@ -6527,7 +6527,7 @@
 #### Example
 
 The following code produces this diagnostic because the dependency on the
-package `transmogrify` is not a pub, `git`, or `path` based dependency:
+package `transmogrify` isn't a pub, `git`, or `path` based dependency:
 
 ```yaml
 name: example
@@ -6968,7 +6968,7 @@
 `isEven` if `s` is `null`. In other words, if `s` is `null`, then neither
 `length` nor `isEven` will be invoked, and if `s` is non-`null`, then
 `length` can't return a `null` value. Either way, `isEven` can't be invoked
-on a `null` value, so the null-aware operator is not necessary. See
+on a `null` value, so the null-aware operator isn't necessary. See
 [Understanding null safety](/null-safety/understanding-null-safety#smarter-null-aware-methods)
 for more details.
 
@@ -7152,46 +7152,6 @@
 }
 {% endprettify %}
 
-### invalid_super_invocation
-
-_The superclass call must be last in an initializer list: '{0}'._
-
-#### Description
-
-The analyzer produces this diagnostic when the initializer list of a
-constructor contains an invocation of a constructor in the superclass, but
-the invocation isn't the last item in the initializer list.
-
-#### Example
-
-The following code produces this diagnostic because the invocation of the
-superclass' constructor isn't the last item in the initializer list:
-
-{% prettify dart tag=pre+code %}
-class A {
-  A(int x);
-}
-
-class B extends A {
-  B(int x) : [!super!](x), assert(x >= 0);
-}
-{% endprettify %}
-
-#### Common fixes
-
-Move the invocation of the superclass' constructor to the end of the
-initializer list:
-
-{% prettify dart tag=pre+code %}
-class A {
-  A(int x);
-}
-
-class B extends A {
-  B(int x) : assert(x >= 0), super(x);
-}
-{% endprettify %}
-
 ### invalid_type_argument_in_const_literal
 
 _Constant list literals can't include a type parameter as a type argument, such
@@ -12846,6 +12806,48 @@
 class C extends Object {}
 {% endprettify %}
 
+### super_invocation_not_last
+
+<a id="invalid_super_invocation" aria-hidden="true"></a>_(Previously known as `invalid_super_invocation`)_
+
+_The superconstructor call must be last in an initializer list: '{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the initializer list of a
+constructor contains an invocation of a constructor in the superclass, but
+the invocation isn't the last item in the initializer list.
+
+#### Example
+
+The following code produces this diagnostic because the invocation of the
+superclass' constructor isn't the last item in the initializer list:
+
+{% prettify dart tag=pre+code %}
+class A {
+  A(int x);
+}
+
+class B extends A {
+  B(int x) : [!super!](x), assert(x >= 0);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Move the invocation of the superclass' constructor to the end of the
+initializer list:
+
+{% prettify dart tag=pre+code %}
+class A {
+  A(int x);
+}
+
+class B extends A {
+  B(int x) : assert(x >= 0), super(x);
+}
+{% endprettify %}
+
 ### super_in_extension
 
 _The 'super' keyword can't be used in an extension because an extension doesn't
@@ -14405,7 +14407,7 @@
 
 ### undefined_referenced_parameter
 
-_The parameter '{0}' is not defined by '{1}'._
+_The parameter '{0}' isn't defined by '{1}'._
 
 #### Description
 
@@ -14511,6 +14513,8 @@
 
 ### undefined_super_member
 
+<a id="undefined_super_method" aria-hidden="true"></a>_(Previously known as `undefined_super_method`)_
+
 _The getter '{0}' isn't defined in a superclass of '{1}'._
 
 _The method '{0}' isn't defined in a superclass of '{1}'._
@@ -15829,14 +15833,17 @@
 
 ### yield_of_invalid_type
 
-_The type '{0}' implied by the 'yield' expression must be assignable to '{1}'._
+_A yielded value of type '{0}' must be assignable to '{1}'._
+
+_The type '{0}' implied by the 'yield*' expression must be assignable to '{1}'._
 
 #### Description
 
-The analyzer produces this diagnostic when the type of object produced by a
-`yield` expression doesn't match the type of objects that are to be
-returned from the `Iterable` or `Stream` types that are returned from a
-generator (a function or method marked with either `sync*` or `async*`).
+The analyzer produces this diagnostic when the type of object produced by
+a `yield` or `yield*` expression doesn't match the type of objects that
+are to be returned from the `Iterable` or `Stream` types that are returned
+from a generator (a function or method marked with either `sync*` or
+`async*`).
 
 #### Example
 
@@ -15869,7 +15876,3 @@
   yield '0';
 }
 {% endprettify %}
-
-### undefined_super_method
-
-See [undefined_super_member](#undefined_super_member).
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index c726a25..9f58663 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -39,6 +39,9 @@
   /// The messages associated with the diagnostic.
   List<String> messages;
 
+  /// The previous names by which this diagnostic has been known.
+  List<String> previousNames = [];
+
   /// The documentation text associated with the diagnostic.
   String? documentation;
 
@@ -56,10 +59,22 @@
     }
   }
 
+  void addPreviousName(String previousName) {
+    if (!previousNames.contains(previousName)) {
+      previousNames.add(previousName);
+    }
+  }
+
   /// Return the full documentation for this diagnostic.
   void writeOn(StringSink sink) {
     messages.sort();
     sink.writeln('### ${name.toLowerCase()}');
+    for (var previousName in previousNames) {
+      sink.writeln();
+      var previousInLowerCase = previousName.toLowerCase();
+      sink.writeln('<a id="$previousInLowerCase" aria-hidden="true"></a>'
+          '_(Previously known as `$previousInLowerCase`)_');
+    }
     for (String message in messages) {
       sink.writeln();
       for (String line in _split('_${_escape(message)}_')) {
@@ -120,7 +135,6 @@
     _writeHeader(sink);
     _writeGlossary(sink);
     _writeDiagnostics(sink);
-    _writeForwards(sink);
   }
 
   /// Extract documentation from all of the files containing the definitions of
@@ -140,6 +154,10 @@
       } else {
         info.addMessage(message);
       }
+      var previousName = errorCodeInfo.previousName;
+      if (previousName != null) {
+        info.addPreviousName(previousName);
+      }
       var docs = _extractDoc('$className.$errorName', errorCodeInfo);
       if (docs.isNotEmpty) {
         if (info.documentation != null) {
@@ -185,17 +203,6 @@
     }
   }
 
-  /// Write the forwarding documentation for all of the diagnostics that have
-  /// been renamed.
-  void _writeForwards(StringSink sink) {
-    sink.write('''
-
-### undefined_super_method
-
-See [undefined_super_member](#undefined_super_member).
-''');
-  }
-
   /// Write the glossary.
   void _writeGlossary(StringSink sink) {
     sink.write(r'''
diff --git a/pkg/analyzer/tool/messages/error_code_info.dart b/pkg/analyzer/tool/messages/error_code_info.dart
index 907a564..e89d24d 100644
--- a/pkg/analyzer/tool/messages/error_code_info.dart
+++ b/pkg/analyzer/tool/messages/error_code_info.dart
@@ -76,7 +76,7 @@
 ];
 
 /// Decoded messages from the analyzer's `messages.yaml` file.
-final Map<String, Map<String, ErrorCodeInfo>> analyzerMessages =
+final Map<String, Map<String, AnalyzerErrorCodeInfo>> analyzerMessages =
     _loadAnalyzerMessages();
 
 /// The path to the `analyzer` package.
@@ -88,7 +88,8 @@
     CfeToAnalyzerErrorCodeTables._(frontEndMessages);
 
 /// Decoded messages from the front end's `messages.yaml` file.
-final Map<String, ErrorCodeInfo> frontEndMessages = _loadFrontEndMessages();
+final Map<String, FrontEndErrorCodeInfo> frontEndMessages =
+    _loadFrontEndMessages();
 
 /// The path to the `front_end` package.
 final String frontEndPkgPath =
@@ -110,13 +111,13 @@
 /// Decodes a YAML object (obtained from `pkg/analyzer/messages.yaml`) into a
 /// two-level map of [ErrorCodeInfo], indexed first by class name and then by
 /// error name.
-Map<String, Map<String, ErrorCodeInfo>> decodeAnalyzerMessagesYaml(
+Map<String, Map<String, AnalyzerErrorCodeInfo>> decodeAnalyzerMessagesYaml(
     Object? yaml) {
   Never problem(String message) {
     throw 'Problem in pkg/analyzer/messages.yaml: $message';
   }
 
-  var result = <String, Map<String, ErrorCodeInfo>>{};
+  var result = <String, Map<String, AnalyzerErrorCodeInfo>>{};
   if (yaml is! Map<Object?, Object?>) {
     problem('root node is not a map');
   }
@@ -142,7 +143,7 @@
       }
       try {
         (result[className] ??= {})[errorName] =
-            ErrorCodeInfo.fromYaml(errorValue);
+            AnalyzerErrorCodeInfo.fromYaml(errorValue);
       } catch (e) {
         problem('while processing '
             '$className.$errorName, $e');
@@ -154,12 +155,12 @@
 
 /// Decodes a YAML object (obtained from `pkg/front_end/messages.yaml`) into a
 /// map from error name to [ErrorCodeInfo].
-Map<String, ErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
+Map<String, FrontEndErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
   Never problem(String message) {
     throw 'Problem in pkg/front_end/messages.yaml: $message';
   }
 
-  var result = <String, ErrorCodeInfo>{};
+  var result = <String, FrontEndErrorCodeInfo>{};
   if (yaml is! Map<Object?, Object?>) {
     problem('root node is not a map');
   }
@@ -172,25 +173,49 @@
     if (errorValue is! Map<Object?, Object?>) {
       problem('value associated with error $errorName is not a map');
     }
-    result[errorName] = ErrorCodeInfo.fromYaml(errorValue);
+    result[errorName] = FrontEndErrorCodeInfo.fromYaml(errorValue);
   }
   return result;
 }
 
 /// Loads analyzer messages from the analyzer's `messages.yaml` file.
-Map<String, Map<String, ErrorCodeInfo>> _loadAnalyzerMessages() {
+Map<String, Map<String, AnalyzerErrorCodeInfo>> _loadAnalyzerMessages() {
   Object? messagesYaml =
       loadYaml(File(join(analyzerPkgPath, 'messages.yaml')).readAsStringSync());
   return decodeAnalyzerMessagesYaml(messagesYaml);
 }
 
 /// Loads front end messages from the front end's `messages.yaml` file.
-Map<String, ErrorCodeInfo> _loadFrontEndMessages() {
+Map<String, FrontEndErrorCodeInfo> _loadFrontEndMessages() {
   Object? messagesYaml =
       loadYaml(File(join(frontEndPkgPath, 'messages.yaml')).readAsStringSync());
   return decodeCfeMessagesYaml(messagesYaml);
 }
 
+/// In-memory representation of error code information obtained from the
+/// analyzer's `messages.yaml` file.
+class AnalyzerErrorCodeInfo extends ErrorCodeInfo {
+  AnalyzerErrorCodeInfo(
+      {String? comment,
+      String? correctionMessage,
+      String? documentation,
+      bool hasPublishedDocs = false,
+      bool isUnresolvedIdentifier = false,
+      required String problemMessage,
+      String? sharedName})
+      : super(
+            comment: comment,
+            correctionMessage: correctionMessage,
+            documentation: documentation,
+            hasPublishedDocs: hasPublishedDocs,
+            isUnresolvedIdentifier: isUnresolvedIdentifier,
+            problemMessage: problemMessage,
+            sharedName: sharedName);
+
+  AnalyzerErrorCodeInfo.fromYaml(Map<Object?, Object?> yaml)
+      : super.fromYaml(yaml);
+}
+
 /// Data tables mapping between CFE errors and their corresponding automatically
 /// generated analyzer errors.
 class CfeToAnalyzerErrorCodeTables {
@@ -218,7 +243,7 @@
   /// automatically generated, and whose values are the front end error name.
   final Map<ErrorCodeInfo, String> infoToFrontEndCode = {};
 
-  CfeToAnalyzerErrorCodeTables._(Map<String, ErrorCodeInfo> messages) {
+  CfeToAnalyzerErrorCodeTables._(Map<String, FrontEndErrorCodeInfo> messages) {
     for (var entry in messages.entries) {
       var errorCodeInfo = entry.value;
       var index = errorCodeInfo.index;
@@ -322,14 +347,10 @@
   String get typeCode => 'ErrorType.$type';
 }
 
-/// In-memory representation of error code information obtained from either a
-/// `messages.yaml` file.  Supports both the analyzer and front_end message file
-/// formats.
-class ErrorCodeInfo {
-  /// For error code information obtained from the CFE, the set of analyzer
-  /// error codes that corresponds to this error code, if any.
-  final List<String> analyzerCode;
-
+/// In-memory representation of error code information obtained from either the
+/// analyzer or the front end's `messages.yaml` file.  This class contains the
+/// common functionality supported by both formats.
+abstract class ErrorCodeInfo {
   /// If present, a documentation comment that should be associated with the
   /// error in code generated output.
   final String? comment;
@@ -345,10 +366,6 @@
   /// been published.
   final bool hasPublishedDocs;
 
-  /// For error code information obtained from the CFE, the index of the error
-  /// in the analyzer's `fastaAnalyzerErrorCodes` table.
-  final int? index;
-
   /// Indicates whether this error is caused by an unresolved identifier.
   final bool isUnresolvedIdentifier;
 
@@ -360,30 +377,32 @@
   /// codes.
   final String? sharedName;
 
+  /// If present, indicates that this error code has been renamed from
+  /// [previousName] to its current name (or [sharedName]).
+  final String? previousName;
+
   ErrorCodeInfo(
-      {this.analyzerCode = const [],
-      this.comment,
+      {this.comment,
       this.documentation,
       this.hasPublishedDocs = false,
-      this.index,
       this.isUnresolvedIdentifier = false,
       this.sharedName,
       required this.problemMessage,
-      this.correctionMessage});
+      this.correctionMessage,
+      this.previousName});
 
   /// Decodes an [ErrorCodeInfo] object from its YAML representation.
   ErrorCodeInfo.fromYaml(Map<Object?, Object?> yaml)
       : this(
-            analyzerCode: _decodeAnalyzerCode(yaml['analyzerCode']),
             comment: yaml['comment'] as String?,
             correctionMessage: yaml['correctionMessage'] as String?,
             documentation: yaml['documentation'] as String?,
             hasPublishedDocs: yaml['hasPublishedDocs'] as bool? ?? false,
-            index: yaml['index'] as int?,
             isUnresolvedIdentifier:
                 yaml['isUnresolvedIdentifier'] as bool? ?? false,
             problemMessage: yaml['problemMessage'] as String,
-            sharedName: yaml['sharedName'] as String?);
+            sharedName: yaml['sharedName'] as String?,
+            previousName: yaml['previousName'] as String?);
 
   /// Given a messages.yaml entry, come up with a mapping from placeholder
   /// patterns in its message strings to their corresponding indices.
@@ -459,8 +478,6 @@
   /// Encodes this object into a YAML representation.
   Map<Object?, Object?> toYaml() => {
         if (sharedName != null) 'sharedName': sharedName,
-        if (analyzerCode.isNotEmpty)
-          'analyzerCode': _encodeAnalyzerCode(analyzerCode),
         'problemMessage': problemMessage,
         if (correctionMessage != null) 'correctionMessage': correctionMessage,
         if (isUnresolvedIdentifier) 'isUnresolvedIdentifier': true,
@@ -468,6 +485,30 @@
         if (comment != null) 'comment': comment,
         if (documentation != null) 'documentation': documentation,
       };
+}
+
+/// In-memory representation of error code information obtained from the front
+/// end's `messages.yaml` file.
+class FrontEndErrorCodeInfo extends ErrorCodeInfo {
+  /// The set of analyzer error codes that corresponds to this error code, if
+  /// any.
+  final List<String> analyzerCode;
+
+  /// The index of the error in the analyzer's `fastaAnalyzerErrorCodes` table.
+  final int? index;
+
+  FrontEndErrorCodeInfo.fromYaml(Map<Object?, Object?> yaml)
+      : analyzerCode = _decodeAnalyzerCode(yaml['analyzerCode']),
+        index = yaml['index'] as int?,
+        super.fromYaml(yaml);
+
+  @override
+  Map<Object?, Object?> toYaml() => {
+        if (analyzerCode.isNotEmpty)
+          'analyzerCode': _encodeAnalyzerCode(analyzerCode),
+        if (index != null) 'index': index,
+        ...super.toYaml(),
+      };
 
   static List<String> _decodeAnalyzerCode(Object? value) {
     if (value == null) {
diff --git a/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart b/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
index 75b6f60..d26eab1 100644
--- a/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
+++ b/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
@@ -221,7 +221,7 @@
       var commentInfo = _extractCommentInfo(fieldDeclaration);
       var documentationComment = commentInfo.documentationComment;
       var otherComment = commentInfo.otherComment;
-      yamlCodes[uniqueNameSuffix] = ErrorCodeInfo(
+      yamlCodes[uniqueNameSuffix] = AnalyzerErrorCodeInfo(
               sharedName: uniqueNameSuffix == name ? null : name,
               problemMessage: code.problemMessage,
               correctionMessage: code.correctionMessage,
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index 928fbf4..2e58862 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -285,16 +285,14 @@
   }
 
   @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
+  void endConstructorReference(Token start, Token? periodBeforeName,
+      Token endToken, ConstructorReferenceContext constructorReferenceContext) {
+    debugEvent("ConstructorReference");
+  }
+
+  @override
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
     debugEvent("Enum");
-    var constants =
-        List<EnumConstantDeclaration?>.filled(count, null, growable: true);
-    popList(count, constants);
-    var name = pop() as String;
-    var metadata = popTypedList<Annotation>();
-    var comment = pop() as Comment?;
-    compilationUnit.declarations.add(EnumDeclaration(
-        comment, metadata, name, constants.whereNotNull().toList()));
   }
 
   @override
@@ -306,7 +304,8 @@
   @override
   void endFormalParameter(
       Token? thisKeyword,
-      Token? periodAfterThis,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
       Token nameToken,
       Token? initializerStart,
       Token? initializerEnd,
@@ -421,6 +420,37 @@
   }
 
   @override
+  void handleEnumElement(Token beginToken) {
+    debugEvent("EnumElement");
+    pop(); // Arguments.
+    pop(); // Type arguments.
+  }
+
+  @override
+  void handleEnumElements(Token endToken, int count) {
+    debugEvent("EnumElements");
+    var constants =
+        List<EnumConstantDeclaration?>.filled(count, null, growable: true);
+    popList(count, constants);
+    pop(); // Type variables.
+    var name = pop() as String;
+    var metadata = popTypedList<Annotation>();
+    var comment = pop() as Comment?;
+    compilationUnit.declarations.add(EnumDeclaration(
+        comment, metadata, name, constants.whereNotNull().toList()));
+  }
+
+  @override
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    debugEvent("EnumHeader");
+  }
+
+  @override
+  void handleEnumNoWithClause() {
+    debugEvent("NoEnumWithClause");
+  }
+
+  @override
   void handleFormalParameterWithoutValue(Token token) {
     debugEvent("FormalParameterWithoutValue");
   }
@@ -539,6 +569,11 @@
   }
 
   @override
+  void handleNoTypeNameInConstructorReference(Token token) {
+    debugEvent("NoTypeNameInConstructorReference");
+  }
+
+  @override
   void handleQualified(Token period) {
     debugEvent("Qualified");
     var suffix = pop() as String;
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 4b3846b..19caf6d 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -11,8 +11,6 @@
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/error_formatter.dart';
 import 'package:analyzer_cli/src/error_severity.dart';
@@ -46,25 +44,22 @@
   /// specified on the command line as though it is reached via a "package:"
   /// URI, but avoid suppressing its output in the event that the user has not
   /// specified the "--package-warnings" option.
-  String _selfPackageName;
+  String? _selfPackageName;
 
   AnalyzerImpl(this.analysisOptions, this.analysisDriver, this.libraryFile,
       this.options, this.stats, this.startTime);
 
   void addCompilationUnitSource(
       CompilationUnitElement unit, Set<CompilationUnitElement> units) {
-    if (unit == null || !units.add(unit)) {
+    if (!units.add(unit)) {
       return;
     }
-    var source = unit.source;
-    if (source != null) {
-      files.add(source.fullName);
-    }
+    files.add(unit.source.fullName);
   }
 
   void addLibrarySources(LibraryElement library, Set<LibraryElement> libraries,
       Set<CompilationUnitElement> units) {
-    if (library == null || !libraries.add(library)) {
+    if (!libraries.add(library)) {
       return;
     }
     // Maybe skip library.
@@ -104,7 +99,7 @@
         if (_defaultSeverityProcessor(error) == null) {
           continue;
         }
-        status = status.max(computeSeverity(error, options, analysisOptions));
+        status = status.max(computeSeverity(error, options, analysisOptions)!);
       }
     }
     return status;
@@ -162,22 +157,21 @@
     return computeMaxErrorSeverity();
   }
 
-  ErrorSeverity _defaultSeverityProcessor(AnalysisError error) =>
+  ErrorSeverity? _defaultSeverityProcessor(AnalysisError error) =>
       determineProcessedSeverity(error, options, analysisOptions);
 
   /// Returns true if we want to report diagnostics for this library.
   bool _isAnalyzedLibrary(LibraryElement library) {
     var source = library.source;
-    switch (source.uriKind) {
-      case UriKind.DART_URI:
-        return options.showSdkWarnings;
-      case UriKind.PACKAGE_URI:
-        if (_isPathInPubCache(source.fullName)) {
-          return false;
-        }
-        return _isAnalyzedPackage(source.uri);
-      default:
-        return true;
+    if (source.uri.isScheme('dart')) {
+      return options.showSdkWarnings;
+    } else if (source.uri.isScheme('package')) {
+      if (_isPathInPubCache(source.fullName)) {
+        return false;
+      }
+      return _isAnalyzedPackage(source.uri);
+    } else {
+      return true;
     }
   }
 
@@ -194,7 +188,7 @@
     } else if (options.showPackageWarningsPrefix == null) {
       return true;
     } else {
-      return packageName.startsWith(options.showPackageWarningsPrefix);
+      return packageName.startsWith(options.showPackageWarningsPrefix!);
     }
   }
 
@@ -238,14 +232,14 @@
 
   @override
   void logException(dynamic exception,
-      [StackTrace stackTrace,
-      List<InstrumentationServiceAttachment> attachments = const []]) {
+      [StackTrace? stackTrace,
+      List<InstrumentationServiceAttachment>? attachments = const []]) {
     errorSink.writeln(exception);
     errorSink.writeln(stackTrace);
   }
 
   @override
-  void logInfo(String message, [Object exception]) {
+  void logInfo(String message, [Object? exception]) {
     outSink.writeln(message);
     if (exception != null) {
       outSink.writeln(exception);
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 28e3590..b2dd53f 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -41,10 +41,10 @@
 import 'package:yaml/yaml.dart';
 
 /// Shared IO sink for standard error reporting.
-StringSink errorSink = io.stderr;
+late StringSink errorSink = io.stderr;
 
 /// Shared IO sink for standard out reporting.
-StringSink outSink = io.stdout;
+late StringSink outSink = io.stdout;
 
 /// Test this option map to see if it specifies lint rules.
 bool containsLintRuleEntry(YamlMap options) {
@@ -55,13 +55,14 @@
 class Driver implements CommandLineStarter {
   static final ByteStore analysisDriverMemoryByteStore = MemoryByteStore();
 
-  _AnalysisContextProvider _analysisContextProvider;
-  DriverBasedAnalysisContext analysisContext;
+  bool _isStarted = false;
 
-  /// The driver that was most recently created by a call to [_analyzeAll], or
-  /// `null` if [_analyzeAll] hasn't been called yet.
+  late _AnalysisContextProvider _analysisContextProvider;
+  DriverBasedAnalysisContext? analysisContext;
+
+  /// The driver that was most recently created by a call to [_analyzeAll].
   @visibleForTesting
-  AnalysisDriver analysisDriver;
+  AnalysisDriver? analysisDriver;
 
   /// The total number of source files loaded by an AnalysisContext.
   int _analyzedFileCount = 0;
@@ -73,7 +74,7 @@
   final AnalysisStats stats = AnalysisStats();
 
   /// The [PathFilter] for excluded files with wildcards, etc.
-  PathFilter pathFilter;
+  late PathFilter pathFilter;
 
   /// Create a new Driver instance.
   Driver({@Deprecated('This parameter has no effect') bool isTesting = false});
@@ -88,9 +89,10 @@
 
   @override
   Future<void> start(List<String> arguments) async {
-    if (analysisDriver != null) {
+    if (_isStarted) {
       throw StateError('start() can only be called once');
     }
+    _isStarted = true;
     var startTime = DateTime.now().millisecondsSinceEpoch;
 
     StringUtilities.INTERNER = MappedInterner();
@@ -98,7 +100,7 @@
     linter.registerLintRules();
 
     // Parse commandline options.
-    var options = CommandLineOptions.parse(resourceProvider, arguments);
+    var options = CommandLineOptions.parse(resourceProvider, arguments)!;
 
     _analysisContextProvider = _AnalysisContextProvider(resourceProvider);
 
@@ -106,7 +108,7 @@
     if (options.batchMode) {
       var batchRunner = BatchRunner(outSink, errorSink);
       batchRunner.runAsBatch(arguments, (List<String> args) async {
-        var options = CommandLineOptions.parse(resourceProvider, args);
+        var options = CommandLineOptions.parse(resourceProvider, args)!;
         return await _analyzeAll(options);
       });
     } else {
@@ -129,7 +131,7 @@
       for (var i = 0; i < 3; i++) {
         buildSdkSummary(
           resourceProvider: PhysicalResourceProvider.INSTANCE,
-          sdkPath: options.dartSdkPath,
+          sdkPath: options.dartSdkPath!,
         );
       }
 
@@ -137,13 +139,13 @@
     }
 
     if (analysisDriver != null) {
-      _analyzedFileCount += analysisDriver.knownFiles.length;
+      _analyzedFileCount += analysisDriver!.knownFiles.length;
     }
 
     if (options.perfReport != null) {
       var json = makePerfReport(
           startTime, currentTimeMillis, options, _analyzedFileCount, stats);
-      io.File(options.perfReport).writeAsStringSync(json);
+      io.File(options.perfReport!).writeAsStringSync(json);
     }
   }
 
@@ -175,7 +177,7 @@
     SeverityProcessor defaultSeverityProcessor;
     defaultSeverityProcessor = (AnalysisError error) {
       return determineProcessedSeverity(
-          error, options, analysisDriver.analysisOptions);
+          error, options, analysisDriver!.analysisOptions);
     };
 
     // We currently print out to stderr to ensure that when in batch mode we
@@ -213,7 +215,8 @@
     for (var sourcePath in pathList) {
       _analysisContextProvider.configureForPath(sourcePath);
       analysisContext = _analysisContextProvider.analysisContext;
-      analysisDriver = _analysisContextProvider.analysisDriver;
+      final analysisDriver =
+          this.analysisDriver = _analysisContextProvider.analysisDriver;
       pathFilter = _analysisContextProvider.pathFilter;
 
       // Add all the files to be analyzed en masse to the context. Skip any
@@ -250,8 +253,8 @@
             analysisDriver.currentSession.analysisContext.contextRoot.root.path,
           );
           formatter.formatErrors([
-            ErrorsResultImpl(analysisDriver.currentSession, path, null,
-                lineInfo, false, errors)
+            ErrorsResultImpl(analysisDriver.currentSession, path,
+                pathContext.toUri(path), lineInfo, false, errors)
           ]);
           for (var error in errors) {
             var severity = determineProcessedSeverity(
@@ -272,7 +275,7 @@
               errors.addAll(validator.validate(node.nodes));
             }
 
-            if (analysisDriver != null && analysisDriver.analysisOptions.lint) {
+            if (analysisDriver.analysisOptions.lint) {
               var visitors = <LintRule, PubspecVisitor>{};
               for (var linter in analysisDriver.analysisOptions.lintRules) {
                 if (linter is LintRule) {
@@ -301,13 +304,13 @@
             if (errors.isNotEmpty) {
               for (var error in errors) {
                 var severity = determineProcessedSeverity(
-                    error, options, analysisDriver.analysisOptions);
+                    error, options, analysisDriver.analysisOptions)!;
                 allResult = allResult.max(severity);
               }
               var lineInfo = LineInfo.fromContent(content);
               formatter.formatErrors([
-                ErrorsResultImpl(analysisDriver.currentSession, path, null,
-                    lineInfo, false, errors)
+                ErrorsResultImpl(analysisDriver.currentSession, path,
+                    pathContext.toUri(path), lineInfo, false, errors)
               ]);
             }
           } catch (exception) {
@@ -322,12 +325,12 @@
             var errors = validator.validate(
                 content, analysisDriver.analysisOptions.chromeOsManifestChecks);
             formatter.formatErrors([
-              ErrorsResultImpl(analysisDriver.currentSession, path, null,
-                  lineInfo, false, errors)
+              ErrorsResultImpl(analysisDriver.currentSession, path,
+                  pathContext.toUri(path), lineInfo, false, errors)
             ]);
             for (var error in errors) {
               var severity = determineProcessedSeverity(
-                  error, options, analysisDriver.analysisOptions);
+                  error, options, analysisDriver.analysisOptions)!;
               allResult = allResult.max(severity);
             }
           } catch (exception) {
@@ -360,7 +363,7 @@
     // The next batch should not be affected by a previous batch.
     // E.g. the same parts in both batches, but with different libraries.
     for (var path in dartFiles) {
-      analysisDriver.removeFile(path);
+      analysisDriver!.removeFile(path);
     }
 
     // Any dangling parts still in this list were definitely dangling.
@@ -412,6 +415,7 @@
   Future<ErrorSeverity> _runAnalyzer(
       FileState file, CommandLineOptions options, ErrorFormatter formatter) {
     var startTime = currentTimeMillis;
+    final analysisDriver = this.analysisDriver!;
     var analyzer = AnalyzerImpl(analysisDriver.analysisOptions, analysisDriver,
         file, options, stats, startTime);
     return analyzer.analyze(formatter);
@@ -446,9 +450,8 @@
 
   /// Return whether the [newOptions] are equal to the [previous].
   static bool _equalCommandLineOptions(
-      CommandLineOptions previous, CommandLineOptions newOptions) {
+      CommandLineOptions? previous, CommandLineOptions newOptions) {
     return previous != null &&
-        newOptions != null &&
         newOptions.defaultPackagesPath == previous.defaultPackagesPath &&
         _equalMaps(newOptions.declaredVariables, previous.declaredVariables) &&
         newOptions.log == previous.log &&
@@ -460,7 +463,8 @@
         newOptions.lints == previous.lints &&
         newOptions.defaultLanguageVersion == previous.defaultLanguageVersion &&
         newOptions.disableCacheFlushing == previous.disableCacheFlushing &&
-        _equalLists(newOptions.enabledExperiments, previous.enabledExperiments);
+        _equalLists(
+            newOptions.enabledExperiments!, previous.enabledExperiments!);
   }
 
   /// Perform a deep comparison of two string lists.
@@ -494,27 +498,27 @@
   final ResourceProvider _resourceProvider;
   final FileContentCache _fileContentCache;
 
-  CommandLineOptions _commandLineOptions;
-  List<String> _pathList;
+  CommandLineOptions? _commandLineOptions;
+  late List<String> _pathList;
 
-  final Map<Folder, DriverBasedAnalysisContext> _folderContexts = {};
-  AnalysisContextCollectionImpl _collection;
-  DriverBasedAnalysisContext _analysisContext;
+  final Map<Folder, DriverBasedAnalysisContext?> _folderContexts = {};
+  AnalysisContextCollectionImpl? _collection;
+  DriverBasedAnalysisContext? _analysisContext;
 
   _AnalysisContextProvider(this._resourceProvider)
       : _fileContentCache = FileContentCache(_resourceProvider);
 
-  DriverBasedAnalysisContext get analysisContext {
+  DriverBasedAnalysisContext? get analysisContext {
     return _analysisContext;
   }
 
   AnalysisDriver get analysisDriver {
-    return _analysisContext.driver;
+    return _analysisContext!.driver;
   }
 
   /// TODO(scheglov) Use analyzedFiles()
   PathFilter get pathFilter {
-    var contextRoot = analysisContext.contextRoot;
+    var contextRoot = analysisContext!.contextRoot;
     var optionsFile = contextRoot.optionsFile;
 
     // If there is no options file, there can be no excludes.
@@ -524,7 +528,7 @@
 
     // Exclude patterns are relative to the directory with the options file.
     return PathFilter(contextRoot.root.path, optionsFile.parent2.path,
-        analysisContext.analysisOptions.excludePatterns);
+        analysisContext!.analysisOptions.excludePatterns);
   }
 
   void configureForPath(String path) {
@@ -554,10 +558,10 @@
     _collection = AnalysisContextCollectionImpl(
       byteStore: Driver.analysisDriverMemoryByteStore,
       includedPaths: _pathList,
-      optionsFile: _commandLineOptions.defaultAnalysisOptionsPath,
-      packagesFile: _commandLineOptions.defaultPackagesPath,
+      optionsFile: _commandLineOptions!.defaultAnalysisOptionsPath,
+      packagesFile: _commandLineOptions!.defaultPackagesPath,
       resourceProvider: _resourceProvider,
-      sdkPath: _commandLineOptions.dartSdkPath,
+      sdkPath: _commandLineOptions!.dartSdkPath,
       updateAnalysisOptions: _updateAnalysisOptions,
       fileContentCache: _fileContentCache,
     );
@@ -580,10 +584,10 @@
   }
 
   void _setContextForPath(String path) {
-    _analysisContext = _collection.contextFor(path);
+    _analysisContext = _collection!.contextFor(path);
   }
 
   void _updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
-    _commandLineOptions.updateAnalysisOptions(analysisOptions);
+    _commandLineOptions!.updateAnalysisOptions(analysisOptions);
   }
 }
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index f496762..51c7002 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -34,7 +34,7 @@
 
 /// Returns desired severity for the given [error] (or `null` if it's to be
 /// suppressed).
-typedef SeverityProcessor = ErrorSeverity Function(AnalysisError error);
+typedef SeverityProcessor = ErrorSeverity? Function(AnalysisError error);
 
 /// Analysis statistics counter.
 class AnalysisStats {
@@ -113,20 +113,20 @@
   final String message;
   final List<ContextMessage> contextMessages;
   final String errorCode;
-  final String correction;
-  final String url;
+  final String? correction;
+  final String? url;
 
   CLIError({
-    this.severity,
-    this.sourcePath,
-    this.offset,
-    this.line,
-    this.column,
-    this.message,
-    this.contextMessages,
-    this.errorCode,
-    this.correction,
-    this.url,
+    required this.severity,
+    required this.sourcePath,
+    required this.offset,
+    required this.line,
+    required this.column,
+    required this.message,
+    required this.contextMessages,
+    required this.errorCode,
+    required this.correction,
+    required this.url,
   });
 
   @override
@@ -150,7 +150,8 @@
   @override
   int compareTo(CLIError other) {
     // severity
-    var compare = _severityCompare[other.severity] - _severityCompare[severity];
+    var compare =
+        _severityCompare[other.severity]! - _severityCompare[severity]!;
     if (compare != 0) return compare;
 
     // path
@@ -179,12 +180,11 @@
   final StringSink out;
   final CommandLineOptions options;
   final AnalysisStats stats;
-  SeverityProcessor _severityProcessor;
+  final SeverityProcessor _severityProcessor;
 
   ErrorFormatter(this.out, this.options, this.stats,
-      {SeverityProcessor severityProcessor}) {
-    _severityProcessor = severityProcessor ?? _severityIdentity;
-  }
+      {SeverityProcessor? severityProcessor})
+      : _severityProcessor = severityProcessor ?? _severityIdentity;
 
   /// Call to write any batched up errors from [formatErrors].
   void flush();
@@ -213,22 +213,20 @@
 
   /// Compute the severity for this [error] or `null` if this error should be
   /// filtered.
-  ErrorSeverity _computeSeverity(AnalysisError error) =>
+  ErrorSeverity? _computeSeverity(AnalysisError error) =>
       _severityProcessor(error);
 }
 
 class HumanErrorFormatter extends ErrorFormatter {
-  AnsiLogger ansi;
+  late final AnsiLogger ansi = AnsiLogger(options.color);
 
   // This is a Set in order to de-dup CLI errors.
   final Set<CLIError> batchedErrors = {};
 
   HumanErrorFormatter(
       StringSink out, CommandLineOptions options, AnalysisStats stats,
-      {SeverityProcessor severityProcessor})
-      : super(out, options, stats, severityProcessor: severityProcessor) {
-    ansi = AnsiLogger(this.options.color);
-  }
+      {SeverityProcessor? severityProcessor})
+      : super(out, options, stats, severityProcessor: severityProcessor);
 
   @override
   void flush() {
@@ -281,10 +279,10 @@
   void formatError(
       Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
     var source = error.source;
-    var result = errorToLine[error];
+    var result = errorToLine[error]!;
     var location = result.lineInfo.getLocation(error.offset);
 
-    var severity = _severityProcessor(error);
+    var severity = _severityProcessor(error)!;
 
     // Get display name; translate INFOs into LINTS and HINTS.
     var errorType = severity.displayName;
@@ -297,9 +295,9 @@
 
     // warning • 'foo' is not a bar. • lib/foo.dart:1:2 • foo_warning
     String sourcePath;
-    if (source.uriKind == UriKind.DART_URI) {
+    if (source.uri.isScheme('dart')) {
       sourcePath = source.uri.toString();
-    } else if (source.uriKind == UriKind.PACKAGE_URI) {
+    } else if (source.uri.isScheme('package')) {
       sourcePath = _relative(source.fullName);
       if (sourcePath == source.fullName) {
         // If we weren't able to shorten the path name, use the package: version.
@@ -314,7 +312,7 @@
       if (session is DriverBasedAnalysisContext) {
         var fileResult = session.driver.getFileSync(message.filePath);
         if (fileResult is FileResult) {
-          var lineInfo = fileResult?.lineInfo;
+          var lineInfo = fileResult.lineInfo;
           var location = lineInfo.getLocation(message.offset);
           contextMessages.add(ContextMessage(
               message.filePath,
@@ -343,7 +341,7 @@
 class JsonErrorFormatter extends ErrorFormatter {
   JsonErrorFormatter(
       StringSink out, CommandLineOptions options, AnalysisStats stats,
-      {SeverityProcessor severityProcessor})
+      {SeverityProcessor? severityProcessor})
       : super(out, options, stats, severityProcessor: severityProcessor);
 
   @override
@@ -430,7 +428,7 @@
 
   MachineErrorFormatter(
       StringSink out, CommandLineOptions options, AnalysisStats stats,
-      {SeverityProcessor severityProcessor})
+      {SeverityProcessor? severityProcessor})
       : super(out, options, stats, severityProcessor: severityProcessor);
 
   @override
@@ -444,7 +442,7 @@
       return;
     }
     var source = error.source;
-    var location = errorToLine[error].lineInfo.getLocation(error.offset);
+    var location = errorToLine[error]!.lineInfo.getLocation(error.offset);
     var length = error.length;
 
     var severity = _severityProcessor(error);
diff --git a/pkg/analyzer_cli/lib/src/error_severity.dart b/pkg/analyzer_cli/lib/src/error_severity.dart
index dc7e4ec..23bfe3e 100644
--- a/pkg/analyzer_cli/lib/src/error_severity.dart
+++ b/pkg/analyzer_cli/lib/src/error_severity.dart
@@ -12,17 +12,15 @@
 /// - if [options.enableTypeChecks] is false, then de-escalate checked-mode
 ///   compile time errors to a severity of [ErrorSeverity.INFO].
 /// - if [options.lintsAreFatal] is true, escalate lints to errors.
-ErrorSeverity computeSeverity(
+ErrorSeverity? computeSeverity(
   AnalysisError error,
   CommandLineOptions commandLineOptions,
   AnalysisOptions analysisOptions,
 ) {
-  if (analysisOptions != null) {
-    var processor = ErrorProcessor.getProcessor(analysisOptions, error);
-    // If there is a processor for this error, defer to it.
-    if (processor != null) {
-      return processor.severity;
-    }
+  var processor = ErrorProcessor.getProcessor(analysisOptions, error);
+  // If there is a processor for this error, defer to it.
+  if (processor != null) {
+    return processor.severity;
   }
 
   if (commandLineOptions.lintsAreFatal && error.errorCode is LintCode) {
@@ -34,7 +32,7 @@
 
 /// Check various configuration options to get a desired severity for this
 /// [error] (or `null` if it's to be suppressed).
-ErrorSeverity determineProcessedSeverity(AnalysisError error,
+ErrorSeverity? determineProcessedSeverity(AnalysisError error,
     CommandLineOptions commandLineOptions, AnalysisOptions analysisOptions) {
   var severity = computeSeverity(error, commandLineOptions, analysisOptions);
   // Skip TODOs categorically unless escalated to ERROR or HINT (#26215).
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index fa01214..4ad9d00 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -35,6 +35,8 @@
 
 T cast<T>(dynamic value) => value as T;
 
+T? castNullable<T>(dynamic value) => value as T?;
+
 /// Print the given [message] to stderr and exit with the given [exitCode].
 void printAndFail(String message, {int exitCode = 15}) {
   errorSink.writeln(message);
@@ -53,18 +55,18 @@
   /// The file path of the analysis options file that should be used in place of
   /// any file in the root directory or a parent of the root directory,
   /// or `null` if the normal lookup mechanism should be used.
-  String defaultAnalysisOptionsPath;
+  String? defaultAnalysisOptionsPath;
 
   /// The file path of the .packages file that should be used in place of any
   /// file found using the normal (Package Specification DEP) lookup mechanism,
   /// or `null` if the normal lookup mechanism should be used.
-  String defaultPackagesPath;
+  String? defaultPackagesPath;
 
   /// A table mapping variable names to values for the declared variables.
   final Map<String, String> declaredVariables = {};
 
   /// The path to the dart SDK.
-  String dartSdkPath;
+  String? dartSdkPath;
 
   /// Whether to disable cache flushing. This option can improve analysis
   /// speed at the expense of memory usage. It may also be useful for working
@@ -91,7 +93,7 @@
 
   /// The path to a file to write a performance log.
   /// (Or null if not enabled.)
-  final String perfReport;
+  final String? perfReport;
 
   /// Batch mode (for unit testing)
   final bool batchMode;
@@ -100,7 +102,7 @@
   final bool showPackageWarnings;
 
   /// If not null, show package: warnings only for matching packages.
-  final String showPackageWarningsPrefix;
+  final String? showPackageWarningsPrefix;
 
   /// Whether to show SDK warnings
   final bool showSdkWarnings;
@@ -133,7 +135,7 @@
     ResourceProvider resourceProvider,
     ArgResults args,
   )   : _argResults = args,
-        dartSdkPath = cast(args[_sdkPathOption]),
+        dartSdkPath = castNullable(args[_sdkPathOption]),
         disableCacheFlushing = cast(args['disable-cache-flushing']),
         disableHints = cast(args['no-hints']),
         displayVersion = cast(args['version']),
@@ -141,12 +143,13 @@
         log = cast(args['log']),
         jsonFormat = args['format'] == 'json',
         machineFormat = args['format'] == 'machine',
-        perfReport = cast(args['x-perf-report']),
+        perfReport = castNullable(args['x-perf-report']),
         batchMode = cast(args['batch']),
         showPackageWarnings = cast(args['show-package-warnings']) ||
             cast(args['package-warnings']) ||
             args['x-package-warnings-prefix'] != null,
-        showPackageWarningsPrefix = cast(args['x-package-warnings-prefix']),
+        showPackageWarningsPrefix =
+            castNullable(args['x-package-warnings-prefix']),
         showSdkWarnings = cast(args['sdk-warnings']),
         sourceFiles = args.rest,
         infosAreFatal = cast(args['fatal-infos']) || cast(args['fatal-hints']),
@@ -160,11 +163,11 @@
     //
     defaultAnalysisOptionsPath = _absoluteNormalizedPath(
       resourceProvider,
-      cast(args[_analysisOptionsFileOption]),
+      castNullable(args[_analysisOptionsFileOption]),
     );
     defaultPackagesPath = _absoluteNormalizedPath(
       resourceProvider,
-      cast(args[_packagesOption]),
+      castNullable(args[_packagesOption]),
     );
 
     //
@@ -192,20 +195,20 @@
 
   /// The default language version for files that are not in a package.
   /// (Or null if no default language version to force.)
-  String get defaultLanguageVersion {
-    return cast(_argResults[_defaultLanguageVersionOption]);
+  String? get defaultLanguageVersion {
+    return castNullable(_argResults[_defaultLanguageVersionOption]);
   }
 
   /// A list of the names of the experiments that are to be enabled.
-  List<String> get enabledExperiments {
-    return cast(_argResults[_enableExperimentOption]);
+  List<String>? get enabledExperiments {
+    return castNullable(_argResults[_enableExperimentOption]);
   }
 
-  bool get implicitCasts => _argResults[_implicitCastsFlag] as bool;
+  bool? get implicitCasts => _argResults[_implicitCastsFlag] as bool?;
 
-  bool get lints => _argResults[_lintsFlag] as bool;
+  bool? get lints => _argResults[_lintsFlag] as bool?;
 
-  bool get noImplicitDynamic => _argResults[_noImplicitDynamicFlag] as bool;
+  bool? get noImplicitDynamic => _argResults[_noImplicitDynamicFlag] as bool?;
 
   /// Update the [analysisOptions] with flags that the user specified
   /// explicitly. The [analysisOptions] are usually loaded from one of
@@ -222,7 +225,7 @@
           .restrictToVersion(nonPackageLanguageVersion);
     }
 
-    var enabledExperiments = this.enabledExperiments;
+    var enabledExperiments = this.enabledExperiments!;
     if (enabledExperiments.isNotEmpty) {
       analysisOptions.contextFeatures = FeatureSet.fromEnableFlags2(
         sdkLanguageVersion: ExperimentStatus.currentVersion,
@@ -303,7 +306,7 @@
   /// Parse [args] into [CommandLineOptions] describing the specified
   /// analyzer options. In case of a format error, calls [printAndFail], which
   /// by default prints an error message to stderr and exits.
-  static CommandLineOptions parse(
+  static CommandLineOptions? parse(
       ResourceProvider resourceProvider, List<String> args,
       {void Function(String msg) printAndFail = printAndFail}) {
     var options = _parse(resourceProvider, args);
@@ -335,9 +338,9 @@
     return options;
   }
 
-  static String _absoluteNormalizedPath(
+  static String? _absoluteNormalizedPath(
     ResourceProvider resourceProvider,
-    String path,
+    String? path,
   ) {
     if (path == null) {
       return null;
@@ -425,7 +428,7 @@
     }
   }
 
-  static CommandLineOptions _parse(
+  static CommandLineOptions? _parse(
     ResourceProvider resourceProvider,
     List<String> args,
   ) {
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 5297838..0580b81 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -5,7 +5,7 @@
 publish_to: none
 
 environment:
-  sdk: "^2.7.0"
+  sdk: "^2.14.0"
 
 dependencies:
   analyzer: any
diff --git a/pkg/analyzer_cli/test/analysis_options_test.dart b/pkg/analyzer_cli/test/analysis_options_test.dart
index 0c68a22..72e1bb4 100644
--- a/pkg/analyzer_cli/test/analysis_options_test.dart
+++ b/pkg/analyzer_cli/test/analysis_options_test.dart
@@ -18,15 +18,10 @@
 
 @reflectiveTest
 class OptionsTest {
-  _Runner runner;
-
-  void setUp() {
-    runner = _Runner.setUp();
-  }
+  final _Runner runner = _Runner.setUp();
 
   void tearDown() {
     runner.tearDown();
-    runner = null;
   }
 
   Future<void> test_options() async {
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 19d778d..de57da2 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -34,16 +34,16 @@
 class BaseTest {
   static const emptyOptionsFile = 'data/empty_options.yaml';
 
-  StringSink _savedOutSink, _savedErrorSink;
-  int _savedExitCode;
-  ExitHandler _savedExitHandler;
+  late StringSink _savedOutSink, _savedErrorSink;
+  late int _savedExitCode;
+  late ExitHandler _savedExitHandler;
 
-  Driver driver;
+  late Driver driver;
 
-  AnalysisOptions get analysisOptions => driver.analysisDriver.analysisOptions;
+  AnalysisOptions get analysisOptions => driver.analysisDriver!.analysisOptions;
 
   /// Normalize text with bullets.
-  String bulletToDash(StringSink item) => '$item'.replaceAll('•', '-');
+  String bulletToDash(StringSink? item) => '$item'.replaceAll('•', '-');
 
   /// Start a driver for the given [source], optionally providing additional
   /// [args] and an [options] file path. The value of [options] defaults to an
@@ -60,7 +60,7 @@
   /// Like [drive], but takes an array of sources.
   Future<void> driveMany(
     List<String> sources, {
-    String options = emptyOptionsFile,
+    String? options = emptyOptionsFile,
     List<String> args = const <String>[],
   }) async {
     options = _posixToPlatformPath(options);
@@ -112,7 +112,7 @@
   ///
   /// This is a utility method for testing; paths passed in to other methods in
   /// this class are never converted automatically.
-  String _posixToPlatformPath(String filePath) {
+  String? _posixToPlatformPath(String? filePath) {
     if (filePath == null) {
       return null;
     }
@@ -359,7 +359,7 @@
       expect(
           bulletToDash(outSink),
           contains(
-              'warning - The feature android.software.home_screen is not supported on Chrome OS'));
+              "warning - The feature android.software.home_screen isn't supported on Chrome OS"));
       expect(exitCode, 0);
     });
   }
@@ -464,7 +464,7 @@
     ]);
     expect(processorFor(missing_return).severity, ErrorSeverity.ERROR);
     expect(bulletToDash(outSink),
-        contains("error - This function has a return type of 'int'"));
+        contains("error - The body might complete normally"));
     expect(outSink.toString(), contains('1 error and 1 warning found.'));
   }
 
diff --git a/pkg/analyzer_cli/test/embedder_test.dart b/pkg/analyzer_cli/test/embedder_test.dart
index 3420843..584f477 100644
--- a/pkg/analyzer_cli/test/embedder_test.dart
+++ b/pkg/analyzer_cli/test/embedder_test.dart
@@ -12,8 +12,8 @@
 
 void main() {
   group('_embedder.yaml', () {
-    StringSink savedOutSink, savedErrorSink;
-    int savedExitCode;
+    late StringSink savedOutSink, savedErrorSink;
+    late int savedExitCode;
 
     setUp(() {
       savedOutSink = outSink;
diff --git a/pkg/analyzer_cli/test/errors_reported_once_test.dart b/pkg/analyzer_cli/test/errors_reported_once_test.dart
index d25a78e..9fdabc2 100644
--- a/pkg/analyzer_cli/test/errors_reported_once_test.dart
+++ b/pkg/analyzer_cli/test/errors_reported_once_test.dart
@@ -18,9 +18,9 @@
 
 @reflectiveTest
 class ErrorsReportedOnceTest {
-  StringSink savedOutSink, savedErrorSink;
-  int savedExitCode;
-  ExitHandler savedExitHandler;
+  late StringSink savedOutSink, savedErrorSink;
+  late int savedExitCode;
+  late ExitHandler savedExitHandler;
 
   void setUp() {
     savedOutSink = outSink;
diff --git a/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart b/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart
index 16d79dd..510a9ad 100644
--- a/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart
+++ b/pkg/analyzer_cli/test/errors_upgrade_fails_cli_test.dart
@@ -18,9 +18,9 @@
 
 @reflectiveTest
 class ErrorUpgradeFailsCli {
-  StringSink savedOutSink, savedErrorSink;
-  int savedExitCode;
-  ExitHandler savedExitHandler;
+  late StringSink savedOutSink, savedErrorSink;
+  late int savedExitCode;
+  late ExitHandler savedExitHandler;
 
   void setUp() {
     savedOutSink = outSink;
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 405448e..a8b487a 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -32,10 +32,10 @@
   List<DiagnosticMessage> get contextMessages => const [];
 
   @override
-  String get correction => null;
+  String? get correction => null;
 
   @override
-  String get correctionMessage => null;
+  String? get correctionMessage => null;
 
   @override
   DiagnosticMessage get problemMessage => DiagnosticMessageImpl(
@@ -46,7 +46,7 @@
       url: null);
 
   @override
-  Severity get severity => null;
+  Severity get severity => Severity.error;
 }
 
 class MockAnalysisErrorInfo implements AnalysisErrorInfo {
@@ -87,7 +87,7 @@
   String name;
 
   @override
-  String url;
+  String? url;
 
   MockErrorCode(this.type, this.errorSeverity, this.name);
 
@@ -120,7 +120,7 @@
 }
 
 class MockLineInfo implements LineInfo {
-  CharacterLocation defaultLocation;
+  CharacterLocation? defaultLocation;
 
   MockLineInfo({this.defaultLocation});
 
@@ -137,7 +137,7 @@
   @override
   CharacterLocation getLocation(int offset) {
     if (defaultLocation != null) {
-      return defaultLocation;
+      return defaultLocation!;
     }
     throw StateError('Unexpected invocation of getLocation');
   }
@@ -155,55 +155,13 @@
 
 class MockSource implements Source {
   @override
-  String fullName;
-
-  MockSource(this.fullName);
+  final String fullName;
 
   @override
-  TimestampedData<String> get contents {
-    throw StateError('Unexpected invocation of contents');
-  }
+  final Uri uri;
+
+  MockSource(this.fullName, this.uri);
 
   @override
-  String get encoding {
-    throw StateError('Unexpected invocation of encoding');
-  }
-
-  @override
-  bool get isInSystemLibrary {
-    throw StateError('Unexpected invocation of isInSystemLibrary');
-  }
-
-  @override
-  Source get librarySource {
-    throw StateError('Unexpected invocation of librarySource');
-  }
-
-  @override
-  int get modificationStamp {
-    throw StateError('Unexpected invocation of modificationStamp');
-  }
-
-  @override
-  String get shortName {
-    throw StateError('Unexpected invocation of shortName');
-  }
-
-  @override
-  Source get source {
-    throw StateError('Unexpected invocation of source');
-  }
-
-  @override
-  Uri get uri {
-    throw StateError('Unexpected invocation of uri');
-  }
-
-  @override
-  UriKind get uriKind => null; //UriKind.FILE_URI;
-
-  @override
-  bool exists() {
-    throw StateError('Unexpected invocation of exists');
-  }
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 4b7167b..1c151dd 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -24,11 +24,11 @@
       var outStringBuffer = StringBuffer();
       var errorStringBuffer = StringBuffer();
 
-      StringSink savedOutSink, savedErrorSink;
-      int savedExitCode;
-      ExitHandler savedExitHandler;
+      late StringSink savedOutSink, savedErrorSink;
+      late int savedExitCode;
+      late ExitHandler savedExitHandler;
 
-      CommandLineOptions parse(List<String> args,
+      CommandLineOptions? parse(List<String> args,
           {void Function(String msg) printAndFail = printAndFail}) {
         var resourceProvider = PhysicalResourceProvider.INSTANCE;
         return CommandLineOptions.parse(resourceProvider, args,
@@ -53,7 +53,7 @@
       });
 
       test('defaults', () {
-        var options = parse(['--dart-sdk', '.', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', 'foo.dart'])!;
         expect(options, isNotNull);
         expect(options.dartSdkPath, isNotNull);
         expect(options.disableCacheFlushing, isFalse);
@@ -78,19 +78,19 @@
       });
 
       test('batch', () {
-        var options = parse(['--dart-sdk', '.', '--batch']);
+        var options = parse(['--dart-sdk', '.', '--batch'])!;
         expect(options.batchMode, isTrue);
       });
 
       test('defined variables', () {
-        var options = parse(['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart'])!;
         expect(options.declaredVariables['foo'], equals('bar'));
         expect(options.declaredVariables['bar'], isNull);
       });
 
       test('disable cache flushing', () {
         var options =
-            parse(['--dart-sdk', '.', '--disable-cache-flushing', 'foo.dart']);
+            parse(['--dart-sdk', '.', '--disable-cache-flushing', 'foo.dart'])!;
         expect(options.disableCacheFlushing, isTrue);
       });
 
@@ -126,119 +126,126 @@
         };
 
         test('no values', () {
-          var options =
-              overrideKnownFeatures(knownFeatures, () => parse(['foo.dart']));
+          var options = overrideKnownFeatures(
+              knownFeatures, (() => parse(['foo.dart'])!));
           expect(options.enabledExperiments, isEmpty);
         });
 
         test('single value', () {
           var options = overrideKnownFeatures(knownFeatures,
-              () => parse(['--enable-experiment', 'a', 'foo.dart']));
+              (() => parse(['--enable-experiment', 'a', 'foo.dart'])!));
           expect(options.enabledExperiments, ['a']);
         });
 
         group('multiple values', () {
           test('single flag', () {
             var options = overrideKnownFeatures(knownFeatures,
-                () => parse(['--enable-experiment', 'a,b', 'foo.dart']));
+                (() => parse(['--enable-experiment', 'a,b', 'foo.dart'])!));
             expect(options.enabledExperiments, ['a', 'b']);
           });
 
           test('mixed single and multiple flags', () {
             var options = overrideKnownFeatures(
                 knownFeatures,
-                () => parse([
+                (() => parse([
                       '--enable-experiment',
                       'a,b',
                       '--enable-experiment',
                       'c',
                       'foo.dart'
-                    ]));
+                    ])!));
             expect(options.enabledExperiments, ['a', 'b', 'c']);
           });
 
           test('multiple flags', () {
             var options = overrideKnownFeatures(
                 knownFeatures,
-                () => parse([
+                (() => parse([
                       '--enable-experiment',
                       'a',
                       '--enable-experiment',
                       'b',
                       'foo.dart'
-                    ]));
+                    ])!));
             expect(options.enabledExperiments, ['a', 'b']);
           });
         });
       });
 
       test('hintsAreFatal', () {
-        var options = parse(['--dart-sdk', '.', '--fatal-hints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--fatal-hints', 'foo.dart'])!;
         expect(options.infosAreFatal, isTrue);
       });
 
       test('infosAreFatal', () {
-        var options = parse(['--dart-sdk', '.', '--fatal-infos', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--fatal-infos', 'foo.dart'])!;
         expect(options.infosAreFatal, isTrue);
       });
 
       test('log', () {
-        var options = parse(['--dart-sdk', '.', '--log', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--log', 'foo.dart'])!;
         expect(options.log, isTrue);
       });
 
       group('format', () {
         test('json', () {
-          var options = parse(['--dart-sdk', '.', '--format=json', 'foo.dart']);
+          var options =
+              parse(['--dart-sdk', '.', '--format=json', 'foo.dart'])!;
           expect(options.jsonFormat, isTrue);
           expect(options.machineFormat, isFalse);
         });
 
         test('machine', () {
           var options =
-              parse(['--dart-sdk', '.', '--format=machine', 'foo.dart']);
+              parse(['--dart-sdk', '.', '--format=machine', 'foo.dart'])!;
           expect(options.jsonFormat, isFalse);
           expect(options.machineFormat, isTrue);
         });
       });
 
       test('no-hints', () {
-        var options = parse(['--dart-sdk', '.', '--no-hints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--no-hints', 'foo.dart'])!;
         expect(options.disableHints, isTrue);
       });
 
       test('options', () {
-        var options =
-            parse(['--dart-sdk', '.', '--options', 'options.yaml', 'foo.dart']);
+        var options = parse(
+            ['--dart-sdk', '.', '--options', 'options.yaml', 'foo.dart'])!;
         expect(options.defaultAnalysisOptionsPath, endsWith('options.yaml'));
       });
 
       test('lints', () {
-        var options = parse(['--dart-sdk', '.', '--lints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--lints', 'foo.dart'])!;
         expect(options.lints, isTrue);
       });
 
       test('package warnings', () {
         var options =
-            parse(['--dart-sdk', '.', '--package-warnings', 'foo.dart']);
+            parse(['--dart-sdk', '.', '--package-warnings', 'foo.dart'])!;
         expect(options.showPackageWarnings, isTrue);
       });
 
       test('sdk warnings', () {
-        var options = parse(['--dart-sdk', '.', '--sdk-warnings', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--sdk-warnings', 'foo.dart'])!;
         expect(options.showSdkWarnings, isTrue);
       });
 
       test('sourceFiles', () {
-        var options = parse(
-            ['--dart-sdk', '.', '--log', 'foo.dart', 'foo2.dart', 'foo3.dart']);
+        var options = parse([
+          '--dart-sdk',
+          '.',
+          '--log',
+          'foo.dart',
+          'foo2.dart',
+          'foo3.dart'
+        ])!;
         expect(options.sourceFiles,
             equals(['foo.dart', 'foo2.dart', 'foo3.dart']));
       });
 
       test('warningsAreFatal', () {
         var options =
-            parse(['--dart-sdk', '.', '--fatal-warnings', 'foo.dart']);
+            parse(['--dart-sdk', '.', '--fatal-warnings', 'foo.dart'])!;
         expect(options.warningsAreFatal, isTrue);
       });
 
@@ -250,25 +257,25 @@
           '--dart-sdk',
           '.',
           'foo.dart'
-        ]);
+        ])!;
         expect(options, isNotNull);
         expect(options.sourceFiles, equals(['foo.dart']));
       });
 
       test('hintsAreFatal', () {
-        var options = parse(['--dart-sdk', '.', '--fatal-lints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--fatal-lints', 'foo.dart'])!;
         expect(options.lintsAreFatal, isTrue);
       });
 
       test('bad SDK dir', () {
-        String failureMessage;
+        String? failureMessage;
         parse(['--dart-sdk', '&&&&&', 'foo.dart'],
             printAndFail: (msg) => failureMessage = msg);
         expect(failureMessage, equals('Invalid Dart SDK path: &&&&&'));
       });
 
       test('--train-snapshot', () {
-        var options = parse(['--train-snapshot', 'foo.dart']);
+        var options = parse(['--train-snapshot', 'foo.dart'])!;
         expect(options.trainSnapshot, isTrue);
       });
     });
@@ -278,13 +285,13 @@
 
 @reflectiveTest
 class ArgumentsTest with ResourceProviderMixin {
-  CommandLineOptions commandLineOptions;
-  String failureMessage;
+  CommandLineOptions? commandLineOptions;
+  String? failureMessage;
 
   void test_declaredVariables() {
     _parse(['-Da=0', '-Db=', 'a.dart']);
 
-    var definedVariables = commandLineOptions.declaredVariables;
+    var definedVariables = commandLineOptions!.declaredVariables;
 
     expect(definedVariables['a'], '0');
     expect(definedVariables['b'], '');
@@ -296,7 +303,7 @@
     _parse(['--options=$expected', 'a.dart']);
 
     expect(
-      commandLineOptions.defaultAnalysisOptionsPath,
+      commandLineOptions!.defaultAnalysisOptionsPath,
       endsWith(expected),
     );
   }
@@ -306,16 +313,16 @@
     _parse(['--packages=$expected', 'a.dart']);
 
     expect(
-      commandLineOptions.defaultPackagesPath,
+      commandLineOptions!.defaultPackagesPath,
       endsWith(expected),
     );
   }
 
   void test_defaults() {
     _parse(['a.dart']);
-    expect(commandLineOptions.declaredVariables, isEmpty);
-    expect(commandLineOptions.defaultAnalysisOptionsPath, isNull);
-    expect(commandLineOptions.defaultPackagesPath, isNull);
+    expect(commandLineOptions!.declaredVariables, isEmpty);
+    expect(commandLineOptions!.defaultAnalysisOptionsPath, isNull);
+    expect(commandLineOptions!.defaultPackagesPath, isNull);
   }
 
   void test_filterUnknownArguments() {
@@ -554,7 +561,7 @@
     var analysisOptions = AnalysisOptionsImpl();
     configureInitial(analysisOptions);
 
-    commandLineOptions.updateAnalysisOptions(analysisOptions);
+    commandLineOptions!.updateAnalysisOptions(analysisOptions);
     checkApplied(analysisOptions);
   }
 
diff --git a/pkg/analyzer_cli/test/package_prefix_test.dart b/pkg/analyzer_cli/test/package_prefix_test.dart
index 157ffe9..9aa0d57 100644
--- a/pkg/analyzer_cli/test/package_prefix_test.dart
+++ b/pkg/analyzer_cli/test/package_prefix_test.dart
@@ -13,7 +13,7 @@
 
 void main() {
   group('--x-package-warnings-prefix', () {
-    _Runner runner;
+    late _Runner runner;
 
     setUp(() {
       runner = _Runner.setUp();
@@ -21,7 +21,6 @@
 
     tearDown(() {
       runner.tearDown();
-      runner = null;
     });
 
     test('shows only the hint whose package matches the prefix', () async {
diff --git a/pkg/analyzer_cli/test/perf_report_test.dart b/pkg/analyzer_cli/test/perf_report_test.dart
index 933b455..321bb89 100644
--- a/pkg/analyzer_cli/test/perf_report_test.dart
+++ b/pkg/analyzer_cli/test/perf_report_test.dart
@@ -15,7 +15,7 @@
     var options = CommandLineOptions.parse(
       PhysicalResourceProvider.INSTANCE,
       ['somefile.dart'],
-    );
+    )!;
     var encoded = makePerfReport(1000, 1234, options, 0, AnalysisStats());
 
     var jsonData = json.decode(encoded);
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index e0edaba..cffb0ff 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -2,21 +2,23 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/results.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
 import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:path/path.dart' as package_path;
 import 'package:test/test.dart' hide ErrorFormatter;
 
 import 'mocks.dart';
 
 void main() {
   group('reporter', () {
-    StringBuffer out;
-    AnalysisStats stats;
-    MockCommandLineOptions options;
-    ErrorFormatter reporter;
+    late StringBuffer out;
+    late AnalysisStats stats;
+    late MockCommandLineOptions options;
+    late ErrorFormatter reporter;
 
     setUp(() {
       ansi.runningTests = true;
@@ -102,9 +104,15 @@
 
   // Details
   var code = MockErrorCode(type, severity, 'mock_code');
-  var source = MockSource('/foo/bar/baz.dart');
+  var path = '/foo/bar/baz.dart';
+  var source = MockSource(path, package_path.toUri(path));
   var error = MockAnalysisError(source, code, 20, 'MSG');
 
-  return ErrorsResultImpl(
-      null, source.fullName, null, lineInfo, false, [error]);
+  return ErrorsResultImpl(_MockAnslysisSession(), source.fullName,
+      Uri.file('/'), lineInfo, false, [error]);
+}
+
+class _MockAnslysisSession implements AnalysisSession {
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer_cli/test/strong_mode_test.dart b/pkg/analyzer_cli/test/strong_mode_test.dart
index 914a3ef..2f9dc3f 100644
--- a/pkg/analyzer_cli/test/strong_mode_test.dart
+++ b/pkg/analyzer_cli/test/strong_mode_test.dart
@@ -29,7 +29,7 @@
     expect(exitCode, 3);
     var stdout = bulletToDash(outSink);
     expect(stdout, contains("isn't a valid override of"));
-    expect(stdout, contains('error - The list literal type'));
+    expect(stdout, contains('error - A value of type'));
     expect(stdout, contains('2 errors found'));
   }
 }
diff --git a/pkg/analyzer_cli/tool/perf.dart b/pkg/analyzer_cli/tool/perf.dart
index e4e3dcb..2ad2424 100644
--- a/pkg/analyzer_cli/tool/perf.dart
+++ b/pkg/analyzer_cli/tool/perf.dart
@@ -19,7 +19,6 @@
 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 
 void main(List<String> args) async {
@@ -64,12 +63,12 @@
 int scanTotalChars = 0;
 
 /// Factory to load and resolve app, packages, and sdk sources.
-SourceFactory sources;
+late SourceFactory sources;
 
 /// Add to [files] all sources reachable from [start].
-void collectSources(Source start, Set<Source> files) {
+void collectSources(Source? start, Set<Source?> files) {
   if (!files.add(start)) return;
-  var unit = parseDirectives(start);
+  var unit = parseDirectives(start!);
   for (var directive in unit.directives) {
     if (directive is UriBasedDirective) {
       var next = sources.resolveUri(start, directive.uri.stringValue);
@@ -90,7 +89,7 @@
 }
 
 /// Parses every file in [files] and reports the time spent doing so.
-void parseFiles(Set<Source> files) {
+void parseFiles(Set<Source?> files) {
   // The code below will record again how many chars are scanned and how long it
   // takes to scan them, even though we already did so in [scanReachableFiles].
   // Recording and reporting this twice is unnecessary, but we do so for now to
@@ -100,7 +99,7 @@
   scanTotalChars = 0;
   var parseTimer = Stopwatch()..start();
   for (var source in files) {
-    parseFull(source);
+    parseFull(source!);
   }
   parseTimer.stop();
 
@@ -133,7 +132,7 @@
 }
 
 /// Scans every file in [files] and reports the time spent doing so.
-void scanFiles(Set<Source> files) {
+void scanFiles(Set<Source?> files) {
   // The code below will record again how many chars are scanned and how long it
   // takes to scan them, even though we already did so in [scanReachableFiles].
   // Recording and reporting this twice is unnecessary, but we do so for now to
@@ -142,7 +141,7 @@
   var old = scanTotalChars;
   scanTotalChars = 0;
   for (var source in files) {
-    tokenize(source);
+    tokenize(source!);
   }
 
   // Report size and scanning time again. See discussion above.
@@ -152,8 +151,8 @@
 
 /// Load and scans all files we need to process: files reachable from the
 /// entrypoint and all core libraries automatically included by the VM.
-Set<Source> scanReachableFiles(Uri entryUri) {
-  var files = <Source>{};
+Set<Source?> scanReachableFiles(Uri entryUri) {
+  var files = <Source?>{};
   var loadTimer = Stopwatch()..start();
   collectSources(sources.forUri2(entryUri), files);
 
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
index a9597f71..d2d24b8 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
@@ -242,6 +242,13 @@
   }
 
   @override
+  bool hasEditsFor(String path) {
+    return _dartFileEditBuilders.containsKey(path) ||
+        _genericFileEditBuilders.containsKey(path) ||
+        _yamlFileEditBuilders.containsKey(path);
+  }
+
+  @override
   void setSelection(Position position) {
     _selection = position;
   }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 9b0c895..104fc79 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -17,6 +17,7 @@
     hide Element, ElementKind;
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/src/utilities/charcodes.dart';
+import 'package:analyzer_plugin/src/utilities/library.dart';
 import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
@@ -1337,11 +1338,6 @@
   /// the names used in generated code, to information about these imports.
   Map<Uri, _LibraryToImport> librariesToImport = {};
 
-  /// A mapping from libraries that need to be imported relatively in order to
-  /// make visible the names used in generated code, to information about these
-  /// imports.
-  Map<String, _LibraryToImport> librariesToRelativelyImport = {};
-
   /// Initialize a newly created builder to build a source file edit within the
   /// change being built by the given [changeBuilder]. The file being edited has
   /// the given [resolvedUnit] and [timeStamp].
@@ -1350,10 +1346,7 @@
       : super(changeBuilder, resolvedUnit.path, timeStamp);
 
   @override
-  bool get hasEdits =>
-      super.hasEdits ||
-      librariesToImport.isNotEmpty ||
-      librariesToRelativelyImport.isNotEmpty;
+  bool get hasEdits => super.hasEdits || librariesToImport.isNotEmpty;
 
   @override
   void addInsertion(
@@ -1402,9 +1395,6 @@
     for (var entry in librariesToImport.entries) {
       copy.librariesToImport[entry.key] = entry.value;
     }
-    for (var entry in librariesToRelativelyImport.entries) {
-      copy.librariesToRelativelyImport[entry.key] = entry.value;
-    }
     return copy;
   }
 
@@ -1418,9 +1408,6 @@
     if (librariesToImport.isNotEmpty) {
       _addLibraryImports(librariesToImport.values);
     }
-    if (librariesToRelativelyImport.isNotEmpty) {
-      _addLibraryImports(librariesToRelativelyImport.values);
-    }
   }
 
   @override
@@ -1480,8 +1467,12 @@
     return ImportLibraryElementResultImpl(null);
   }
 
-  String importLibraryWithRelativeUri(String uriText, [String? prefix]) {
-    return _importLibraryWithRelativeUri(uriText, prefix).uriText;
+  String importLibraryWithAbsoluteUri(Uri uri, [String? prefix]) {
+    return _importLibrary(uri, prefix: prefix, forceAbsolute: true).uriText;
+  }
+
+  String importLibraryWithRelativeUri(Uri uri, [String? prefix]) {
+    return _importLibrary(uri, prefix: prefix, forceRelative: true).uriText;
   }
 
   @override
@@ -1720,24 +1711,55 @@
   }
 
   /// Computes the best URI to import [uri] into the target library.
-  String _getLibraryUriText(Uri uri) {
-    if (uri.scheme == 'file') {
-      var pathContext = resolvedUnit.session.resourceProvider.pathContext;
-      var whatPath = pathContext.fromUri(uri);
+  ///
+  /// [uri] may be converted from an absolute URI to a relative URI depending on
+  /// user preferences/lints unless [forceAbsolute] or [forceRelative] are `true`.
+  String _getLibraryUriText(
+    Uri uri, {
+    bool forceAbsolute = false,
+    bool forceRelative = false,
+  }) {
+    var pathContext = resolvedUnit.session.resourceProvider.pathContext;
+
+    /// Returns the relative path to import [whatPath] into [resolvedUnit].
+    String getRelativePath(String whatPath) {
       var libraryPath = resolvedUnit.libraryElement.source.fullName;
       var libraryFolder = pathContext.dirname(libraryPath);
       var relativeFile = pathContext.relative(whatPath, from: libraryFolder);
       return pathContext.split(relativeFile).join('/');
     }
+
+    if (uri.isScheme('file')) {
+      var whatPath = pathContext.fromUri(uri);
+      return getRelativePath(whatPath);
+    }
+    var preferRelative = _isLintEnabled('prefer_relative_imports');
+    if (forceRelative || (preferRelative && !forceAbsolute)) {
+      if (canBeRelativeImport(uri, resolvedUnit.uri)) {
+        var whatPath = resolvedUnit.session.uriConverter.uriToPath(uri);
+        if (whatPath != null) {
+          return getRelativePath(whatPath);
+        }
+      }
+    }
     return uri.toString();
   }
 
   /// Arrange to have an import added for the library with the given [uri].
-  _LibraryToImport _importLibrary(Uri uri) {
+  ///
+  /// [uri] may be converted from an absolute URI to a relative URI depending on
+  /// user preferences/lints unless [forceAbsolute] or [forceRelative] are `true`.
+  _LibraryToImport _importLibrary(
+    Uri uri, {
+    String? prefix,
+    bool forceAbsolute = false,
+    bool forceRelative = false,
+  }) {
     var import = (libraryChangeBuilder ?? this).librariesToImport[uri];
     if (import == null) {
-      var uriText = _getLibraryUriText(uri);
-      var prefix =
+      var uriText = _getLibraryUriText(uri,
+          forceAbsolute: forceAbsolute, forceRelative: forceRelative);
+      prefix ??=
           importPrefixGenerator != null ? importPrefixGenerator!(uri) : null;
       import = _LibraryToImport(uriText, prefix);
       (libraryChangeBuilder ?? this).librariesToImport[uri] = import;
@@ -1745,23 +1767,17 @@
     return import;
   }
 
-  /// Arrange to have an import added for the library with the given relative
-  /// [uriText].
-  _LibraryToImport _importLibraryWithRelativeUri(String uriText,
-      [String? prefix]) {
-    var import = librariesToRelativelyImport[uriText];
-    if (import == null) {
-      import = _LibraryToImport(uriText, prefix);
-      librariesToRelativelyImport[uriText] = import;
-    }
-    return import;
-  }
-
   /// Return `true` if the [element] is defined in the target library.
   bool _isDefinedLocally(Element element) {
     return element.library == resolvedUnit.libraryElement;
   }
 
+  bool _isLintEnabled(String lintName) {
+    final analysisOptions =
+        resolvedUnit.session.analysisContext.analysisOptions;
+    return analysisOptions.isLintEnabled(lintName);
+  }
+
   /// Create an edit to replace the return type of the innermost function
   /// containing the given [node] with the type `Future`. The [typeProvider] is
   /// used to check the current return type, because if it is already `Future`
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 2fe6603..bb03fc8 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -69,9 +69,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 class CompletionTarget {
-  /// The compilation unit in which the completion is occurring.
-  final CompilationUnit unit;
-
   /// The offset within the source at which the completion is being requested.
   final int offset;
 
@@ -122,14 +119,8 @@
   ParameterElement? _parameterElement;
 
   /// Compute the appropriate [CompletionTarget] for the given [offset] within
-  /// the [compilationUnit].
-  ///
-  /// Optionally, start the search from within [entryPoint] instead of using
-  /// the [compilationUnit], which is useful for analyzing ASTs that have no
-  /// [compilationUnit] such as dart expressions within angular templates.
-  factory CompletionTarget.forOffset(
-      CompilationUnit compilationUnit, int offset,
-      {AstNode? entryPoint}) {
+  /// the [entryPoint].
+  factory CompletionTarget.forOffset(AstNode entryPoint, int offset) {
     // The precise algorithm is as follows. We perform a depth-first search of
     // all edges in the parse tree (both those that point to AST nodes and
     // those that point to tokens), visiting parents before children. The
@@ -144,7 +135,6 @@
     // prune the search to the point where no recursion is necessary; at each
     // step in the process we know exactly which child node we need to proceed
     // to.
-    entryPoint ??= compilationUnit;
     var containingNode = entryPoint;
     outerLoop:
     while (true) {
@@ -167,11 +157,10 @@
             var commentToken = _getContainingCommentToken(entity, offset);
             if (commentToken != null) {
               return CompletionTarget._(
-                  compilationUnit, offset, containingNode, commentToken, true);
+                  offset, containingNode, commentToken, true);
             }
             // Target found.
-            return CompletionTarget._(
-                compilationUnit, offset, containingNode, entity, false);
+            return CompletionTarget._(offset, containingNode, entity, false);
           } else {
             // Since entity is a token, we don't need to look inside it; just
             // proceed to the next entity.
@@ -198,14 +187,13 @@
                   _getContainingDocComment(containingNode, commentToken);
               if (docComment != null) {
                 return CompletionTarget._(
-                    compilationUnit, offset, docComment, commentToken, false);
+                    offset, docComment, commentToken, false);
               } else {
-                return CompletionTarget._(compilationUnit, offset,
-                    compilationUnit, commentToken, true);
+                return CompletionTarget._(
+                    offset, entryPoint, commentToken, true);
               }
             }
-            return CompletionTarget._(
-                compilationUnit, offset, containingNode, entity, false);
+            return CompletionTarget._(offset, containingNode, entity, false);
           }
 
           // Otherwise, the completion target is somewhere inside the entity,
@@ -228,23 +216,23 @@
       assert(identical(containingNode, entryPoint));
 
       // Check for comments on the EOF token (trailing comments in a file).
-      var commentToken =
-          _getContainingCommentToken(compilationUnit.endToken, offset);
-      if (commentToken != null) {
-        return CompletionTarget._(
-            compilationUnit, offset, compilationUnit, commentToken, true);
+      if (entryPoint is CompilationUnit) {
+        var commentToken =
+            _getContainingCommentToken(entryPoint.endToken, offset);
+        if (commentToken != null) {
+          return CompletionTarget._(offset, entryPoint, commentToken, true);
+        }
       }
 
       // Since no completion target was found, we set the completion target
       // entity to null and use the entryPoint as the parent.
-      return CompletionTarget._(
-          compilationUnit, offset, entryPoint, null, false);
+      return CompletionTarget._(offset, entryPoint, null, false);
     }
   }
 
   /// Create a [CompletionTarget] holding the given [containingNode] and
   /// [entity].
-  CompletionTarget._(this.unit, this.offset, AstNode containingNode,
+  CompletionTarget._(this.offset, AstNode containingNode,
       SyntacticEntity? entity, this.isCommentText)
       : containingNode = containingNode,
         entity = entity,
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index dea31e3..2110c49 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
@@ -20,22 +19,12 @@
 /// suggestions should be made based upon the type of node in which the
 /// suggestions were requested.
 class OpType {
-  /// The [TypeSystem] used during resolution of the current unit.
-  TypeSystem? _typeSystem;
-
   /// Indicates whether constructor suggestions should be included.
   bool includeConstructorSuggestions = false;
 
   /// Indicates whether type names should be suggested.
   bool includeTypeNameSuggestions = false;
 
-  /// If [includeTypeNameSuggestions] is set to true, then this function may
-  /// be set to a non-default function to filter out potential suggestions
-  /// (null) based on their static [DartType], or change the relative relevance
-  /// by returning a higher or lower relevance.
-  SuggestionsFilter typeNameSuggestionsFilter =
-      (DartType _, int relevance) => relevance;
-
   /// Indicates whether setters along with methods and functions that
   /// have a [void] return type should be suggested.
   bool includeVoidReturnSuggestions = false;
@@ -76,10 +65,6 @@
   /// An representation of the location at which completion was requested.
   String? completionLocation;
 
-  /// The type that is required by the context in which the completion was
-  /// activated, or `null` if there is no such type, or it cannot be determined.
-  DartType? _requiredType;
-
   /// Determine the suggestions that should be made based upon the given
   /// [CompletionTarget] and [offset].
   factory OpType.forCompletion(CompletionTarget target, int offset) {
@@ -90,8 +75,6 @@
       return optype;
     }
 
-    optype._typeSystem = target.unit.declaredElement?.library.typeSystem;
-
     var targetNode = target.containingNode;
     targetNode.accept(_OpTypeAstVisitor(optype, target.entity, offset));
 
@@ -111,16 +94,9 @@
 
     // If a value should be suggested, suggest also constructors.
     if (optype.includeReturnValueSuggestions) {
-      // Careful: in angular plugin, `target.unit` may be null!
-      var unitElement = target.unit.declaredElement;
-      if (unitElement != null) {
-        optype.includeConstructorSuggestions = true;
-      }
+      optype.includeConstructorSuggestions = true;
     }
 
-    // Compute the type required by the context and set filters.
-    optype._computeRequiredTypeAndFilters(target);
-
     return optype;
   }
 
@@ -142,59 +118,6 @@
       !includeReturnValueSuggestions &&
       !includeVoidReturnSuggestions;
 
-  /// Try to determine the required context type, and configure filters.
-  void _computeRequiredTypeAndFilters(CompletionTarget target) {
-    var entity = target.entity;
-    AstNode? node = target.containingNode;
-
-    if (node is InstanceCreationExpression &&
-        node.keyword != null &&
-        node.constructorName == entity) {
-      entity = node;
-      node = node.parent;
-    }
-
-    if (node is AssignmentExpression &&
-        node.operator.type == TokenType.EQ &&
-        node.rightHandSide == entity) {
-      _requiredType = node.leftHandSide.staticType;
-    } else if (node is BinaryExpression &&
-        node.operator.type == TokenType.EQ_EQ &&
-        node.rightOperand == entity) {
-      _requiredType = node.leftOperand.staticType;
-    } else if (node is NamedExpression && node.expression == entity) {
-      _requiredType = node.staticParameterElement?.type;
-    } else if (node is SwitchCase && node.expression == entity) {
-      var parent = node.parent;
-      if (parent is SwitchStatement) {
-        _requiredType = parent.expression.staticType;
-      }
-    } else if (node is VariableDeclaration && node.initializer == entity) {
-      _requiredType = node.declaredElement?.type;
-    } else if (entity is Expression && entity.staticParameterElement != null) {
-      _requiredType = entity.staticParameterElement?.type;
-    }
-
-    var requiredType = _requiredType;
-    if (requiredType == null) {
-      return;
-    }
-    if (requiredType.isDynamic || requiredType.isDartCoreObject) {
-      _requiredType = null;
-      return;
-    }
-  }
-
-  /// Return `true` if the [leftType] is a subtype of the [rightType].
-  bool _isSubtypeOf(DartType leftType, DartType rightType) {
-    var typeSystem = _typeSystem;
-    if (typeSystem == null) {
-      return false;
-    }
-
-    return typeSystem.isSubtypeOf(leftType, rightType);
-  }
-
   /// Return the statement before [entity]
   /// where [entity] can be a statement or the `}` closing the given block.
   static Statement? getPreviousStatement(Block node, Object? entity) {
@@ -334,17 +257,6 @@
     if (identical(entity, node.type)) {
       optype.completionLocation = 'AsExpression_type';
       optype.includeTypeNameSuggestions = true;
-      optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
-        var staticType = node.expression.staticType;
-        if (staticType != null &&
-            (staticType.isDynamic ||
-                (optype._isSubtypeOf(dartType, staticType) &&
-                    dartType != staticType))) {
-          return relevance;
-        } else {
-          return null;
-        }
-      };
     }
   }
 
@@ -652,7 +564,6 @@
     if (identical(entity, node.superclass2)) {
       optype.completionLocation = 'ExtendsClause_superclass';
       optype.includeTypeNameSuggestions = true;
-      optype.typeNameSuggestionsFilter = _nonMixinClasses;
     }
   }
 
@@ -947,17 +858,6 @@
     if (identical(entity, node.type)) {
       optype.completionLocation = 'IsExpression_type';
       optype.includeTypeNameSuggestions = true;
-      optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
-        var staticType = node.expression.staticType;
-        if (staticType != null &&
-            (staticType.isDynamic ||
-                (optype._isSubtypeOf(dartType, staticType) &&
-                    dartType != staticType))) {
-          return relevance;
-        } else {
-          return null;
-        }
-      };
     }
   }
 
@@ -1473,18 +1373,6 @@
     return false;
   }
 
-  /// A filter used to disable everything except classes (such as functions and
-  /// mixins).
-  int? _nonMixinClasses(DartType type, int relevance) {
-    if (type is InterfaceType) {
-      if (type.element.isMixin) {
-        return null;
-      }
-      return relevance;
-    }
-    return null;
-  }
-
   static bool _isParameterOfGenericFunctionType(FormalParameter node) {
     var parameterList = node.parent;
     if (parameterList is DefaultFormalParameter) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/library.dart b/pkg/analyzer_plugin/lib/src/utilities/library.dart
new file mode 100644
index 0000000..8fa8383
--- /dev/null
+++ b/pkg/analyzer_plugin/lib/src/utilities/library.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Checks whether importing the library with URI [library2] into the
+/// library with URI [library1] could be a relative import.
+///
+/// Both URIs must be package: URIs and belong to the same package for this to
+/// be true.
+bool canBeRelativeImport(Uri library1, Uri library2) {
+  return library1.isScheme('package') &&
+      library2.isScheme('package') &&
+      library1.pathSegments.isNotEmpty &&
+      library2.pathSegments.isNotEmpty &&
+      library1.pathSegments.first == library2.pathSegments.first;
+}
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index 3e6290b..58791ae 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -69,7 +69,8 @@
   /// for example to allow key-binding specific fixes (or groups of).
   final String id;
 
-  /// The priority of this kind of assist for the kind of error being addressed.
+  /// The priority of this kind of assist for the kind of error being addressed
+  /// where a higher integer value indicates a higher priority and relevance.
   final int priority;
 
   /// A human-readable description of the changes that will be applied by this
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart
index e407543..804c3c4c 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_core.dart
@@ -63,6 +63,10 @@
   /// that changes to the copy will not effect this change builder.
   ChangeBuilder copy();
 
+  /// Return `true` if this builder already has edits for the file with the
+  /// given [path].
+  bool hasEditsFor(String path);
+
   /// Set the selection for the change being built to the given [position].
   void setSelection(Position position);
 }
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 6bd6c78..4eababe 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -346,6 +346,9 @@
   ///
   /// Returns the text of the URI that will be used in the import directive.
   /// It can be different than the given [Uri].
+  ///
+  /// [uri] may be converted from an absolute URI to a relative URI depending on
+  /// user preferences/lints.
   String importLibrary(Uri uri);
 
   /// Ensure that the library with the given [uri] is imported.
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
index cf0a57b..77cc825 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -59,8 +59,8 @@
     CompletionTarget? target,
     OpType? optype,
   }) async {
-    target ??= CompletionTarget.forOffset(request.result.unit, request.offset,
-        entryPoint: entryPoint);
+    entryPoint ??= request.result.unit;
+    target ??= CompletionTarget.forOffset(entryPoint, request.offset);
     optype ??= OpType.forCompletion(target, request.offset);
     if (!optype.includeIdentifiers) {
       return;
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
index a27010c..d88f47a 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
@@ -29,7 +29,7 @@
     var containingLibrary = request.result.libraryElement;
 
     // Recompute the target since resolution may have changed it
-    var expression = _computeDotTarget(request, null);
+    var expression = _computeDotTarget(request.result.unit, request.offset);
     if (expression == null || expression.isSynthetic) {
       return;
     }
@@ -42,7 +42,7 @@
     var containingLibrary = request.result.libraryElement;
 
     // Recompute the target since resolution may have changed it
-    var expression = _computeDotTarget(request, entryPoint);
+    var expression = _computeDotTarget(entryPoint, request.offset);
     if (expression == null || expression.isSynthetic) {
       return;
     }
@@ -50,10 +50,8 @@
   }
 
   /// Update the completion [target] and [dotTarget] based on the given [unit].
-  Expression? _computeDotTarget(
-      DartCompletionRequest request, AstNode? entryPoint) {
-    var target = CompletionTarget.forOffset(request.result.unit, request.offset,
-        entryPoint: entryPoint);
+  Expression? _computeDotTarget(AstNode entryPoint, int offset) {
+    var target = CompletionTarget.forOffset(entryPoint, offset);
     return target.dotTarget;
   }
 
diff --git a/pkg/analyzer_plugin/test/plugin/mocks.dart b/pkg/analyzer_plugin/test/plugin/mocks.dart
index 338593b..bf4de1d 100644
--- a/pkg/analyzer_plugin/test/plugin/mocks.dart
+++ b/pkg/analyzer_plugin/test/plugin/mocks.dart
@@ -159,18 +159,18 @@
   @override
   TimestampedData<String> get contents => TimestampedData(0, '');
 
+  @Deprecated('Not used anymore')
   @override
   String get encoding => '';
 
   @override
   String get fullName => '/pkg/lib/test.dart';
 
+  @Deprecated('Use uri.isScheme("dart") instead')
   @override
   bool get isInSystemLibrary => false;
 
-  @override
-  Source get librarySource => this;
-
+  @Deprecated('Not used anymore')
   @override
   int get modificationStamp => 0;
 
@@ -178,11 +178,9 @@
   String get shortName => 'test.dart';
 
   @override
-  Source get source => this;
-
-  @override
   Uri get uri => Uri.parse('package:test/test.dart');
 
+  @Deprecated('Use Source.uri instead')
   @override
   UriKind get uriKind => UriKind.PACKAGE_URI;
 
diff --git a/pkg/analyzer_utilities/lib/check/bool.dart b/pkg/analyzer_utilities/lib/check/bool.dart
new file mode 100644
index 0000000..18d5054
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/bool.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check.dart';
+
+extension BoolExtension on CheckTarget<bool> {
+  void get isTrue {
+    if (!value) {
+      fail('is not true');
+    }
+  }
+
+  void get isFalse {
+    if (value) {
+      fail('is not false');
+    }
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/check/check.dart b/pkg/analyzer_utilities/lib/check/check.dart
new file mode 100644
index 0000000..b3147bb
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/check.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check_target.dart';
+import 'package:meta/meta.dart';
+
+export 'package:analyzer_utilities/check/bool.dart';
+export 'package:analyzer_utilities/check/check_target.dart';
+export 'package:analyzer_utilities/check/equality.dart';
+export 'package:analyzer_utilities/check/int.dart';
+export 'package:analyzer_utilities/check/iterable.dart';
+export 'package:analyzer_utilities/check/string.dart';
+export 'package:analyzer_utilities/check/type.dart';
+
+@useResult
+CheckTarget<T> check<T>(T value) {
+  return CheckTarget(value, 0, () => '$value');
+}
diff --git a/pkg/analyzer_utilities/lib/check/check_target.dart b/pkg/analyzer_utilities/lib/check/check_target.dart
new file mode 100644
index 0000000..1d0e608
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/check_target.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart' as test_package;
+
+class CheckTarget<T> {
+  final T value;
+  final int _depth;
+
+  /// The function that return the description of the value, and of the
+  /// chain how we arrived to this value.
+  final String Function() _describe;
+
+  CheckTarget(this.value, this._depth, this._describe);
+
+  String get _indent => '  ' * (_depth + 1);
+
+  String valueStr(value) {
+    if (value is String) {
+      return "'$value'";
+    }
+    return '$value';
+  }
+
+  Never fail(String message) {
+    test_package.fail(_describe() + '\n' + _indent + message);
+  }
+
+  /// Chains to the given [value]; if a subsequent check fails, [describe]
+  /// will be invoked to describe the [value].
+  CheckTarget<U> nest<U>(
+    U value,
+    String Function(U value) describe,
+  ) {
+    return CheckTarget(value, _depth + 1, () {
+      return _describe() + '\n' + _indent + describe(value);
+    });
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/check/equality.dart b/pkg/analyzer_utilities/lib/check/equality.dart
new file mode 100644
index 0000000..2d265b8
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/equality.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check.dart';
+
+extension EqualityExtension<T> on CheckTarget<T> {
+  void isEqualTo(Object? other) {
+    if (value != other) {
+      fail('is not equal to $other');
+    }
+  }
+
+  void isNotEqualTo(Object? other) {
+    if (value == other) {
+      fail('is equal to $other');
+    }
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/check/int.dart b/pkg/analyzer_utilities/lib/check/int.dart
new file mode 100644
index 0000000..59587b2
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/int.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check.dart';
+
+extension IntExtension on CheckTarget<int> {
+  void get isZero {
+    if (value != 0) {
+      fail('is not zero');
+    }
+  }
+
+  void isGreaterThan(int other) {
+    if (!(value > other)) {
+      fail('is not greater than $other');
+    }
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/check/iterable.dart b/pkg/analyzer_utilities/lib/check/iterable.dart
new file mode 100644
index 0000000..0e3e0d3
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/iterable.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
+
+extension IterableExtension<T> on CheckTarget<Iterable<T>> {
+  void get isEmpty {
+    if (value.isNotEmpty) {
+      fail('is not empty');
+    }
+  }
+
+  void get isNotEmpty {
+    if (value.isEmpty) {
+      fail('is empty');
+    }
+  }
+
+  @UseResult.unless(parameterDefined: 'expected')
+  CheckTarget<int> hasLength([int? expected]) {
+    var actual = value.length;
+
+    if (expected != null && actual != expected) {
+      fail('does not have length ${valueStr(expected)}');
+    }
+
+    return nest(actual, (length) => 'has length $length');
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/check/string.dart b/pkg/analyzer_utilities/lib/check/string.dart
new file mode 100644
index 0000000..3d80003
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/string.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
+
+extension StringExtension on CheckTarget<String> {
+  void contains(Pattern other) {
+    if (!value.contains(other)) {
+      fail('does not contain ${valueStr(other)}');
+    }
+  }
+
+  void startsWith(Pattern other) {
+    if (!value.startsWith(other)) {
+      fail('does not start with ${valueStr(other)}');
+    }
+  }
+
+  @UseResult.unless(parameterDefined: 'expected')
+  CheckTarget<int> hasLength([int? expected]) {
+    var actual = value.length;
+
+    if (expected != null && actual != expected) {
+      fail('does not have length ${valueStr(expected)}');
+    }
+
+    return nest(actual, (length) => 'has length $length');
+  }
+}
diff --git a/pkg/analyzer_utilities/lib/check/type.dart b/pkg/analyzer_utilities/lib/check/type.dart
new file mode 100644
index 0000000..ea28b9e
--- /dev/null
+++ b/pkg/analyzer_utilities/lib/check/type.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check.dart';
+
+extension IsExtension<T> on CheckTarget<T> {
+  CheckTarget<U> isA<U extends T>() {
+    final value = this.value;
+    if (value is U) {
+      return nest(value, (_) => 'is of type $U');
+    } else {
+      fail('is not of type $U');
+    }
+  }
+}
diff --git a/pkg/analyzer_utilities/pubspec.yaml b/pkg/analyzer_utilities/pubspec.yaml
index a8426e4..d0aac18 100644
--- a/pkg/analyzer_utilities/pubspec.yaml
+++ b/pkg/analyzer_utilities/pubspec.yaml
@@ -9,5 +9,7 @@
   analyzer:
     path: ../analyzer
   html: any
+  meta:
+    path: ../meta
   path: any
   test: any
diff --git a/pkg/analyzer_utilities/test/check/check_test.dart b/pkg/analyzer_utilities/test/check/check_test.dart
new file mode 100644
index 0000000..cc52f80
--- /dev/null
+++ b/pkg/analyzer_utilities/test/check/check_test.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('type', () {
+    group('bool', () {
+      test('isEqualTo', () {
+        check(true).isEqualTo(true);
+        check(false).isEqualTo(false);
+        _fails(() => check(true).isEqualTo(false));
+        _fails(() => check(false).isEqualTo(true));
+      });
+      test('isFalse', () {
+        check(false).isFalse;
+        _fails(() => check(true).isFalse);
+      });
+      test('isNotEqualTo', () {
+        check(true).isNotEqualTo(false);
+        check(false).isNotEqualTo(true);
+        _fails(() => check(true).isNotEqualTo(true));
+        _fails(() => check(false).isNotEqualTo(false));
+      });
+      test('isTrue', () {
+        check(true).isTrue;
+        _fails(() => check(false).isTrue);
+      });
+    });
+    group('int', () {
+      test('isEqualTo', () {
+        check(0).isEqualTo(0);
+        check(1).isEqualTo(1);
+        check(2).isEqualTo(2);
+        _fails(() => check(0).isEqualTo(1));
+        _fails(() => check(1).isEqualTo(0));
+      });
+      test('isGreaterThan', () {
+        check(2).isGreaterThan(1);
+        check(1).isGreaterThan(0);
+        check(-1).isGreaterThan(-2);
+        _fails(() => check(0).isGreaterThan(0));
+        _fails(() => check(0).isGreaterThan(1));
+        _fails(() => check(1).isGreaterThan(2));
+        _fails(() => check(-2).isGreaterThan(-1));
+      });
+      test('isNotEqualTo', () {
+        check(0).isNotEqualTo(1);
+        check(1).isNotEqualTo(0);
+        check(1).isNotEqualTo(2);
+        check(2).isNotEqualTo(1);
+        _fails(() => check(0).isNotEqualTo(0));
+        _fails(() => check(1).isNotEqualTo(1));
+        _fails(() => check(2).isNotEqualTo(2));
+      });
+      test('isZero', () {
+        check(0).isZero;
+        _fails(() => check(1).isZero);
+        _fails(() => check(-1).isZero);
+      });
+    });
+    group('Iterable', () {
+      test('hasLength', () {
+        check(<int>[]).hasLength().isZero;
+        check(<int>[0]).hasLength().isEqualTo(1);
+        check(<int>[0]).hasLength(1);
+        check(<int>[0, 1]).hasLength().isEqualTo(2);
+        check(<int>[0, 1]).hasLength(2);
+        check(<int>{}).hasLength().isZero;
+        check(<int>{0}).hasLength().isEqualTo(1);
+        check(<int>{0}).hasLength(1);
+        check(<int>{0, 1}).hasLength().isEqualTo(2);
+        check(<int>{0, 1}).hasLength(2);
+        _fails(() => check(<int>[]).hasLength(1));
+        _fails(() => check(<int>[]).hasLength(2));
+        _fails(() => check(<int>{}).hasLength(1));
+        _fails(() => check(<int>{}).hasLength(2));
+        _fails(() => check(<int>[]).hasLength().isEqualTo(1));
+        _fails(() => check(<int>[0]).hasLength().isEqualTo(0));
+      });
+      test('isEmpty', () {
+        check(<int>[]).isEmpty;
+        check(<int>{}).isEmpty;
+        _fails(() => check([0]).isEmpty);
+        _fails(() => check([0, 1]).isEmpty);
+        _fails(() => check({0}).isEmpty);
+        _fails(() => check({0, 1}).isEmpty);
+      });
+      test('isNotEmpty', () {
+        check([0]).isNotEmpty;
+        check([0, 1]).isNotEmpty;
+        check({0}).isNotEmpty;
+        check({0, 1}).isNotEmpty;
+        _fails(() => check(<int>[]).isNotEmpty);
+        _fails(() => check(<int>{}).isNotEmpty);
+      });
+    });
+    group('String', () {
+      test('contains', () {
+        check('abc').contains('a');
+        check('abc').contains('b');
+        check('abc').contains('c');
+        check('abc').contains('ab');
+        check('abc').contains('bc');
+        check('abc').contains(RegExp('a'));
+        check('abc').contains(RegExp('a.'));
+        check('abc').contains(RegExp('a.c'));
+        check('abc').contains(RegExp('.b.'));
+        _fails(() => check('abc').contains('x'));
+        _fails(() => check('abc').contains('ac'));
+        _fails(() => check('abc').contains(RegExp('ac.')));
+      });
+      test('hasLength', () {
+        check('').hasLength().isZero;
+        check('').hasLength(0);
+        check('a').hasLength().isEqualTo(1);
+        check('a').hasLength(1);
+        check('abc').hasLength().isEqualTo(3);
+        check('abc').hasLength(3);
+        _fails(() => check('abc').hasLength(0));
+        _fails(() => check('abc').hasLength(1));
+        _fails(() => check('abc').hasLength(2));
+      });
+      test('isEqualTo', () {
+        check('').isEqualTo('');
+        check('abc').isEqualTo('abc');
+        check('foobar').isEqualTo('foobar');
+        _fails(() => check('abc').isEqualTo('ab'));
+        _fails(() => check('abc').isEqualTo('xyz'));
+      });
+      test('isNotEqualTo', () {
+        check('abc').isNotEqualTo('ab');
+        check('abc').isNotEqualTo('xyz');
+        _fails(() => check('abc').isNotEqualTo('abc'));
+        _fails(() => check('foobar').isNotEqualTo('foobar'));
+      });
+      test('startsWith', () {
+        check('abc').startsWith('a');
+        check('abc').startsWith('ab');
+        check('abc').startsWith('abc');
+        check('abc').startsWith(RegExp('..c'));
+        check('abc').startsWith(RegExp('.*c'));
+        _fails(() => check('abc').startsWith('b'));
+        _fails(() => check('abc').startsWith('x'));
+        _fails(() => check('abc').startsWith(RegExp('.c')));
+      });
+    });
+    group('type', () {
+      test('isA', () {
+        check(0).isA<int>();
+        _fails(() => check('abc' as dynamic).isA<int>());
+      });
+    });
+  });
+}
+
+void _fails(void Function() f) {
+  try {
+    f();
+  } on TestFailure {
+    return;
+  }
+  fail('expected to fail');
+}
diff --git a/pkg/compiler/lib/compiler_new.dart b/pkg/compiler/lib/compiler_new.dart
index 4b1d89f..5a4ccc8 100644
--- a/pkg/compiler/lib/compiler_new.dart
+++ b/pkg/compiler/lib/compiler_new.dart
@@ -82,6 +82,9 @@
   /// Deferred map output.
   deferredMap,
 
+  /// Unused libraries output.
+  dumpUnusedLibraries,
+
   /// Implementation specific output used for debugging the compiler.
   debug,
 }
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 8737b26..18fa4cb 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -175,6 +175,9 @@
   // For backward compatibility the option is still accepted, but it is ignored.
   static const String initializingFormalAccess = '--initializing-formal-access';
 
+  // Whether or not to dump a list of unused libraries.
+  static const String dumpUnusedLibraries = '--dump-unused-libraries';
+
   // Experimental flags.
   static const String resolveOnly = '--resolve-only';
 
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index e8b8488..3f766ba 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -23,6 +23,7 @@
 import '../js_backend/string_reference.dart' show StringReference;
 import '../js_backend/type_reference.dart' show TypeReference;
 import '../js_emitter/code_emitter_task.dart' show Emitter;
+import '../js_model/elements.dart' show JGeneratorBody;
 import '../js_model/type_recipe.dart' show TypeRecipe;
 import '../native/behavior.dart';
 import '../serialization/serialization.dart';
@@ -720,32 +721,35 @@
     sink.end(tag);
   }
 
+  @override
+  bool get isFinalized => _value != null;
+
   js.Name get value {
-    assert(_value != null, 'value not set for $this');
+    assert(isFinalized, 'value not set for $this');
     return _value;
   }
 
   void set value(js.Name node) {
-    assert(_value == null);
+    assert(!isFinalized);
     assert(node != null);
     _value = node.withSourceInformation(sourceInformation);
   }
 
   @override
   String get key {
-    assert(_value != null);
+    assert(isFinalized);
     return _value.key;
   }
 
   @override
   String get name {
-    assert(_value != null, 'value not set for $this');
+    assert(isFinalized, 'value not set for $this');
     return _value.name;
   }
 
   @override
   bool get allowRename {
-    assert(_value != null, 'value not set for $this');
+    assert(isFinalized, 'value not set for $this');
     return _value.allowRename;
   }
 
@@ -771,6 +775,98 @@
   @override
   String toString() =>
       'ModularName(kind=$kind, data=$data, value=${_value?.key})';
+
+  @override
+  String nonfinalizedDebugText() {
+    switch (kind) {
+      case ModularNameKind.rtiField:
+        return r'ModularName"$ti"';
+      case ModularNameKind.instanceField:
+        return 'ModularName"field:${(data as Entity).name}"';
+      case ModularNameKind.instanceMethod:
+        return 'ModularName"${_instanceMethodName(data)}"';
+      case ModularNameKind.methodProperty:
+        return 'ModularName"methodProperty:${(data as Entity).name}"';
+      case ModularNameKind.operatorIs:
+        return 'ModularName"is:${_className(data)}"';
+      case ModularNameKind.className:
+        return 'ModularName"class:${_className(data)}"';
+      case ModularNameKind.globalPropertyNameForClass:
+        return 'ModularName"classref:${_className(data)}"';
+      case ModularNameKind.aliasedSuperMember:
+        MemberEntity member = (data as MemberEntity);
+        String className = _className(member.enclosingClass);
+        String invocationName = Namer.operatorNameToIdentifier(member.name);
+        final description = "$className.$invocationName";
+        return 'ModularName"alias:$description"';
+      case ModularNameKind.staticClosure:
+        return 'ModularName"closure:${_qualifiedStaticName(data)}"';
+      case ModularNameKind.lazyInitializer:
+        return 'ModularName"lazy:${(data as MemberEntity).name}"';
+      case ModularNameKind.globalPropertyNameForMember:
+        MemberEntity member = data as MemberEntity;
+        return 'ModularName"ref:${_qualifiedStaticName(member)}"';
+      case ModularNameKind.invocation:
+        return 'ModularName"selector:${_selectorText(data as Selector)}"';
+      case ModularNameKind.nameForOneShotInterceptor:
+        return 'ModularName"oneshot:${_selectorText(data as Selector)}"';
+      case ModularNameKind.globalNameForInterfaceTypeVariable:
+        break;
+      case ModularNameKind.nameForGetInterceptor:
+        return 'ModularName"getInterceptor"';
+      case ModularNameKind.asName:
+        return 'ModularName"asName:$data"';
+    }
+    return super.nonfinalizedDebugText();
+  }
+
+  String _className(ClassEntity cls) {
+    return cls.name.replaceAll('&', '_');
+  }
+
+  String _qualifiedStaticName(MemberEntity member) {
+    if (member.isConstructor || member.isStatic) {
+      return '${_className(member.enclosingClass)}.${member.name}';
+    }
+    return member.name;
+  }
+
+  String _instanceMethodInvocationName(MemberEntity member) {
+    String invocationName = Namer.operatorNameToIdentifier(member.name);
+    if (member.isGetter) invocationName = r'get$' + invocationName;
+    if (member.isSetter) invocationName = r'set$' + invocationName;
+    return invocationName;
+  }
+
+  String _instanceMethodName(MemberEntity member) {
+    if (member is ConstructorBodyEntity) {
+      return 'constructorBody:${_qualifiedStaticName(member.constructor)}';
+    }
+    if (member is JGeneratorBody) {
+      MemberEntity function = member.function;
+      return 'generatorBody:'
+          '${_className(function.enclosingClass)}.'
+          '${_instanceMethodInvocationName(function)}';
+    }
+    return 'instanceMethod:${_instanceMethodInvocationName(member)}';
+  }
+
+  String _selectorText(Selector selector) {
+    // Approximation to unminified selector.
+    if (selector.isGetter) return r'get$' + selector.name;
+    if (selector.isSetter) return r'set$' + selector.name;
+    if (selector.isOperator || selector.isIndex || selector.isIndexSet) {
+      return Namer.operatorNameToIdentifier(selector.name);
+    }
+    List<String> parts = [
+      selector.name,
+      if (selector.callStructure.typeArgumentCount > 0)
+        '${selector.callStructure.typeArgumentCount}',
+      '${selector.callStructure.argumentCount}',
+      ...selector.callStructure.getOrderedNamedArguments()
+    ];
+    return parts.join(r'$');
+  }
 }
 
 enum ModularExpressionKind {
@@ -819,13 +915,16 @@
   }
 
   @override
+  bool get isFinalized => _value != null;
+
+  @override
   js.Expression get value {
-    assert(_value != null);
+    assert(isFinalized);
     return _value;
   }
 
   void set value(js.Expression node) {
-    assert(_value == null);
+    assert(!isFinalized);
     assert(node != null);
     _value = node.withSourceInformation(sourceInformation);
   }
@@ -863,6 +962,17 @@
     sb.write(',value=$_value)');
     return sb.toString();
   }
+
+  @override
+  String nonfinalizedDebugText() {
+    switch (kind) {
+      case ModularExpressionKind.constant:
+        return 'ModularExpression"<constant>"';
+      case ModularExpressionKind.embeddedGlobalAccess:
+        return 'ModularExpression"init.$data"';
+    }
+    return super.nonfinalizedDebugText();
+  }
 }
 
 enum JsNodeKind {
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 84c3c2b..d4e63fb 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -2228,13 +2228,13 @@
   /// Return `null` if the member is not found in the class or any superclass.
   MemberEntity lookupClassMember(ClassEntity cls, String name,
       {bool setter = false}) {
-    var entity = lookupLocalClassMember(cls, name, setter: setter);
-    if (entity != null) return entity;
+    while (true) {
+      final entity = lookupLocalClassMember(cls, name, setter: setter);
+      if (entity != null) return entity;
 
-    var superclass = getSuperClass(cls);
-    if (superclass == null) return null;
-
-    return lookupClassMember(superclass, name, setter: setter);
+      cls = getSuperClass(cls);
+      if (cls == null) return null;
+    }
   }
 
   /// Lookup the constructor [name] in [cls], fail if the class is missing and
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index b899fbe..146e093 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -5,6 +5,7 @@
 library dart2js.compiler_base;
 
 import 'dart:async' show Future;
+import 'dart:convert' show jsonEncode;
 
 import 'package:front_end/src/api_unstable/dart2js.dart'
     show clearStringTokenCanonicalizer;
@@ -178,8 +179,7 @@
     enqueuer = EnqueueTask(this);
 
     tasks = [
-      kernelLoader = KernelLoaderTask(
-          options, provider, _outputProvider, reporter, measurer),
+      kernelLoader = KernelLoaderTask(options, provider, reporter, measurer),
       kernelFrontEndTask,
       globalInference = GlobalTypeInferenceTask(this),
       deferredLoadTask = frontendStrategy.createDeferredLoadTask(this),
@@ -247,6 +247,31 @@
     return options.readClosedWorldUri != null && options.readDataUri != null;
   }
 
+  /// Dumps a list of unused [ir.Library]'s in the [KernelResult]. This *must*
+  /// be called before [setMainAndTrimComponent], because that method will
+  /// discard the unused [ir.Library]s.
+  void dumpUnusedLibraries(KernelResult result) {
+    var usedUris = result.libraries.toSet();
+    bool isUnused(ir.Library l) => !usedUris.contains(l.importUri);
+    String libraryString(ir.Library library) {
+      return '${library.importUri}(${library.fileUri})';
+    }
+
+    var unusedLibraries =
+        result.component.libraries.where(isUnused).map(libraryString).toList();
+    unusedLibraries.sort();
+    var jsonLibraries = jsonEncode(unusedLibraries);
+    outputProvider.createOutputSink(options.outputUri.pathSegments.last,
+        'unused.json', api.OutputType.dumpUnusedLibraries)
+      ..add(jsonLibraries)
+      ..close();
+    reporter.reportInfo(
+        reporter.createMessage(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, {
+      'text': "${unusedLibraries.length} unused libraries out of "
+          "${result.component.libraries.length}. Dumping to JSON."
+    }));
+  }
+
   Future runInternal() async {
     clearState();
     var compilationTarget = options.compilationTarget;
@@ -275,13 +300,8 @@
           performGlobalTypeInference(closedWorldAndIndices.closedWorld);
       var indices = closedWorldAndIndices.indices;
       if (options.writeDataUri != null) {
-        if (options.noClosedWorldInData) {
-          serializationTask.serializeGlobalTypeInference(
-              globalTypeInferenceResults, indices);
-        } else {
-          serializationTask
-              .serializeGlobalTypeInferenceLegacy(globalTypeInferenceResults);
-        }
+        serializationTask.serializeGlobalTypeInference(
+            globalTypeInferenceResults, indices);
         return;
       }
       await generateJavaScriptCode(globalTypeInferenceResults,
@@ -301,12 +321,6 @@
               closedWorldAndIndices);
       await generateJavaScriptCode(globalTypeInferenceResults,
           indices: closedWorldAndIndices.indices);
-    } else if (options.readDataUri != null) {
-      // TODO(joshualitt) delete and clean up after google3 roll
-      var globalTypeInferenceResults =
-          await serializationTask.deserializeGlobalTypeInferenceLegacy(
-              environment, abstractValueStrategy);
-      await generateJavaScriptCode(globalTypeInferenceResults);
     } else {
       KernelResult result = await kernelLoader.load();
       reporter.log("Kernel load complete");
@@ -317,7 +331,6 @@
       if (retainDataForTesting) {
         componentForTesting = result.component;
       }
-      if (options.cfeOnly) return;
 
       frontendStrategy.registerLoadedLibraries(result);
 
@@ -325,12 +338,37 @@
         await runModularAnalysis(result);
       } else {
         List<ModuleData> data;
-        if (options.modularAnalysisInputs != null) {
+        if (options.hasModularAnalysisInputs) {
           data =
               await serializationTask.deserializeModuleData(result.component);
         }
         frontendStrategy.registerModuleData(data);
-        await compileFromKernel(result.rootLibraryUri, result.libraries);
+
+        // After we've deserialized modular data, we set and verify the main
+        // method as well as trim the component of any unnecessary dependencies.
+        // Note: It is critical we wait to trim the dill until after we've
+        // deserialized modular data because some of this data may reference
+        // 'trimmed' elements.
+        if (options.fromDill) {
+          if (options.dumpUnusedLibraries) {
+            dumpUnusedLibraries(result);
+          }
+          if (options.entryUri != null) {
+            result.setMainAndTrimComponent(options.entryUri);
+          }
+          if (result.component.mainMethod == null) {
+            // TODO(sigmund): move this so that we use the same error template
+            // from the CFE.
+            _reporter.reportError(_reporter.createMessage(NO_LOCATION_SPANNABLE,
+                MessageKind.GENERIC, {'text': "No 'main' method found."}));
+            return;
+          }
+        }
+        if (options.cfeOnly) {
+          await serializationTask.serializeComponent(result.component);
+        } else {
+          await compileFromKernel(result.rootLibraryUri, result.libraries);
+        }
       }
     }
   }
@@ -543,16 +581,6 @@
       if (stopAfterClosedWorld || options.stopAfterProgramSplit) return;
       GlobalTypeInferenceResults globalInferenceResults =
           performGlobalTypeInference(closedWorld);
-      if (options.writeDataUri != null) {
-        // TODO(joshualitt) delete after google3 roll.
-        if (options.noClosedWorldInData) {
-          throw '"no-closed-world-in-data" requires serializing closed world.';
-        } else {
-          serializationTask
-              .serializeGlobalTypeInferenceLegacy(globalInferenceResults);
-        }
-        return;
-      }
       if (options.testMode) {
         globalInferenceResults =
             globalTypeInferenceResultsTestMode(globalInferenceResults);
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 144d936..86abfd0 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -857,10 +857,16 @@
   ConstantValueKind get kind => ConstantValueKind.JS_NAME;
 
   @override
-  String toDartText(DartTypes dartTypes) => 'js_name(${name})';
+  String toDartText(DartTypes dartTypes) {
+    if (name.isFinalized) 'js_name(${name})';
+    return 'js_name(name.nonfinalizedDebugText())';
+  }
 
   @override
-  String toStructuredText(DartTypes dartTypes) => 'JsNameConstant(${name})';
+  String toStructuredText(DartTypes dartTypes) {
+    if (name.isFinalized) return 'JsNameConstant(${name})';
+    return 'JsNameConstant(name.nonfinalizedDebugText())';
+  }
 }
 
 /// A constant used as the dummy receiver value for intercepted calls with
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index bd60c69..8a49df4 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -548,7 +548,7 @@
         setWriteModularAnalysis),
     OptionHandler('${Flags.readData}|${Flags.readData}=.+', setReadData),
     OptionHandler('${Flags.writeData}|${Flags.writeData}=.+', setWriteData),
-    OptionHandler(Flags.noClosedWorldInData, passThrough),
+    OptionHandler(Flags.noClosedWorldInData, ignoreOption),
     OptionHandler('${Flags.readClosedWorld}|${Flags.readClosedWorld}=.+',
         setReadClosedWorld),
     OptionHandler('${Flags.writeClosedWorld}|${Flags.writeClosedWorld}=.+',
@@ -627,6 +627,7 @@
     OptionHandler(Flags.benchmarkingExperiment, passThrough),
     OptionHandler(Flags.soundNullSafety, setNullSafetyMode),
     OptionHandler(Flags.noSoundNullSafety, setNullSafetyMode),
+    OptionHandler(Flags.dumpUnusedLibraries, passThrough),
 
     // TODO(floitsch): remove conditional directives flag.
     // We don't provide the info-message yet, since we haven't publicly
@@ -664,10 +665,17 @@
     // Wire up feature flags.
     OptionHandler(Flags.canary, passThrough),
     OptionHandler(Flags.noShipping, passThrough),
+    // Shipped features.
+    for (var feature in features.shipped)
+      OptionHandler('--${feature.flag}', passThrough),
+    for (var feature in features.shipped)
+      OptionHandler('--no-${feature.flag}', passThrough),
+    // Shipping features.
     for (var feature in features.shipping)
       OptionHandler('--${feature.flag}', passThrough),
     for (var feature in features.shipping)
       OptionHandler('--no-${feature.flag}', passThrough),
+    // Canary features.
     for (var feature in features.canary)
       OptionHandler('--${feature.flag}', passThrough),
     for (var feature in features.canary)
@@ -825,9 +833,7 @@
       if (readStrategy == ReadStrategy.fromCodegen) {
         fail("Cannot read and write serialized codegen simultaneously.");
       }
-      // TODO(joshualitt) cleanup after google3 roll.
-      if (readStrategy != ReadStrategy.fromData &&
-          readStrategy != ReadStrategy.fromDataAndClosedWorld) {
+      if (readStrategy != ReadStrategy.fromDataAndClosedWorld) {
         fail("Can only write serialized codegen from serialized data.");
       }
       if (codegenShards == null) {
@@ -855,10 +861,7 @@
       options.add('${Flags.readClosedWorld}=${readClosedWorldUri}');
       break;
     case ReadStrategy.fromData:
-      // TODO(joshualitt): fail after Google3 roll.
-      // fail("Must read from closed world and data.");
-      readDataUri ??= Uri.base.resolve('$scriptName.data');
-      options.add('${Flags.readData}=${readDataUri}');
+      fail("Must read from closed world and data.");
       break;
     case ReadStrategy.fromDataAndClosedWorld:
       readClosedWorldUri ??= Uri.base.resolve('$scriptName.world');
@@ -868,19 +871,6 @@
       break;
     case ReadStrategy.fromCodegen:
     case ReadStrategy.fromCodegenAndData:
-      // TODO(joshualitt): fall through to fail after google3 roll.
-      readDataUri ??= Uri.base.resolve('$scriptName.data');
-      options.add('${Flags.readData}=${readDataUri}');
-      readCodegenUri ??= Uri.base.resolve('$scriptName.code');
-      options.add('${Flags.readCodegen}=${readCodegenUri}');
-      if (codegenShards == null) {
-        fail("Cannot write serialized codegen without setting "
-            "${Flags.codegenShards}.");
-      } else if (codegenShards <= 0) {
-        fail("${Flags.codegenShards} must be a positive integer.");
-      }
-      options.add('${Flags.codegenShards}=$codegenShards');
-      break;
     case ReadStrategy.fromCodegenAndClosedWorld:
       fail("Must read from closed world, data, and codegen");
       break;
@@ -929,7 +919,7 @@
     String summary;
     switch (readStrategy) {
       case ReadStrategy.fromDart:
-        inputName = 'characters Dart';
+        inputName = inputDillUri != null ? 'kernel bytes' : 'characters Dart';
         inputSize = inputProvider.dartCharactersRead;
         summary = 'Dart file $input ';
         break;
@@ -941,13 +931,7 @@
         summary = 'Data files $input and $dataInput ';
         break;
       case ReadStrategy.fromData:
-        // TODO(joshualitt): fail after google3 roll.
-        //fail("Must read from closed world and data.");
-        inputName = 'bytes data';
-        inputSize = inputProvider.dartCharactersRead;
-        String dataInput =
-            fe.relativizeUri(Uri.base, readDataUri, Platform.isWindows);
-        summary = 'Data files $input and $dataInput ';
+        fail("Must read from closed world and data.");
         break;
       case ReadStrategy.fromDataAndClosedWorld:
         inputName = 'bytes data';
@@ -960,16 +944,6 @@
         break;
       case ReadStrategy.fromCodegen:
       case ReadStrategy.fromCodegenAndData:
-        // TODO(joshualitt): Fall through to fail after google3 roll.
-        inputName = 'bytes data';
-        inputSize = inputProvider.dartCharactersRead;
-        String dataInput =
-            fe.relativizeUri(Uri.base, readDataUri, Platform.isWindows);
-        String codeInput =
-            fe.relativizeUri(Uri.base, readCodegenUri, Platform.isWindows);
-        summary = 'Data files $input, $dataInput and '
-            '${codeInput}[0-${codegenShards - 1}] ';
-        break;
       case ReadStrategy.fromCodegenAndClosedWorld:
         fail("Must read from closed world, data, and codegen");
         break;
@@ -1378,7 +1352,7 @@
   fail(message);
 }
 
-void main(List<String> arguments) {
+Future<void> main(List<String> arguments) async {
   // Expand `@path/to/file`
   // When running from bazel, argument of the form `@path/to/file` might be
   // provided. It needs to be replaced by reading all the contents of the
@@ -1396,7 +1370,7 @@
     batchMain(arguments.sublist(0, arguments.length - 1));
     return;
   }
-  internalMain(arguments);
+  await internalMain(arguments);
 }
 
 /// Return all non-empty lines in a file found at [path].
diff --git a/pkg/compiler/lib/src/deferred_load/program_split_constraints/nodes.dart b/pkg/compiler/lib/src/deferred_load/program_split_constraints/nodes.dart
index 9f10c18..92068f6 100644
--- a/pkg/compiler/lib/src/deferred_load/program_split_constraints/nodes.dart
+++ b/pkg/compiler/lib/src/deferred_load/program_split_constraints/nodes.dart
@@ -44,8 +44,7 @@
   Uri get uri => _uriAndPrefix.uri;
   String get prefix => _uriAndPrefix.prefix;
 
-  ReferenceNode(this._uriAndPrefix, {name})
-      : super(name ?? _uriAndPrefix.prefix);
+  ReferenceNode(String name, this._uriAndPrefix) : super(name);
 
   @override
   Map<String, dynamic> toJson() {
@@ -60,8 +59,8 @@
     if (nodeJson['type'] != 'reference') {
       throw 'Unrecognized type for reference node: ${nodeJson['type']}.';
     }
-    return ReferenceNode(UriAndPrefix.fromJson(nodeJson['import']),
-        name: nodeJson['name']);
+    return ReferenceNode(
+        nodeJson['name'], UriAndPrefix.fromJson(nodeJson['import']));
   }
 
   @override
@@ -193,9 +192,10 @@
   final Map<String, NamedNode> namedNodes = {};
   ReferenceNodeNamer _referenceNodeNamer;
 
-  /// The prefix in the 'uri#prefix' string will become a key to reference this
-  /// node in other builder calls.
-  String _prefixNamer(UriAndPrefix uriAndPrefix) => uriAndPrefix.prefix;
+  /// 'uri#prefix' will become a key to reference this node in other builder
+  /// calls.
+  String _uriAndPrefixNamer(UriAndPrefix uriAndPrefix) =>
+      uriAndPrefix.toString();
 
   /// Override the default reference node namer.
   set referenceNodeNamer(ReferenceNodeNamer namer) =>
@@ -203,7 +203,23 @@
 
   /// Returns the [ReferenceNodeNamer] to use for naming.
   ReferenceNodeNamer get referenceNodeNamer =>
-      _referenceNodeNamer ?? _prefixNamer;
+      _referenceNodeNamer ?? _uriAndPrefixNamer;
+
+  NamedNode _addNamedNode(NamedNode node) {
+    if (namedNodes.containsKey(node.name)) {
+      throw 'Node with name ${node.name} already exists: '
+          '${namedNodes[node.name]}';
+    }
+    namedNodes[node.name] = node;
+    return node;
+  }
+
+  NamedNode _lookupNamedNode(String nodeName) {
+    if (!namedNodes.containsKey(nodeName)) {
+      throw 'Missing reference node for $nodeName';
+    }
+    return namedNodes[nodeName];
+  }
 
   /// Returns a [ReferenceNode] referencing [importUriAndPrefix].
   /// [ReferenceNode]s are typically created in bulk, by mapping over a list of
@@ -212,43 +228,47 @@
   /// [referenceNodeNamer] per [ReferenceNode].
   ReferenceNode referenceNode(String importUriAndPrefix) {
     var uriAndPrefix = UriAndPrefix.fromJson(importUriAndPrefix);
-    var referenceNode = ReferenceNode(uriAndPrefix);
     var name = referenceNodeNamer(uriAndPrefix);
-    namedNodes[name] = referenceNode;
-    return referenceNode;
+    return _addNamedNode(ReferenceNode(name, uriAndPrefix));
   }
 
   /// Creates an unnamed [RelativeOrderNode] referencing two [NamedNode]s.
   RelativeOrderNode orderNode(String predecessor, String successor) {
     return RelativeOrderNode(
-        predecessor: namedNodes[predecessor], successor: namedNodes[successor]);
+        predecessor: _lookupNamedNode(predecessor),
+        successor: _lookupNamedNode(successor));
   }
 
   /// Creates a [CombinerNode] which can be referenced by [name] in further
   /// calls to the builder.
-  CombinerNode combinerNode(
-      String name, List<String> nodes, CombinerType type) {
-    var combinerNode = CombinerNode(name, type,
-        nodes.map((name) => namedNodes[name] as ReferenceNode).toSet());
-    namedNodes[name] = combinerNode;
-    return combinerNode;
+  CombinerNode combinerNode(String name, Set<String> nodes, CombinerType type) {
+    ReferenceNode _lookup(String nodeName) {
+      var node = _lookupNamedNode(nodeName);
+      if (node is! ReferenceNode) {
+        // TODO(joshualitt): Implement nested combiners.
+        throw '$name references node $nodeName which is not a ReferenceNode.';
+      }
+      return node as ReferenceNode;
+    }
+
+    return _addNamedNode(CombinerNode(name, type, nodes.map(_lookup).toSet()));
   }
 
   /// Creates an 'and' [CombinerNode] which can be referenced by [name] in
   /// further calls to the builder.
-  CombinerNode andNode(String name, List<String> nodes) {
+  CombinerNode andNode(String name, Set<String> nodes) {
     return combinerNode(name, nodes, CombinerType.and);
   }
 
   /// Creates a 'fuse' [CombinerNode] which can be referenced by [name] in
   /// further calls to the builder.
-  CombinerNode fuseNode(String name, List<String> nodes) {
+  CombinerNode fuseNode(String name, Set<String> nodes) {
     return combinerNode(name, nodes, CombinerType.fuse);
   }
 
   /// Creates an 'or' [CombinerNode] which can be referenced by [name] in
   /// further calls to the builder.
-  CombinerNode orNode(String name, List<String> nodes) {
+  CombinerNode orNode(String name, Set<String> nodes) {
     return combinerNode(name, nodes, CombinerType.or);
   }
 }
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index f3d8702..3e7f7fca 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -858,4 +858,11 @@
   void visitNullConstant(ir.NullConstant node) {
     registry.registerNullLiteral();
   }
+
+  @override
+  void visitConstructorTearOffConstant(ir.ConstructorTearOffConstant node) {
+    // The CFE encoding of redirecting factories, which dart2js doesn't use,
+    // uses ConstructorTearOff(Constant) to point to its effective target.
+    // However, these should be safe to ignore.
+  }
 }
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index b122154..9696343 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -1556,31 +1556,32 @@
     // for-in [iterableType] is a subtype of `Stream`.
     ir.DartType iterableType = visitNode(node.iterable);
     ir.DartType iteratorType = const ir.DynamicType();
-    if (node.isAsync) {
-      ir.InterfaceType streamInterfaceType = getInterfaceTypeOf(iterableType);
-      ir.InterfaceType streamType = typeEnvironment.getTypeAsInstanceOf(
-          streamInterfaceType,
-          typeEnvironment.coreTypes.streamClass,
-          currentLibrary,
-          typeEnvironment.coreTypes);
-      if (streamType != null) {
-        iteratorType = ir.InterfaceType(
-            typeEnvironment.coreTypes.streamIteratorClass,
-            ir.Nullability.nonNullable,
-            streamType.typeArguments);
-      }
-    } else {
-      ir.InterfaceType iterableInterfaceType = getInterfaceTypeOf(iterableType);
-      ir.Member member = hierarchy.getInterfaceMember(
-          iterableInterfaceType.classNode, ir.Name(Identifiers.iterator));
-      if (member != null) {
-        iteratorType = ir.Substitution.fromInterfaceType(
-                typeEnvironment.getTypeAsInstanceOf(
-                    iterableInterfaceType,
-                    member.enclosingClass,
-                    currentLibrary,
-                    typeEnvironment.coreTypes))
-            .substituteType(member.getterType);
+    ir.InterfaceType iterableInterfaceType = getInterfaceTypeOf(iterableType);
+    if (iterableInterfaceType != null) {
+      if (node.isAsync) {
+        ir.InterfaceType streamType = typeEnvironment.getTypeAsInstanceOf(
+            iterableInterfaceType,
+            typeEnvironment.coreTypes.streamClass,
+            currentLibrary,
+            typeEnvironment.coreTypes);
+        if (streamType != null) {
+          iteratorType = ir.InterfaceType(
+              typeEnvironment.coreTypes.streamIteratorClass,
+              ir.Nullability.nonNullable,
+              streamType.typeArguments);
+        }
+      } else {
+        ir.Member member = hierarchy.getInterfaceMember(
+            iterableInterfaceType.classNode, ir.Name(Identifiers.iterator));
+        if (member != null) {
+          iteratorType = ir.Substitution.fromInterfaceType(
+                  typeEnvironment.getTypeAsInstanceOf(
+                      iterableInterfaceType,
+                      member.enclosingClass,
+                      currentLibrary,
+                      typeEnvironment.coreTypes))
+              .substituteType(member.getterType);
+        }
       }
     }
     _staticTypeCache._forInIteratorTypes[node] = iteratorType;
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index 1b1ac8e..c8f5a30 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -83,6 +83,9 @@
     codePositionListener.onPositions(
         node, startPosition, endPosition, closingPosition);
   }
+
+  @override
+  bool get isDebugContext => false;
 }
 
 /// Interface for ast nodes that encapsulate an ast that needs to be
diff --git a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
index 3df93c3..8b46bb4 100644
--- a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
+++ b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
@@ -147,6 +147,32 @@
   }
 
   @override
+  String nonfinalizedDebugText() {
+    switch (kind) {
+      case DeferredHolderExpressionKind.globalObjectForClass:
+        return 'Holder"${_className(data)}"';
+      case DeferredHolderExpressionKind.globalObjectForMember:
+        return 'Holder"${_qualifiedStaticName(data)}"';
+      case DeferredHolderExpressionKind.globalObjectForInterceptors:
+        return 'J';
+      case DeferredHolderExpressionKind.globalObjectForConstant:
+        return 'Holder"constants"';
+      case DeferredHolderExpressionKind.globalObjectForStaticState:
+        return r'$';
+    }
+    return super.nonfinalizedDebugText();
+  }
+
+  String _className(ClassEntity cls) => cls.name.replaceAll('&', '_');
+
+  String _qualifiedStaticName(MemberEntity member) {
+    if (member.isConstructor || member.isStatic) {
+      return '${_className(member.enclosingClass)}.${member.name}';
+    }
+    return member.name;
+  }
+
+  @override
   Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
 }
 
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index 94f28fc..82c7200 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -380,7 +380,7 @@
   jsAst.Name nameForOneShotInterceptor(
       Selector selector, Iterable<ClassEntity> classes) {
     String root = selector.isOperator
-        ? operatorNameToIdentifier(selector.name)
+        ? Namer.operatorNameToIdentifier(selector.name)
         : privateName(selector.memberName);
     String prefix = selector.isGetter
         ? r"$get"
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 11d3b51..83c7797 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1425,7 +1425,7 @@
     return StringBackedName(name);
   }
 
-  String operatorNameToIdentifier(String name) {
+  static String operatorNameToIdentifier(String name) {
     if (name == null) return null;
     if (name == '==') {
       return r'$eq';
diff --git a/pkg/compiler/lib/src/js_backend/string_reference.dart b/pkg/compiler/lib/src/js_backend/string_reference.dart
index 62c378b..69d1a2d 100644
--- a/pkg/compiler/lib/src/js_backend/string_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/string_reference.dart
@@ -143,6 +143,26 @@
 
   @override
   Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
+
+  @override
+  String nonfinalizedDebugText() {
+    const doubleQuote = 0x22;
+    final buffer = StringBuffer('StringReference');
+    if (constant.stringValue.length <= 1000) {
+      buffer.writeCharCode(doubleQuote);
+      for (int rune in constant.stringValue.runes) {
+        if (rune >= 0x20 && rune < 0x7F && rune != doubleQuote) {
+          buffer.writeCharCode(rune);
+        } else {
+          buffer.write(r'\u{');
+          buffer.write(rune.toRadixString(16));
+          buffer.write(r'}');
+        }
+      }
+      buffer.writeCharCode(doubleQuote);
+    }
+    return '$buffer';
+  }
 }
 
 /// A [StringReferenceResource] is a deferred JavaScript statement determined
diff --git a/pkg/compiler/lib/src/js_backend/type_reference.dart b/pkg/compiler/lib/src/js_backend/type_reference.dart
index d488b24..7bfc470 100644
--- a/pkg/compiler/lib/src/js_backend/type_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/type_reference.dart
@@ -161,6 +161,15 @@
 
   @override
   Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
+
+  @override
+  String nonfinalizedDebugText() {
+    TypeRecipe typeRecipe = this.typeRecipe;
+    if (typeRecipe is TypeExpressionRecipe) {
+      return 'TypeReference"${typeRecipe.type.toString()}"';
+    }
+    return super.nonfinalizedDebugText();
+  }
 }
 
 /// A [TypeReferenceResource] is a deferred JavaScript statement determined by
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 91c66d3..cd26c6b 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -189,11 +189,12 @@
   };
 }
 
-// Creates a lazy final field that uses non-nullable initialization semantics.
+// Creates a lazy final static field that uses non-nullable initialization
+// semantics.
 //
-// A lazy field has a storage entry, [name], which holds the value, and a
-// getter ([getterName]) to access the field. If the field wasn't set before
-// the first access, it is initialized with the [initializer].
+// A lazy final field has a storage entry, [name], which holds the value, and a
+// getter ([getterName]) to access the field. The field is initialized on first
+// access with the [initializer].
 function lazyFinal(holder, name, getterName, initializer) {
   var uninitializedSentinel = holder;
   holder[name] = uninitializedSentinel;
@@ -201,12 +202,21 @@
     if (holder[name] === uninitializedSentinel) {
       var value = initializer();
       if (holder[name] !== uninitializedSentinel) {
+        // Since there is no setter, the only way to get here is via bounded
+        // recursion, where `initializer` calls the lazy final getter.
         #throwLateFieldADI(name);
       }
       holder[name] = value;
     }
-    holder[getterName] = function() { return this[name]; };
-    return holder[name];
+    // TODO(sra): Does the value need to be stored in the holder at all?
+    // Potentially a call to the getter could be replaced with an access to
+    // holder slot if dominated by a previous call to the getter. Does the
+    // optimizer do this? If so, within a single function, the dominance
+    // relations should allow a local copy via GVN, so it is not that valuable
+    // an optimization for a `final` static variable.
+    var finalValue = holder[name];
+    holder[getterName] = function() { return finalValue; };
+    return finalValue;
   };
 }
 
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index ae463a8..d8985b7 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -93,7 +93,7 @@
   int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.all;
 
   @override
-  List<String> get extraRequiredLibraries => _requiredLibraries[name]!;
+  List<String> get extraRequiredLibraries => requiredLibraries[name]!;
 
   @override
   List<String> get extraIndexedLibraries => const [
@@ -222,49 +222,86 @@
 
 // TODO(sigmund): this "extraRequiredLibraries" needs to be removed...
 // compile-platform should just specify which libraries to compile instead.
-const _requiredLibraries = <String, List<String>>{
+const requiredLibraries = <String, List<String>>{
   'dart2js': [
+    'dart:_async_await_error_codes',
     'dart:_dart2js_runtime_metrics',
     'dart:_foreign_helper',
+    'dart:_http',
     'dart:_interceptors',
     'dart:_internal',
+    'dart:_js',
     'dart:_js_annotations',
     'dart:_js_embedded_names',
     'dart:_js_helper',
     'dart:_js_names',
+    'dart:_js_primitives',
     'dart:_late_helper',
+    'dart:_metadata',
     'dart:_native_typed_data',
+    'dart:_recipe_syntax',
+    'dart:_rti',
     'dart:async',
     'dart:collection',
+    'dart:convert',
+    'dart:developer',
     'dart:html',
     'dart:html_common',
     'dart:indexed_db',
     'dart:io',
+    'dart:isolate',
     'dart:js',
     'dart:js_util',
+    'dart:math',
     'dart:svg',
+    'dart:typed_data',
     'dart:web_audio',
     'dart:web_gl',
   ],
   'dart2js_server': [
+    'dart:_async_await_error_codes',
     'dart:_dart2js_runtime_metrics',
     'dart:_foreign_helper',
+    'dart:_http',
     'dart:_interceptors',
     'dart:_internal',
+    'dart:_js',
     'dart:_js_annotations',
     'dart:_js_embedded_names',
     'dart:_js_helper',
     'dart:_js_names',
+    'dart:_js_primitives',
     'dart:_late_helper',
     'dart:_native_typed_data',
+    'dart:_recipe_syntax',
+    'dart:_rti',
     'dart:async',
     'dart:collection',
+    'dart:convert',
+    'dart:developer',
     'dart:io',
+    'dart:isolate',
     'dart:js',
     'dart:js_util',
+    'dart:math',
+    'dart:typed_data',
   ]
 };
 
+/// Extends the Dart2jsTarget to transform outlines to meet the requirements
+/// of summaries in bazel and package-build.
+class Dart2jsSummaryTarget extends Dart2jsTarget with SummaryMixin {
+  @override
+  final List<Uri> sources;
+
+  @override
+  final bool excludeNonSources;
+
+  Dart2jsSummaryTarget(String name, this.sources, this.excludeNonSources,
+      TargetFlags targetFlags)
+      : super(name, targetFlags);
+}
+
 class Dart2jsConstantsBackend extends ConstantsBackend {
   @override
   final bool supportsUnevaluatedConstants;
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index 79e95d4..dbefdbb 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -9,7 +9,6 @@
 import 'package:front_end/src/fasta/kernel/utils.dart';
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
-import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
 
 import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
 import 'package:kernel/kernel.dart' hide LibraryDependency, Combinator;
@@ -20,7 +19,6 @@
 import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../common.dart';
 import '../options.dart';
-import '../util/sink_adapter.dart';
 
 import 'front_end_adapter.dart';
 import 'dart2js_target.dart' show Dart2jsTarget;
@@ -34,7 +32,6 @@
   final DiagnosticReporter _reporter;
 
   final api.CompilerInput _compilerInput;
-  final api.CompilerOutput _compilerOutput;
 
   final CompilerOptions _options;
 
@@ -47,40 +44,14 @@
   /// This is used for testing.
   bool forceSerialization = false;
 
-  KernelLoaderTask(this._options, this._compilerInput, this._compilerOutput,
-      this._reporter, Measurer measurer)
+  KernelLoaderTask(
+      this._options, this._compilerInput, this._reporter, Measurer measurer)
       : initializedCompilerState = _options.kernelInitializedCompilerState,
         super(measurer);
 
   @override
   String get name => 'kernel loader';
 
-  ir.Reference findMainMethod(Component component, Uri entryUri) {
-    var entryLibrary = component.libraries
-        .firstWhere((l) => l.fileUri == entryUri, orElse: () => null);
-    if (entryLibrary == null) {
-      throw ArgumentError('Entry uri $entryUri not found in dill.');
-    }
-    var mainMethod = entryLibrary.procedures
-        .firstWhere((p) => p.name.text == 'main', orElse: () => null);
-
-    // In some cases, a main method is defined in another file, and then
-    // exported. In these cases, we search for the main method in
-    // [additionalExports].
-    ir.Reference mainMethodReference;
-    if (mainMethod == null) {
-      mainMethodReference = entryLibrary.additionalExports.firstWhere(
-          (p) => p.canonicalName.name == 'main',
-          orElse: () => null);
-    } else {
-      mainMethodReference = mainMethod.reference;
-    }
-    if (mainMethodReference == null) {
-      throw ArgumentError('Entry uri $entryUri has no main method.');
-    }
-    return mainMethodReference;
-  }
-
   /// Loads an entire Kernel [Component] from a file on disk.
   Future<KernelResult> load() {
     return measure(() async {
@@ -97,9 +68,6 @@
       var resolvedUri = _options.compilationTarget;
       ir.Component component;
       List<Uri> moduleLibraries = const [];
-      var isDill = resolvedUri.path.endsWith('.dill') ||
-          resolvedUri.path.endsWith('.gdill') ||
-          resolvedUri.path.endsWith('.mdill');
 
       void inferNullSafetyMode(bool isSound) {
         if (_options.nullSafetyMode == NullSafetyMode.unspecified) {
@@ -112,7 +80,7 @@
         assert(_options.nullSafetyMode != NullSafetyMode.unspecified);
       }
 
-      if (isDill) {
+      if (_options.fromDill) {
         component = ir.Component();
         Future<void> read(Uri uri) async {
           api.Input input = await _compilerInput.readFromUri(uri,
@@ -122,13 +90,6 @@
 
         await read(resolvedUri);
 
-        // If an entryUri is supplied, we use it to manually select the main
-        // method.
-        if (_options.entryUri != null) {
-          var mainMethod = findMainMethod(component, _options.entryUri);
-          component.setMainMethodAndMode(mainMethod, true, component.mode);
-        }
-
         if (_options.modularMode) {
           moduleLibraries =
               component.libraries.map((lib) => lib.importUri).toList();
@@ -161,25 +122,12 @@
           if (platformUri != resolvedUri) await read(platformUri);
         }
 
-        // Concatenate dills and then reset main method.
-        var mainMethod = component.mainMethodName;
-        var mainMode = component.mode;
+        // Concatenate dills.
         if (_options.dillDependencies != null) {
           for (Uri dependency in _options.dillDependencies) {
             await read(dependency);
           }
         }
-        component.setMainMethodAndMode(mainMethod, true, mainMode);
-
-        // This is not expected to be null when creating a whole-program .dill
-        // file, but needs to be checked for modular inputs.
-        if (component.mainMethod == null && !_options.modularMode) {
-          // TODO(sigmund): move this so that we use the same error template
-          // from the CFE.
-          _reporter.reportError(_reporter.createMessage(NO_LOCATION_SPANNABLE,
-              MessageKind.GENERIC, {'text': "No 'main' method found."}));
-          return null;
-        }
       } else {
         bool verbose = false;
         Target target =
@@ -232,18 +180,6 @@
         validateNullSafetyMode();
       }
 
-      if (_options.cfeOnly) {
-        measureSubtask('serialize dill', () {
-          _reporter.log('Writing dill to ${_options.outputUri}');
-          api.BinaryOutputSink dillOutput =
-              _compilerOutput.createBinarySink(_options.outputUri);
-          BinaryOutputSinkAdapter irSink = BinaryOutputSinkAdapter(dillOutput);
-          BinaryPrinter printer = BinaryPrinter(irSink);
-          printer.writeComponentFile(component);
-          irSink.close();
-        });
-      }
-
       if (forceSerialization) {
         // TODO(johnniwinther): Remove this when #34942 is fixed.
         List<int> data = serializeComponent(component);
@@ -290,7 +226,7 @@
 
 /// Result of invoking the CFE to produce the kernel IR.
 class KernelResult {
-  final ir.Component component;
+  ir.Component component;
 
   /// The [Uri] of the root library containing main.
   /// Note: rootLibraryUri will be null for some modules, for example in the
@@ -314,6 +250,55 @@
   KernelResult(this.component, this.rootLibraryUri, this.libraries,
       this.moduleLibraries);
 
+  static Library _findEntryLibrary(Component component, Uri entryUri) {
+    var entryLibrary = component.libraries
+        .firstWhere((l) => l.fileUri == entryUri, orElse: () => null);
+    if (entryLibrary == null) {
+      throw ArgumentError('Entry uri $entryUri not found in dill.');
+    }
+    return entryLibrary;
+  }
+
+  static ir.Reference _findMainMethod(Library entryLibrary) {
+    var mainMethod = entryLibrary.procedures
+        .firstWhere((p) => p.name.text == 'main', orElse: () => null);
+
+    // In some cases, a main method is defined in another file, and then
+    // exported. In these cases, we search for the main method in
+    // [additionalExports].
+    ir.Reference mainMethodReference;
+    if (mainMethod == null) {
+      mainMethodReference = entryLibrary.additionalExports.firstWhere(
+          (p) => p.canonicalName.name == 'main',
+          orElse: () => null);
+    } else {
+      mainMethodReference = mainMethod.reference;
+    }
+    if (mainMethodReference == null) {
+      throw ArgumentError(
+          'Entry uri ${entryLibrary.fileUri} has no main method.');
+    }
+    return mainMethodReference;
+  }
+
+  void setMainAndTrimComponent(Uri entryUri) {
+    var entryLibrary = _findEntryLibrary(component, entryUri);
+    var mainMethod = _findMainMethod(entryLibrary);
+    var irLibraryMap = <Uri, Library>{};
+    var irLibraries = <Library>[];
+    for (var library in component.libraries) {
+      irLibraryMap[library.importUri] = library;
+    }
+    for (var library in libraries) {
+      irLibraries.add(irLibraryMap[library]);
+    }
+    component = ir.Component(
+        libraries: irLibraries,
+        uriToSource: component.uriToSource,
+        nameRoot: component.root);
+    component.setMainMethodAndMode(mainMethod, true, component.mode);
+  }
+
   @override
   String toString() =>
       'root=$rootLibraryUri,libraries=$libraries,module=$moduleLibraries';
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index d0a06d4..d78db4c 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -18,6 +18,7 @@
 }
 
 enum FeatureStatus {
+  shipped,
   shipping,
   canary,
 }
@@ -31,6 +32,10 @@
 /// passed. The [isNegativeFlag] bool flips things around so while in [canary]
 /// the [FeatureOption] is enabled unless explicitly disabled, and while in
 /// [staging] it is disabled unless explicitly enabled.
+///
+/// Finally, mature features can be moved to [shipped], at which point we ignore
+/// the flag, but throw if the value of the flag is unexpected(i.e. if a
+/// positive flag is disabled, or a negative flag is enabled).
 class FeatureOption {
   final String flag;
   final bool isNegativeFlag;
@@ -71,6 +76,9 @@
   /// Whether to generate code compliant with Content Security Policy.
   FeatureOption useContentSecurityPolicy = FeatureOption('csp');
 
+  /// [FeatureOption]s which are shipped and cannot be toggled.
+  late final List<FeatureOption> shipped = [];
+
   /// [FeatureOption]s which default to enabled.
   late final List<FeatureOption> shipping = [
     legacyJavaScript,
@@ -107,6 +115,7 @@
 
   /// Parses a [List<String>] and enables / disables features as necessary.
   void parse(List<String> options) {
+    _verifyShippedFeatures(options, shipped);
     _extractFeatures(options, shipping, FeatureStatus.shipping);
     _extractFeatures(options, canary, FeatureStatus.canary);
   }
@@ -151,6 +160,13 @@
   /// Returns the compilation target specified by these options.
   Uri? get compilationTarget => inputDillUri ?? entryUri;
 
+  bool get fromDill {
+    var targetPath = compilationTarget!.path;
+    return targetPath.endsWith('.dill') ||
+        targetPath.endsWith('.gdill') ||
+        targetPath.endsWith('.mdill');
+  }
+
   /// Location of the package configuration file.
   ///
   /// If not null then [packageRoot] should be null.
@@ -176,6 +192,8 @@
 
   List<Uri>? modularAnalysisInputs;
 
+  bool get hasModularAnalysisInputs => modularAnalysisInputs != null;
+
   /// Location from which serialized inference data is read.
   ///
   /// If this is set, the [entryUri] is expected to be a .dill file and the
@@ -546,6 +564,9 @@
   /// Verbosity level used for filtering messages during compilation.
   fe.Verbosity verbosity = fe.Verbosity.all;
 
+  // Whether or not to dump a list of unused libraries.
+  bool dumpUnusedLibraries = false;
+
   late FeatureOptions features;
 
   // -------------------------------------------------
@@ -672,6 +693,7 @@
       .._noSoundNullSafety = _hasOption(options, Flags.noSoundNullSafety)
       .._mergeFragmentsThreshold =
           _extractIntOption(options, '${Flags.mergeFragmentsThreshold}=')
+      ..dumpUnusedLibraries = _hasOption(options, Flags.dumpUnusedLibraries)
       ..cfeInvocationModes = fe.InvocationMode.parseArguments(
           _extractStringOption(options, '${Flags.cfeInvocationModes}=', '')!,
           onError: onError)
@@ -908,4 +930,28 @@
   }
 }
 
+void _verifyShippedFeatures(
+    List<String> options, List<FeatureOption> features) {
+  for (var feature in features) {
+    String featureFlag = feature.flag;
+    String enableFeatureFlag = '--$featureFlag';
+    String disableFeatureFlag = '--no-$featureFlag';
+    bool enableFeature = _hasOption(options, enableFeatureFlag);
+    bool disableFeature = _hasOption(options, disableFeatureFlag);
+    if (enableFeature && disableFeature) {
+      throw ArgumentError("'$enableFeatureFlag' incompatible with "
+          "'$disableFeatureFlag'");
+    }
+    if (enableFeature && feature.isNegativeFlag) {
+      throw ArgumentError(
+          "$disableFeatureFlag has already shipped and cannot be enabled.");
+    }
+    if (disableFeature && !feature.isNegativeFlag) {
+      throw ArgumentError(
+          "$enableFeatureFlag has already shipped and cannot be disabled.");
+    }
+    feature.state = !feature.isNegativeFlag;
+  }
+}
+
 const String _UNDETERMINED_BUILD_ID = "build number could not be determined";
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 27d75ae..e63f515 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -66,40 +66,6 @@
       closedWorld.elementMap, closedWorld, globalLocalsMap, inferredData);
 }
 
-void serializeGlobalTypeInferenceResultsToSinkLegacy(
-    GlobalTypeInferenceResults results, DataSink sink) {
-  JsClosedWorld closedWorld = results.closedWorld;
-  GlobalLocalsMap globalLocalsMap = results.globalLocalsMap;
-  InferredData inferredData = results.inferredData;
-  closedWorld.writeToDataSink(sink);
-  globalLocalsMap.writeToDataSink(sink);
-  inferredData.writeToDataSink(sink);
-  results.writeToDataSink(sink, closedWorld.elementMap);
-  sink.close();
-}
-
-GlobalTypeInferenceResults
-    deserializeGlobalTypeInferenceResultsFromSourceLegacy(
-        CompilerOptions options,
-        DiagnosticReporter reporter,
-        Environment environment,
-        AbstractValueStrategy abstractValueStrategy,
-        ir.Component component,
-        DataSource source) {
-  JsClosedWorld newClosedWorld = JsClosedWorld.readFromDataSource(
-      options, reporter, environment, abstractValueStrategy, component, source);
-  GlobalLocalsMap newGlobalLocalsMap = GlobalLocalsMap.readFromDataSource(
-      newClosedWorld.closureDataLookup.getEnclosingMember, source);
-  InferredData newInferredData =
-      InferredData.readFromDataSource(source, newClosedWorld);
-  return GlobalTypeInferenceResults.readFromDataSource(
-      source,
-      newClosedWorld.elementMap,
-      newClosedWorld,
-      newGlobalLocalsMap,
-      newInferredData);
-}
-
 void serializeClosedWorldToSink(JsClosedWorld closedWorld, DataSink sink) {
   closedWorld.writeToDataSink(sink);
   sink.close();
@@ -321,39 +287,6 @@
     });
   }
 
-  // TODO(joshualitt) get rid of legacy functions after Google3 roll.
-  void serializeGlobalTypeInferenceLegacy(GlobalTypeInferenceResults results) {
-    JsClosedWorld closedWorld = results.closedWorld;
-    ir.Component component = closedWorld.elementMap.programEnv.mainComponent;
-    serializeComponent(component);
-
-    measureSubtask('serialize data', () {
-      _reporter.log('Writing data to ${_options.writeDataUri}');
-      api.BinaryOutputSink dataOutput =
-          _outputProvider.createBinarySink(_options.writeDataUri);
-      DataSink sink = BinarySink(BinaryOutputSinkAdapter(dataOutput));
-      serializeGlobalTypeInferenceResultsToSinkLegacy(results, sink);
-    });
-  }
-
-  Future<GlobalTypeInferenceResults> deserializeGlobalTypeInferenceLegacy(
-      Environment environment,
-      AbstractValueStrategy abstractValueStrategy) async {
-    ir.Component component = await deserializeComponentAndUpdateOptions();
-
-    return await measureIoSubtask('deserialize data', () async {
-      _reporter.log('Reading data from ${_options.readDataUri}');
-      api.Input<List<int>> dataInput = await _provider
-          .readFromUri(_options.readDataUri, inputKind: api.InputKind.binary);
-      DataSource source =
-          BinarySourceImpl(dataInput.data, stringInterner: _stringInterner);
-      return deserializeGlobalTypeInferenceResultsFromSourceLegacy(_options,
-          _reporter, environment, abstractValueStrategy, component, source);
-    });
-  }
-
-  // TODO(joshualitt): Investigate whether closed world indices can be shared
-  // with codegen.
   void serializeCodegen(BackendStrategy backendStrategy,
       CodegenResults codegenResults, DataSourceIndices indices) {
     GlobalTypeInferenceResults globalTypeInferenceResults =
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index cc5e875..359fead 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -351,6 +351,7 @@
         uri = out.resolve('$name.$extension');
         break;
       case OutputType.dumpInfo:
+      case OutputType.dumpUnusedLibraries:
       case OutputType.deferredMap:
         if (name == '') {
           name = out.pathSegments.last;
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index e7ec92f..5e44fa5 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -95,13 +95,18 @@
       CodegenRegistry registry,
       ModularNamer namer,
       ModularEmitter emitter) {
+    js.Expression code;
     if (member.isField) {
-      return generateLazyInitializer(
+      code = generateLazyInitializer(
           member, graph, codegen, closedWorld, registry, namer, emitter);
     } else {
-      return generateMethod(
+      code = generateMethod(
           member, graph, codegen, closedWorld, registry, namer, emitter);
     }
+    if (code != null) {
+      codegen.tracer.traceJavaScriptText('JavaScript', code.debugPrint);
+    }
+    return code;
   }
 
   js.Expression generateLazyInitializer(
@@ -113,7 +118,6 @@
       ModularNamer namer,
       ModularEmitter emitter) {
     return measure(() {
-      codegen.tracer.traceGraph("codegen", graph);
       SourceInformation sourceInformation = sourceInformationStrategy
           .createBuilderForContext(field)
           .buildDeclaration(field);
@@ -129,6 +133,7 @@
           closedWorld,
           registry);
       codeGenerator.visitGraph(graph);
+      codegen.tracer.traceGraph("codegen", graph);
       return js.Fun(codeGenerator.parameters, codeGenerator.body)
           .withSourceInformation(sourceInformation);
     });
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 2ceac61..ab0b1a6 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -117,9 +117,24 @@
         .isEmitted;
   }
 
-  HBoundsCheck insertBoundsCheck(HInstruction indexerNode, HInstruction array,
-      HInstruction indexArgument, JClosedWorld closedWorld) {
+  HBoundsCheck insertBoundsCheck(
+      HInvokeDynamic indexerNode,
+      HInstruction array,
+      HInstruction indexArgument,
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     final abstractValueDomain = closedWorld.abstractValueDomain;
+
+    if (abstractValueDomain.isNull(array.instructionType).isPotentiallyTrue) {
+      HNullCheck check = HNullCheck(
+          array, abstractValueDomain.excludeNull(array.instructionType))
+        ..selector = indexerNode.selector
+        ..sourceInformation = indexerNode.sourceInformation;
+      log?.registerNullCheck(indexerNode, check);
+      indexerNode.block.addBefore(indexerNode, check);
+      array = check;
+    }
+
     HGetLength length = HGetLength(array, abstractValueDomain.positiveIntType,
         isAssignable: abstractValueDomain
             .isFixedLengthJsIndexable(array.instructionType)
@@ -212,7 +227,7 @@
     HInstruction checkedIndex = index;
     if (requiresBoundsCheck(instruction, closedWorld)) {
       checkedIndex =
-          insertBoundsCheck(instruction, receiver, index, closedWorld);
+          insertBoundsCheck(instruction, receiver, index, closedWorld, log);
     }
     HIndexAssign converted = HIndexAssign(
         closedWorld.abstractValueDomain, receiver, checkedIndex, value);
@@ -291,7 +306,7 @@
     HInstruction checkedIndex = index;
     if (requiresBoundsCheck(instruction, closedWorld)) {
       checkedIndex =
-          insertBoundsCheck(instruction, receiver, index, closedWorld);
+          insertBoundsCheck(instruction, receiver, index, closedWorld, log);
     }
     HIndex converted = HIndex(receiver, checkedIndex, elementType);
     log?.registerIndex(instruction, converted);
@@ -322,7 +337,7 @@
     if (requiresBoundsCheck(instruction, closedWorld)) {
       HConstant zeroIndex = graph.addConstantInt(0, closedWorld);
       HBoundsCheck check =
-          insertBoundsCheck(instruction, receiver, zeroIndex, closedWorld);
+          insertBoundsCheck(instruction, receiver, zeroIndex, closedWorld, log);
       HInstruction minusOne = graph.addConstantInt(-1, closedWorld);
       check.inputs.add(minusOne);
       minusOne.usedBy.add(check);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index d600d7e..0475798 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -606,8 +606,20 @@
           .isDefinitelyTrue) {
         resultType = _abstractValueDomain.uint32Type;
       }
+      HInstruction checkedReceiver = actualReceiver;
+      if (actualReceiver.isNull(_abstractValueDomain).isPotentiallyTrue) {
+        // The receiver is potentially `null` so we insert a null receiver
+        // check. This will be folded into the length access later.
+        HNullCheck check = HNullCheck(actualReceiver,
+            _abstractValueDomain.excludeNull(actualReceiver.instructionType))
+          ..selector = node.selector
+          ..sourceInformation = node.sourceInformation;
+        _log?.registerNullCheck(node, check);
+        node.block.addBefore(node, check);
+        checkedReceiver = check;
+      }
       HGetLength result =
-          HGetLength(actualReceiver, resultType, isAssignable: !isFixed);
+          HGetLength(checkedReceiver, resultType, isAssignable: !isFixed);
       return result;
     } else if (actualReceiver.isConstantMap()) {
       HConstant constantInput = actualReceiver;
@@ -2607,12 +2619,14 @@
     if (branch is HIf) {
       if (branch.thenBlock.isLive == branch.elseBlock.isLive) return;
       assert(branch.condition.isConstant());
-      HBasicBlock target =
+      HBasicBlock liveSuccessor =
           branch.thenBlock.isLive ? branch.thenBlock : branch.elseBlock;
-      HInstruction instruction = target.first;
-      while (!instruction.isControlFlow()) {
-        HInstruction next = instruction.next;
+      HInstruction instruction = liveSuccessor.first;
+      // Move instructions up until the final control flow instruction or pinned
+      // HTypeKnown.
+      while (instruction.next != null) {
         if (instruction is HTypeKnown && instruction.isPinned) break;
+        HInstruction next = instruction.next;
         // It might be worth re-running GVN optimizations if we hoisted a
         // GVN-able instructions from [target] into [block].
         newGvnCandidates = newGvnCandidates || instruction.useGvn();
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 5b825ce..39c3355 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -101,6 +101,8 @@
           graph.asyncElementType,
           sourceInformationBuilder.buildAsyncBody(),
           sourceInformationBuilder.buildAsyncExit());
+      _codegen.tracer
+          .traceJavaScriptText('JavaScript.rewrite', result.debugPrint);
     }
     if (result.sourceInformation == null) {
       result = result.withSourceInformation(
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 8887610..c8a843f 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -30,6 +30,35 @@
     });
   }
 
+  void traceJavaScriptText(String name, String data) {
+    DEBUG_MODE = true;
+    tag("cfg", () {
+      printProperty("name", name);
+      // Emit a fake basic block, with one 'instruction' per line of text.
+      tag("block", () {
+        printProperty("name", "B1");
+        printProperty("from_bci", -1);
+        printProperty("to_bci", -1);
+        printEmptyProperty("predecessors");
+        printEmptyProperty("successors");
+        printEmptyProperty("xhandlers");
+        printEmptyProperty("flags");
+        tag("states", () {
+          tag("locals", () {
+            printProperty("size", 0);
+            printProperty("method", "None");
+          });
+        });
+        tag("HIR", () {
+          for (final line in data.split('\n')) {
+            addIndent();
+            add("0 0 i0 js | $line<|@\n");
+          }
+        });
+      });
+    });
+  }
+
   void addPredecessors(HBasicBlock block) {
     if (block.predecessors.isEmpty) {
       printEmptyProperty("predecessors");
diff --git a/pkg/compiler/lib/src/tracer.dart b/pkg/compiler/lib/src/tracer.dart
index 3386c81..26f4bb3d 100644
--- a/pkg/compiler/lib/src/tracer.dart
+++ b/pkg/compiler/lib/src/tracer.dart
@@ -55,6 +55,11 @@
     }
   }
 
+  void traceJavaScriptText(String name, String Function() getText) {
+    if (!traceActive) return;
+    HTracer(output, closedWorld).traceJavaScriptText(name, getText());
+  }
+
   void close() {
     if (output != null) {
       output.close();
diff --git a/pkg/compiler/test/custom_split/custom_split_test.dart b/pkg/compiler/test/custom_split/custom_split_test.dart
index fb0968a..f1e4fd4 100644
--- a/pkg/compiler/test/custom_split/custom_split_test.dart
+++ b/pkg/compiler/test/custom_split/custom_split_test.dart
@@ -83,17 +83,30 @@
   return json;
 }
 
+Uri getFileInTestFolder(String test, String file) =>
+    Platform.script.resolve('data/$test/$file');
+
+Future<String> compileConstraintsToJson(String test, Compiler compiler) async {
+  var constraints = getFileInTestFolder(test, 'constraints.dart');
+  var component = compiler.componentForTesting;
+  return constraintsToJson(component, constraints);
+}
+
+File getConstraintsJsonFile(String test) {
+  var constraintsJsonUri = getFileInTestFolder(test, 'constraints.json');
+  return File(constraintsJsonUri.toFilePath());
+}
+
 /// Verifies the programmatic API produces the expected JSON.
 Future<void> verifyCompiler(String test, Compiler compiler) async {
-  var constraints = Platform.script.resolve('data/$test/constraints.dart');
-  var constraintsJsonUri =
-      Platform.script.resolve('data/$test/constraints.json');
-  var component = compiler.componentForTesting;
-  var json = await constraintsToJson(component, constraints);
-  var constraintsJson =
-      File(constraintsJsonUri.toFilePath()).readAsStringSync();
-  constraintsJson = constraintsJson.substring(0, constraintsJson.length - 1);
-  Expect.equals(json, constraintsJson);
+  var json = await compileConstraintsToJson(test, compiler);
+  Expect.equals(getConstraintsJsonFile(test).readAsStringSync(), json);
+}
+
+/// Generates constraint JSON.
+Future<void> generateJSON(String test, Compiler compiler) async {
+  var json = await compileConstraintsToJson(test, compiler);
+  getConstraintsJsonFile(test).writeAsStringSync(json);
 }
 
 /// Compute the [OutputUnit]s for all source files involved in the test, and
@@ -102,6 +115,7 @@
 /// or all supporting libraries to be in the `libs` folder, starting with the
 /// same name as the original file in `data`.
 main(List<String> args) {
+  bool generateGoldens = args.contains('-g');
   asyncTest(() async {
     Directory dataDir = Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, const OutputUnitDataComputer(),
@@ -109,6 +123,8 @@
         perTestOptions: createPerTestOptions(),
         args: args, setUpFunction: () {
       importPrefixes.clear();
-    }, testedConfigs: allSpecConfigs, verifyCompiler: verifyCompiler);
+    },
+        testedConfigs: allSpecConfigs,
+        verifyCompiler: generateGoldens ? generateJSON : verifyCompiler);
   });
 }
diff --git a/pkg/compiler/test/custom_split/data/diamond/constraints.dart b/pkg/compiler/test/custom_split/data/diamond/constraints.dart
index 92a7665..88ccb84 100644
--- a/pkg/compiler/test/custom_split/data/diamond/constraints.dart
+++ b/pkg/compiler/test/custom_split/data/diamond/constraints.dart
@@ -12,12 +12,16 @@
 }
 
 List<Node> processDeferredImports(List<String> imports) {
+  var step1 = 'memory:sdk/tests/web/native/main.dart#step1';
+  var step2a = 'memory:sdk/tests/web/native/main.dart#step2a';
+  var step2b = 'memory:sdk/tests/web/native/main.dart#step2b';
+  var step3 = 'memory:sdk/tests/web/native/main.dart#step3';
   var builder = ProgramSplitBuilder();
   return [
     ...imports.map(builder.referenceNode),
-    builder.orderNode('step1', 'step2a'),
-    builder.orderNode('step1', 'step2b'),
-    builder.orderNode('step2a', 'step3'),
-    builder.orderNode('step2b', 'step3'),
+    builder.orderNode(step1, step2a),
+    builder.orderNode(step1, step2b),
+    builder.orderNode(step2a, step3),
+    builder.orderNode(step2b, step3),
   ];
 }
diff --git a/pkg/compiler/test/custom_split/data/diamond/constraints.json b/pkg/compiler/test/custom_split/data/diamond/constraints.json
index 83dfe0a..21b8afa 100644
--- a/pkg/compiler/test/custom_split/data/diamond/constraints.json
+++ b/pkg/compiler/test/custom_split/data/diamond/constraints.json
@@ -1,42 +1,42 @@
 [
   {
     "type": "reference",
-    "name": "step1",
+    "name": "memory:sdk/tests/web/native/main.dart#step1",
     "import": "memory:sdk/tests/web/native/main.dart#step1"
   },
   {
     "type": "reference",
-    "name": "step2a",
+    "name": "memory:sdk/tests/web/native/main.dart#step2a",
     "import": "memory:sdk/tests/web/native/main.dart#step2a"
   },
   {
     "type": "reference",
-    "name": "step2b",
+    "name": "memory:sdk/tests/web/native/main.dart#step2b",
     "import": "memory:sdk/tests/web/native/main.dart#step2b"
   },
   {
     "type": "reference",
-    "name": "step3",
+    "name": "memory:sdk/tests/web/native/main.dart#step3",
     "import": "memory:sdk/tests/web/native/main.dart#step3"
   },
   {
     "type": "order",
-    "predecessor": "step1",
-    "successor": "step2a"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
+    "successor": "memory:sdk/tests/web/native/main.dart#step2a"
   },
   {
     "type": "order",
-    "predecessor": "step1",
-    "successor": "step2b"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
+    "successor": "memory:sdk/tests/web/native/main.dart#step2b"
   },
   {
     "type": "order",
-    "predecessor": "step2a",
-    "successor": "step3"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step2a",
+    "successor": "memory:sdk/tests/web/native/main.dart#step3"
   },
   {
     "type": "order",
-    "predecessor": "step2b",
-    "successor": "step3"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step2b",
+    "successor": "memory:sdk/tests/web/native/main.dart#step3"
   }
-]
+]
\ No newline at end of file
diff --git a/pkg/compiler/test/custom_split/data/diamond_and/constraints.dart b/pkg/compiler/test/custom_split/data/diamond_and/constraints.dart
index b3a40ca..a333016 100644
--- a/pkg/compiler/test/custom_split/data/diamond_and/constraints.dart
+++ b/pkg/compiler/test/custom_split/data/diamond_and/constraints.dart
@@ -12,11 +12,15 @@
 }
 
 List<Node> processDeferredImports(List<String> imports) {
+  var step1 = 'memory:sdk/tests/web/native/main.dart#step1';
+  var step2a = 'memory:sdk/tests/web/native/main.dart#step2a';
+  var step2b = 'memory:sdk/tests/web/native/main.dart#step2b';
+  var step3 = 'memory:sdk/tests/web/native/main.dart#step3';
   var builder = ProgramSplitBuilder();
   return [
     ...imports.map(builder.referenceNode),
-    builder.andNode('step2', ['step2a', 'step2b']),
-    builder.orderNode('step1', 'step2'),
-    builder.orderNode('step2', 'step3'),
+    builder.andNode('step2', {step2a, step2b}),
+    builder.orderNode(step1, 'step2'),
+    builder.orderNode('step2', step3),
   ];
 }
diff --git a/pkg/compiler/test/custom_split/data/diamond_and/constraints.json b/pkg/compiler/test/custom_split/data/diamond_and/constraints.json
index 931a910..85344e7 100644
--- a/pkg/compiler/test/custom_split/data/diamond_and/constraints.json
+++ b/pkg/compiler/test/custom_split/data/diamond_and/constraints.json
@@ -1,40 +1,40 @@
 [
   {
     "type": "reference",
-    "name": "step1",
+    "name": "memory:sdk/tests/web/native/main.dart#step1",
     "import": "memory:sdk/tests/web/native/main.dart#step1"
   },
   {
     "type": "reference",
-    "name": "step2a",
+    "name": "memory:sdk/tests/web/native/main.dart#step2a",
     "import": "memory:sdk/tests/web/native/main.dart#step2a"
   },
   {
     "type": "reference",
-    "name": "step2b",
+    "name": "memory:sdk/tests/web/native/main.dart#step2b",
     "import": "memory:sdk/tests/web/native/main.dart#step2b"
   },
   {
     "type": "reference",
-    "name": "step3",
+    "name": "memory:sdk/tests/web/native/main.dart#step3",
     "import": "memory:sdk/tests/web/native/main.dart#step3"
   },
   {
     "type": "and",
     "name": "step2",
     "nodes": [
-      "step2a",
-      "step2b"
+      "memory:sdk/tests/web/native/main.dart#step2a",
+      "memory:sdk/tests/web/native/main.dart#step2b"
     ]
   },
   {
     "type": "order",
-    "predecessor": "step1",
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
     "successor": "step2"
   },
   {
     "type": "order",
     "predecessor": "step2",
-    "successor": "step3"
+    "successor": "memory:sdk/tests/web/native/main.dart#step3"
   }
-]
+]
\ No newline at end of file
diff --git a/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.dart b/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.dart
index 6fdf62e..145cbd1 100644
--- a/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.dart
+++ b/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.dart
@@ -12,11 +12,15 @@
 }
 
 List<Node> processDeferredImports(List<String> imports) {
+  var step1 = 'memory:sdk/tests/web/native/main.dart#step1';
+  var step2a = 'memory:sdk/tests/web/native/main.dart#step2a';
+  var step2b = 'memory:sdk/tests/web/native/main.dart#step2b';
+  var step3 = 'memory:sdk/tests/web/native/main.dart#step3';
   var builder = ProgramSplitBuilder();
   return [
     ...imports.map(builder.referenceNode),
-    builder.fuseNode('step2', ['step2a', 'step2b']),
-    builder.orderNode('step1', 'step2'),
-    builder.orderNode('step2', 'step3'),
+    builder.fuseNode('step2', {step2a, step2b}),
+    builder.orderNode(step1, 'step2'),
+    builder.orderNode('step2', step3),
   ];
 }
diff --git a/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.json b/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.json
index f170d18..dccfe20 100644
--- a/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.json
+++ b/pkg/compiler/test/custom_split/data/diamond_fuse/constraints.json
@@ -1,40 +1,40 @@
 [
   {
     "type": "reference",
-    "name": "step1",
+    "name": "memory:sdk/tests/web/native/main.dart#step1",
     "import": "memory:sdk/tests/web/native/main.dart#step1"
   },
   {
     "type": "reference",
-    "name": "step2a",
+    "name": "memory:sdk/tests/web/native/main.dart#step2a",
     "import": "memory:sdk/tests/web/native/main.dart#step2a"
   },
   {
     "type": "reference",
-    "name": "step2b",
+    "name": "memory:sdk/tests/web/native/main.dart#step2b",
     "import": "memory:sdk/tests/web/native/main.dart#step2b"
   },
   {
     "type": "reference",
-    "name": "step3",
+    "name": "memory:sdk/tests/web/native/main.dart#step3",
     "import": "memory:sdk/tests/web/native/main.dart#step3"
   },
   {
     "type": "fuse",
     "name": "step2",
     "nodes": [
-      "step2a",
-      "step2b"
+      "memory:sdk/tests/web/native/main.dart#step2a",
+      "memory:sdk/tests/web/native/main.dart#step2b"
     ]
   },
   {
     "type": "order",
-    "predecessor": "step1",
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
     "successor": "step2"
   },
   {
     "type": "order",
     "predecessor": "step2",
-    "successor": "step3"
+    "successor": "memory:sdk/tests/web/native/main.dart#step3"
   }
-]
+]
\ No newline at end of file
diff --git a/pkg/compiler/test/custom_split/data/diamond_or/constraints.dart b/pkg/compiler/test/custom_split/data/diamond_or/constraints.dart
index 659bf73..bdc5e1f 100644
--- a/pkg/compiler/test/custom_split/data/diamond_or/constraints.dart
+++ b/pkg/compiler/test/custom_split/data/diamond_or/constraints.dart
@@ -12,11 +12,15 @@
 }
 
 List<Node> processDeferredImports(List<String> imports) {
+  var step1 = 'memory:sdk/tests/web/native/main.dart#step1';
+  var step2a = 'memory:sdk/tests/web/native/main.dart#step2a';
+  var step2b = 'memory:sdk/tests/web/native/main.dart#step2b';
+  var step3 = 'memory:sdk/tests/web/native/main.dart#step3';
   var builder = ProgramSplitBuilder();
   return [
     ...imports.map(builder.referenceNode),
-    builder.orNode('step2', ['step2a', 'step2b']),
-    builder.orderNode('step1', 'step2'),
-    builder.orderNode('step2', 'step3'),
+    builder.orNode('step2', {step2a, step2b}),
+    builder.orderNode(step1, 'step2'),
+    builder.orderNode('step2', step3),
   ];
 }
diff --git a/pkg/compiler/test/custom_split/data/diamond_or/constraints.json b/pkg/compiler/test/custom_split/data/diamond_or/constraints.json
index 5fcc300..c4091f4 100644
--- a/pkg/compiler/test/custom_split/data/diamond_or/constraints.json
+++ b/pkg/compiler/test/custom_split/data/diamond_or/constraints.json
@@ -1,40 +1,40 @@
 [
   {
     "type": "reference",
-    "name": "step1",
+    "name": "memory:sdk/tests/web/native/main.dart#step1",
     "import": "memory:sdk/tests/web/native/main.dart#step1"
   },
   {
     "type": "reference",
-    "name": "step2a",
+    "name": "memory:sdk/tests/web/native/main.dart#step2a",
     "import": "memory:sdk/tests/web/native/main.dart#step2a"
   },
   {
     "type": "reference",
-    "name": "step2b",
+    "name": "memory:sdk/tests/web/native/main.dart#step2b",
     "import": "memory:sdk/tests/web/native/main.dart#step2b"
   },
   {
     "type": "reference",
-    "name": "step3",
+    "name": "memory:sdk/tests/web/native/main.dart#step3",
     "import": "memory:sdk/tests/web/native/main.dart#step3"
   },
   {
     "type": "or",
     "name": "step2",
     "nodes": [
-      "step2a",
-      "step2b"
+      "memory:sdk/tests/web/native/main.dart#step2a",
+      "memory:sdk/tests/web/native/main.dart#step2b"
     ]
   },
   {
     "type": "order",
-    "predecessor": "step1",
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
     "successor": "step2"
   },
   {
     "type": "order",
     "predecessor": "step2",
-    "successor": "step3"
+    "successor": "memory:sdk/tests/web/native/main.dart#step3"
   }
-]
+]
\ No newline at end of file
diff --git a/pkg/compiler/test/custom_split/data/two_branch/constraints.dart b/pkg/compiler/test/custom_split/data/two_branch/constraints.dart
index 1e6ad05..27a00ab 100644
--- a/pkg/compiler/test/custom_split/data/two_branch/constraints.dart
+++ b/pkg/compiler/test/custom_split/data/two_branch/constraints.dart
@@ -12,10 +12,13 @@
 }
 
 List<Node> processDeferredImports(List<String> imports) {
+  var step1 = 'memory:sdk/tests/web/native/main.dart#step1';
+  var step2a = 'memory:sdk/tests/web/native/main.dart#step2a';
+  var step2b = 'memory:sdk/tests/web/native/main.dart#step2b';
   var builder = ProgramSplitBuilder();
   return [
     ...imports.map(builder.referenceNode),
-    builder.orderNode('step1', 'step2a'),
-    builder.orderNode('step1', 'step2b'),
+    builder.orderNode(step1, step2a),
+    builder.orderNode(step1, step2b),
   ];
 }
diff --git a/pkg/compiler/test/custom_split/data/two_branch/constraints.json b/pkg/compiler/test/custom_split/data/two_branch/constraints.json
index 8b86071..1a29d7b 100644
--- a/pkg/compiler/test/custom_split/data/two_branch/constraints.json
+++ b/pkg/compiler/test/custom_split/data/two_branch/constraints.json
@@ -1,27 +1,27 @@
 [
   {
     "type": "reference",
-    "name": "step1",
+    "name": "memory:sdk/tests/web/native/main.dart#step1",
     "import": "memory:sdk/tests/web/native/main.dart#step1"
   },
   {
     "type": "reference",
-    "name": "step2a",
+    "name": "memory:sdk/tests/web/native/main.dart#step2a",
     "import": "memory:sdk/tests/web/native/main.dart#step2a"
   },
   {
     "type": "reference",
-    "name": "step2b",
+    "name": "memory:sdk/tests/web/native/main.dart#step2b",
     "import": "memory:sdk/tests/web/native/main.dart#step2b"
   },
   {
     "type": "order",
-    "predecessor": "step1",
-    "successor": "step2a"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
+    "successor": "memory:sdk/tests/web/native/main.dart#step2a"
   },
   {
     "type": "order",
-    "predecessor": "step1",
-    "successor": "step2b"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
+    "successor": "memory:sdk/tests/web/native/main.dart#step2b"
   }
-]
+]
\ No newline at end of file
diff --git a/pkg/compiler/test/custom_split/data/two_step/constraints.dart b/pkg/compiler/test/custom_split/data/two_step/constraints.dart
index 9089c5c..fe0d8a5 100644
--- a/pkg/compiler/test/custom_split/data/two_step/constraints.dart
+++ b/pkg/compiler/test/custom_split/data/two_step/constraints.dart
@@ -12,10 +12,13 @@
 }
 
 List<Node> processDeferredImports(List<String> imports) {
+  var step1 = 'memory:sdk/tests/web/native/main.dart#step1';
+  var step2 = 'memory:sdk/tests/web/native/main.dart#step2';
+  var step3 = 'memory:sdk/tests/web/native/main.dart#step3';
   var builder = ProgramSplitBuilder();
   return [
     ...imports.map(builder.referenceNode),
-    builder.orderNode('step1', 'step2'),
-    builder.orderNode('step2', 'step3'),
+    builder.orderNode(step1, step2),
+    builder.orderNode(step2, step3),
   ];
 }
diff --git a/pkg/compiler/test/custom_split/data/two_step/constraints.json b/pkg/compiler/test/custom_split/data/two_step/constraints.json
index b72db44..77a02de 100644
--- a/pkg/compiler/test/custom_split/data/two_step/constraints.json
+++ b/pkg/compiler/test/custom_split/data/two_step/constraints.json
@@ -1,27 +1,27 @@
 [
   {
     "type": "reference",
-    "name": "step1",
+    "name": "memory:sdk/tests/web/native/main.dart#step1",
     "import": "memory:sdk/tests/web/native/main.dart#step1"
   },
   {
     "type": "reference",
-    "name": "step2",
+    "name": "memory:sdk/tests/web/native/main.dart#step2",
     "import": "memory:sdk/tests/web/native/main.dart#step2"
   },
   {
     "type": "reference",
-    "name": "step3",
+    "name": "memory:sdk/tests/web/native/main.dart#step3",
     "import": "memory:sdk/tests/web/native/main.dart#step3"
   },
   {
     "type": "order",
-    "predecessor": "step1",
-    "successor": "step2"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step1",
+    "successor": "memory:sdk/tests/web/native/main.dart#step2"
   },
   {
     "type": "order",
-    "predecessor": "step2",
-    "successor": "step3"
+    "predecessor": "memory:sdk/tests/web/native/main.dart#step2",
+    "successor": "memory:sdk/tests/web/native/main.dart#step3"
   }
-]
+]
\ No newline at end of file
diff --git a/pkg/compiler/test/end_to_end/command_line_test.dart b/pkg/compiler/test/end_to_end/command_line_test.dart
index ec0a78a..f3ecc57 100644
--- a/pkg/compiler/test/end_to_end/command_line_test.dart
+++ b/pkg/compiler/test/end_to_end/command_line_test.dart
@@ -91,14 +91,27 @@
       '--out=foo.dill'
     ], out: 'foo.dill', readClosedWorld: 'foo.world', writeData: 'foo.data');
 
-    await test([Flags.readData, 'foo.dill'],
-        out: 'out.js', readData: 'foo.dill.data');
-    await test([Flags.readData, 'foo.dill', '--out=foo.js'],
-        out: 'foo.js', readData: 'foo.dill.data');
-    await test(['${Flags.readData}=out.data', 'foo.dill'],
-        out: 'out.js', readData: 'out.data');
-    await test(['${Flags.readData}=out.data', 'foo.dill', '--out=foo.js'],
-        out: 'foo.js', readData: 'out.data');
+    await test([Flags.readData, 'foo.dill'], exitCode: 1);
+    await test([Flags.readClosedWorld, Flags.readData, 'foo.dill'],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data');
+    await test(
+        [Flags.readClosedWorld, Flags.readData, 'foo.dill', '--out=foo.js'],
+        out: 'foo.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data');
+    await test([
+      '${Flags.readClosedWorld}=out.world',
+      '${Flags.readData}=out.data',
+      'foo.dill'
+    ], out: 'out.js', readClosedWorld: 'out.world', readData: 'out.data');
+    await test([
+      '${Flags.readClosedWorld}=out.world',
+      '${Flags.readData}=out.data',
+      'foo.dill',
+      '--out=foo.js'
+    ], out: 'foo.js', readClosedWorld: 'out.world', readData: 'out.data');
 
     await test([
       Flags.writeCodegen,
@@ -107,6 +120,7 @@
       '${Flags.codegenShards}=2'
     ], exitCode: 1);
     await test([
+      Flags.readClosedWorld,
       Flags.readData,
       Flags.writeCodegen,
       'foo.dill',
@@ -114,6 +128,7 @@
       '${Flags.codegenShards}=2'
     ],
         out: 'out',
+        readClosedWorld: 'foo.dill.world',
         readData: 'foo.dill.data',
         writeCodegen: 'out.code',
         codegenShard: 0,
@@ -121,16 +136,19 @@
     await test([
       Flags.writeCodegen,
       Flags.readData,
+      Flags.readClosedWorld,
       'foo.dill',
       '${Flags.codegenShard}=1',
       '${Flags.codegenShards}=2'
     ],
         out: 'out',
+        readClosedWorld: 'foo.dill.world',
         readData: 'foo.dill.data',
         writeCodegen: 'out.code',
         codegenShard: 1,
         codegenShards: 2);
     await test([
+      '${Flags.readClosedWorld}=foo.world',
       '${Flags.readData}=foo.data',
       '${Flags.writeCodegen}=foo.code',
       'foo.dill',
@@ -138,6 +156,7 @@
       '${Flags.codegenShards}=3'
     ],
         out: 'out',
+        readClosedWorld: 'foo.world',
         readData: 'foo.data',
         writeCodegen: 'foo.code',
         codegenShard: 0,
@@ -145,12 +164,14 @@
     await test([
       '${Flags.readData}=foo.data',
       '${Flags.writeCodegen}',
+      '${Flags.readClosedWorld}=foo.world',
       'foo.dill',
       '--out=foo.js',
       '${Flags.codegenShard}=0',
       '${Flags.codegenShards}=2'
     ],
         out: 'foo.js',
+        readClosedWorld: 'foo.world',
         readData: 'foo.data',
         writeCodegen: 'foo.js.code',
         codegenShard: 0,
@@ -203,28 +224,126 @@
       '${Flags.codegenShards}=2'
     ], exitCode: 1);
 
-    await test([Flags.readCodegen, 'foo.dill', '${Flags.codegenShards}=2'],
-        out: 'out.js',
-        readData: 'foo.dill.data',
-        readCodegen: 'foo.dill.code',
-        codegenShards: 2);
+    // These three flags should parse in any order, but all are required.
     await test([
-      '${Flags.readCodegen}=foo.code',
-      'foo.dill',
-      '${Flags.codegenShards}=3'
-    ],
-        out: 'out.js',
-        readData: 'foo.dill.data',
-        readCodegen: 'foo.code',
-        codegenShards: 3);
-
-    await test([
+      Flags.readClosedWorld,
       Flags.readData,
       Flags.readCodegen,
       'foo.dill',
       '${Flags.codegenShards}=2'
     ],
         out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data',
+        readCodegen: 'foo.dill.code',
+        codegenShards: 2);
+    await test([
+      Flags.readClosedWorld,
+      Flags.readCodegen,
+      Flags.readData,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data',
+        readCodegen: 'foo.dill.code',
+        codegenShards: 2);
+    await test([
+      Flags.readCodegen,
+      Flags.readClosedWorld,
+      Flags.readData,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data',
+        readCodegen: 'foo.dill.code',
+        codegenShards: 2);
+    await test([
+      Flags.readCodegen,
+      Flags.readData,
+      Flags.readClosedWorld,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data',
+        readCodegen: 'foo.dill.code',
+        codegenShards: 2);
+    await test([
+      Flags.readData,
+      Flags.readCodegen,
+      Flags.readClosedWorld,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data',
+        readCodegen: 'foo.dill.code',
+        codegenShards: 2);
+    await test([
+      Flags.readData,
+      Flags.readClosedWorld,
+      Flags.readCodegen,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data',
+        readCodegen: 'foo.dill.code',
+        codegenShards: 2);
+    await test([
+      Flags.readClosedWorld,
+      Flags.readCodegen,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ], exitCode: 1);
+    await test([
+      Flags.readData,
+      Flags.readCodegen,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ], exitCode: 1);
+
+    await test([
+      Flags.readData,
+      Flags.readClosedWorld,
+      Flags.readCodegen,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
+        readData: 'foo.dill.data',
+        readCodegen: 'foo.dill.code',
+        codegenShards: 2);
+    await test([
+      '${Flags.readCodegen}=foo.code',
+      'foo.dill',
+      '${Flags.codegenShards}=3',
+      Flags.readData,
+      Flags.readClosedWorld,
+    ],
+        out: 'out.js',
+        readData: 'foo.dill.data',
+        readClosedWorld: 'foo.dill.world',
+        readCodegen: 'foo.code',
+        codegenShards: 3);
+
+    await test([
+      Flags.readData,
+      Flags.readCodegen,
+      Flags.readClosedWorld,
+      'foo.dill',
+      '${Flags.codegenShards}=2'
+    ],
+        out: 'out.js',
+        readClosedWorld: 'foo.dill.world',
         readData: 'foo.dill.data',
         readCodegen: 'foo.dill.code',
         codegenShards: 2);
@@ -233,9 +352,11 @@
       '${Flags.readCodegen}=foo.code',
       'foo.dill',
       '${Flags.codegenShards}=3',
+      '${Flags.readClosedWorld}=foo.world',
       '-v'
     ],
         out: 'out.js',
+        readClosedWorld: 'foo.world',
         readData: 'foo.data',
         readCodegen: 'foo.code',
         codegenShards: 3);
diff --git a/pkg/compiler/test/end_to_end/feature_options_test.dart b/pkg/compiler/test/end_to_end/feature_options_test.dart
index d950d19..db2c87e 100644
--- a/pkg/compiler/test/end_to_end/feature_options_test.dart
+++ b/pkg/compiler/test/end_to_end/feature_options_test.dart
@@ -12,6 +12,8 @@
 import 'package:compiler/src/options.dart' show FeatureOptions, FeatureOption;
 
 class TestFeatureOptions extends FeatureOptions {
+  FeatureOption f1 = FeatureOption('f1');
+  FeatureOption noF2 = FeatureOption('f2', isNegativeFlag: true);
   FeatureOption sf1 = FeatureOption('sf1');
   FeatureOption sf2 = FeatureOption('sf2');
   FeatureOption noSf3 = FeatureOption('sf3', isNegativeFlag: true);
@@ -22,6 +24,9 @@
   FeatureOption noCf4 = FeatureOption('cf4', isNegativeFlag: true);
 
   @override
+  List<FeatureOption> shipped;
+
+  @override
   List<FeatureOption> shipping;
 
   @override
@@ -29,6 +34,7 @@
 
   // Initialize feature lists.
   TestFeatureOptions() {
+    shipped = [f1, noF2];
     shipping = [sf1, sf2, noSf3, noSf4];
     canary = [cf1, cf2, noCf3, noCf4];
   }
@@ -40,8 +46,14 @@
   return tfo;
 }
 
+void expectShipped(TestFeatureOptions tfo) {
+  Expect.isTrue(tfo.f1.isEnabled);
+  Expect.isTrue(tfo.noF2.isDisabled);
+}
+
 void testShipping() {
   var tfo = test([]);
+  expectShipped(tfo);
   Expect.isTrue(tfo.sf1.isEnabled);
   Expect.isTrue(tfo.sf2.isEnabled);
   Expect.isTrue(tfo.noSf3.isDisabled);
@@ -54,6 +66,7 @@
 
 void testNoShipping() {
   var tfo = test([Flags.noShipping]);
+  expectShipped(tfo);
   Expect.isTrue(tfo.sf1.isDisabled);
   Expect.isTrue(tfo.sf2.isDisabled);
   Expect.isTrue(tfo.noSf3.isEnabled);
@@ -66,6 +79,7 @@
 
 void testCanary() {
   var tfo = test([Flags.canary]);
+  expectShipped(tfo);
   Expect.isTrue(tfo.sf1.isEnabled);
   Expect.isTrue(tfo.sf2.isEnabled);
   Expect.isTrue(tfo.noSf3.isDisabled);
@@ -78,6 +92,7 @@
 
 void testShippingDisabled() {
   var tfo = test(['--no-sf2', '--sf3']);
+  expectShipped(tfo);
   Expect.isTrue(tfo.sf1.isEnabled);
   Expect.isTrue(tfo.sf2.isDisabled);
   Expect.isTrue(tfo.noSf3.isEnabled);
@@ -90,6 +105,7 @@
 
 void testCanaryDisabled() {
   var tfo = test([Flags.canary, '--no-sf2', '--sf3', '--no-cf1', '--cf3']);
+  expectShipped(tfo);
   Expect.isTrue(tfo.sf1.isEnabled);
   Expect.isTrue(tfo.sf2.isDisabled);
   Expect.isTrue(tfo.noSf3.isEnabled);
@@ -102,6 +118,7 @@
 
 void testNoShippingEnabled() {
   var tfo = test([Flags.noShipping, '--sf1', '--no-sf3', '--cf2', '--no-cf3']);
+  expectShipped(tfo);
   Expect.isTrue(tfo.sf1.isEnabled);
   Expect.isTrue(tfo.sf2.isDisabled);
   Expect.isTrue(tfo.noSf3.isDisabled);
@@ -114,6 +131,7 @@
 
 void testNoCanaryEnabled() {
   var tfo = test(['--cf1', '--no-cf3']);
+  expectShipped(tfo);
   Expect.isTrue(tfo.sf1.isEnabled);
   Expect.isTrue(tfo.sf2.isEnabled);
   Expect.isTrue(tfo.noSf3.isDisabled);
@@ -128,6 +146,11 @@
   Expect.throwsArgumentError(() => test(['--cf1', '--no-cf1']));
 }
 
+void testNoShippedDisable() {
+  Expect.throwsArgumentError(() => test(['--no-f1']));
+  Expect.throwsArgumentError(() => test(['--f2']));
+}
+
 void flavorStringTest(List<String> options, String expectedFlavorString) {
   var tfo = test(options);
   Expect.equals(expectedFlavorString, tfo.flavorString());
@@ -159,6 +182,7 @@
   testNoCanaryEnabled();
   testNoShippingEnabled();
   testFlagCollision();
+  testNoShippedDisable();
 
   // Supplemental tests.
   flavorStringTests();
diff --git a/pkg/compiler/test/model/cfe_annotations_test.dart b/pkg/compiler/test/model/cfe_annotations_test.dart
index c9bd48e..9cb3b6e 100644
--- a/pkg/compiler/test/model/cfe_annotations_test.dart
+++ b/pkg/compiler/test/model/cfe_annotations_test.dart
@@ -14,6 +14,7 @@
 import 'package:compiler/src/kernel/element_map.dart';
 import 'package:compiler/src/kernel/element_map_impl.dart';
 import 'package:expect/expect.dart';
+import 'package:front_end/src/api_prototype/lowering_predicates.dart';
 import 'package:kernel/ast.dart' as ir;
 
 import '../helpers/args_helper.dart';
@@ -434,6 +435,7 @@
                     implicitJsInteropMember:
                         nativeData.isJsInteropClass(classEntity),
                     implicitNativeMember: member is! ir.Constructor &&
+                        !isTearOffLowering(member) &&
                         nativeData.isNativeClass(classEntity) &&
                         !nativeData.isJsInteropClass(classEntity));
               }
diff --git a/pkg/compiler/tool/modular_test_suite.dart b/pkg/compiler/tool/modular_test_suite.dart
index 6195548..7a20a67 100644
--- a/pkg/compiler/tool/modular_test_suite.dart
+++ b/pkg/compiler/tool/modular_test_suite.dart
@@ -5,39 +5,23 @@
 /// Test the modular compilation pipeline of dart2js.
 ///
 /// This is a shell that runs multiple tests, one per folder under `data/`.
-import 'dart:io';
 import 'dart:async';
 
-import 'package:compiler/src/commandline_options.dart';
-import 'package:front_end/src/compute_platform_binaries_location.dart'
-    show computePlatformBinariesLocation;
 import 'package:modular_test/src/io_pipeline.dart';
-import 'package:modular_test/src/pipeline.dart';
-import 'package:modular_test/src/suite.dart';
 import 'package:modular_test/src/runner.dart';
-import 'package:package_config/package_config.dart';
+import 'modular_test_suite_helper.dart';
 
-String packageConfigJsonPath = ".dart_tool/package_config.json";
-Uri sdkRoot = Platform.script.resolve("../../../");
-Uri packageConfigUri = sdkRoot.resolve(packageConfigJsonPath);
-Options _options;
-String _dart2jsScript;
-String _kernelWorkerScript;
-
-// TODO(joshualitt): Figure out a way to support package configs in
-// tests/modular.
-PackageConfig _packageConfig;
 main(List<String> args) async {
-  _options = Options.parse(args);
-  _packageConfig = await loadPackageConfigUri(packageConfigUri);
-  await _resolveScripts();
+  var options = Options.parse(args);
+  await resolveScripts(options);
   await Future.wait([
     runSuite(
         sdkRoot.resolve('tests/modular/'),
         'tests/modular',
-        _options,
+        options,
         IOPipeline([
-          SourceToDillStep(),
+          OutlineDillCompilationStep(),
+          FullDillCompilationStep(),
           ModularAnalysisStep(),
           ComputeClosedWorldStep(useModularAnalysis: true),
           GlobalAnalysisStep(),
@@ -46,740 +30,5 @@
           Dart2jsEmissionStep(),
           RunD8(),
         ], cacheSharedModules: true)),
-    runSuite(
-        sdkRoot.resolve('tests/modular/'),
-        'tests/modular',
-        _options,
-        IOPipeline([
-          SourceToDillStep(),
-          ComputeClosedWorldStep(useModularAnalysis: false),
-          LegacyGlobalAnalysisStep(),
-          LegacyDart2jsCodegenStep(codeId0),
-          LegacyDart2jsCodegenStep(codeId1),
-          LegacyDart2jsEmissionStep(),
-          RunD8(),
-        ], cacheSharedModules: true))
   ]);
 }
-
-const dillId = DataId("dill");
-const modularUpdatedDillId = DataId("mdill");
-const modularDataId = DataId("mdata");
-const closedWorldId = DataId("world");
-const globalUpdatedDillId = DataId("gdill");
-const globalDataId = DataId("gdata");
-const codeId = ShardsDataId("code", 2);
-const codeId0 = ShardDataId(codeId, 0);
-const codeId1 = ShardDataId(codeId, 1);
-const jsId = DataId("js");
-const txtId = DataId("txt");
-const fakeRoot = 'dev-dart-app:/';
-
-String _packageConfigEntry(String name, Uri root,
-    {Uri packageRoot, LanguageVersion version}) {
-  var fields = [
-    '"name": "${name}"',
-    '"rootUri": "$root"',
-    if (packageRoot != null) '"packageUri": "$packageRoot"',
-    if (version != null) '"languageVersion": "$version"'
-  ];
-  return '{${fields.join(',')}}';
-}
-
-// Step that compiles sources in a module to a .dill file.
-class SourceToDillStep implements IOModularStep {
-  @override
-  List<DataId> get resultData => const [dillId];
-
-  @override
-  bool get needsSources => true;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [dillId];
-
-  @override
-  List<DataId> get moduleDataNeeded => const [];
-
-  @override
-  bool get onlyOnMain => false;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("\nstep: source-to-dill on $module");
-
-    // We use non file-URI schemes for representeing source locations in a
-    // root-agnostic way. This allows us to refer to file across modules and
-    // across steps without exposing the underlying temporary folders that are
-    // created by the framework. In build systems like bazel this is especially
-    // important because each step may be run on a different machine.
-    //
-    // Files in packages are defined in terms of `package:` URIs, while
-    // non-package URIs are defined using the `dart-dev-app` scheme.
-    String rootScheme = module.isSdk ? 'dart-dev-sdk' : 'dev-dart-app';
-    String sourceToImportUri(Uri relativeUri) {
-      if (module.isPackage) {
-        var basePath = module.packageBase.path;
-        var packageRelativePath = basePath == "./"
-            ? relativeUri.path
-            : relativeUri.path.substring(basePath.length);
-        return 'package:${module.name}/$packageRelativePath';
-      } else {
-        return '$rootScheme:/$relativeUri';
-      }
-    }
-
-    // We create both a .packages and package_config.json file which defines
-    // the location of this module if it is a package.  The CFE requires that
-    // if a `package:` URI of a dependency is used in an import, then we need
-    // that package entry in the associated file. However, after it checks that
-    // the definition exists, the CFE will not actually use the resolved URI if
-    // a library for the import URI is already found in one of the provide
-    // .dill files of the dependencies. For that reason, and to ensure that
-    // a step only has access to the files provided in a module, we generate a
-    // config file with invalid folders for other packages.
-    // TODO(sigmund): follow up with the CFE to see if we can remove the need
-    // for these dummy entries..
-    // TODO(joshualitt): Generate just the json file.
-    var packagesJson = [];
-    var packagesContents = StringBuffer();
-    if (module.isPackage) {
-      packagesContents.write('${module.name}:${module.packageBase}\n');
-      packagesJson.add(_packageConfigEntry(
-          module.name, Uri.parse('../${module.packageBase}')));
-    }
-
-    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
-    int unusedNum = 0;
-    for (Module dependency in transitiveDependencies) {
-      if (dependency.isPackage) {
-        // rootUri should be ignored for dependent modules, so we pass in a
-        // bogus value.
-        var rootUri = Uri.parse('unused$unusedNum');
-        unusedNum++;
-
-        var dependentPackage = _packageConfig[dependency.name];
-        var packageJson = dependentPackage == null
-            ? _packageConfigEntry(dependency.name, rootUri)
-            : _packageConfigEntry(dependentPackage.name, rootUri,
-                version: dependentPackage.languageVersion);
-        packagesJson.add(packageJson);
-        packagesContents.write('${dependency.name}:$rootUri\n');
-      }
-    }
-
-    if (module.isPackage) {
-      await File.fromUri(root.resolve(packageConfigJsonPath))
-          .create(recursive: true);
-      await File.fromUri(root.resolve(packageConfigJsonPath)).writeAsString('{'
-          '  "configVersion": ${_packageConfig.version},'
-          '  "packages": [ ${packagesJson.join(',')} ]'
-          '}');
-    }
-
-    await File.fromUri(root.resolve('.packages'))
-        .writeAsString('$packagesContents');
-
-    List<String> sources;
-    List<String> extraArgs;
-    if (module.isSdk) {
-      // When no flags are passed, we can skip compilation and reuse the
-      // platform.dill created by build.py.
-      if (flags.isEmpty) {
-        var platform = computePlatformBinariesLocation()
-            .resolve("dart2js_platform_unsound.dill");
-        var destination = root.resolveUri(toUri(module, dillId));
-        if (_options.verbose) {
-          print('command:\ncp $platform $destination');
-        }
-        await File.fromUri(platform).copy(destination.toFilePath());
-        return;
-      }
-      sources = ['dart:core'];
-      extraArgs = ['--libraries-file', '$rootScheme:///sdk/lib/libraries.json'];
-      assert(transitiveDependencies.isEmpty);
-    } else {
-      sources = module.sources.map(sourceToImportUri).toList();
-      extraArgs = ['--packages-file', '$rootScheme:/.packages'];
-    }
-
-    // TODO(joshualitt): Ensure the kernel worker has some way to specify
-    // --no-sound-null-safety
-    List<String> args = [
-      _kernelWorkerScript,
-      '--no-summary-only',
-      '--target',
-      'dart2js',
-      '--multi-root',
-      '$root',
-      '--multi-root-scheme',
-      rootScheme,
-      ...extraArgs,
-      '--output',
-      '${toUri(module, dillId)}',
-      ...(transitiveDependencies
-          .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
-      ...(sources.expand((String uri) => ['--source', uri])),
-      ...(flags.expand((String flag) => ['--enable-experiment', flag])),
-    ];
-
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose) print("\ncached step: source-to-dill on $module");
-  }
-}
-
-class ModularAnalysisStep implements IOModularStep {
-  @override
-  List<DataId> get resultData => const [modularDataId, modularUpdatedDillId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [dillId];
-
-  @override
-  List<DataId> get moduleDataNeeded => const [dillId];
-
-  @override
-  bool get onlyOnMain => false;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("\nstep: modular analysis on $module");
-    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
-    Iterable<String> dillDependencies =
-        transitiveDependencies.map((m) => '${toUri(m, dillId)}');
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.inputDill}=${toUri(module, dillId)}',
-      if (dillDependencies.isNotEmpty)
-        '--dill-dependencies=${dillDependencies.join(',')}',
-      '--out=${toUri(module, modularUpdatedDillId)}',
-      '${Flags.writeModularAnalysis}=${toUri(module, modularDataId)}',
-      for (String flag in flags) '--enable-experiment=$flag',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose) {
-      print("cached step: dart2js modular analysis on $module");
-    }
-  }
-}
-
-DataId idForDill({bool useModularAnalysis}) =>
-    useModularAnalysis ? modularUpdatedDillId : dillId;
-
-List<DataId> inputFromAnalysis({bool useModularAnalysis = false}) => [
-      idForDill(useModularAnalysis: useModularAnalysis),
-      if (useModularAnalysis) modularDataId,
-    ];
-
-// Step that invokes the dart2js closed world computation.
-class ComputeClosedWorldStep implements IOModularStep {
-  final bool useModularAnalysis;
-
-  ComputeClosedWorldStep({this.useModularAnalysis});
-
-  @override
-  List<DataId> get resultData => const [closedWorldId, globalUpdatedDillId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded =>
-      inputFromAnalysis(useModularAnalysis: useModularAnalysis);
-
-  @override
-  List<DataId> get moduleDataNeeded =>
-      inputFromAnalysis(useModularAnalysis: useModularAnalysis);
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose)
-      print("\nstep: dart2js compute closed world on $module");
-    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
-    DataId dillId = idForDill(useModularAnalysis: useModularAnalysis);
-    Iterable<String> dillDependencies =
-        transitiveDependencies.map((m) => '${toUri(m, dillId)}');
-    List<String> dataDependencies = transitiveDependencies
-        .map((m) => '${toUri(m, modularDataId)}')
-        .toList();
-    dataDependencies.add('${toUri(module, modularDataId)}');
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      // TODO(sigmund): remove this dependency on libraries.json
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
-      '${Flags.inputDill}=${toUri(module, dillId)}',
-      for (String flag in flags) '--enable-experiment=$flag',
-      '${Flags.dillDependencies}=${dillDependencies.join(',')}',
-      if (useModularAnalysis)
-        '${Flags.readModularAnalysis}=${dataDependencies.join(',')}',
-      '${Flags.writeClosedWorld}=${toUri(module, closedWorldId)}',
-      Flags.noClosedWorldInData,
-      '--out=${toUri(module, globalUpdatedDillId)}',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose)
-      print("\ncached step: dart2js compute closed world on $module");
-  }
-}
-
-// Step that runs the dart2js modular analysis.
-class GlobalAnalysisStep implements IOModularStep {
-  @override
-  List<DataId> get resultData => const [globalDataId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [globalUpdatedDillId];
-
-  @override
-  List<DataId> get moduleDataNeeded =>
-      const [closedWorldId, globalUpdatedDillId];
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("\nstep: dart2js global analysis on $module");
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      // TODO(sigmund): remove this dependency on libraries.json
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
-      '${Flags.inputDill}=${toUri(module, globalUpdatedDillId)}',
-      for (String flag in flags) '--enable-experiment=$flag',
-      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
-      '${Flags.writeData}=${toUri(module, globalDataId)}',
-      // TODO(joshualitt): delete this flag after google3 roll
-      '${Flags.noClosedWorldInData}',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose)
-      print("\ncached step: dart2js global analysis on $module");
-  }
-}
-
-// Step that invokes the dart2js code generation on the main module given the
-// results of the global analysis step and produces one shard of the codegen
-// output.
-class Dart2jsCodegenStep implements IOModularStep {
-  final ShardDataId codeId;
-
-  Dart2jsCodegenStep(this.codeId);
-
-  @override
-  List<DataId> get resultData => [codeId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [];
-
-  @override
-  List<DataId> get moduleDataNeeded =>
-      const [globalUpdatedDillId, closedWorldId, globalDataId];
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("\nstep: dart2js backend on $module");
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
-      '${Flags.inputDill}=${toUri(module, globalUpdatedDillId)}',
-      for (String flag in flags) '--enable-experiment=$flag',
-      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
-      '${Flags.readData}=${toUri(module, globalDataId)}',
-      '${Flags.writeCodegen}=${toUri(module, codeId.dataId)}',
-      '${Flags.codegenShard}=${codeId.shard}',
-      '${Flags.codegenShards}=${codeId.dataId.shards}',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose) print("cached step: dart2js backend on $module");
-  }
-}
-
-// Step that invokes the dart2js codegen enqueuer and emitter on the main module
-// given the results of the global analysis step and codegen shards.
-class Dart2jsEmissionStep implements IOModularStep {
-  @override
-  List<DataId> get resultData => const [jsId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [];
-
-  @override
-  List<DataId> get moduleDataNeeded => const [
-        globalUpdatedDillId,
-        closedWorldId,
-        globalDataId,
-        codeId0,
-        codeId1
-      ];
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("step: dart2js backend on $module");
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
-      '${Flags.inputDill}=${toUri(module, globalUpdatedDillId)}',
-      for (String flag in flags) '${Flags.enableLanguageExperiments}=$flag',
-      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
-      '${Flags.readData}=${toUri(module, globalDataId)}',
-      '${Flags.readCodegen}=${toUri(module, codeId)}',
-      '${Flags.codegenShards}=${codeId.shards}',
-      '--out=${toUri(module, jsId)}',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose) print("\ncached step: dart2js backend on $module");
-  }
-}
-
-// TODO(joshualitt): delete after google3 roll.
-class LegacyGlobalAnalysisStep implements IOModularStep {
-  @override
-  List<DataId> get resultData => const [globalDataId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [globalUpdatedDillId];
-
-  @override
-  List<DataId> get moduleDataNeeded =>
-      const [closedWorldId, globalUpdatedDillId];
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("\nstep: dart2js global analysis on $module");
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      // TODO(sigmund): remove this dependency on libraries.json
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
-      '${toUri(module, globalUpdatedDillId)}',
-      for (String flag in flags) '--enable-experiment=$flag',
-      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
-      '${Flags.writeData}=${toUri(module, globalDataId)}',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose)
-      print("\ncached step: dart2js global analysis on $module");
-  }
-}
-
-// Step that invokes the dart2js code generation on the main module given the
-// results of the global analysis step and produces one shard of the codegen
-// output.
-// Note: Legacy.
-class LegacyDart2jsCodegenStep implements IOModularStep {
-  final ShardDataId codeId;
-
-  LegacyDart2jsCodegenStep(this.codeId);
-
-  @override
-  List<DataId> get resultData => [codeId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [];
-
-  @override
-  List<DataId> get moduleDataNeeded =>
-      const [globalUpdatedDillId, globalDataId];
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("\nstep: dart2js backend on $module");
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
-      '${toUri(module, globalUpdatedDillId)}',
-      for (String flag in flags) '--enable-experiment=$flag',
-      '${Flags.readData}=${toUri(module, globalDataId)}',
-      '${Flags.writeCodegen}=${toUri(module, codeId.dataId)}',
-      '${Flags.codegenShard}=${codeId.shard}',
-      '${Flags.codegenShards}=${codeId.dataId.shards}',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose) print("cached step: dart2js backend on $module");
-  }
-}
-
-// Step that invokes the dart2js codegen enqueuer and emitter on the main module
-// given the results of the global analysis step and codegen shards.
-// Note: Legacy.
-class LegacyDart2jsEmissionStep implements IOModularStep {
-  @override
-  List<DataId> get resultData => const [jsId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [];
-
-  @override
-  List<DataId> get moduleDataNeeded =>
-      const [globalUpdatedDillId, globalDataId, codeId0, codeId1];
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("step: dart2js backend on $module");
-    List<String> args = [
-      '--packages=${sdkRoot.toFilePath()}/.packages',
-      _dart2jsScript,
-      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
-      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
-      '${toUri(module, globalUpdatedDillId)}',
-      for (String flag in flags) '${Flags.enableLanguageExperiments}=$flag',
-      '${Flags.readData}=${toUri(module, globalDataId)}',
-      '${Flags.readCodegen}=${toUri(module, codeId)}',
-      '${Flags.codegenShards}=${codeId.shards}',
-      '--out=${toUri(module, jsId)}',
-    ];
-    var result =
-        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose) print("\ncached step: dart2js backend on $module");
-  }
-}
-
-/// Step that runs the output of dart2js in d8 and saves the output.
-class RunD8 implements IOModularStep {
-  @override
-  List<DataId> get resultData => const [txtId];
-
-  @override
-  bool get needsSources => false;
-
-  @override
-  List<DataId> get dependencyDataNeeded => const [];
-
-  @override
-  List<DataId> get moduleDataNeeded => const [jsId];
-
-  @override
-  bool get onlyOnMain => true;
-
-  @override
-  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
-      List<String> flags) async {
-    if (_options.verbose) print("\nstep: d8 on $module");
-    List<String> d8Args = [
-      sdkRoot
-          .resolve('sdk/lib/_internal/js_runtime/lib/preambles/d8.js')
-          .toFilePath(),
-      root.resolveUri(toUri(module, jsId)).toFilePath(),
-    ];
-    var result = await _runProcess(
-        sdkRoot.resolve(_d8executable).toFilePath(), d8Args, root.toFilePath());
-
-    _checkExitCode(result, this, module);
-
-    await File.fromUri(root.resolveUri(toUri(module, txtId)))
-        .writeAsString(result.stdout);
-  }
-
-  @override
-  void notifyCached(Module module) {
-    if (_options.verbose) print("\ncached step: d8 on $module");
-  }
-}
-
-void _checkExitCode(ProcessResult result, IOModularStep step, Module module) {
-  if (result.exitCode != 0 || _options.verbose) {
-    stdout.write(result.stdout);
-    stderr.write(result.stderr);
-  }
-  if (result.exitCode != 0) {
-    throw "${step.runtimeType} failed on $module:\n\n"
-        "stdout:\n${result.stdout}\n\n"
-        "stderr:\n${result.stderr}";
-  }
-}
-
-Future<ProcessResult> _runProcess(
-    String command, List<String> arguments, String workingDirectory) {
-  if (_options.verbose) {
-    print('command:\n$command ${arguments.join(' ')} from $workingDirectory');
-  }
-  return Process.run(command, arguments, workingDirectory: workingDirectory);
-}
-
-String get _d8executable {
-  if (Platform.isWindows) {
-    return 'third_party/d8/windows/d8.exe';
-  } else if (Platform.isLinux) {
-    return 'third_party/d8/linux/d8';
-  } else if (Platform.isMacOS) {
-    return 'third_party/d8/macos/d8';
-  }
-  throw UnsupportedError('Unsupported platform.');
-}
-
-class ShardsDataId implements DataId {
-  @override
-  final String name;
-  final int shards;
-
-  const ShardsDataId(this.name, this.shards);
-
-  @override
-  String toString() => name;
-}
-
-class ShardDataId implements DataId {
-  final ShardsDataId dataId;
-  final int _shard;
-
-  const ShardDataId(this.dataId, this._shard);
-
-  int get shard {
-    assert(0 <= _shard && _shard < dataId.shards);
-    return _shard;
-  }
-
-  @override
-  String get name => '${dataId.name}${shard}';
-
-  @override
-  String toString() => name;
-}
-
-Future<void> _resolveScripts() async {
-  Future<String> resolve(
-      String sourceUriOrPath, String relativeSnapshotPath) async {
-    Uri sourceUri = sdkRoot.resolve(sourceUriOrPath);
-    String result =
-        sourceUri.scheme == 'file' ? sourceUri.toFilePath() : sourceUriOrPath;
-    if (_options.useSdk) {
-      String snapshot = Uri.file(Platform.resolvedExecutable)
-          .resolve(relativeSnapshotPath)
-          .toFilePath();
-      if (await File(snapshot).exists()) {
-        return snapshot;
-      }
-    }
-    return result;
-  }
-
-  _dart2jsScript = await resolve(
-      'package:compiler/src/dart2js.dart', 'snapshots/dart2js.dart.snapshot');
-  _kernelWorkerScript = await resolve('utils/bazel/kernel_worker.dart',
-      'snapshots/kernel_worker.dart.snapshot');
-}
-
-String _librarySpecForSnapshot = Uri.file(Platform.resolvedExecutable)
-    .resolve('../lib/libraries.json')
-    .toFilePath();
diff --git a/pkg/compiler/tool/modular_test_suite_helper.dart b/pkg/compiler/tool/modular_test_suite_helper.dart
new file mode 100644
index 0000000..cd583ad
--- /dev/null
+++ b/pkg/compiler/tool/modular_test_suite_helper.dart
@@ -0,0 +1,662 @@
+// Copyright (c) 2019, 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.
+
+/// Test the modular compilation pipeline of dart2js.
+///
+/// This is a shell that runs multiple tests, one per folder under `data/`.
+import 'dart:io';
+import 'dart:async';
+
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/kernel/dart2js_target.dart';
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+    show computePlatformBinariesLocation;
+import 'package:modular_test/src/io_pipeline.dart';
+import 'package:modular_test/src/pipeline.dart';
+import 'package:modular_test/src/suite.dart';
+import 'package:modular_test/src/runner.dart';
+import 'package:package_config/package_config.dart';
+
+String packageConfigJsonPath = ".dart_tool/package_config.json";
+Uri sdkRoot = Platform.script.resolve("../../../");
+Uri packageConfigUri = sdkRoot.resolve(packageConfigJsonPath);
+Options _options;
+String _dart2jsScript;
+String _kernelWorkerScript;
+
+const dillSummaryId = DataId("sdill");
+const dillId = DataId("dill");
+const modularUpdatedDillId = DataId("mdill");
+const modularDataId = DataId("mdata");
+const closedWorldId = DataId("world");
+const globalUpdatedDillId = DataId("gdill");
+const globalDataId = DataId("gdata");
+const codeId = ShardsDataId("code", 2);
+const codeId0 = ShardDataId(codeId, 0);
+const codeId1 = ShardDataId(codeId, 1);
+const jsId = DataId("js");
+const txtId = DataId("txt");
+const fakeRoot = 'dev-dart-app:/';
+
+String _packageConfigEntry(String name, Uri root,
+    {Uri packageRoot, LanguageVersion version}) {
+  var fields = [
+    '"name": "${name}"',
+    '"rootUri": "$root"',
+    if (packageRoot != null) '"packageUri": "$packageRoot"',
+    if (version != null) '"languageVersion": "$version"'
+  ];
+  return '{${fields.join(',')}}';
+}
+
+abstract class CFEStep implements IOModularStep {
+  final String stepName;
+
+  CFEStep(this.stepName);
+
+  @override
+  bool get needsSources => true;
+
+  @override
+  bool get onlyOnMain => false;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("\nstep: $stepName on $module");
+
+    // TODO(joshualitt): Figure out a way to support package configs in
+    // tests/modular.
+    var packageConfig = await loadPackageConfigUri(packageConfigUri);
+
+    // We use non file-URI schemes for representeing source locations in a
+    // root-agnostic way. This allows us to refer to file across modules and
+    // across steps without exposing the underlying temporary folders that are
+    // created by the framework. In build systems like bazel this is especially
+    // important because each step may be run on a different machine.
+    //
+    // Files in packages are defined in terms of `package:` URIs, while
+    // non-package URIs are defined using the `dart-dev-app` scheme.
+    String rootScheme = module.isSdk ? 'dart-dev-sdk' : 'dev-dart-app';
+    String sourceToImportUri(Uri relativeUri) {
+      if (module.isPackage) {
+        var basePath = module.packageBase.path;
+        var packageRelativePath = basePath == "./"
+            ? relativeUri.path
+            : relativeUri.path.substring(basePath.length);
+        return 'package:${module.name}/$packageRelativePath';
+      } else {
+        return '$rootScheme:/$relativeUri';
+      }
+    }
+
+    // We create both a .packages and package_config.json file which defines
+    // the location of this module if it is a package.  The CFE requires that
+    // if a `package:` URI of a dependency is used in an import, then we need
+    // that package entry in the associated file. However, after it checks that
+    // the definition exists, the CFE will not actually use the resolved URI if
+    // a library for the import URI is already found in one of the provide
+    // .dill files of the dependencies. For that reason, and to ensure that
+    // a step only has access to the files provided in a module, we generate a
+    // config file with invalid folders for other packages.
+    // TODO(sigmund): follow up with the CFE to see if we can remove the need
+    // for these dummy entries..
+    // TODO(joshualitt): Generate just the json file.
+    var packagesJson = [];
+    var packagesContents = StringBuffer();
+    if (module.isPackage) {
+      packagesContents.write('${module.name}:${module.packageBase}\n');
+      packagesJson.add(_packageConfigEntry(
+          module.name, Uri.parse('../${module.packageBase}')));
+    }
+
+    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
+    int unusedNum = 0;
+    for (Module dependency in transitiveDependencies) {
+      if (dependency.isPackage) {
+        // rootUri should be ignored for dependent modules, so we pass in a
+        // bogus value.
+        var rootUri = Uri.parse('unused$unusedNum');
+        unusedNum++;
+
+        var dependentPackage = packageConfig[dependency.name];
+        var packageJson = dependentPackage == null
+            ? _packageConfigEntry(dependency.name, rootUri)
+            : _packageConfigEntry(dependentPackage.name, rootUri,
+                version: dependentPackage.languageVersion);
+        packagesJson.add(packageJson);
+        packagesContents.write('${dependency.name}:$rootUri\n');
+      }
+    }
+
+    if (module.isPackage) {
+      await File.fromUri(root.resolve(packageConfigJsonPath))
+          .create(recursive: true);
+      await File.fromUri(root.resolve(packageConfigJsonPath)).writeAsString('{'
+          '  "configVersion": ${packageConfig.version},'
+          '  "packages": [ ${packagesJson.join(',')} ]'
+          '}');
+    }
+
+    await File.fromUri(root.resolve('.packages'))
+        .writeAsString('$packagesContents');
+
+    List<String> sources;
+    List<String> extraArgs = ['--packages-file', '$rootScheme:/.packages'];
+    if (module.isSdk) {
+      // When no flags are passed, we can skip compilation and reuse the
+      // platform.dill created by build.py.
+      if (flags.isEmpty) {
+        var platform = computePlatformBinariesLocation()
+            .resolve("dart2js_platform_unsound.dill");
+        var destination = root.resolveUri(toUri(module, outputData));
+        if (_options.verbose) {
+          print('command:\ncp $platform $destination');
+        }
+        await File.fromUri(platform).copy(destination.toFilePath());
+        return;
+      }
+      sources = requiredLibraries['dart2js'] + ['dart:core'];
+      extraArgs += [
+        '--libraries-file',
+        '$rootScheme:///sdk/lib/libraries.json'
+      ];
+      assert(transitiveDependencies.isEmpty);
+    } else {
+      sources = module.sources.map(sourceToImportUri).toList();
+    }
+
+    // TODO(joshualitt): Ensure the kernel worker has some way to specify
+    // --no-sound-null-safety
+    List<String> args = [
+      _kernelWorkerScript,
+      ...stepArguments,
+      '--exclude-non-sources',
+      '--multi-root',
+      '$root',
+      '--multi-root-scheme',
+      rootScheme,
+      ...extraArgs,
+      '--output',
+      '${toUri(module, outputData)}',
+      ...(transitiveDependencies
+          .expand((m) => ['--input-summary', '${toUri(m, inputData)}'])),
+      ...(sources.expand((String uri) => ['--source', uri])),
+      ...(flags.expand((String flag) => ['--enable-experiment', flag])),
+    ];
+
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+    _checkExitCode(result, this, module);
+  }
+
+  List<String> get stepArguments;
+
+  DataId get inputData;
+
+  DataId get outputData;
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose) print("\ncached step: $stepName on $module");
+  }
+}
+
+// Step that compiles sources in a module to a summary .dill file.
+class OutlineDillCompilationStep extends CFEStep {
+  @override
+  List<DataId> get resultData => const [dillSummaryId];
+
+  @override
+  bool get needsSources => true;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [dillSummaryId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [];
+
+  @override
+  List<String> get stepArguments =>
+      ['--target', 'dart2js_summary', '--summary-only'];
+
+  @override
+  DataId get inputData => dillSummaryId;
+
+  @override
+  DataId get outputData => dillSummaryId;
+
+  OutlineDillCompilationStep() : super('outline-dill-compilation');
+}
+
+// Step that compiles sources in a module to a .dill file.
+class FullDillCompilationStep extends CFEStep {
+  @override
+  List<DataId> get resultData => const [dillId];
+
+  @override
+  bool get needsSources => true;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [dillSummaryId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [];
+
+  @override
+  List<String> get stepArguments =>
+      ['--target', 'dart2js', '--no-summary', '--no-summary-only'];
+
+  @override
+  DataId get inputData => dillSummaryId;
+
+  @override
+  DataId get outputData => dillId;
+
+  FullDillCompilationStep() : super('full-dill-compilation');
+}
+
+class ModularAnalysisStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [modularDataId, modularUpdatedDillId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [dillId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [dillId];
+
+  @override
+  bool get onlyOnMain => false;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("\nstep: modular analysis on $module");
+    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
+    Iterable<String> dillDependencies =
+        transitiveDependencies.map((m) => '${toUri(m, dillId)}');
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${Flags.inputDill}=${toUri(module, dillId)}',
+      if (dillDependencies.isNotEmpty)
+        '--dill-dependencies=${dillDependencies.join(',')}',
+      '--out=${toUri(module, modularUpdatedDillId)}',
+      '${Flags.writeModularAnalysis}=${toUri(module, modularDataId)}',
+      for (String flag in flags) '--enable-experiment=$flag',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose) {
+      print("cached step: dart2js modular analysis on $module");
+    }
+  }
+}
+
+DataId idForDill({bool useModularAnalysis}) =>
+    useModularAnalysis ? modularUpdatedDillId : dillId;
+
+List<DataId> inputFromAnalysis({bool useModularAnalysis = false}) => [
+      idForDill(useModularAnalysis: useModularAnalysis),
+      if (useModularAnalysis) modularDataId,
+    ];
+
+// Step that invokes the dart2js closed world computation.
+class ComputeClosedWorldStep implements IOModularStep {
+  final bool useModularAnalysis;
+
+  ComputeClosedWorldStep({this.useModularAnalysis});
+
+  @override
+  List<DataId> get resultData => const [closedWorldId, globalUpdatedDillId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded =>
+      inputFromAnalysis(useModularAnalysis: useModularAnalysis);
+
+  @override
+  List<DataId> get moduleDataNeeded =>
+      inputFromAnalysis(useModularAnalysis: useModularAnalysis);
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose)
+      print("\nstep: dart2js compute closed world on $module");
+    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
+    DataId dillId = idForDill(useModularAnalysis: useModularAnalysis);
+    Iterable<String> dillDependencies =
+        transitiveDependencies.map((m) => '${toUri(m, dillId)}');
+    List<String> dataDependencies = transitiveDependencies
+        .map((m) => '${toUri(m, modularDataId)}')
+        .toList();
+    dataDependencies.add('${toUri(module, modularDataId)}');
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      // TODO(sigmund): remove this dependency on libraries.json
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
+      '${Flags.inputDill}=${toUri(module, dillId)}',
+      for (String flag in flags) '--enable-experiment=$flag',
+      '${Flags.dillDependencies}=${dillDependencies.join(',')}',
+      if (useModularAnalysis)
+        '${Flags.readModularAnalysis}=${dataDependencies.join(',')}',
+      '${Flags.writeClosedWorld}=${toUri(module, closedWorldId)}',
+      Flags.noClosedWorldInData,
+      '--out=${toUri(module, globalUpdatedDillId)}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose)
+      print("\ncached step: dart2js compute closed world on $module");
+  }
+}
+
+// Step that runs the dart2js modular analysis.
+class GlobalAnalysisStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [globalDataId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [globalUpdatedDillId];
+
+  @override
+  List<DataId> get moduleDataNeeded =>
+      const [closedWorldId, globalUpdatedDillId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("\nstep: dart2js global analysis on $module");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      // TODO(sigmund): remove this dependency on libraries.json
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
+      '${Flags.inputDill}=${toUri(module, globalUpdatedDillId)}',
+      for (String flag in flags) '--enable-experiment=$flag',
+      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
+      '${Flags.writeData}=${toUri(module, globalDataId)}',
+      // TODO(joshualitt): delete this flag after google3 roll
+      '${Flags.noClosedWorldInData}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose)
+      print("\ncached step: dart2js global analysis on $module");
+  }
+}
+
+// Step that invokes the dart2js code generation on the main module given the
+// results of the global analysis step and produces one shard of the codegen
+// output.
+class Dart2jsCodegenStep implements IOModularStep {
+  final ShardDataId codeId;
+
+  Dart2jsCodegenStep(this.codeId);
+
+  @override
+  List<DataId> get resultData => [codeId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
+  List<DataId> get moduleDataNeeded =>
+      const [globalUpdatedDillId, closedWorldId, globalDataId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("\nstep: dart2js backend on $module");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
+      '${Flags.inputDill}=${toUri(module, globalUpdatedDillId)}',
+      for (String flag in flags) '--enable-experiment=$flag',
+      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
+      '${Flags.readData}=${toUri(module, globalDataId)}',
+      '${Flags.writeCodegen}=${toUri(module, codeId.dataId)}',
+      '${Flags.codegenShard}=${codeId.shard}',
+      '${Flags.codegenShards}=${codeId.dataId.shards}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose) print("cached step: dart2js backend on $module");
+  }
+}
+
+// Step that invokes the dart2js codegen enqueuer and emitter on the main module
+// given the results of the global analysis step and codegen shards.
+class Dart2jsEmissionStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [jsId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [
+        globalUpdatedDillId,
+        closedWorldId,
+        globalDataId,
+        codeId0,
+        codeId1
+      ];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("step: dart2js backend on $module");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      _dart2jsScript,
+      if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
+      '${Flags.entryUri}=$fakeRoot${module.mainSource}',
+      '${Flags.inputDill}=${toUri(module, globalUpdatedDillId)}',
+      for (String flag in flags) '${Flags.enableLanguageExperiments}=$flag',
+      '${Flags.readClosedWorld}=${toUri(module, closedWorldId)}',
+      '${Flags.readData}=${toUri(module, globalDataId)}',
+      '${Flags.readCodegen}=${toUri(module, codeId)}',
+      '${Flags.codegenShards}=${codeId.shards}',
+      '--out=${toUri(module, jsId)}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose) print("\ncached step: dart2js backend on $module");
+  }
+}
+
+/// Step that runs the output of dart2js in d8 and saves the output.
+class RunD8 implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [txtId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [jsId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+      List<String> flags) async {
+    if (_options.verbose) print("\nstep: d8 on $module");
+    List<String> d8Args = [
+      sdkRoot
+          .resolve('sdk/lib/_internal/js_runtime/lib/preambles/d8.js')
+          .toFilePath(),
+      root.resolveUri(toUri(module, jsId)).toFilePath(),
+    ];
+    var result = await _runProcess(
+        sdkRoot.resolve(_d8executable).toFilePath(), d8Args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+
+    await File.fromUri(root.resolveUri(toUri(module, txtId)))
+        .writeAsString(result.stdout);
+  }
+
+  @override
+  void notifyCached(Module module) {
+    if (_options.verbose) print("\ncached step: d8 on $module");
+  }
+}
+
+void _checkExitCode(ProcessResult result, IOModularStep step, Module module) {
+  if (result.exitCode != 0 || _options.verbose) {
+    stdout.write(result.stdout);
+    stderr.write(result.stderr);
+  }
+  if (result.exitCode != 0) {
+    throw "${step.runtimeType} failed on $module:\n\n"
+        "stdout:\n${result.stdout}\n\n"
+        "stderr:\n${result.stderr}";
+  }
+}
+
+Future<ProcessResult> _runProcess(
+    String command, List<String> arguments, String workingDirectory) {
+  if (_options.verbose) {
+    print('command:\n$command ${arguments.join(' ')} from $workingDirectory');
+  }
+  return Process.run(command, arguments, workingDirectory: workingDirectory);
+}
+
+String get _d8executable {
+  if (Platform.isWindows) {
+    return 'third_party/d8/windows/d8.exe';
+  } else if (Platform.isLinux) {
+    return 'third_party/d8/linux/d8';
+  } else if (Platform.isMacOS) {
+    return 'third_party/d8/macos/d8';
+  }
+  throw UnsupportedError('Unsupported platform.');
+}
+
+class ShardsDataId implements DataId {
+  @override
+  final String name;
+  final int shards;
+
+  const ShardsDataId(this.name, this.shards);
+
+  @override
+  String toString() => name;
+}
+
+class ShardDataId implements DataId {
+  final ShardsDataId dataId;
+  final int _shard;
+
+  const ShardDataId(this.dataId, this._shard);
+
+  int get shard {
+    assert(0 <= _shard && _shard < dataId.shards);
+    return _shard;
+  }
+
+  @override
+  String get name => '${dataId.name}${shard}';
+
+  @override
+  String toString() => name;
+}
+
+Future<void> resolveScripts(Options options) async {
+  Future<String> resolve(
+      String sourceUriOrPath, String relativeSnapshotPath) async {
+    Uri sourceUri = sdkRoot.resolve(sourceUriOrPath);
+    String result =
+        sourceUri.scheme == 'file' ? sourceUri.toFilePath() : sourceUriOrPath;
+    if (_options.useSdk) {
+      String snapshot = Uri.file(Platform.resolvedExecutable)
+          .resolve(relativeSnapshotPath)
+          .toFilePath();
+      if (await File(snapshot).exists()) {
+        return snapshot;
+      }
+    }
+    return result;
+  }
+
+  _options = options;
+  _dart2jsScript = await resolve(
+      'package:compiler/src/dart2js.dart', 'snapshots/dart2js.dart.snapshot');
+  _kernelWorkerScript = await resolve('utils/bazel/kernel_worker.dart',
+      'snapshots/kernel_worker.dart.snapshot');
+}
+
+String _librarySpecForSnapshot = Uri.file(Platform.resolvedExecutable)
+    .resolve('../lib/libraries.json')
+    .toFilePath();
diff --git a/pkg/compiler/tool/modular_test_suite_legacy.dart b/pkg/compiler/tool/modular_test_suite_legacy.dart
new file mode 100644
index 0000000..875a64a
--- /dev/null
+++ b/pkg/compiler/tool/modular_test_suite_legacy.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, 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.
+
+/// Test the modular compilation pipeline of dart2js.
+///
+/// This is a shell that runs multiple tests, one per folder under `data/`.
+import 'dart:async';
+
+import 'package:modular_test/src/io_pipeline.dart';
+import 'package:modular_test/src/runner.dart';
+import 'modular_test_suite_helper.dart';
+
+main(List<String> args) async {
+  var options = Options.parse(args);
+  await resolveScripts(options);
+  await Future.wait([
+    runSuite(
+        sdkRoot.resolve('tests/modular/'),
+        'tests/modular',
+        options,
+        IOPipeline([
+          OutlineDillCompilationStep(),
+          FullDillCompilationStep(),
+          ComputeClosedWorldStep(useModularAnalysis: false),
+          GlobalAnalysisStep(),
+          Dart2jsCodegenStep(codeId0),
+          Dart2jsCodegenStep(codeId1),
+          Dart2jsEmissionStep(),
+          RunD8(),
+        ], cacheSharedModules: true)),
+  ]);
+}
diff --git a/pkg/dart2native/lib/dart2native.dart b/pkg/dart2native/lib/dart2native.dart
index f5f0dfe..be47b4c 100644
--- a/pkg/dart2native/lib/dart2native.dart
+++ b/pkg/dart2native/lib/dart2native.dart
@@ -6,8 +6,8 @@
 import 'dart:typed_data';
 
 // Maximum page size across all supported architectures (arm64 macOS has 16K
-// pages, the rest are all 4k pages).
-const elfPageSize = 16384;
+// pages, some arm64 Linux distributions have 64K pages).
+const elfPageSize = 65536;
 const appjitMagicNumber = <int>[0xdc, 0xdc, 0xf6, 0xf6, 0, 0, 0, 0];
 
 enum Kind { aot, exe }
diff --git a/pkg/dart_internal/CHANGELOG.md b/pkg/dart_internal/CHANGELOG.md
index c49fe05..8894fed 100644
--- a/pkg/dart_internal/CHANGELOG.md
+++ b/pkg/dart_internal/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.2.3
+
+- Support the latest Dart SDK.
+
+## 0.2.2
+
+- Support the latest Dart SDK.
+
 ## 0.2.1
 
 - Support the latest Dart SDK.
diff --git a/pkg/dart_internal/pubspec.yaml b/pkg/dart_internal/pubspec.yaml
index d871d5c..9d5dacc 100644
--- a/pkg/dart_internal/pubspec.yaml
+++ b/pkg/dart_internal/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dart_internal
-version: 0.2.2
+version: 0.2.3
 repository: https://github.com/dart-lang/sdk/tree/master/pkg/dart_internal
 description: >-
   This package is not intended for wide use. It provides a temporary API to
@@ -9,4 +9,4 @@
 environment:
   # Restrict the upper bound so that we can remove support for this in a later
   # version of the SDK without it being a breaking change.
-  sdk: ">=2.12.0 <2.16.0"
+  sdk: ">=2.12.0 <2.17.0"
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 9367cf6..a545f1a 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -213,7 +213,10 @@
     final path = commandNames.join('/');
     // Send the screen view to analytics
     unawaited(
-      analytics.sendScreenView(path),
+      analytics.sendScreenView(path, parameters:
+          // Starts a new analytics session.
+          // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#sc
+          {'sc': 'start'}),
     );
 
     // The exit code for the dartdev process; null indicates that it has not been
diff --git a/pkg/dartdev/lib/src/analysis_server.dart b/pkg/dartdev/lib/src/analysis_server.dart
index 580619b..1666afc 100644
--- a/pkg/dartdev/lib/src/analysis_server.dart
+++ b/pkg/dartdev/lib/src/analysis_server.dart
@@ -8,7 +8,11 @@
 
 import 'package:analysis_server/src/server/driver.dart' show Driver;
 import 'package:analysis_server_client/protocol.dart'
-    show EditBulkFixesResult, ResponseDecoder;
+    show
+        AddContentOverlay,
+        AnalysisUpdateContentParams,
+        EditBulkFixesResult,
+        ResponseDecoder;
 import 'package:args/args.dart';
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
@@ -167,6 +171,12 @@
     });
   }
 
+  /// Send an `analysis.updateContent` request with the given [files].
+  Future<void> updateContent(Map<String, AddContentOverlay> files) async {
+    await _sendCommand('analysis.updateContent',
+        params: AnalysisUpdateContentParams(files).toJson());
+  }
+
   Future<Map<String, dynamic>> _sendCommand(String method,
       {Map<String, dynamic> params}) {
     final String id = (++_id).toString();
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index c81e467..d6c8b5a 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -7,6 +7,7 @@
 
 import 'package:analysis_server_client/protocol.dart' hide AnalysisError;
 import 'package:intl/intl.dart';
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 
 import '../analysis_server.dart';
@@ -26,6 +27,12 @@
 
 To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed changes for a project, or ['dart fix --apply'] to apply the changes.''';
 
+  /// The maximum number of times that fixes will be requested from the server.
+  static const maxPasses = 4;
+
+  /// A map from the absolute path of a file to the updated content of the file.
+  final Map<String, String> fileContentCache = {};
+
   FixCommand({bool verbose = false}) : super(cmdName, cmdDescription, verbose) {
     argParser.addFlag('dry-run',
         abbr: 'n',
@@ -86,7 +93,7 @@
     var modeText = dryRun ? ' (dry run)' : '';
 
     final projectName = path.basename(dirPath);
-    var progress = log.progress(
+    var computeFixesProgress = log.progress(
         'Computing fixes in ${log.ansi.emphasized(projectName)}$modeText');
 
     var server = AnalysisServer(
@@ -99,53 +106,60 @@
 
     await server.start();
 
-    EditBulkFixesResult fixes;
     server.onExit.then((int exitCode) {
-      if (fixes == null && exitCode != 0) {
-        progress?.cancel();
+      if (computeFixesProgress != null && exitCode != 0) {
+        computeFixesProgress?.cancel();
+        computeFixesProgress = null;
         io.exitCode = exitCode;
       }
     });
 
-    fixes = await server.requestBulkFixes(dirPath, inTestMode);
-    final List<SourceFileEdit> edits = fixes.edits;
+    Future<Map<String, BulkFix>> _applyAllEdits() async {
+      var detailsMap = <String, BulkFix>{};
+      List<SourceFileEdit> edits;
+      var pass = 0;
+      do {
+        var fixes = await server.requestBulkFixes(dirPath, inTestMode);
+        _mergeDetails(detailsMap, fixes.details);
+        edits = fixes.edits;
+        _applyEdits(server, edits);
+        pass++;
+        // TODO(brianwilkerson) Be more intelligent about detecting infinite
+        //  loops so that we can increase [maxPasses].
+      } while (pass < maxPasses && edits.isNotEmpty);
+      return detailsMap;
+    }
 
+    var detailsMap = await _applyAllEdits();
     await server.shutdown();
 
-    progress.finish(showTiming: true);
+    if (computeFixesProgress != null) {
+      computeFixesProgress.finish(showTiming: true);
+      computeFixesProgress = null;
+    }
 
     if (inTestMode) {
-      var result = _compareFixesInDirectory(dir, edits);
+      var result = _compareFixesInDirectory(dir);
       log.stdout('Passed: ${result.passCount}, Failed: ${result.failCount}');
       return result.failCount > 0 ? 1 : 0;
-    } else if (edits.isEmpty) {
+    } else if (detailsMap.isEmpty) {
       log.stdout('Nothing to fix!');
     } else {
-      var details = fixes.details;
-      details.sort((f1, f2) => path
-          .relative(f1.path, from: dirPath)
-          .compareTo(path.relative(f2.path, from: dirPath)));
-
-      var fileCount = 0;
-      var fixCount = 0;
-
-      for (var d in details) {
-        ++fileCount;
-        for (var f in d.fixes) {
-          fixCount += f.occurrences;
-        }
-      }
+      var fileCount = detailsMap.length;
+      var fixCount = detailsMap.values
+          .expand((detail) => detail.fixes)
+          .fold(0, (previousValue, fixes) => previousValue + fixes.occurrences);
 
       if (dryRun) {
         log.stdout('');
         log.stdout('${_format(fixCount)} proposed ${_pluralFix(fixCount)} '
             'in ${_format(fileCount)} ${pluralize("file", fileCount)}.');
-        _printDetails(details, dir);
+        _printDetails(detailsMap, dir);
       } else {
-        progress = log.progress('Applying fixes');
-        _applyFixes(edits);
-        progress.finish(showTiming: true);
-        _printDetails(details, dir);
+        var applyFixesProgress = log.progress('Applying fixes');
+        _writeFiles();
+        applyFixesProgress.finish(showTiming: true);
+        _printDetails(detailsMap, dir);
         log.stdout('${_format(fixCount)} ${_pluralFix(fixCount)} made in '
             '${_format(fileCount)} ${pluralize("file", fileCount)}.');
       }
@@ -154,20 +168,24 @@
     return 0;
   }
 
-  void _applyFixes(List<SourceFileEdit> edits) {
+  void _applyEdits(AnalysisServer server, List<SourceFileEdit> edits) {
+    var overlays = <String, AddContentOverlay>{};
     for (var edit in edits) {
-      var fileName = edit.file;
-      var file = io.File(fileName);
-      var code = file.existsSync() ? file.readAsStringSync() : '';
-      code = SourceEdit.applySequence(code, edit.edits);
-      file.writeAsStringSync(code);
+      var filePath = edit.file;
+      var content = fileContentCache.putIfAbsent(filePath, () {
+        var file = io.File(filePath);
+        return file.existsSync() ? file.readAsStringSync() : '';
+      });
+      var newContent = SourceEdit.applySequence(content, edit.edits);
+      fileContentCache[filePath] = newContent;
+      overlays[filePath] = AddContentOverlay(newContent);
     }
+    server.updateContent(overlays);
   }
 
   /// Return `true` if any of the fixes fail to create the same content as is
   /// found in the golden file.
-  _TestResult _compareFixesInDirectory(
-      io.Directory directory, List<SourceFileEdit> edits) {
+  _TestResult _compareFixesInDirectory(io.Directory directory) {
     var result = _TestResult();
     //
     // Gather the files of interest in this directory and process
@@ -177,7 +195,7 @@
     var expectFileMap = <String, io.File>{};
     for (var child in directory.listSync()) {
       if (child is io.Directory) {
-        var childResult = _compareFixesInDirectory(child, edits);
+        var childResult = _compareFixesInDirectory(child);
         result.passCount += childResult.passCount;
         result.failCount += childResult.failCount;
       } else if (child is io.File) {
@@ -189,10 +207,6 @@
         }
       }
     }
-    var editMap = <String, SourceFileEdit>{};
-    for (var edit in edits) {
-      editMap[edit.file] = edit;
-    }
     for (var originalFile in dartFiles) {
       var filePath = originalFile.path;
       var baseName = path.basename(filePath);
@@ -205,19 +219,24 @@
             'No corresponding expect file for the Dart file at "$filePath".');
         continue;
       }
-      var edit = editMap[filePath];
       try {
-        var originalCode = originalFile.readAsStringSync();
         var expectedCode = expectFile.readAsStringSync();
-        var actualCode = edit == null
-            ? originalCode
-            : SourceEdit.applySequence(originalCode, edit.edits);
+        var actualIsOriginal = !fileContentCache.containsKey(filePath);
+        var actualCode = actualIsOriginal
+            ? originalFile.readAsStringSync()
+            : fileContentCache[filePath];
         // Use a whitespace insensitive comparison.
         if (_compressWhitespace(actualCode) !=
             _compressWhitespace(expectedCode)) {
           result.failCount++;
-          _reportFailure(filePath, actualCode, expectedCode);
-          _printEdits(edits);
+          // TODO(brianwilkerson) Do a better job of displaying the differences.
+          //  It's very hard to see the diff with large files.
+          _reportFailure(
+            filePath,
+            actualCode,
+            expectedCode,
+            actualIsOriginal: actualIsOriginal,
+          );
         } else {
           result.passCount++;
         }
@@ -243,15 +262,54 @@
   String _compressWhitespace(String code) =>
       code.replaceAll(RegExp(r'\s+'), ' ');
 
+  /// Merge the fixes from the current round's [details] into the [detailsMap].
+  void _mergeDetails(Map<String, BulkFix> detailsMap, List<BulkFix> details) {
+    for (var detail in details) {
+      var previousDetail = detailsMap[detail.path];
+      if (previousDetail != null) {
+        _mergeFixCounts(previousDetail.fixes, detail.fixes);
+      } else {
+        detailsMap[detail.path] = detail;
+      }
+    }
+  }
+
+  void _mergeFixCounts(
+      List<BulkFixDetail> oldFixes, List<BulkFixDetail> newFixes) {
+    var originalOldLength = oldFixes.length;
+    newFixLoop:
+    for (var newFix in newFixes) {
+      var newCode = newFix.code;
+      // Iterate over the original content of the list, not any of the newly
+      // added fixes, because the newly added fixes can't be a match.
+      for (var i = 0; i < originalOldLength; i++) {
+        var oldFix = oldFixes[i];
+        if (oldFix.code == newCode) {
+          oldFix.occurrences += newFix.occurrences;
+          continue newFixLoop;
+        }
+      }
+      oldFixes.add(newFix);
+    }
+  }
+
   String _pluralFix(int count) => count == 1 ? 'fix' : 'fixes';
 
-  void _printDetails(List<BulkFix> details, io.Directory workingDir) {
+  void _printDetails(Map<String, BulkFix> detailsMap, io.Directory workingDir) {
+    String relative(String absolutePath) {
+      return path.relative(absolutePath, from: workingDir.path);
+    }
+
     log.stdout('');
 
     final bullet = log.ansi.bullet;
 
-    for (var detail in details) {
-      log.stdout(path.relative(detail.path, from: workingDir.path));
+    var modifiedFilePaths = detailsMap.keys.toList();
+    modifiedFilePaths
+        .sort((first, second) => relative(first).compareTo(relative(second)));
+    for (var filePath in modifiedFilePaths) {
+      var detail = detailsMap[filePath];
+      log.stdout(relative(detail.path));
       final fixes = detail.fixes.toList();
       fixes.sort((a, b) => a.code.compareTo(b.code));
       for (var fix in fixes) {
@@ -262,27 +320,30 @@
     }
   }
 
-  void _printEdits(List<SourceFileEdit> edits) {
-    log.stdout('Edits returned from server:');
-    for (var fileEdit in edits) {
-      log.stdout('  ${fileEdit.file}');
-      for (var edit in fileEdit.edits) {
-        log.stdout("    ${edit.offset} - ${edit.end}, '${edit.replacement}'");
-      }
-    }
-  }
-
   /// Report that the [actualCode] produced by applying fixes to the content of
   /// [filePath] did not match the [expectedCode].
-  void _reportFailure(String filePath, String actualCode, String expectedCode) {
+  void _reportFailure(String filePath, String actualCode, String expectedCode,
+      {@required bool actualIsOriginal}) {
     log.stdout('Failed when applying fixes to $filePath');
     log.stdout('Expected:');
     log.stdout(expectedCode);
     log.stdout('');
-    log.stdout('Actual:');
+    if (actualIsOriginal) {
+      log.stdout('Actual (original code was unchanged):');
+    } else {
+      log.stdout('Actual:');
+    }
     log.stdout(actualCode);
   }
 
+  /// Write the modified contents of files in the [fileContentCache] to disk.
+  void _writeFiles() {
+    for (var entry in fileContentCache.entries) {
+      var file = io.File(entry.key);
+      file.writeAsStringSync(entry.value);
+    }
+  }
+
   static String _format(int value) => _numberFormat.format(value);
 }
 
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 69db956..a74fa84 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -318,10 +318,11 @@
         stderrSub.cancel();
         completer.complete();
       } else {
+        final error = result['error'] ?? event;
+        final stacktrace = result['stacktrace'] ?? '';
         stderrSub.cancel();
         completer.completeError(
-          'Could not start Observatory HTTP server',
-        );
+            'Could not start Observatory HTTP server:\n$error\n$stacktrace\n');
       }
     });
     try {
diff --git a/pkg/dartdev/test/analytics_test.dart b/pkg/dartdev/test/analytics_test.dart
index 3ae1f16..450db64 100644
--- a/pkg/dartdev/test/analytics_test.dart
+++ b/pkg/dartdev/test/analytics_test.dart
@@ -40,9 +40,9 @@
     });
   });
 
-  test('Analytics control smoke test', () {
+  test('Analytics control smoke test', () async {
     final p = project(logAnalytics: true);
-    var result = p.runSync(['--disable-analytics']);
+    var result = await p.run(['--disable-analytics']);
     expect(result.stdout, contains('''
   ╔════════════════════════════════════════════════════════════════════════════╗
   ║ Analytics reporting disabled. In order to enable it, run:                  ║
@@ -52,7 +52,7 @@
   ╚════════════════════════════════════════════════════════════════════════════╝
 '''));
 
-    result = p.runSync(['--enable-analytics']);
+    result = await p.run(['--enable-analytics']);
     expect(result.stdout, contains('''
   ╔════════════════════════════════════════════════════════════════════════════╗
   ║ The Dart tool uses Google Analytics to report feature usage statistics     ║
@@ -69,13 +69,13 @@
 
   final experiments = await experimentsWithValidation();
   group('Sending analytics', () {
-    test('help', () {
+    test('help', () async {
       final p = project(logAnalytics: true);
-      final result = p.runSync(['help']);
+      final result = await p.run(['help']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
-          'message': {'viewName': 'help'}
+          'message': {'viewName': 'help', 'sc': 'start'}
         },
         {
           'hitType': 'event',
@@ -97,14 +97,14 @@
         }
       ]);
     });
-    test('create', () {
+    test('create', () async {
       final p = project(logAnalytics: true);
       final result =
-          p.runSync(['create', '--no-pub', '-tpackage-simple', 'name']);
+          await p.run(['create', '--no-pub', '-tpackage-simple', 'name']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
-          'message': {'viewName': 'create'}
+          'message': {'viewName': 'create', 'sc': 'start'}
         },
         {
           'hitType': 'event',
@@ -129,17 +129,17 @@
       ]);
     });
 
-    test('pub get dry run', () {
+    test('pub get dry run', () async {
       final p = project(logAnalytics: true, pubspec: {
         'name': 'foo',
         'environment': {'sdk': '>=2.10.0 <3.0.0'},
         'dependencies': {'_dummy_pkg': '0.0.1'}
       });
-      final result = p.runSync(['pub', 'get', '--dry-run']);
+      final result = await p.run(['pub', 'get', '--dry-run']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
-          'message': {'viewName': 'pub/get'}
+          'message': {'viewName': 'pub/get', 'sc': 'start'}
         },
         {
           'hitType': 'event',
@@ -164,17 +164,17 @@
       ]);
     });
 
-    test('pub get', () {
+    test('pub get', () async {
       final p = project(logAnalytics: true, pubspec: {
         'name': 'foo',
         'environment': {'sdk': '>=2.10.0 <3.0.0'},
         'dependencies': {'_dummy_pkg': '0.0.1'}
       });
-      final result = p.runSync(['pub', 'get']);
+      final result = await p.run(['pub', 'get']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
-          'message': {'viewName': 'pub/get'}
+          'message': {'viewName': 'pub/get', 'sc': 'start'},
         },
         {
           'hitType': 'event',
@@ -218,13 +218,13 @@
       ]);
     });
 
-    test('format', () {
+    test('format', () async {
       final p = project(logAnalytics: true);
-      final result = p.runSync(['format', '-l80', '.']);
+      final result = await p.run(['format', '-l80', '.']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
-          'message': {'viewName': 'format'}
+          'message': {'viewName': 'format', 'sc': 'start'}
         },
         {
           'hitType': 'event',
@@ -249,11 +249,11 @@
       ]);
     });
 
-    test('run', () {
+    test('run', () async {
       final p = project(
           mainSrc: 'void main(List<String> args) => print(args)',
           logAnalytics: true);
-      final result = p.runSync([
+      final result = await p.run([
         'run',
         '--no-pause-isolates-on-exit',
         '--enable-asserts',
@@ -263,7 +263,7 @@
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
-          'message': {'viewName': 'run'}
+          'message': {'viewName': 'run', 'sc': 'start'},
         },
         {
           'hitType': 'event',
@@ -289,11 +289,11 @@
     });
     group('run --enable-experiments', () {
       for (final experiment in experiments) {
-        test(experiment.name, () {
+        test(experiment.name, () async {
           final p = project(mainSrc: experiment.validation, logAnalytics: true);
           {
             for (final no in ['', 'no-']) {
-              final result = p.runSync([
+              final result = await p.run([
                 'run',
                 '--enable-experiment=$no${experiment.name}',
                 'lib/main.dart',
@@ -301,7 +301,7 @@
               expect(extractAnalytics(result), [
                 {
                   'hitType': 'screenView',
-                  'message': {'viewName': 'run'}
+                  'message': {'viewName': 'run', 'sc': 'start'},
                 },
                 {
                   'hitType': 'event',
@@ -330,16 +330,16 @@
       }
     });
 
-    test('compile', () {
+    test('compile', () async {
       final p = project(
           mainSrc: 'void main(List<String> args) => print(args);',
           logAnalytics: true);
-      final result = p
-          .runSync(['compile', 'kernel', 'lib/main.dart', '-o', 'main.kernel']);
+      final result = await p
+          .run(['compile', 'kernel', 'lib/main.dart', '-o', 'main.kernel']);
       expect(extractAnalytics(result), [
         {
           'hitType': 'screenView',
-          'message': {'viewName': 'compile/kernel'}
+          'message': {'viewName': 'compile/kernel', 'sc': 'start'},
         },
         {
           'hitType': 'event',
diff --git a/pkg/dartdev/test/commands/analyze_test.dart b/pkg/dartdev/test/commands/analyze_test.dart
index af8984c..11613ef 100644
--- a/pkg/dartdev/test/commands/analyze_test.dart
+++ b/pkg/dartdev/test/commands/analyze_test.dart
@@ -178,9 +178,9 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
-    var result = p.runSync(['analyze', '--help']);
+    var result = await p.run(['analyze', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -188,9 +188,9 @@
     expect(result.stdout, contains(_analyzeUsageText));
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project();
-    var result = p.runSync(['analyze', '--help', '--verbose']);
+    var result = await p.run(['analyze', '--help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -203,10 +203,10 @@
 
     tearDown(() => secondProject?.dispose());
 
-    test('folder and file', () {
+    test('folder and file', () async {
       p = project(mainSrc: "int get foo => 'str';\n");
       secondProject = project(mainSrc: "int get foo => 'str';\n");
-      var result = p.runSync(['analyze', p.dirPath, secondProject.mainPath]);
+      var result = await p.run(['analyze', p.dirPath, secondProject.mainPath]);
 
       expect(result.exitCode, 3);
       expect(result.stderr, isEmpty);
@@ -216,10 +216,10 @@
       expect(result.stdout, contains('2 issues found.'));
     });
 
-    test('two folders', () {
+    test('two folders', () async {
       p = project(mainSrc: "int get foo => 'str';\n");
       secondProject = project(mainSrc: "int get foo => 'str';\n");
-      var result = p.runSync(['analyze', p.dirPath, secondProject.dirPath]);
+      var result = await p.run(['analyze', p.dirPath, secondProject.dirPath]);
 
       expect(result.exitCode, 3);
       expect(result.stderr, isEmpty);
@@ -230,9 +230,9 @@
     });
   });
 
-  test('no such directory', () {
+  test('no such directory', () async {
     p = project();
-    var result = p.runSync(['analyze', '/no/such/dir1/']);
+    var result = await p.run(['analyze', '/no/such/dir1/']);
 
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
@@ -241,10 +241,10 @@
     expect(result.stderr, contains(_analyzeUsageText));
   });
 
-  test('current working directory', () {
+  test('current working directory', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = p.runSync(['analyze'], workingDir: p.dirPath);
+    var result = await p.run(['analyze'], workingDir: p.dirPath);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -252,18 +252,18 @@
   });
 
   group('single directory', () {
-    test('no errors', () {
+    test('no errors', () async {
       p = project(mainSrc: 'int get foo => 1;\n');
-      var result = p.runSync(['analyze', p.dirPath]);
+      var result = await p.run(['analyze', p.dirPath]);
 
       expect(result.exitCode, 0);
       expect(result.stderr, isEmpty);
       expect(result.stdout, contains('No issues found!'));
     });
 
-    test('one error', () {
+    test('one error', () async {
       p = project(mainSrc: "int get foo => 'str';\n");
-      var result = p.runSync(['analyze', p.dirPath]);
+      var result = await p.run(['analyze', p.dirPath]);
 
       expect(result.exitCode, 3);
       expect(result.stderr, isEmpty);
@@ -273,9 +273,9 @@
       expect(result.stdout, contains('1 issue found.'));
     });
 
-    test('two errors', () {
+    test('two errors', () async {
       p = project(mainSrc: "int get foo => 'str';\nint get bar => 'str';\n");
-      var result = p.runSync(['analyze', p.dirPath]);
+      var result = await p.run(['analyze', p.dirPath]);
 
       expect(result.exitCode, 3);
       expect(result.stderr, isEmpty);
@@ -284,18 +284,18 @@
   });
 
   group('single file', () {
-    test('no errors', () {
+    test('no errors', () async {
       p = project(mainSrc: 'int get foo => 1;\n');
-      var result = p.runSync(['analyze', p.mainPath]);
+      var result = await p.run(['analyze', p.mainPath]);
 
       expect(result.exitCode, 0);
       expect(result.stderr, isEmpty);
       expect(result.stdout, contains('No issues found!'));
     });
 
-    test('one error', () {
+    test('one error', () async {
       p = project(mainSrc: "int get foo => 'str';\n");
-      var result = p.runSync(['analyze', p.mainPath]);
+      var result = await p.run(['analyze', p.mainPath]);
 
       expect(result.exitCode, 3);
       expect(result.stderr, isEmpty);
@@ -306,65 +306,65 @@
     });
   });
 
-  test('warning --fatal-warnings', () {
+  test('warning --fatal-warnings', () async {
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync(['analyze', '--fatal-warnings', p.dirPath]);
+    var result = await p.run(['analyze', '--fatal-warnings', p.dirPath]);
 
     expect(result.exitCode, equals(2));
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('1 issue found.'));
   });
 
-  test('warning implicit --fatal-warnings', () {
+  test('warning implicit --fatal-warnings', () async {
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync(['analyze', p.dirPath]);
+    var result = await p.run(['analyze', p.dirPath]);
 
     expect(result.exitCode, equals(2));
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('1 issue found.'));
   });
 
-  test('warning --no-fatal-warnings', () {
+  test('warning --no-fatal-warnings', () async {
     p = project(
         mainSrc: _unusedImportCodeSnippet,
         analysisOptions: _unusedImportAnalysisOptions);
-    var result = p.runSync(['analyze', '--no-fatal-warnings', p.dirPath]);
+    var result = await p.run(['analyze', '--no-fatal-warnings', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('1 issue found.'));
   });
 
-  test('info implicit no --fatal-infos', () {
+  test('info implicit no --fatal-infos', () async {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
-    var result = p.runSync(['analyze', p.dirPath]);
+    var result = await p.run(['analyze', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('1 issue found.'));
   });
 
-  test('info --fatal-infos', () {
+  test('info --fatal-infos', () async {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
-    var result = p.runSync(['analyze', '--fatal-infos', p.dirPath]);
+    var result = await p.run(['analyze', '--fatal-infos', p.dirPath]);
 
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('1 issue found.'));
   });
 
-  test('--verbose', () {
+  test('--verbose', () async {
     p = project(mainSrc: '''
 int f() {
   var result = one + 2;
   var one = 1;
   return result;
 }''');
-    var result = p.runSync(['analyze', '--verbose', p.dirPath]);
+    var result = await p.run(['analyze', '--verbose', p.dirPath]);
 
     expect(result.exitCode, 3);
     expect(result.stderr, isEmpty);
@@ -377,7 +377,7 @@
   });
 
   group('--packages', () {
-    test('existing', () {
+    test('existing', () async {
       final foo = project(name: 'foo');
       foo.file('lib/foo.dart', 'var my_foo = 0;');
 
@@ -399,7 +399,7 @@
   ]
 }
 ''');
-      var result = p.runSync([
+      var result = await p.run([
         'analyze',
         '--packages=${p.findFile('my_packages.json').path}',
         p.dirPath,
@@ -410,9 +410,9 @@
       expect(result.stdout, contains('No issues found!'));
     });
 
-    test('not existing', () {
+    test('not existing', () async {
       p = project();
-      var result = p.runSync([
+      var result = await p.run([
         'analyze',
         '--packages=no.such.file',
         p.dirPath,
@@ -424,11 +424,11 @@
     });
   });
 
-  test('--cache', () {
+  test('--cache', () async {
     var cache = project(name: 'cache');
 
     p = project(mainSrc: 'var v = 0;');
-    var result = p.runSync([
+    var result = await p.run([
       'analyze',
       '--cache=${cache.dirPath}',
       p.mainPath,
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index be43ac7..2facc8c 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -29,9 +29,9 @@
     expect(binDir.path, contains('bin'));
   });
 
-  test('Implicit --help', () {
+  test('Implicit --help', () async {
     final p = project();
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
       ],
@@ -40,9 +40,9 @@
     expect(result.exitCode, compileErrorExitCode);
   });
 
-  test('--help', () {
+  test('--help', () async {
     final p = project();
-    final result = p.runSync(
+    final result = await p.run(
       ['compile', '--help'],
     );
     expect(result.stdout, contains('Compile Dart'));
@@ -61,9 +61,9 @@
     expect(result.exitCode, 0);
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     final p = project();
-    final result = p.runSync(
+    final result = await p.run(
       ['compile', '--help', '--verbose'],
     );
     expect(result.stdout, contains('Compile Dart'));
@@ -76,10 +76,10 @@
     expect(result.exitCode, 0);
   });
 
-  test('Compile and run jit snapshot', () {
+  test('Compile and run jit snapshot', () async {
     final p = project(mainSrc: 'void main() { print("I love jit"); }');
     final outFile = path.join(p.dirPath, 'main.jit');
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'jit-snapshot',
@@ -93,18 +93,18 @@
     expect(File(outFile).existsSync(), true,
         reason: 'File not found: $outFile');
 
-    result = p.runSync(['run', 'main.jit']);
+    result = await p.run(['run', 'main.jit']);
     expect(result.stdout, contains('I love jit'));
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
   });
 
-  test('Compile and run executable', () {
+  test('Compile and run executable', () async {
     final p = project(mainSrc: 'void main() { print("I love executables"); }');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'lib', 'main.exe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -127,11 +127,11 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile to executable disabled on IA32', () {
+  test('Compile to executable disabled on IA32', () async {
     final p = project(mainSrc: 'void main() { print("I love executables"); }');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -144,11 +144,11 @@
     expect(result.exitCode, 64);
   }, skip: !isRunningOnIA32);
 
-  test('Compile to AOT snapshot disabled on IA32', () {
+  test('Compile to AOT snapshot disabled on IA32', () async {
     final p = project(mainSrc: 'void main() { print("I love executables"); }');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'aot-snapshot',
@@ -161,13 +161,13 @@
     expect(result.exitCode, 64);
   }, skip: !isRunningOnIA32);
 
-  test('Compile and run executable with options', () {
+  test('Compile and run executable with options', () async {
     final p = project(
         mainSrc: 'void main() {print(const String.fromEnvironment("life"));}');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -194,12 +194,12 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile and run aot snapshot', () {
+  test('Compile and run aot snapshot', () async {
     final p = project(mainSrc: 'void main() { print("I love AOT"); }');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'main.aot'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'aot-snapshot',
@@ -225,10 +225,10 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile and run kernel snapshot', () {
+  test('Compile and run kernel snapshot', () async {
     final p = project(mainSrc: 'void main() { print("I love kernel"); }');
     final outFile = path.join(p.dirPath, 'main.dill');
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'kernel',
@@ -242,13 +242,13 @@
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
 
-    result = p.runSync(['run', 'main.dill']);
+    result = await p.run(['run', 'main.dill']);
     expect(result.stdout, contains('I love kernel'));
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
   });
 
-  test('Compile JS', () {
+  test('Compile JS', () async {
     final p = project(mainSrc: '''
         void main() {
           print('1: ' + const String.fromEnvironment('foo'));
@@ -257,7 +257,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'main.js'));
 
-    final result = p.runSync([
+    final result = await p.run([
       'compile',
       'js',
       '-m',
@@ -279,7 +279,7 @@
     expect(contents.contains('2: foo'), true);
   });
 
-  test('Compile exe with error', () {
+  test('Compile exe with error', () async {
     final p = project(mainSrc: '''
 void main() {
   int? i;
@@ -289,7 +289,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -309,7 +309,7 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile exe with warnings', () {
+  test('Compile exe with warnings', () async {
     final p = project(mainSrc: '''
 void main() {
   int i = 0;
@@ -319,7 +319,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -336,12 +336,12 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile exe with sound null safety', () {
+  test('Compile exe with sound null safety', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -358,7 +358,7 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile exe with unsound null safety', () {
+  test('Compile exe with unsound null safety', () async {
     final p = project(mainSrc: '''
 // @dart=2.9
 void main() {}
@@ -366,7 +366,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -383,14 +383,14 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile and run exe with --sound-null-safety', () {
+  test('Compile and run exe with --sound-null-safety', () async {
     final p = project(mainSrc: '''void main() {
       print((<int?>[] is List<int>) ? 'oh no' : 'sound');
     }''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -417,14 +417,14 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile and run exe with --no-sound-null-safety', () {
+  test('Compile and run exe with --no-sound-null-safety', () async {
     final p = project(mainSrc: '''void main() {
       print((<int?>[] is List<int>) ? 'unsound' : 'oh no');
     }''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -451,12 +451,12 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile exe without info', () {
+  test('Compile exe without info', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -475,7 +475,7 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile exe without warnings', () {
+  test('Compile exe without warnings', () async {
     final p = project(mainSrc: '''
 void main() {
   int i = 0;
@@ -485,7 +485,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'exe',
@@ -502,12 +502,12 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile JS with sound null safety', () {
+  test('Compile JS with sound null safety', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjs'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'js',
@@ -524,7 +524,7 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile JS with unsound null safety', () {
+  test('Compile JS with unsound null safety', () async {
     final p = project(mainSrc: '''
 // @dart=2.9
 void main() {}
@@ -532,7 +532,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjs'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'js',
@@ -549,12 +549,12 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile JS without info', () {
+  test('Compile JS without info', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjs'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'js',
@@ -573,7 +573,7 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile JS without warnings', () {
+  test('Compile JS without warnings', () async {
     final p = project(mainSrc: '''
 void main() {
   int i = 0;
@@ -583,7 +583,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjs'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'js',
@@ -600,12 +600,12 @@
     expect(result.exitCode, 0);
   });
 
-  test('Compile AOT snapshot with sound null safety', () {
+  test('Compile AOT snapshot with sound null safety', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'aot-snapshot',
@@ -622,7 +622,7 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile AOT snapshot with unsound null safety', () {
+  test('Compile AOT snapshot with unsound null safety', () async {
     final p = project(mainSrc: '''
 // @dart=2.9
 void main() {}
@@ -630,7 +630,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'aot-snapshot',
@@ -647,12 +647,12 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile AOT snapshot without info', () {
+  test('Compile AOT snapshot without info', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'aot-snapshot',
@@ -671,7 +671,7 @@
         reason: 'File not found: $outFile');
   }, skip: isRunningOnIA32);
 
-  test('Compile AOT snapshot without warnings', () {
+  test('Compile AOT snapshot without warnings', () async {
     final p = project(mainSrc: '''
 void main() {
   int i = 0;
@@ -681,7 +681,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'aot-snapshot',
@@ -698,7 +698,7 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile AOT snapshot with warnings', () {
+  test('Compile AOT snapshot with warnings', () async {
     final p = project(mainSrc: '''
 void main() {
   int i = 0;
@@ -708,7 +708,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'aot-snapshot',
@@ -726,12 +726,12 @@
     expect(result.exitCode, 0);
   }, skip: isRunningOnIA32);
 
-  test('Compile kernel with invalid trailing argument', () {
+  test('Compile kernel with invalid trailing argument', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'kernel',
@@ -754,12 +754,12 @@
     expect(File(outFile).existsSync(), false, reason: 'File found: $outFile');
   });
 
-  test('Compile kernel with sound null safety', () {
+  test('Compile kernel with sound null safety', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'kernel',
@@ -776,7 +776,7 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile kernel with unsound null safety', () {
+  test('Compile kernel with unsound null safety', () async {
     final p = project(mainSrc: '''
 // @dart=2.9
 void main() {}
@@ -784,7 +784,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'kernel',
@@ -801,12 +801,12 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile kernel without info', () {
+  test('Compile kernel without info', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'kernel',
@@ -825,7 +825,7 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile kernel without warning', () {
+  test('Compile kernel without warning', () async {
     final p = project(mainSrc: '''
 void main() {
     int i;
@@ -834,7 +834,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'kernel',
@@ -851,7 +851,7 @@
     expect(result.exitCode, 254);
   });
 
-  test('Compile kernel with warnings', () {
+  test('Compile kernel with warnings', () async {
     final p = project(mainSrc: '''
 void main() {
     int i = 0;
@@ -860,7 +860,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'kernel',
@@ -877,12 +877,12 @@
     expect(result.exitCode, 0);
   });
 
-  test('Compile JIT snapshot with sound null safety', () {
+  test('Compile JIT snapshot with sound null safety', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'jit-snapshot',
@@ -899,7 +899,7 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile JIT snapshot with unsound null safety', () {
+  test('Compile JIT snapshot with unsound null safety', () async {
     final p = project(mainSrc: '''
 // @dart=2.9
 void main() {}
@@ -907,7 +907,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'jit-snapshot',
@@ -924,13 +924,13 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile JIT snapshot with training args', () {
+  test('Compile JIT snapshot with training args', () async {
     final p =
         project(mainSrc: '''void main(List<String> args) => print(args);''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'jit-snapshot',
@@ -948,12 +948,12 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile JIT snapshot without info', () {
+  test('Compile JIT snapshot without info', () async {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'jit-snapshot',
@@ -972,7 +972,7 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile JIT snapshot without warnings', () {
+  test('Compile JIT snapshot without warnings', () async {
     final p = project(mainSrc: '''
 void main() {
     int i;
@@ -981,7 +981,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'jit-snapshot',
@@ -998,7 +998,7 @@
     expect(result.exitCode, 254);
   });
 
-  test('Compile JIT snapshot with warnings', () {
+  test('Compile JIT snapshot with warnings', () async {
     final p = project(mainSrc: '''
 void main() {
     int i = 0;
@@ -1007,7 +1007,7 @@
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
     final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'compile',
         'jit-snapshot',
diff --git a/pkg/dartdev/test/commands/create_integration_test.dart b/pkg/dartdev/test/commands/create_integration_test.dart
index 8bc1066..e4363a4 100644
--- a/pkg/dartdev/test/commands/create_integration_test.dart
+++ b/pkg/dartdev/test/commands/create_integration_test.dart
@@ -22,10 +22,10 @@
 
   // Create tests for each template.
   for (String templateId in CreateCommand.legalTemplateIds) {
-    test(templateId, () {
+    test(templateId, () async {
       p = project();
 
-      ProcessResult createResult = p.runSync([
+      ProcessResult createResult = await p.run([
         'create',
         '--force',
         '--template',
@@ -37,11 +37,11 @@
       // Validate that the project analyzes cleanly.
       // TODO: Should we use --fatal-infos here?
       ProcessResult analyzeResult =
-          p.runSync(['analyze'], workingDir: p.dir.path);
+          await p.run(['analyze'], workingDir: p.dir.path);
       expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout);
 
       // Validate that the code is well formatted.
-      ProcessResult formatResult = p.runSync([
+      ProcessResult formatResult = await p.run([
         'format',
         '--output',
         'none',
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 5af3323..6978d98 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -23,9 +23,9 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
-    var result = p.runSync(['create', '--help']);
+    var result = await p.run(['create', '--help']);
 
     expect(result.stdout, contains('Create a new Dart project.'));
     expect(
@@ -38,9 +38,9 @@
     expect(result.exitCode, 0);
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project();
-    var result = p.runSync(['create', '--help', '--verbose']);
+    var result = await p.run(['create', '--help', '--verbose']);
 
     expect(result.stdout, contains('Create a new Dart project.'));
     expect(
@@ -53,21 +53,21 @@
     expect(result.exitCode, 0);
   });
 
-  test('default template exists', () {
+  test('default template exists', () async {
     expect(CreateCommand.legalTemplateIds,
         contains(CreateCommand.defaultTemplateId));
   });
 
-  test('all templates exist', () {
+  test('all templates exist', () async {
     for (String templateId in CreateCommand.legalTemplateIds) {
       expect(CreateCommand.legalTemplateIds, contains(templateId));
     }
   });
 
-  test('list templates', () {
+  test('list templates', () async {
     p = project();
 
-    ProcessResult result = p.runSync(['create', '--list-templates']);
+    ProcessResult result = await p.run(['create', '--list-templates']);
     expect(result.exitCode, 0);
 
     String output = result.stdout.toString();
@@ -78,27 +78,27 @@
     expect(parsedResult[0]['description'], isNotNull);
   });
 
-  test('no directory given', () {
+  test('no directory given', () async {
     p = project();
 
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'create',
     ]);
     expect(result.exitCode, 1);
   });
 
-  test('directory already exists', () {
+  test('directory already exists', () async {
     p = project();
 
-    ProcessResult result = p.runSync(
+    ProcessResult result = await p.run(
         ['create', '--template', CreateCommand.defaultTemplateId, p.dir.path]);
     expect(result.exitCode, 73);
   });
 
-  test('project in current directory', () {
+  test('project in current directory', () async {
     p = project();
     final projectDir = Directory('foo')..createSync();
-    final result = p.runSync(
+    final result = await p.run(
       ['create', '--force', '.'],
       workingDir: projectDir.path,
     );
@@ -107,9 +107,9 @@
     expect(result.exitCode, 0);
   });
 
-  test('project with normalized package name', () {
+  test('project with normalized package name', () async {
     p = project();
-    final result = p.runSync(['create', 'requires-normalization']);
+    final result = await p.run(['create', 'requires-normalization']);
     expect(result.stderr, isEmpty);
     expect(
         result.stdout,
@@ -118,9 +118,9 @@
     expect(result.exitCode, 0);
   });
 
-  test('project with an invalid package name', () {
+  test('project with an invalid package name', () async {
     p = project();
-    final result = p.runSync(['create', 'bad-package^name']);
+    final result = await p.run(['create', 'bad-package^name']);
     expect(
       result.stderr,
       contains(
@@ -131,20 +131,20 @@
     expect(result.exitCode, 73);
   });
 
-  test('bad template id', () {
+  test('bad template id', () async {
     p = project();
 
-    ProcessResult result =
-        p.runSync(['create', '--no-pub', '--template', 'foo-bar', p.dir.path]);
+    ProcessResult result = await p
+        .run(['create', '--no-pub', '--template', 'foo-bar', p.dir.path]);
     expect(result.exitCode, isNot(0));
   });
 
   // Create tests for each template.
   for (String templateId in CreateCommand.legalTemplateIds) {
-    test(templateId, () {
+    test(templateId, () async {
       p = project();
       const projectName = 'template_project';
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         'create',
         '--force',
         '--no-pub',
diff --git a/pkg/dartdev/test/commands/debug_adapter_test.dart b/pkg/dartdev/test/commands/debug_adapter_test.dart
index c21f476..00a7e8c 100644
--- a/pkg/dartdev/test/commands/debug_adapter_test.dart
+++ b/pkg/dartdev/test/commands/debug_adapter_test.dart
@@ -13,9 +13,9 @@
 void debugAdapter() {
   // Implementation of debug_adapter is tested in the DDS package where the
   // DAP implementation lives.
-  test('--help', () {
+  test('--help', () async {
     final p = project();
-    var result = p.runSync(['debug_adapter', '--help']);
+    var result = await p.run(['debug_adapter', '--help']);
 
     expect(
         result.stdout,
diff --git a/pkg/dartdev/test/commands/devtools_test.dart b/pkg/dartdev/test/commands/devtools_test.dart
index 37bc32e..656b8c6 100644
--- a/pkg/dartdev/test/commands/devtools_test.dart
+++ b/pkg/dartdev/test/commands/devtools_test.dart
@@ -18,9 +18,9 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
-    var result = p.runSync(['devtools', '--help']);
+    var result = await p.run(['devtools', '--help']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Open DevTools'));
@@ -31,9 +31,9 @@
     expect(result.stdout.contains('--try-ports'), isFalse);
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project();
-    var result = p.runSync(['devtools', '--help', '--verbose']);
+    var result = await p.run(['devtools', '--help', '--verbose']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Open DevTools'));
diff --git a/pkg/dartdev/test/commands/fix_test.dart b/pkg/dartdev/test/commands/fix_test.dart
index 97cddf9..1f0dd94 100644
--- a/pkg/dartdev/test/commands/fix_test.dart
+++ b/pkg/dartdev/test/commands/fix_test.dart
@@ -52,18 +52,18 @@
 ''');
   }
 
-  ProcessResult runFix(List<String> args, {String workingDir}) {
+  Future<ProcessResult> runFix(List<String> args, {String workingDir}) async {
     if (runFromSource) {
       var binary = path.join(Directory.current.path, 'bin', 'dartdev.dart');
-      return p.runSync([binary, 'fix', ...?args], workingDir: workingDir);
+      return await p.run([binary, 'fix', ...?args], workingDir: workingDir);
     }
-    return p.runSync(['fix', ...args], workingDir: workingDir);
+    return await p.run(['fix', ...args], workingDir: workingDir);
   }
 
-  test('--help', () {
+  test('--help', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = runFix([p.dirPath, '--help']);
+    var result = await runFix([p.dirPath, '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -76,10 +76,10 @@
     expect(result.stdout, contains('Usage: dart fix [arguments]'));
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = runFix([p.dirPath, '--help', '--verbose']);
+    var result = await runFix([p.dirPath, '--help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -95,10 +95,10 @@
     );
   });
 
-  test('none', () {
+  test('none', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = runFix([p.dirPath]);
+    var result = await runFix([p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -106,17 +106,17 @@
         result.stdout, contains('Apply automated fixes to Dart source code.'));
   });
 
-  test('--apply (none)', () {
+  test('--apply (none)', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
 
-    var result = runFix(['--apply', p.dirPath]);
+    var result = await runFix(['--apply', p.dirPath]);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Nothing to fix!'));
   });
 
-  test('--apply (no args)', () {
+  test('--apply (no args)', () async {
     p = project(
       mainSrc: '''
 var x = "";
@@ -128,7 +128,7 @@
 ''',
     );
 
-    var result = runFix(['--apply'], workingDir: p.dirPath);
+    var result = await runFix(['--apply'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(
@@ -140,7 +140,7 @@
         ]));
   });
 
-  test('--dry-run', () {
+  test('--dry-run', () async {
     p = project(
       mainSrc: '''
 class A {
@@ -158,7 +158,7 @@
     - prefer_single_quotes
 ''',
     );
-    var result = runFix(['--dry-run', '.'], workingDir: p.dirPath);
+    var result = await runFix(['--dry-run', '.'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(
@@ -171,7 +171,7 @@
         ]));
   });
 
-  test('--apply (.)', () {
+  test('--apply (.)', () async {
     p = project(
       mainSrc: '''
 var x = "";
@@ -182,7 +182,7 @@
     - prefer_single_quotes
 ''',
     );
-    var result = runFix(['--apply', '.'], workingDir: p.dirPath);
+    var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(
@@ -195,7 +195,33 @@
         ]));
   });
 
-  test('--apply (excludes)', () {
+  test('--apply (contradictory lints do not loop infinitely)', () async {
+    p = project(
+      mainSrc: '''
+var x = "";
+''',
+      analysisOptions: '''
+linter:
+  rules:
+    - prefer_double_quotes
+    - prefer_single_quotes
+''',
+    );
+    var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
+    expect(result.exitCode, 0);
+    expect(result.stderr, isEmpty);
+    expect(
+        result.stdout,
+        stringContainsInOrder([
+          'Applying fixes...',
+          'lib${Platform.pathSeparator}main.dart',
+          '  prefer_double_quotes $bullet 2 fixes',
+          '  prefer_single_quotes $bullet 2 fixes',
+          '4 fixes made in 1 file.',
+        ]));
+  });
+
+  test('--apply (excludes)', () async {
     p = project(
       mainSrc: '''
 var x = "";
@@ -209,13 +235,13 @@
     - prefer_single_quotes
 ''',
     );
-    var result = runFix(['--apply', '.'], workingDir: p.dirPath);
+    var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Nothing to fix!'));
   });
 
-  test('--apply (ignores)', () {
+  test('--apply (ignores)', () async {
     p = project(
       mainSrc: '''
 // ignore: prefer_single_quotes
@@ -227,14 +253,41 @@
     - prefer_single_quotes
 ''',
     );
-    var result = runFix(['--apply', '.'], workingDir: p.dirPath);
+    var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Nothing to fix!'));
   });
 
+  test('--apply (unused imports require a second pass)', () async {
+    p = project(
+      mainSrc: '''
+import 'dart:math';
+
+var x = "";
+''',
+      analysisOptions: '''
+linter:
+  rules:
+    - prefer_single_quotes
+''',
+    );
+    var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
+    expect(result.exitCode, 0);
+    expect(result.stderr, isEmpty);
+    expect(
+        result.stdout,
+        stringContainsInOrder([
+          'Applying fixes...',
+          'lib${Platform.pathSeparator}main.dart',
+          '  prefer_single_quotes $bullet 1 fix',
+          '  unused_import $bullet 1 fix',
+          '2 fixes made in 1 file.',
+        ]));
+  });
+
   group('compare-to-golden', () {
-    test('applied fixes do not match expected', () {
+    test('applied fixes do not match expected', () async {
       p = project(
         mainSrc: '''
 class A {
@@ -261,11 +314,12 @@
   String a() => '';
 }
 ''');
-      result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
+      result =
+          await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
       assertResult(exitCode: 1);
     });
 
-    test('applied fixes match expected', () {
+    test('applied fixes match expected', () async {
       p = project(
         mainSrc: '''
 class A {
@@ -293,11 +347,12 @@
   String a() => '';
 }
 ''');
-      result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
+      result =
+          await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
       assertResult();
     });
 
-    test('missing expect', () {
+    test('missing expect', () async {
       p = project(
         mainSrc: '''
 class A {
@@ -315,11 +370,12 @@
     - prefer_single_quotes
 ''',
       );
-      result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
+      result =
+          await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
       assertResult(exitCode: 1);
     });
 
-    test('missing original', () {
+    test('missing original', () async {
       p = project(mainSrc: '''
 class C {}
 ''');
@@ -329,11 +385,12 @@
       p.file('lib/secondary.dart.expect', '''
 class A {}
 ''');
-      result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
+      result =
+          await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
       assertResult(exitCode: 1);
     });
 
-    test('no fixes to apply does not match expected', () {
+    test('no fixes to apply does not match expected', () async {
       p = project(
         mainSrc: '''
 class A {
@@ -351,7 +408,8 @@
   String a() => '';
 }
 ''');
-      result = runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
+      result =
+          await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
       assertResult(exitCode: 1);
     });
   });
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index da055db..b5aa76e 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -59,9 +59,9 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
-    var result = p.runSync(['--help']);
+    var result = await p.run(['--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -77,9 +77,9 @@
     expect(result.stdout, contains('migrate '));
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project();
-    var result = p.runSync(['--help', '--verbose']);
+    var result = await p.run(['--help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -87,9 +87,9 @@
         contains('The following options are only used for VM development'));
   });
 
-  test('--help -v', () {
+  test('--help -v', () async {
     p = project();
-    var result = p.runSync(['--help', '-v']);
+    var result = await p.run(['--help', '-v']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -97,25 +97,26 @@
         contains('The following options are only used for VM development'));
   });
 
-  test('print Dart CLI help on usage error', () {
+  test('print Dart CLI help on usage error', () async {
     p = project();
-    var result = p.runSync(['---help']);
+    var result = await p.run(['---help']);
     expect(result.exitCode, 255);
     expect(result.stdout, contains(DartdevRunner.dartdevDescription));
     expect(result.stderr, isEmpty);
   });
 
-  test('print VM help on usage error when --disable-dart-dev is provided', () {
+  test('print VM help on usage error when --disable-dart-dev is provided',
+      () async {
     p = project();
-    var result = p.runSync(['---help', '--disable-dart-dev']);
+    var result = await p.run(['---help', '--disable-dart-dev']);
     expect(result.exitCode, 255);
     expect(result.stdout, isNot(contains(DartdevRunner.dartdevDescription)));
     expect(result.stderr, isEmpty);
   });
 
-  test('help', () {
+  test('help', () async {
     p = project();
-    var result = p.runSync(['help']);
+    var result = await p.run(['help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -131,9 +132,9 @@
     expect(result.stdout, contains('migrate '));
   });
 
-  test('help --verbose', () {
+  test('help --verbose', () async {
     p = project();
-    var result = p.runSync(['help', '--verbose']);
+    var result = await p.run(['help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stdout,
@@ -141,9 +142,9 @@
     expect(result.stdout, contains('migrate '));
   });
 
-  test('help -v', () {
+  test('help -v', () async {
     p = project();
-    var result = p.runSync(['help', '-v']);
+    var result = await p.run(['help', '-v']);
 
     expect(result.exitCode, 0);
     expect(result.stdout,
diff --git a/pkg/dartdev/test/commands/format_test.dart b/pkg/dartdev/test/commands/format_test.dart
index 568f3ce..5331c6d 100644
--- a/pkg/dartdev/test/commands/format_test.dart
+++ b/pkg/dartdev/test/commands/format_test.dart
@@ -18,9 +18,9 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
-    var result = p.runSync(['format', '--help']);
+    var result = await p.run(['format', '--help']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Idiomatically format Dart source code.'));
@@ -31,9 +31,9 @@
     expect(result.stdout.contains('--stdin-name'), isFalse);
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project();
-    var result = p.runSync(['format', '--help', '--verbose']);
+    var result = await p.run(['format', '--help', '--verbose']);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Idiomatically format Dart source code.'));
@@ -44,17 +44,17 @@
     expect(result.stdout, contains('--stdin-name'));
   });
 
-  test('unchanged', () {
+  test('unchanged', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
-    ProcessResult result = p.runSync(['format', p.relativeFilePath]);
+    ProcessResult result = await p.run(['format', p.relativeFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, startsWith('Formatted 1 file (0 changed) in '));
   });
 
-  test('formatted', () {
+  test('formatted', () async {
     p = project(mainSrc: 'int get foo =>       1;\n');
-    ProcessResult result = p.runSync(['format', p.relativeFilePath]);
+    ProcessResult result = await p.run(['format', p.relativeFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(
@@ -63,9 +63,9 @@
             'Formatted lib/main.dart\nFormatted 1 file (1 changed) in '));
   });
 
-  test('formatted with exit code set', () {
+  test('formatted with exit code set', () async {
     p = project(mainSrc: 'int get foo =>       1;\n');
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'format',
       '--set-exit-if-changed',
       p.relativeFilePath,
@@ -78,9 +78,9 @@
             'Formatted lib/main.dart\nFormatted 1 file (1 changed) in '));
   });
 
-  test('not formatted with exit code set', () {
+  test('not formatted with exit code set', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'format',
       '--set-exit-if-changed',
       p.relativeFilePath,
@@ -90,10 +90,10 @@
     expect(result.stdout, startsWith('Formatted 1 file (0 changed) in '));
   });
 
-  test('unknown file', () {
+  test('unknown file', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
     var unknownFilePath = '${p.relativeFilePath}-unknown-file.dart';
-    ProcessResult result = p.runSync(['format', unknownFilePath]);
+    ProcessResult result = await p.run(['format', unknownFilePath]);
     expect(result.exitCode, 0);
     expect(result.stderr,
         startsWith('No file or directory found at "$unknownFilePath".'));
diff --git a/pkg/dartdev/test/commands/help_test.dart b/pkg/dartdev/test/commands/help_test.dart
index 09c3c41..2202b56 100644
--- a/pkg/dartdev/test/commands/help_test.dart
+++ b/pkg/dartdev/test/commands/help_test.dart
@@ -26,10 +26,10 @@
       .commands
       .forEach((String commandKey, Command command) {
     if (!_commandsNotTested.contains(commandKey)) {
-      test('(help $commandKey == $commandKey --help)', () {
+      test('(help $commandKey == $commandKey --help)', () async {
         p = project();
-        var result = p.runSync(['help', commandKey]);
-        var verbHelpResult = p.runSync([commandKey, '--help']);
+        var result = await p.run(['help', commandKey]);
+        var verbHelpResult = await p.run([commandKey, '--help']);
 
         expect(result.stdout, contains(verbHelpResult.stdout));
         expect(result.stderr, contains(verbHelpResult.stderr));
@@ -37,20 +37,20 @@
     }
   });
 
-  test('(help test ~= test --help) outside project', () {
+  test('(help test ~= test --help) outside project', () async {
     p = project();
     p.deleteFile('pubspec.yaml');
-    var result = p.runSync(['help', 'test']);
-    var testHelpResult = p.runSync(['test', '--help']);
+    var result = await p.run(['help', 'test']);
+    var testHelpResult = await p.run(['test', '--help']);
 
     expect(testHelpResult.stdout, contains(result.stdout));
     expect(testHelpResult.stderr, contains(result.stderr));
   });
 
-  test('(help pub == pub --help)', () {
+  test('(help pub == pub --help)', () async {
     p = project();
-    var result = p.runSync(['help', 'pub']);
-    var pubHelpResult = p.runSync(['pub', '--help']);
+    var result = await p.run(['help', 'pub']);
+    var pubHelpResult = await p.run(['pub', '--help']);
 
     expect(result.stdout, contains(pubHelpResult.stdout));
     expect(result.stderr, contains(pubHelpResult.stderr));
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 94795be..68475ee 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -19,9 +19,9 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
-    var result = p.runSync(['migrate', '--help']);
+    var result = await p.run(['migrate', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -35,9 +35,9 @@
     );
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project();
-    var result = p.runSync(['migrate', '--help', '--verbose']);
+    var result = await p.run(['migrate', '--help', '--verbose']);
 
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
@@ -53,43 +53,43 @@
     );
   });
 
-  test('directory implicit', () {
+  test('directory implicit', () async {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'int get foo => 1;\n');
     var result =
-        p.runSync(['migrate', '--no-web-preview'], workingDir: p.dirPath);
+        await p.run(['migrate', '--no-web-preview'], workingDir: p.dirPath);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Generating migration suggestions'));
   });
 
-  test('directory explicit', () {
+  test('directory explicit', () async {
     p = project(mainSrc: dartVersionFilePrefix2_9 + 'int get foo => 1;\n');
-    var result = p.runSync(['migrate', '--no-web-preview', p.dirPath]);
+    var result = await p.run(['migrate', '--no-web-preview', p.dirPath]);
     expect(result.exitCode, 0);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('Generating migration suggestions'));
   });
 
-  test('bad directory', () {
+  test('bad directory', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync(['migrate', 'foo_bar_dir']);
+    var result = await p.run(['migrate', 'foo_bar_dir']);
     expect(result.exitCode, 1);
     expect(result.stderr, contains('foo_bar_dir does not exist'));
     expect(result.stdout, isEmpty);
   });
 
-  test('pub get needs running', () {
+  test('pub get needs running', () async {
     p = project(mainSrc: 'import "package:foo/foo.dart";\n');
-    var result = p.runSync(['migrate', p.dirPath]);
+    var result = await p.run(['migrate', p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
     expect(result.stdout, runPubGet);
     expect(result.stdout, isNot(setLowerSdkConstraint));
   });
 
-  test('non-pub-related error', () {
+  test('non-pub-related error', () async {
     p = project(mainSrc: 'var missing = "semicolon"\n');
-    var result = p.runSync(['migrate', p.dirPath]);
+    var result = await p.run(['migrate', p.dirPath]);
     expect(result.exitCode, 1);
     expect(result.stderr, isEmpty);
     expect(result.stdout, runPubGet);
diff --git a/pkg/dartdev/test/commands/pub_test.dart b/pkg/dartdev/test/commands/pub_test.dart
index ab5b715..2eafe5e 100644
--- a/pkg/dartdev/test/commands/pub_test.dart
+++ b/pkg/dartdev/test/commands/pub_test.dart
@@ -25,8 +25,8 @@
     expect(result.stderr, isEmpty);
   }
 
-  test('implicit --help', () {
-    final result = project().runSync(['pub']);
+  test('implicit --help', () async {
+    final result = await project().run(['pub']);
     expect(result, isNotNull);
     expect(result.exitCode, 64);
     expect(result.stderr, contains('Missing subcommand for "dart pub".'));
@@ -34,18 +34,18 @@
     expect(result.stdout, isEmpty);
   });
 
-  test('--help', () {
-    _assertPubHelpInvoked(project().runSync(['pub', '--help']));
+  test('--help', () async {
+    _assertPubHelpInvoked(await project().run(['pub', '--help']));
   });
 
-  test('-h', () {
-    _assertPubHelpInvoked(project().runSync(['pub', '-h']));
+  test('-h', () async {
+    _assertPubHelpInvoked(await project().run(['pub', '-h']));
   });
 
-  test('help cache', () {
+  test('help cache', () async {
     p = project();
-    var result = p.runSync(['help', 'pub', 'cache']);
-    var result2 = p.runSync(['pub', 'cache', '--help']);
+    var result = await p.run(['help', 'pub', 'cache']);
+    var result2 = await p.run(['pub', 'cache', '--help']);
 
     expect(result.exitCode, 0);
 
@@ -56,10 +56,10 @@
     expect(result.stderr, result2.stderr);
   });
 
-  test('help publish', () {
+  test('help publish', () async {
     p = project();
-    var result = p.runSync(['help', 'pub', 'publish']);
-    var result2 = p.runSync(['pub', 'publish', '--help']);
+    var result = await p.run(['help', 'pub', 'publish']);
+    var result2 = await p.run(['pub', 'publish', '--help']);
 
     expect(result.exitCode, 0);
 
@@ -71,17 +71,17 @@
     expect(result.stderr, result2.stderr);
   });
 
-  test('failure', () {
+  test('failure', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync(['pub', 'deps']);
+    var result = await p.run(['pub', 'deps']);
     expect(result.exitCode, 65);
     expect(result.stdout, isEmpty);
     expect(result.stderr, contains('No pubspec.lock file found'));
   });
 
-  test('failure unknown option', () {
+  test('failure unknown option', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
-    var result = p.runSync(['pub', 'deps', '--foo']);
+    var result = await p.run(['pub', 'deps', '--foo']);
     expect(result.exitCode, 64);
     expect(result.stdout, isEmpty);
     expect(result.stderr, startsWith('Could not find an option named "foo".'));
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 613a508..1e9b3e0 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -25,9 +25,9 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
-    var result = p.runSync(['run', '--help']);
+    var result = await p.run(['run', '--help']);
 
     expect(result.stdout, contains('Run a Dart program.'));
     expect(result.stdout, contains('Debugging options:'));
@@ -41,9 +41,9 @@
     expect(result.exitCode, 0);
   });
 
-  test('--help --verbose', () {
+  test('--help --verbose', () async {
     p = project();
-    var result = p.runSync(['run', '--help', '--verbose']);
+    var result = await p.run(['run', '--help', '--verbose']);
 
     expect(result.stdout, contains('Run a Dart program.'));
     expect(result.stdout, contains('Debugging options:'));
@@ -57,30 +57,30 @@
     expect(result.exitCode, 0);
   });
 
-  test("'Hello World'", () {
+  test("'Hello World'", () async {
     p = project(mainSrc: "void main() { print('Hello World'); }");
-    ProcessResult result = p.runSync(['run', p.relativeFilePath]);
+    ProcessResult result = await p.run(['run', p.relativeFilePath]);
 
     expect(result.stdout, contains('Hello World'));
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
   });
 
-  test('no such file', () {
+  test('no such file', () async {
     p = project(mainSrc: "void main() { print('Hello World'); }");
     ProcessResult result =
-        p.runSync(['run', 'no/such/file/${p.relativeFilePath}']);
+        await p.run(['run', 'no/such/file/${p.relativeFilePath}']);
 
     expect(result.stderr, isNotEmpty);
     expect(result.exitCode, isNot(0));
   });
 
-  test('implicit packageName.dart', () {
+  test('implicit packageName.dart', () async {
     // TODO(jwren) circle back to reimplement this test if possible, the file
     // name (package name) will be the name of the temporary directory on disk
     p = project(mainSrc: "void main() { print('Hello World'); }");
     p.file('bin/main.dart', "void main() { print('Hello main.dart'); }");
-    ProcessResult result = p.runSync(['run']);
+    ProcessResult result = await p.run(['run']);
 
     expect(result.stdout, contains('Hello main.dart'));
     expect(result.stderr, isEmpty);
@@ -88,10 +88,10 @@
   }, skip: true);
 
   // Could not find the implicit file to run: bin
-  test('missing implicit packageName.dart', () {
+  test('missing implicit packageName.dart', () async {
     p = project(mainSrc: "void main() { print('Hello World'); }");
     p.file('bin/foo.dart', "void main() { print('Hello main.dart'); }");
-    ProcessResult result = p.runSync(['run']);
+    ProcessResult result = await p.run(['run']);
 
     expect(result.stdout, isEmpty);
     expect(
@@ -101,10 +101,10 @@
     expect(result.exitCode, 255);
   });
 
-  test('arguments are properly passed', () {
+  test('arguments are properly passed', () async {
     p = project();
     p.file('main.dart', 'void main(args) { print(args); }');
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'run',
       '--enable-experiment=test-experiment',
       'main.dart',
@@ -118,7 +118,7 @@
     expect(result.exitCode, 0);
   });
 
-  test('from path-dependency with cyclic dependency', () {
+  test('from path-dependency with cyclic dependency', () async {
     p = project(name: 'foo');
     final bar = TestProject(name: 'bar');
     p.file('pubspec.yaml', '''
@@ -141,7 +141,7 @@
 void main(List<String> args) => print("$b $args");
 ''');
 
-      ProcessResult result = p.runSync(['run', 'bar:main', '--arg1', 'arg2']);
+      ProcessResult result = await p.run(['run', 'bar:main', '--arg1', 'arg2']);
 
       expect(result.stderr, isEmpty);
       expect(result.stdout, contains('FOO BAR [--arg1, arg2]'));
@@ -156,7 +156,7 @@
     p.file('main.dart', 'void main(args) { print(args); }');
     // Test with absolute path
     final name = path.join(p.dirPath, 'main.dart');
-    final result = p.runSync([
+    final result = await p.run([
       'run',
       '--enable-experiment=test-experiment',
       name,
@@ -175,7 +175,7 @@
     p.file('main.dart', 'void main(args) { print(args); }');
     // Test with File uri
     final name = path.join(p.dirPath, 'main.dart');
-    final result = p.runSync([
+    final result = await p.run([
       'run',
       Uri.file(name).toString(),
       '--argument1',
@@ -199,7 +199,7 @@
     //
     // This test ensures that allowed arguments for dart run which are valid VM
     // arguments are properly handled by the VM.
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'run',
       '--observe',
       '--pause-isolates-on-start',
@@ -220,7 +220,7 @@
     expect(result.exitCode, 0);
 
     // Again, with --disable-service-auth-codes.
-    result = p.runSync([
+    result = await p.run([
       'run',
       '--observe',
       '--pause-isolates-on-start',
@@ -242,7 +242,7 @@
     expect(result.exitCode, 0);
 
     // Again, with IPv6.
-    result = p.runSync([
+    result = await p.run([
       'run',
       '--observe=8181/::1',
       '--pause-isolates-on-start',
@@ -269,7 +269,7 @@
 
     // Any VM flags not listed under 'dart run help --verbose' should be passed
     // before a dartdev command.
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'run',
       '--vm-name=foo',
       p.relativeFilePath,
@@ -288,7 +288,7 @@
 
     // Any VM flags not listed under 'dart run help --verbose' should be passed
     // before a dartdev command.
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'run',
       '--verbose_gc',
       p.relativeFilePath,
@@ -307,7 +307,7 @@
 
     // Ensure --enable-asserts doesn't cause the dartdev isolate to fail to
     // load. Regression test for: https://github.com/dart-lang/sdk/issues/42831
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'run',
       '--enable-asserts',
       p.relativeFilePath,
@@ -322,7 +322,7 @@
     p = project(mainSrc: 'void main() { assert(false); }');
 
     // Any VM flags passed after the script shouldn't be interpreted by the VM.
-    ProcessResult result = p.runSync([
+    ProcessResult result = await p.run([
       'run',
       p.relativeFilePath,
       '--enable-asserts',
@@ -333,10 +333,10 @@
     expect(result.exitCode, 0);
   });
 
-  test('without verbose CFE info', () {
+  test('without verbose CFE info', () async {
     final p = project(mainSrc: '''void main() {}''');
 
-    var result = p.runSync(
+    var result = await p.run(
       [
         'run',
         '--verbosity=warning',
@@ -352,9 +352,9 @@
 
   group('DDS', () {
     group('disable', () {
-      test('dart run simple', () {
+      test('dart run simple', () async {
         p = project(mainSrc: "void main() { print('Hello World'); }");
-        ProcessResult result = p.runSync([
+        ProcessResult result = await p.run([
           'run',
           '--no-dds',
           '--enable-vm-service',
@@ -364,9 +364,9 @@
         expect(result.stdout, contains(observatoryMessagePrefix));
       });
 
-      test('dart simple', () {
+      test('dart simple', () async {
         p = project(mainSrc: "void main() { print('Hello World'); }");
-        ProcessResult result = p.runSync([
+        ProcessResult result = await p.run([
           '--no-dds',
           '--enable-vm-service',
           p.relativeFilePath,
@@ -377,9 +377,9 @@
     });
 
     group('explicit enable', () {
-      test('dart run simple', () {
+      test('dart run simple', () async {
         p = project(mainSrc: "void main() { print('Hello World'); }");
-        ProcessResult result = p.runSync([
+        ProcessResult result = await p.run([
           'run',
           '--dds',
           '--enable-vm-service',
@@ -389,9 +389,9 @@
         expect(result.stdout, contains(observatoryMessagePrefix));
       });
 
-      test('dart simple', () {
+      test('dart simple', () async {
         p = project(mainSrc: "void main() { print('Hello World'); }");
-        ProcessResult result = p.runSync([
+        ProcessResult result = await p.run([
           '--dds',
           '--enable-vm-service',
           p.relativeFilePath,
@@ -405,7 +405,7 @@
   group('DevTools', () {
     test('dart run simple', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         'run',
         '--enable-vm-service',
         p.relativeFilePath,
@@ -415,7 +415,7 @@
 
     test('dart simple', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         '--enable-vm-service',
         p.relativeFilePath,
       ]);
@@ -424,7 +424,7 @@
 
     test('dart run explicit', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         'run',
         '--serve-devtools',
         '--enable-vm-service',
@@ -435,7 +435,7 @@
 
     test('dart explicit', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         '--serve-devtools',
         '--enable-vm-service',
         p.relativeFilePath,
@@ -445,7 +445,7 @@
 
     test('dart run disabled', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         'run',
         '--enable-vm-service',
         '--no-serve-devtools',
@@ -456,7 +456,7 @@
 
     test('dart disabled', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         '--enable-vm-service',
         '--no-serve-devtools',
         p.relativeFilePath,
@@ -466,7 +466,7 @@
 
     test('dart run VM service not enabled', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         'run',
         '--serve-devtools',
         p.relativeFilePath,
@@ -476,7 +476,7 @@
 
     test('dart VM service not enabled', () async {
       p = project(mainSrc: "void main() { print('Hello World'); }");
-      ProcessResult result = p.runSync([
+      ProcessResult result = await p.run([
         '--serve-devtools',
         p.relativeFilePath,
       ]);
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index bda022bb..634d2b9 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -21,10 +21,10 @@
 
   tearDown(() => p?.dispose());
 
-  test('--help', () {
+  test('--help', () async {
     p = project();
 
-    final result = p.runSync(['test', '--help']);
+    final result = await p.run(['test', '--help']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, startsWith('''
@@ -35,22 +35,22 @@
     expect(result.stderr, isEmpty);
   });
 
-  test('dart help test', () {
+  test('dart help test', () async {
     p = project();
 
-    final result = p.runSync(['help', 'test']);
+    final result = await p.run(['help', 'test']);
 
     expect(result.exitCode, 0);
     expect(result.stdout, contains(' tests for a project'));
     expect(result.stderr, isEmpty);
   });
 
-  test('no pubspec.yaml', () {
+  test('no pubspec.yaml', () async {
     p = project();
     var pubspec = File(path.join(p.dirPath, 'pubspec.yaml'));
     pubspec.deleteSync();
 
-    var result = p.runSync(['test']);
+    var result = await p.run(['test']);
 
     expect(result.stderr, isEmpty);
     expect(result.stdout, '''
@@ -58,7 +58,7 @@
 ''');
     expect(result.exitCode, 65);
 
-    var resultHelp = p.runSync(['test', '--help']);
+    var resultHelp = await p.run(['test', '--help']);
 
     expect(resultHelp.stderr, isEmpty);
     expect(resultHelp.stdout, '''
@@ -74,7 +74,7 @@
     expect(resultHelp.exitCode, 65);
   });
 
-  test('runs test', () {
+  test('runs test', () async {
     p = project();
     p.file('test/foo_test.dart', '''
 import 'package:test/test.dart';
@@ -87,13 +87,14 @@
 ''');
 
     // An implicit `pub get` will happen.
-    final result = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
+    final result =
+        await p.run(['test', '--no-color', '--reporter', 'expanded']);
     expect(result.stderr, isEmpty);
     expect(result.stdout, contains('All tests passed!'));
     expect(result.exitCode, 0);
   });
 
-  test('no package:test dependency', () {
+  test('no package:test dependency', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
     p.file('pubspec.yaml', '''
 name: ${p.name}
@@ -110,7 +111,7 @@
 }
 ''');
 
-    final result = p.runSync(['test']);
+    final result = await p.run(['test']);
     expect(result.exitCode, 65);
     expect(
       result.stdout,
@@ -119,16 +120,17 @@
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 65);
 
-    final resultPubAdd = p.runSync(['pub', 'add', 'test']);
+    final resultPubAdd = await p.run(['pub', 'add', 'test']);
 
     expect(resultPubAdd.exitCode, 0);
-    final result2 = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
+    final result2 =
+        await p.run(['test', '--no-color', '--reporter', 'expanded']);
     expect(result2.stderr, isEmpty);
     expect(result2.stdout, contains('All tests passed!'));
     expect(result2.exitCode, 0);
   });
 
-  test('has package:test dependency', () {
+  test('has package:test dependency', () async {
     p = project(mainSrc: 'int get foo => 1;\n');
     p.file('test/foo_test.dart', '''
 $dartVersionFilePrefix2_9
@@ -142,15 +144,16 @@
 }
 ''');
 
-    final result = p.runSync(['test', '--no-color', '--reporter', 'expanded']);
+    final result =
+        await p.run(['test', '--no-color', '--reporter', 'expanded']);
     expect(result.exitCode, 0);
     expect(result.stdout, contains('All tests passed!'));
     expect(result.stderr, isEmpty);
   });
 
   group('--enable-experiment', () {
-    ProcessResult runTestWithExperimentFlag(String flag) {
-      return p.runSync([
+    Future<ProcessResult> runTestWithExperimentFlag(String flag) async {
+      return await p.run([
         if (flag != null) flag,
         'test',
         '--no-color',
@@ -159,21 +162,21 @@
       ]);
     }
 
-    void expectSuccess(String flag) {
-      final result = runTestWithExperimentFlag(flag);
+    Future<void> expectSuccess(String flag) async {
+      final result = await runTestWithExperimentFlag(flag);
       expect(result.stdout, contains('feature enabled'),
           reason: 'stderr: ${result.stderr}');
       expect(result.exitCode, 0,
           reason: 'stdout: ${result.stdout} stderr: ${result.stderr}');
     }
 
-    void expectFailure(String flag) {
-      final result = runTestWithExperimentFlag(flag);
+    Future<void> expectFailure(String flag) async {
+      final result = await runTestWithExperimentFlag(flag);
       expect(result.exitCode, isNot(0));
     }
 
     for (final experiment in experiments) {
-      test(experiment.name, () {
+      test(experiment.name, () async {
         final currentSdk = Version.parse(Platform.version.split(' ').first);
         p = project(
             mainSrc: experiment.validation,
@@ -190,12 +193,12 @@
 ''');
         if (experiment.enabledIn != null) {
           // The experiment has been released - enabling it should have no effect.
-          expectSuccess(null);
-          expectSuccess('--enable-experiment=${experiment.name}');
+          await expectSuccess(null);
+          await expectSuccess('--enable-experiment=${experiment.name}');
         } else {
-          expectFailure(null);
-          expectFailure('--enable-experiment=no-${experiment.name}');
-          expectSuccess('--enable-experiment=${experiment.name}');
+          await expectFailure(null);
+          await expectFailure('--enable-experiment=no-${experiment.name}');
+          await expectSuccess('--enable-experiment=${experiment.name}');
         }
       });
     }
diff --git a/pkg/dartdev/test/load_from_dill_test.dart b/pkg/dartdev/test/load_from_dill_test.dart
index 6de6c6c..633e7af 100644
--- a/pkg/dartdev/test/load_from_dill_test.dart
+++ b/pkg/dartdev/test/load_from_dill_test.dart
@@ -14,13 +14,13 @@
   tearDown(() => p?.dispose());
 
   test("Fallback to dartdev.dill from dartdev.dart.snapshot for 'Hello World'",
-      () {
+      () async {
     p = project(mainSrc: "void main() { print('Hello World'); }");
-    // The DartDev snapshot includes the --use-bare-instructions flag. If
-    // --no-use-bare-instructions is passed, the VM will fail to load the
+    // The DartDev snapshot includes the --use_field_guards flag. If
+    // --no-use-field-guards is passed, the VM will fail to load the
     // snapshot and should fall back to using the DartDev dill file.
     ProcessResult result =
-        p.runSync(['--no-use-bare-instructions', 'run', p.relativeFilePath]);
+        await p.run(['--no-use-field-guards', 'run', p.relativeFilePath]);
 
     expect(result.stdout, contains('Hello World'));
     expect(result.stderr, isEmpty);
diff --git a/pkg/dartdev/test/no_such_file_test.dart b/pkg/dartdev/test/no_such_file_test.dart
index b5a3452..9b2edc4 100644
--- a/pkg/dartdev/test/no_such_file_test.dart
+++ b/pkg/dartdev/test/no_such_file_test.dart
@@ -11,25 +11,25 @@
 
   tearDown(() => p?.dispose());
 
-  test('Ensure parsing fails after encountering invalid file', () {
+  test('Ensure parsing fails after encountering invalid file', () async {
     // Regression test for https://github.com/dart-lang/sdk/issues/43991
     p = project();
-    final noArgsResult = p.runSync(['foo.dart']);
+    final noArgsResult = await p.run(['foo.dart']);
     expect(noArgsResult.stderr, isNotEmpty);
     expect(noArgsResult.stdout, isEmpty);
     expect(noArgsResult.exitCode, 64);
 
-    final argsResult = p.runSync(['foo.dart', '--bar']);
+    final argsResult = await p.run(['foo.dart', '--bar']);
     expect(argsResult.stderr, noArgsResult.stderr);
     expect(argsResult.stdout, isEmpty);
     expect(argsResult.exitCode, 64);
   });
 
   test('Providing --snapshot VM option with invalid script fails gracefully',
-      () {
+      () async {
     // Regression test for https://github.com/dart-lang/sdk/issues/43785
     p = project();
-    final result = p.runSync(['--snapshot=abc', 'foo.dart']);
+    final result = await p.run(['--snapshot=abc', 'foo.dart']);
     expect(result.stderr, isNotEmpty);
     expect(result.stderr, contains("Error when reading 'foo.dart':"));
     expect(result.stdout, isEmpty);
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index 73f944f..fe656a5 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -51,6 +51,8 @@
 
   final Map<String, dynamic> pubspec;
 
+  Process _process;
+
   TestProject(
       {String mainSrc,
       String analysisOptions,
@@ -92,24 +94,34 @@
   }
 
   void dispose() {
+    _process?.kill();
+    _process = null;
     if (dir.existsSync()) {
       dir.deleteSync(recursive: true);
     }
   }
 
-  ProcessResult runSync(
+  Future<ProcessResult> run(
     List<String> arguments, {
     String workingDir,
-  }) {
-    return Process.runSync(
+  }) async {
+    _process = await Process.start(
         Platform.resolvedExecutable,
         [
           '--no-analytics',
           ...arguments,
         ],
         workingDirectory: workingDir ?? dir.path,
-        environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'},
-        stdoutEncoding: utf8);
+        environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
+    final stdoutContents = _process.stdout.transform(utf8.decoder).join();
+    final stderrContents = _process.stderr.transform(utf8.decoder).join();
+    final code = await _process.exitCode;
+    return ProcessResult(
+      _process.pid,
+      code,
+      await stdoutContents,
+      await stderrContents,
+    );
   }
 
   Future<Process> start(
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index cccc7a8..0b7db0f 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,9 @@
+# 2.1.5
+- Update to new CpuSamplesEvent format for CPU sample caching for improved
+  performance.
+- Add additional context in the case of failure to ascii decode headers caused
+  by utf8 content on the stream.
+
 # 2.1.4
 - A new library `package:dds/dap.dart` exposes classes required to build a custom DAP
   debug-adapter on top of the base Dart DAP functionality in DDS.
diff --git a/pkg/dds/lib/src/cpu_samples_manager.dart b/pkg/dds/lib/src/cpu_samples_manager.dart
index a0c413a..108da99 100644
--- a/pkg/dds/lib/src/cpu_samples_manager.dart
+++ b/pkg/dds/lib/src/cpu_samples_manager.dart
@@ -52,21 +52,31 @@
     int bufferSize = 1000000,
   ]) : super(bufferSize);
 
-  void cacheSamples(CpuSamples samples) {
-    String getFunctionId(ProfileFunction function) {
-      final functionObject = function.function;
-      if (functionObject is NativeFunction) {
-        return 'native/${functionObject.name}';
-      }
-      return functionObject.id!;
-    }
+  ProfileFunction _buildProfileFunction(dynamic function) {
+    // `kind` and `resolvedUrl` are populated in `populateFunctionDetails()`.
+    return ProfileFunction(
+      kind: '',
+      inclusiveTicks: -1,
+      exclusiveTicks: -1,
+      resolvedUrl: '',
+      function: function,
+    );
+  }
 
+  String _getFunctionId(dynamic function) {
+    if (function is NativeFunction) {
+      return 'native/${function.name}';
+    }
+    return function.id!;
+  }
+
+  void cacheSamples(CpuSamplesEvent samples) {
     // Initialize upon seeing our first samples.
     if (functions.isEmpty) {
       samplePeriod = samples.samplePeriod!;
       maxStackDepth = samples.maxStackDepth!;
       pid = samples.pid!;
-      functions.addAll(samples.functions!);
+      functions.addAll(samples.functions!.map(_buildProfileFunction));
 
       // Build the initial id to function index mapping. This allows for us to
       // lookup a ProfileFunction in the global function list stored in this
@@ -77,7 +87,7 @@
       // TODO(bkonyi): investigate creating some form of stable ID for
       // Functions tied to closures.
       for (int i = 0; i < functions.length; ++i) {
-        idToFunctionIndex[getFunctionId(functions[i])] = i;
+        idToFunctionIndex[_getFunctionId(functions[i].function)] = i;
       }
 
       // Clear tick information as we'll need to recalculate these values later
@@ -94,14 +104,14 @@
 
       // Check to see if we've got a function object we've never seen before.
       for (int i = 0; i < newFunctions.length; ++i) {
-        final key = getFunctionId(newFunctions[i]);
+        final key = _getFunctionId(newFunctions[i]);
         if (!idToFunctionIndex.containsKey(key)) {
           idToFunctionIndex[key] = functions.length;
           // Keep track of the original index and the location of the function
           // in the master function list so we can update the function indicies
           // for each sample in this batch.
           indexMapping[i] = functions.length;
-          functions.add(newFunctions[i]);
+          functions.add(_buildProfileFunction(newFunctions[i]));
 
           // Reset tick state as we'll recalculate later.
           functions.last.inclusiveTicks = 0;
@@ -159,6 +169,28 @@
     return evicted;
   }
 
+  Future<void> populateFunctionDetails(
+      DartDevelopmentServiceImpl dds, String isolateId) async {
+    final cpuSamples = await dds.vmServiceClient.sendRequest('getCpuSamples', {
+      'isolateId': isolateId,
+      'timeOriginMicros': 0,
+      'timeExtentMicros': 0,
+    });
+    final fullFunctions = cpuSamples['functions'];
+    for (final func in fullFunctions) {
+      final profileFunc = ProfileFunction.parse(func)!;
+      final id = _getFunctionId(profileFunc.function!);
+      final index = idToFunctionIndex[id];
+      if (index == null) {
+        continue;
+      }
+      final result = functions[index];
+      result.kind = profileFunc.kind;
+      result.resolvedUrl = profileFunc.resolvedUrl;
+      result.function = profileFunc.function;
+    }
+  }
+
   Map<String, dynamic> toJson() {
     return {
       'type': 'CachedCpuSamples',
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart
index 67be4b5..523cadf 100644
--- a/pkg/dds/lib/src/dap/adapters/dart.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -8,11 +8,11 @@
 
 import 'package:collection/collection.dart';
 import 'package:meta/meta.dart';
-import 'package:package_config/package_config.dart';
 import 'package:path/path.dart' as path;
 import 'package:vm_service/vm_service.dart' as vm;
 
 import '../../../dds.dart';
+import '../../rpc_error_codes.dart';
 import '../base_debug_adapter.dart';
 import '../exceptions.dart';
 import '../isolate_manager.dart';
@@ -49,6 +49,16 @@
 /// will work.
 const threadExceptionExpression = r'$_threadException';
 
+/// Typedef for handlers of VM Service stream events.
+typedef _StreamEventHandler<T> = FutureOr<void> Function(T data);
+
+/// A null result passed to `sendResponse` functions when there is no result.
+///
+/// Because the signature of `sendResponse` is generic, an argument must be
+/// provided even when the generic type is `void`. This value is used to make
+/// it clearer in calling code that the result is unused.
+const _noResult = null;
+
 /// Pattern for extracting useful error messages from an evaluation exception.
 final _evalErrorMessagePattern = RegExp('Error: (.*)');
 
@@ -139,6 +149,9 @@
   final String? name;
   final String? cwd;
 
+  /// Environment variables to pass to the launched process.
+  final Map<String, String>? env;
+
   /// Paths that should be considered the users local code.
   ///
   /// These paths will generally be all of the open folders in the users editor
@@ -189,6 +202,8 @@
     required this.restart,
     required this.name,
     required this.cwd,
+    // TODO(dantup): This can be made required after Flutter DAP is passing it.
+    this.env,
     required this.additionalProjectPaths,
     required this.debugSdkLibraries,
     required this.debugExternalPackageLibraries,
@@ -201,6 +216,7 @@
       : restart = obj['restart'],
         name = obj['name'] as String?,
         cwd = obj['cwd'] as String?,
+        env = obj['env'] as Map<String, String>?,
         additionalProjectPaths =
             (obj['additionalProjectPaths'] as List?)?.cast<String>(),
         debugSdkLibraries = obj['debugSdkLibraries'] as bool?,
@@ -216,6 +232,7 @@
         if (restart != null) 'restart': restart,
         if (name != null) 'name': name,
         if (cwd != null) 'cwd': cwd,
+        if (env != null) 'env': env,
         if (additionalProjectPaths != null)
           'additionalProjectPaths': additionalProjectPaths,
         if (debugSdkLibraries != null) 'debugSdkLibraries': debugSdkLibraries,
@@ -354,6 +371,17 @@
 
   late final sendLogsToClient = args.sendLogsToClient ?? false;
 
+  /// Whether or not the DAP is terminating.
+  ///
+  /// When set to `true`, some requests that return "Service Disappeared" errors
+  /// will be caught and dropped as these are expected if the process is
+  /// terminating.
+  ///
+  /// This flag may be set by incoming requests from the client
+  /// (terminateRequest/disconnectRequest) or when a process terminates, or the
+  /// VM Service disconnects.
+  bool isTerminating = false;
+
   DartDebugAdapter(
     ByteStreamServerChannel channel, {
     this.ipv6 = false,
@@ -531,16 +559,20 @@
     this.vmService = vmService;
 
     unawaited(vmService.onDone.then((_) => _handleVmServiceClosed()));
+
+    // Handlers must be wrapped to handle Service Disappeared errors if async
+    // code tries to call the VM Service after termination begins.
+    final wrap = _wrapHandlerWithErrorHandling;
     _subscriptions.addAll([
-      vmService.onIsolateEvent.listen(handleIsolateEvent),
-      vmService.onDebugEvent.listen(handleDebugEvent),
-      vmService.onLoggingEvent.listen(handleLoggingEvent),
-      vmService.onExtensionEvent.listen(handleExtensionEvent),
-      vmService.onServiceEvent.listen(handleServiceEvent),
+      vmService.onIsolateEvent.listen(wrap(handleIsolateEvent)),
+      vmService.onDebugEvent.listen(wrap(handleDebugEvent)),
+      vmService.onLoggingEvent.listen(wrap(handleLoggingEvent)),
+      vmService.onExtensionEvent.listen(wrap(handleExtensionEvent)),
+      vmService.onServiceEvent.listen(wrap(handleServiceEvent)),
       if (_subscribeToOutputStreams)
-        vmService.onStdoutEvent.listen(_handleStdoutEvent),
+        vmService.onStdoutEvent.listen(wrap(_handleStdoutEvent)),
       if (_subscribeToOutputStreams)
-        vmService.onStderrEvent.listen(_handleStderrEvent),
+        vmService.onStderrEvent.listen(wrap(_handleStderrEvent)),
     ]);
     await Future.wait([
       vmService.streamListen(vm.EventStreams.kIsolate),
@@ -558,8 +590,20 @@
     // Let the subclass do any existing setup once we have a connection.
     await debuggerConnected(vmInfo);
 
-    // Process any existing isolates that may have been created before the
-    // streams above were set up.
+    await _withErrorHandling(
+      () => _configureExistingIsolates(vmService, vmInfo, resumeIfStarting),
+    );
+
+    _debuggerInitializedCompleter.complete();
+  }
+
+  /// Process any existing isolates that may have been created before the
+  /// streams above were set up.
+  Future<void> _configureExistingIsolates(
+    vm.VmService vmService,
+    vm.VM vmInfo,
+    bool resumeIfStarting,
+  ) async {
     final existingIsolateRefs = vmInfo.isolates;
     final existingIsolates = existingIsolateRefs != null
         ? await Future.wait(existingIsolateRefs
@@ -596,8 +640,6 @@
         }
       }
     }));
-
-    _debuggerInitializedCompleter.complete();
   }
 
   /// Handles the clients "continue" ("resume") request for the thread in
@@ -632,26 +674,26 @@
   ) async {
     switch (request.command) {
 
-      /// Used by tests to validate available protocols (e.g. DDS). There may be
-      /// value in making this available to clients in future, but for now it's
-      /// internal.
+      // Used by tests to validate available protocols (e.g. DDS). There may be
+      // value in making this available to clients in future, but for now it's
+      // internal.
       case '_getSupportedProtocols':
         final protocols = await vmService?.getSupportedProtocols();
         sendResponse(protocols?.toJson());
         break;
 
-      /// Used to toggle debug settings such as whether SDK/Packages are
-      /// debuggable while the session is in progress.
+      // Used to toggle debug settings such as whether SDK/Packages are
+      // debuggable while the session is in progress.
       case 'updateDebugOptions':
         if (args != null) {
           await _updateDebugOptions(args.args);
         }
-        sendResponse(null);
+        sendResponse(_noResult);
         break;
 
-      /// Allows an editor to call a service/service extension that it was told
-      /// about via a custom 'dart.serviceRegistered' or
-      /// 'dart.serviceExtensionAdded' event.
+      // Allows an editor to call a service/service extension that it was told
+      // about via a custom 'dart.serviceRegistered' or
+      // 'dart.serviceExtensionAdded' event.
       case 'callService':
         final method = args?.args['method'] as String?;
         if (method == null) {
@@ -667,6 +709,15 @@
         sendResponse(response?.json);
         break;
 
+      // Used to reload sources for all isolates. This supports Hot Reload for
+      // Dart apps. Flutter's DAP handles this command itself (and sends it
+      // through the run daemon) as it needs to perform additional work to
+      // rebuild widgets afterwards.
+      case 'hotReload':
+        await _isolateManager.reloadSources();
+        sendResponse(_noResult);
+        break;
+
       default:
         await super.customRequest(request, args, sendResponse);
     }
@@ -695,6 +746,8 @@
     DisconnectArguments? args,
     void Function() sendResponse,
   ) async {
+    isTerminating = true;
+
     await disconnectImpl();
     await shutdown();
     sendResponse();
@@ -839,6 +892,7 @@
       return;
     }
 
+    isTerminating = true;
     _hasSentTerminatedEvent = true;
     // Always add a leading newline since the last written text might not have
     // had one.
@@ -901,12 +955,13 @@
   /// 'additionalProjectPaths' in the launch arguments. An editor should include
   /// the paths of all open workspace folders in 'additionalProjectPaths' to
   /// support this feature correctly.
-  bool isExternalPackageLibrary(Uri uri) {
+  Future<bool> isExternalPackageLibrary(ThreadInfo thread, Uri uri) async {
     if (!uri.isScheme('package')) {
       return false;
     }
-    final libraryPath = resolvePackageUri(uri);
-    if (libraryPath == null) {
+
+    final packagePath = await thread.resolveUriToPackageLibPath(uri);
+    if (packagePath == null) {
       return false;
     }
 
@@ -914,9 +969,10 @@
     // may have returned different casing (e.g. Windows drive letters). It's
     // almost certain a user wouldn't have a "local" package and an "external"
     // package with paths differing only be case.
-    final libraryPathLower = libraryPath.toLowerCase();
-    return !projectPaths.any((projectPath) =>
-        path.isWithin(projectPath.toLowerCase(), libraryPathLower));
+    final packagePathLower = packagePath.toLowerCase();
+    return !projectPaths
+        .map((projectPath) => projectPath.toLowerCase())
+        .any((projectPath) => path.isWithin(projectPath, packagePathLower));
   }
 
   /// Checks whether this library is from the SDK.
@@ -954,10 +1010,10 @@
   ///
   /// Initial values are provided in the launch arguments, but may be updated
   /// by the `updateDebugOptions` custom request.
-  bool libaryIsDebuggable(Uri uri) {
+  Future<bool> libraryIsDebuggable(ThreadInfo thread, Uri uri) async {
     if (isSdkLibrary(uri)) {
       return _isolateManager.debugSdkLibraries;
-    } else if (isExternalPackageLibrary(uri)) {
+    } else if (await isExternalPackageLibrary(thread, uri)) {
       return _isolateManager.debugExternalPackageLibraries;
     } else {
       return true;
@@ -976,12 +1032,6 @@
     sendResponse();
   }
 
-  /// Resolves a `package: URI` to the real underlying source path.
-  ///
-  /// Returns `null` if no mapping was possible, for example if the package is
-  /// not in the package mapping file.
-  String? resolvePackageUri(Uri uri) => _converter.resolvePackageUri(uri);
-
   /// restart is called by the client when the user invokes a restart (for
   /// example with the button on the debug toolbar).
   ///
@@ -1248,6 +1298,15 @@
           (frame) => frame.kind == vm.FrameKind.kAsyncSuspensionMarker,
         );
 
+        // Pre-resolve all URIs in batch so the call below does not trigger
+        // many requests to the server.
+        final allUris = frames
+            .map((frame) => frame.location?.script?.uri)
+            .whereNotNull()
+            .map(Uri.parse)
+            .toList();
+        await thread.resolveUrisToPathsBatch(allUris);
+
         Future<StackFrame> convert(int index, vm.Frame frame) async {
           return _converter.convertVmToDapStackFrame(
             thread,
@@ -1318,6 +1377,8 @@
     TerminateArguments? args,
     void Function() sendResponse,
   ) async {
+    isTerminating = true;
+
     await terminateImpl();
     await shutdown();
     sendResponse();
@@ -1346,14 +1407,12 @@
 
   /// Sets the package config file to use for `package: URI` resolution.
   ///
-  /// TODO(dantup): Remove this once
-  ///   https://github.com/dart-lang/sdk/issues/45530 is done as it will not be
-  ///   necessary.
+  /// It is no longer necessary to call this method as the package config file
+  /// is no longer used. URI lookups are done via the VM Service.
+  @Deprecated('No longer necessary, URI lookups are done via VM Service')
   void usePackageConfigFile(File packageConfig) {
-    _converter.packageConfig = PackageConfig.parseString(
-      packageConfig.readAsStringSync(),
-      Uri.file(packageConfig.path),
-    );
+    // TODO(dantup): Remove this method after Flutter DA is updated not to use
+    // it.
   }
 
   /// [variablesRequest] is called by the client to request child variables for
@@ -1661,6 +1720,7 @@
   }
 
   Future<void> _handleVmServiceClosed() async {
+    isTerminating = true;
     if (terminateOnVmServiceClose) {
       handleSessionTerminate();
     }
@@ -1767,6 +1827,40 @@
       streamClosed: streamClosedCompleter.future,
     );
   }
+
+  /// Wraps a function with an error handler that handles errors that occur when
+  /// the VM Service/DDS shuts down.
+  ///
+  /// When the debug adapter is terminating, it's possible in-flight requests
+  /// triggered by handlers will fail with "Service Disappeared". This is
+  /// normal and such errors can be ignored, rather than allowed to pass
+  /// uncaught.
+  _StreamEventHandler<T> _wrapHandlerWithErrorHandling<T>(
+    _StreamEventHandler<T> handler,
+  ) {
+    return (data) => _withErrorHandling(() => handler(data));
+  }
+
+  /// Calls a function with an error handler that handles errors that occur when
+  /// the VM Service/DDS shuts down.
+  ///
+  /// When the debug adapter is terminating, it's possible in-flight requests
+  /// will fail with "Service Disappeared". This is normal and such errors can
+  /// be ignored, rather than allowed to pass uncaught.
+  FutureOr<T?> _withErrorHandling<T>(FutureOr<T> Function() func) async {
+    try {
+      return await func();
+    } on vm.RPCError catch (e) {
+      // If we're been asked to shut down while this request was occurring,
+      // it's normal to get kServiceDisappeared so we should handle this
+      // silently.
+      if (isTerminating && e.code == RpcErrorCodes.kServiceDisappeared) {
+        return null;
+      }
+
+      rethrow;
+    }
+  }
 }
 
 /// An implementation of [LaunchRequestArguments] that includes all fields used
@@ -1794,6 +1888,15 @@
   /// the VM or Flutter tool).
   final List<String>? toolArgs;
 
+  /// Arguments to be passed directly to the Dart VM that will run [program].
+  ///
+  /// Unlike [toolArgs] which always go after the complete tool, these args
+  /// always go directly after `dart`:
+  ///
+  ///   - dart {vmAdditionalArgs} {toolArgs}
+  ///   - dart {vmAdditionalArgs} run test:test {toolArgs}
+  final List<String>? vmAdditionalArgs;
+
   final int? vmServicePort;
 
   final bool? enableAsserts;
@@ -1810,17 +1913,39 @@
   /// simplest) way, but prevents the user from being able to type into `stdin`.
   final String? console;
 
+  /// An optional tool to run instead of "dart".
+  ///
+  /// In combination with [customToolReplacesArgs] allows invoking a custom
+  /// tool instead of "dart" to launch scripts/tests. The custom tool must be
+  /// completely compatible with the tool/command it is replacing.
+  ///
+  /// This field should be a full absolute path if the tool may not be available
+  /// in `PATH`.
+  final String? customTool;
+
+  /// The number of arguments to delete from the beginning of the argument list
+  /// when invoking [customTool].
+  ///
+  /// For example, setting [customTool] to `dart_test` and
+  /// `customToolReplacesArgs` to `2` for a test run would invoke
+  /// `dart_test foo_test.dart` instead of `dart run test:test foo_test.dart`.
+  final int? customToolReplacesArgs;
+
   DartLaunchRequestArguments({
     this.noDebug,
     required this.program,
     this.args,
     this.vmServicePort,
     this.toolArgs,
+    this.vmAdditionalArgs,
     this.console,
     this.enableAsserts,
+    this.customTool,
+    this.customToolReplacesArgs,
     Object? restart,
     String? name,
     String? cwd,
+    Map<String, String>? env,
     List<String>? additionalProjectPaths,
     bool? debugSdkLibraries,
     bool? debugExternalPackageLibraries,
@@ -1831,6 +1956,7 @@
           restart: restart,
           name: name,
           cwd: cwd,
+          env: env,
           additionalProjectPaths: additionalProjectPaths,
           debugSdkLibraries: debugSdkLibraries,
           debugExternalPackageLibraries: debugExternalPackageLibraries,
@@ -1844,9 +1970,12 @@
         program = obj['program'] as String,
         args = (obj['args'] as List?)?.cast<String>(),
         toolArgs = (obj['toolArgs'] as List?)?.cast<String>(),
+        vmAdditionalArgs = (obj['vmAdditionalArgs'] as List?)?.cast<String>(),
         vmServicePort = obj['vmServicePort'] as int?,
         console = obj['console'] as String?,
         enableAsserts = obj['enableAsserts'] as bool?,
+        customTool = obj['customTool'] as String?,
+        customToolReplacesArgs = obj['customToolReplacesArgs'] as int?,
         super.fromMap(obj);
 
   @override
@@ -1856,9 +1985,13 @@
         'program': program,
         if (args != null) 'args': args,
         if (toolArgs != null) 'toolArgs': toolArgs,
+        if (vmAdditionalArgs != null) 'vmAdditionalArgs': vmAdditionalArgs,
         if (vmServicePort != null) 'vmServicePort': vmServicePort,
         if (console != null) 'console': console,
         if (enableAsserts != null) 'enableAsserts': enableAsserts,
+        if (customTool != null) 'customTool': customTool,
+        if (customToolReplacesArgs != null)
+          'customToolReplacesArgs': customToolReplacesArgs,
       };
 
   static DartLaunchRequestArguments fromJson(Map<String, Object?> obj) =>
diff --git a/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart b/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
index 3dca392..46e28e3 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_cli_adapter.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'dart:math' as math;
 
 import 'package:path/path.dart' as path;
 import 'package:pedantic/pedantic.dart';
@@ -76,7 +77,6 @@
   /// breakpoints, and resume.
   Future<void> launchImpl() async {
     final args = this.args as DartLaunchRequestArguments;
-    final vmPath = Platform.resolvedExecutable;
     File? vmServiceInfoFile;
 
     final debug = !(args.noDebug ?? false);
@@ -87,6 +87,7 @@
     }
 
     final vmArgs = <String>[
+      ...?args.vmAdditionalArgs,
       if (debug) ...[
         '--enable-vm-service=${args.vmServicePort ?? 0}${ipv6 ? '/::1' : ''}',
         '--pause_isolates_on_start',
@@ -101,6 +102,14 @@
       // editor-spawned debug sessions.
       if (args.enableAsserts ?? true) '--enable-asserts',
     ];
+
+    // Handle customTool and deletion of any arguments for it.
+    final executable = args.customTool ?? Platform.resolvedExecutable;
+    final removeArgs = args.customToolReplacesArgs;
+    if (args.customTool != null && removeArgs != null) {
+      vmArgs.removeRange(0, math.min(removeArgs, vmArgs.length));
+    }
+
     final processArgs = [
       ...vmArgs,
       ...?args.toolArgs,
@@ -108,18 +117,6 @@
       ...?args.args,
     ];
 
-    // Find the package_config file for this script.
-    // TODO(dantup): Remove this once
-    //   https://github.com/dart-lang/sdk/issues/45530 is done as it will not be
-    //   necessary.
-    var possibleRoot = path.isAbsolute(args.program)
-        ? path.dirname(args.program)
-        : path.dirname(path.normalize(path.join(args.cwd ?? '', args.program)));
-    final packageConfig = findPackageConfigFile(possibleRoot);
-    if (packageConfig != null) {
-      this.usePackageConfigFile(packageConfig);
-    }
-
     // If the client supports runInTerminal and args.console is set to either
     // 'terminal' or 'runInTerminal' we won't run the process ourselves, but
     // instead call the client to run it for us (this allows it to run in a
@@ -136,12 +133,22 @@
                 : null
         : null;
 
-    // TODO(dantup): Support passing env to both of these.
-
     if (terminalKind != null) {
-      await launchInEditorTerminal(debug, terminalKind, vmPath, processArgs);
+      await launchInEditorTerminal(
+        debug,
+        terminalKind,
+        executable,
+        processArgs,
+        workingDirectory: args.cwd,
+        env: args.env,
+      );
     } else {
-      await launchAsProcess(vmPath, processArgs);
+      await launchAsProcess(
+        executable,
+        processArgs,
+        workingDirectory: args.cwd,
+        env: args.env,
+      );
     }
 
     // Delay responding until the debugger is connected.
@@ -166,18 +173,6 @@
       return;
     }
 
-    // Find the package_config file for this script.
-    // TODO(dantup): Remove this once
-    //   https://github.com/dart-lang/sdk/issues/45530 is done as it will not be
-    //   necessary.
-    final cwd = args.cwd;
-    if (cwd != null) {
-      final packageConfig = findPackageConfigFile(cwd);
-      if (packageConfig != null) {
-        this.usePackageConfigFile(packageConfig);
-      }
-    }
-
     final uri = vmServiceUri != null
         ? Uri.parse(vmServiceUri)
         : await waitForVmServiceInfoFile(logger, File(vmServiceInfoFile!));
@@ -190,11 +185,13 @@
   Future<void> launchInEditorTerminal(
     bool debug,
     String terminalKind,
-    String vmPath,
-    List<String> processArgs,
-  ) async {
+    String executable,
+    List<String> processArgs, {
+    required String? workingDirectory,
+    required Map<String, String>? env,
+  }) async {
     final args = this.args as DartLaunchRequestArguments;
-    logger?.call('Spawning $vmPath with $processArgs in ${args.cwd}'
+    logger?.call('Spawning $executable with $processArgs in $workingDirectory'
         ' via client ${terminalKind} terminal');
 
     // runInTerminal is a DAP request that goes from server-to-client that
@@ -203,8 +200,9 @@
     // for debugging will rely on the process writing the service-info file that
     // we can detect with the normal watching code.
     final requestArgs = RunInTerminalRequestArguments(
-      args: [vmPath, ...processArgs],
-      cwd: args.cwd ?? path.dirname(args.program),
+      args: [executable, ...processArgs],
+      cwd: workingDirectory ?? path.dirname(args.program),
+      env: env,
       kind: terminalKind,
       title: args.name ?? 'Dart',
     );
@@ -234,12 +232,18 @@
   ///
   /// Output to `stdout`/`stderr` will be sent to the editor using
   /// [OutputEvent]s.
-  Future<void> launchAsProcess(String vmPath, List<String> processArgs) async {
-    logger?.call('Spawning $vmPath with $processArgs in ${args.cwd}');
+  Future<void> launchAsProcess(
+    String executable,
+    List<String> processArgs, {
+    required String? workingDirectory,
+    required Map<String, String>? env,
+  }) async {
+    logger?.call('Spawning $executable with $processArgs in $workingDirectory');
     final process = await Process.start(
-      vmPath,
+      executable,
       processArgs,
-      workingDirectory: args.cwd,
+      workingDirectory: workingDirectory,
+      environment: env,
     );
     _process = process;
     pidsToTerminate.add(process.pid);
diff --git a/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart b/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
index 9e517da..0f67af4 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_test_adapter.dart
@@ -5,8 +5,8 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'dart:math' as math;
 
-import 'package:path/path.dart' as path;
 import 'package:pedantic/pedantic.dart';
 import 'package:vm_service/vm_service.dart' as vm;
 
@@ -73,7 +73,6 @@
   /// breakpoints, and resume.
   Future<void> launchImpl() async {
     final args = this.args as DartLaunchRequestArguments;
-    final vmPath = Platform.resolvedExecutable;
     File? vmServiceInfoFile;
 
     final debug = !(args.noDebug ?? false);
@@ -84,6 +83,7 @@
     }
 
     final vmArgs = <String>[
+      ...?args.vmAdditionalArgs,
       if (debug) ...[
         '--enable-vm-service=${args.vmServicePort ?? 0}${ipv6 ? '/::1' : ''}',
         '--pause_isolates_on_start',
@@ -111,6 +111,14 @@
       '-r',
       'json',
     ];
+
+    // Handle customTool and deletion of any arguments for it.
+    final executable = args.customTool ?? Platform.resolvedExecutable;
+    final removeArgs = args.customToolReplacesArgs;
+    if (args.customTool != null && removeArgs != null) {
+      vmArgs.removeRange(0, math.min(removeArgs, vmArgs.length));
+    }
+
     final processArgs = [
       ...vmArgs,
       ...?args.toolArgs,
@@ -118,25 +126,27 @@
       ...?args.args,
     ];
 
-    // Find the package_config file for this script.
-    // TODO(dantup): Remove this once
-    //   https://github.com/dart-lang/sdk/issues/45530 is done as it will not be
-    //   necessary.
-    var possibleRoot = path.isAbsolute(args.program)
-        ? path.dirname(args.program)
-        : path.dirname(path.normalize(path.join(args.cwd ?? '', args.program)));
-    final packageConfig = findPackageConfigFile(possibleRoot);
-    if (packageConfig != null) {
-      this.usePackageConfigFile(packageConfig);
-    }
-
-    // TODO(dantup): Support passing env to both of these.
-
-    logger?.call('Spawning $vmPath with $processArgs in ${args.cwd}');
-    final process = await Process.start(
-      vmPath,
+    await launchAsProcess(
+      executable,
       processArgs,
       workingDirectory: args.cwd,
+      env: args.env,
+    );
+  }
+
+  /// Launches the test script as a process controlled by the debug adapter.
+  Future<void> launchAsProcess(
+    String executable,
+    List<String> processArgs, {
+    required String? workingDirectory,
+    required Map<String, String>? env,
+  }) async {
+    logger?.call('Spawning $executable with $processArgs in $workingDirectory');
+    final process = await Process.start(
+      executable,
+      processArgs,
+      workingDirectory: workingDirectory,
+      environment: env,
     );
     _process = process;
     pidsToTerminate.add(process.pid);
diff --git a/pkg/dds/lib/src/dap/adapters/mixins.dart b/pkg/dds/lib/src/dap/adapters/mixins.dart
index 3b9991a..b9f307f 100644
--- a/pkg/dds/lib/src/dap/adapters/mixins.dart
+++ b/pkg/dds/lib/src/dap/adapters/mixins.dart
@@ -17,32 +17,13 @@
 mixin PackageConfigUtils {
   /// Find the `package_config.json` file for the program being launched.
   ///
-  /// TODO(dantup): Remove this once
-  ///   https://github.com/dart-lang/sdk/issues/45530 is done as it will not be
-  ///   necessary.
+  /// It is no longer necessary to call this method as the package config file
+  /// is no longer used. URI lookups are done via the VM Service.
+  @Deprecated('No longer necessary, URI lookups are done via VM Service')
   File? findPackageConfigFile(String possibleRoot) {
-    File? packageConfig;
-    while (true) {
-      packageConfig =
-          File(path.join(possibleRoot, '.dart_tool', 'package_config.json'));
-
-      // If this packageconfig exists, use it.
-      if (packageConfig.existsSync()) {
-        break;
-      }
-
-      final parent = path.dirname(possibleRoot);
-
-      // If we can't go up anymore, the search failed.
-      if (parent == possibleRoot) {
-        packageConfig = null;
-        break;
-      }
-
-      possibleRoot = parent;
-    }
-
-    return packageConfig;
+    // TODO(dantup): Remove this method after Flutter DA is updated not to use
+    // it.
+    return null;
   }
 }
 
diff --git a/pkg/dds/lib/src/dap/base_debug_adapter.dart b/pkg/dds/lib/src/dap/base_debug_adapter.dart
index 2d82bbd..215a975 100644
--- a/pkg/dds/lib/src/dap/base_debug_adapter.dart
+++ b/pkg/dds/lib/src/dap/base_debug_adapter.dart
@@ -376,7 +376,7 @@
   /// passes an unused arg so that `Function()` can be passed to a function
   /// accepting `Function<T>(T x)` where `T` happens to be `void`.
   ///
-  /// This allows handlers to simple call sendResponse() where they have no
+  /// This allows handlers to simply call sendResponse() where they have no
   /// return value but need to send a valid response.
   _VoidArgRequestHandler<TArg> _withVoidResponse<TArg>(
     _VoidNoArgRequestHandler<TArg> handler,
diff --git a/pkg/dds/lib/src/dap/isolate_manager.dart b/pkg/dds/lib/src/dap/isolate_manager.dart
index fd2d342..cbf2087 100644
--- a/pkg/dds/lib/src/dap/isolate_manager.dart
+++ b/pkg/dds/lib/src/dap/isolate_manager.dart
@@ -4,8 +4,10 @@
 
 import 'dart:async';
 import 'dart:convert';
+import 'dart:io';
 
 import 'package:collection/collection.dart';
+import 'package:path/path.dart' as path;
 import 'package:vm_service/vm_service.dart' as vm;
 
 import 'adapters/dart.dart';
@@ -53,6 +55,9 @@
   /// [debugExternalPackageLibraries] in one step.
   bool debugExternalPackageLibraries = true;
 
+  /// The root of the Dart SDK containing the VM running the debug adapter.
+  late final String sdkRoot;
+
   /// Tracks breakpoints last provided by the client so they can be sent to new
   /// isolates that appear after initial breakpoints were sent.
   final Map<String, List<SourceBreakpoint>> _clientBreakpointsByUri = {};
@@ -93,7 +98,10 @@
   /// Any leading character matched in place of the dollar is in the first capture.
   final _braceNotPrefixedByDollarOrBackslashPattern = RegExp(r'(^|[^\\\$]){');
 
-  IsolateManager(this._adapter);
+  IsolateManager(this._adapter) {
+    final vmPath = Platform.resolvedExecutable;
+    sdkRoot = path.dirname(path.dirname(vmPath));
+  }
 
   /// A list of all current active isolates.
   ///
@@ -110,7 +118,7 @@
     await Future.wait(_threadsByThreadId.values.map(
       // debuggable libraries is the only thing currently affected by these
       // changable options.
-      (isolate) => _sendLibraryDebuggables(isolate.isolate),
+      (thread) => _sendLibraryDebuggables(thread),
     ));
   }
 
@@ -136,10 +144,7 @@
     vm.Event event, {
     bool resumeIfStarting = true,
   }) async {
-    final isolateId = event.isolate?.id;
-    if (isolateId == null) {
-      return;
-    }
+    final isolateId = event.isolate?.id!;
 
     final eventKind = event.kind;
     if (eventKind == vm.EventKind.kIsolateStart ||
@@ -178,7 +183,7 @@
     final registrationCompleter =
         _isolateRegistrations.putIfAbsent(isolate.id!, () => Completer<void>());
 
-    final info = _threadsByIsolateId.putIfAbsent(
+    final thread = _threadsByIsolateId.putIfAbsent(
       isolate.id!,
       () {
         // The first time we see an isolate, start tracking it.
@@ -194,21 +199,25 @@
 
     // If it's just become runnable (IsolateRunnable), configure the isolate
     // by sending breakpoints etc.
-    if (eventKind == vm.EventKind.kIsolateRunnable && !info.runnable) {
-      info.runnable = true;
-      await _configureIsolate(isolate);
+    if (eventKind == vm.EventKind.kIsolateRunnable && !thread.runnable) {
+      thread.runnable = true;
+      await _configureIsolate(thread);
       registrationCompleter.complete();
     }
 
-    return info;
+    return thread;
+  }
+
+  /// Calls reloadSources for all isolates.
+  Future<void> reloadSources() async {
+    await Future.wait(_threadsByThreadId.values.map(
+      (isolate) => _reloadSources(isolate.isolate),
+    ));
   }
 
   Future<void> resumeIsolate(vm.IsolateRef isolateRef,
       [String? resumeType]) async {
-    final isolateId = isolateRef.id;
-    if (isolateId == null) {
-      return;
-    }
+    final isolateId = isolateRef.id!;
 
     final thread = _threadsByIsolateId[isolateId];
     if (thread == null) {
@@ -271,7 +280,7 @@
 
     // Send the breakpoints to all existing threads.
     await Future.wait(_threadsByThreadId.values
-        .map((isolate) => _sendBreakpoints(isolate.isolate, uri: uri)));
+        .map((thread) => _sendBreakpoints(thread, uri: uri)));
   }
 
   /// Records exception pause mode as one of 'None', 'Unhandled' or 'All'. All
@@ -281,7 +290,7 @@
 
     // Send to all existing threads.
     await Future.wait(_threadsByThreadId.values.map(
-      (isolate) => _sendExceptionPauseMode(isolate.isolate),
+      (thread) => _sendExceptionPauseMode(thread),
     ));
   }
 
@@ -319,12 +328,15 @@
 
   /// Configures a new isolate, setting it's exception-pause mode, which
   /// libraries are debuggable, and sending all breakpoints.
-  Future<void> _configureIsolate(vm.IsolateRef isolate) async {
+  Future<void> _configureIsolate(ThreadInfo thread) async {
+    // Libraries must be set as debuggable _before_ sending breakpoints, or
+    // they may fail for SDK sources.
     await Future.wait([
-      _sendLibraryDebuggables(isolate),
-      _sendExceptionPauseMode(isolate),
-      _sendBreakpoints(isolate),
+      _sendLibraryDebuggables(thread),
+      _sendExceptionPauseMode(thread),
     ], eagerError: true);
+
+    await _sendBreakpoints(thread);
   }
 
   /// Evaluates an expression, returning the result if it is a [vm.InstanceRef]
@@ -413,7 +425,7 @@
     // For PausePostRequest we need to re-send all breakpoints; this happens
     // after a hot restart.
     if (eventKind == vm.EventKind.kPausePostRequest) {
-      await _configureIsolate(isolate);
+      await _configureIsolate(thread);
       if (resumeIfStarting) {
         await resumeThread(thread.threadId);
       }
@@ -492,6 +504,26 @@
     }
   }
 
+  /// Attempts to resolve [uris] to file:/// URIs via the VM Service.
+  ///
+  /// This method calls the VM service directly. Most requests to resolve URIs
+  /// should go through [ThreadInfo]'s resolveXxx methods which perform caching
+  /// of results.
+  Future<List<Uri?>?> _lookupResolvedPackageUris<T extends vm.Response>(
+    vm.IsolateRef isolate,
+    List<Uri> uris,
+  ) async {
+    final isolateId = isolate.id!;
+    final uriStrings = uris.map((uri) => uri.toString()).toList();
+    final res = await _adapter.vmService
+        ?.lookupResolvedPackageUris(isolateId, uriStrings);
+
+    return res?.uris
+        ?.cast<String?>()
+        .map((uri) => uri != null ? Uri.parse(uri) : null)
+        .toList();
+  }
+
   /// Interpolates and prints messages for any log points.
   ///
   /// Log Points are breakpoints with string messages attached. When the VM hits
@@ -527,19 +559,31 @@
     }
   }
 
+  /// Calls reloadSources for the given isolate.
+  Future<void> _reloadSources(vm.IsolateRef isolateRef) async {
+    final service = _adapter.vmService;
+    if (!debug || service == null) {
+      return;
+    }
+
+    final isolateId = isolateRef.id!;
+
+    await service.reloadSources(isolateId);
+  }
+
   /// Sets breakpoints for an individual isolate.
   ///
   /// If [uri] is provided, only breakpoints for that URI will be sent (used
   /// when breakpoints are modified for a single file in the editor). Otherwise
   /// breakpoints for all previously set URIs will be sent (used for
   /// newly-created isolates).
-  Future<void> _sendBreakpoints(vm.IsolateRef isolate, {String? uri}) async {
+  Future<void> _sendBreakpoints(ThreadInfo thread, {String? uri}) async {
     final service = _adapter.vmService;
     if (!debug || service == null) {
       return;
     }
 
-    final isolateId = isolate.id!;
+    final isolateId = thread.isolate.id!;
 
     // If we were passed a single URI, we should send breakpoints only for that
     // (this means the request came from the client), otherwise we should send
@@ -559,8 +603,14 @@
       final newBreakpoints = _clientBreakpointsByUri[uri] ?? const [];
       await Future.forEach<SourceBreakpoint>(newBreakpoints, (bp) async {
         try {
+          // Some file URIs (like SDK sources) need to be converted to
+          // appropriate internal URIs to be able to set breakpoints.
+          final vmUri = await thread.resolvePathToUri(
+            Uri.parse(uri).toFilePath(),
+          );
+
           final vmBp = await service.addBreakpointWithScriptUri(
-              isolateId, uri, bp.line,
+              isolateId, vmUri.toString(), bp.line,
               column: bp.column);
           existingBreakpointsForIsolateAndUri.add(vmBp);
           _clientBreakpointsByVmId[vmBp.id!] = bp;
@@ -575,37 +625,47 @@
   }
 
   /// Sets the exception pause mode for an individual isolate.
-  Future<void> _sendExceptionPauseMode(vm.IsolateRef isolate) async {
+  Future<void> _sendExceptionPauseMode(ThreadInfo thread) async {
     final service = _adapter.vmService;
     if (!debug || service == null) {
       return;
     }
 
-    await service.setExceptionPauseMode(isolate.id!, _exceptionPauseMode);
+    await service.setIsolatePauseMode(
+      thread.isolate.id!,
+      exceptionPauseMode: _exceptionPauseMode,
+    );
   }
 
   /// Calls setLibraryDebuggable for all libraries in the given isolate based
   /// on the debug settings.
-  Future<void> _sendLibraryDebuggables(vm.IsolateRef isolateRef) async {
+  Future<void> _sendLibraryDebuggables(ThreadInfo thread) async {
     final service = _adapter.vmService;
     if (!debug || service == null) {
       return;
     }
 
-    final isolateId = isolateRef.id;
-    if (isolateId == null) {
-      return;
-    }
+    final isolateId = thread.isolate.id!;
 
     final isolate = await service.getIsolate(isolateId);
     final libraries = isolate.libraries;
     if (libraries == null) {
       return;
     }
+
+    // Pre-resolve all URIs in batch so the call below does not trigger
+    // many requests to the server.
+    final allUris = libraries
+        .map((library) => library.uri)
+        .whereNotNull()
+        .map(Uri.parse)
+        .toList();
+    await thread.resolveUrisToPackageLibPathsBatch(allUris);
+
     await Future.wait(libraries.map((library) async {
       final libraryUri = library.uri;
       final isDebuggable = libraryUri != null
-          ? _adapter.libaryIsDebuggable(Uri.parse(libraryUri))
+          ? await _adapter.libraryIsDebuggable(thread, Uri.parse(libraryUri))
           : false;
       await service.setLibraryDebuggable(isolateId, library.id!, isDebuggable);
     }));
@@ -660,14 +720,23 @@
   /// breakpoint or exception that occur early on.
   bool hasBeenStarted = false;
 
-  // The most recent pauseEvent for this isolate.
+  /// The most recent pauseEvent for this isolate.
   vm.Event? pauseEvent;
 
-  // A cache of requests (Futures) to fetch scripts, so that multiple requests
-  // that require scripts (for example looking up locations for stack frames from
-  // tokenPos) can share the same response.
+  /// A cache of requests (Futures) to fetch scripts, so that multiple requests
+  /// that require scripts (for example looking up locations for stack frames from
+  /// tokenPos) can share the same response.
   final _scripts = <String, Future<vm.Script>>{};
 
+  /// A cache of requests (Futures) to resolve URIs to their local file paths.
+  ///
+  /// Used so that multiple requests that require them (for example looking up
+  /// locations for stack frames from tokenPos) can share the same response.
+  ///
+  /// Keys are URIs in string form.
+  /// Values are file paths (not file URIs!).
+  final _resolvedPaths = <String, Future<String?>>{};
+
   /// Whether this isolate has an in-flight resume request that has not yet
   /// been responded to.
   var hasPendingResume = false;
@@ -686,9 +755,207 @@
     return _scripts.putIfAbsent(script.id!, () => getObject<vm.Script>(script));
   }
 
+  /// Resolves a source file path into a URI for the VM.
+  ///
+  /// sdk-path/lib/core/print.dart -> dart:core/print.dart
+  ///
+  /// This is required so that when the user sets a breakpoint in an SDK source
+  /// (which they may have nagivated to via the Analysis Server) we generate a
+  /// vaid URI that the VM would create a breakpoint for.
+  Future<Uri?> resolvePathToUri(String filePath) async {
+    // We don't currently need to call lookupPackageUris because the VM can
+    // handle incoming file:/// URIs for packages, and also the org-dartlang-sdk
+    // URIs directly for SDK sources (we do not need to convert to 'dart:'),
+    // however this method is Future-returning in case this changes in future
+    // and we need to include a call to lookupPackageUris here.
+    return _convertPathToOrgDartlangSdk(filePath) ?? Uri.file(filePath);
+  }
+
+  /// Batch resolves source URIs from the VM to a file path for the package lib
+  /// folder.
+  ///
+  /// This method is more performant than repeatedly calling
+  /// [resolveUrisToPackageLibPath] because it resolves multiple URIs in a
+  /// single request to the VM.
+  ///
+  /// Results are cached and shared with [resolveUrisToPackageLibPath] (and
+  /// [resolveUriToPath]) so it's reasonable to call this method up-front and
+  /// then use [resolveUrisToPackageLibPath] (and [resolveUriToPath]) to read
+  /// the results later.
+  Future<List<String?>> resolveUrisToPackageLibPathsBatch(
+    List<Uri> uris,
+  ) async {
+    final results = await resolveUrisToPathsBatch(uris);
+    return results
+        .mapIndexed((i, filePath) => _trimPathToLibFolder(filePath, uris[i]))
+        .toList();
+  }
+
+  /// Batch resolves source URIs from the VM to a file path.
+  ///
+  /// This method is more performant than repeatedly calling [resolveUriToPath]
+  /// because it resolves multiple URIs in a single request to the VM.
+  ///
+  /// Results are cached and shared with [resolveUriToPath] so it's reasonable
+  /// to call this method up-front and then use [resolveUriToPath] to read
+  /// the results later.
+  Future<List<String?>> resolveUrisToPathsBatch(List<Uri> uris) async {
+    // First find the set of URIs we don't already have results for.
+    final requiredUris = uris
+        .where((uri) => !uri.isScheme('file'))
+        .where((uri) => !_resolvedPaths.containsKey(uri.toString()))
+        .toSet() // Take only distinct values.
+        .toList();
+
+    if (requiredUris.isNotEmpty) {
+      // Populate completers for each URI before we start the request so that
+      // concurrent calls to this method will not start their own requests.
+      final completers = Map<String, Completer<String?>>.fromEntries(
+        requiredUris.map((uri) => MapEntry('$uri', Completer<String?>())),
+      );
+      completers.forEach(
+        (uri, completer) => _resolvedPaths[uri] = completer.future,
+      );
+      final results =
+          await _manager._lookupResolvedPackageUris(isolate, requiredUris);
+      if (results == null) {
+        // If no result, all of the results are null.
+        completers.forEach((uri, completer) => completer.complete(null));
+      } else {
+        // Otherwise, complete each one by index with the corresponding value.
+        results.map(_convertUriToFilePath).forEachIndexed((i, result) {
+          final uri = requiredUris[i].toString();
+          completers[uri]!.complete(result);
+        });
+      }
+    }
+
+    // Finally, assemble a list of the values by using the cached futures and
+    // the original list. Any non-file URI is guaranteed to be in [_resolvedPaths]
+    // because they were either filtered out of [requiredUris] because they were
+    // already there, or we then populated completers for them above.
+    final futures = uris.map((uri) async {
+      return uri.isScheme('file')
+          ? uri.toFilePath()
+          : await _resolvedPaths[uri.toString()]!;
+    });
+    return Future.wait(futures);
+  }
+
+  /// Resolves a source URI to a file path for the lib folder of its package.
+  ///
+  /// package:foo/a/b/c/d.dart -> /code/packages/foo/lib
+  ///
+  /// This method is an optimisation over calling [resolveUriToPath] where only
+  /// the package root is required (for example when determining whether a
+  /// package is within the users workspace). This method allows results to be
+  /// cached per-package to avoid hitting the VM Service for each individual
+  /// library within a package.
+  Future<String?> resolveUriToPackageLibPath(Uri uri) async {
+    final result = await resolveUrisToPackageLibPathsBatch([uri]);
+    return result.first;
+  }
+
+  /// Resolves a source URI from the VM to a file path.
+  ///
+  /// dart:core/print.dart -> sdk-path/lib/core/print.dart
+  ///
+  /// This is required so that when the user stops (or navigates via a stack
+  /// frame) we open the same file on their local disk. If we downloaded the
+  /// source from the VM, they would end up seeing two copies of files (and they
+  /// would each have their own breakpoints) which can be confusing.
+  Future<String?> resolveUriToPath(Uri uri) async {
+    final result = await resolveUrisToPathsBatch([uri]);
+    return result.first;
+  }
+
   /// Stores some basic data indexed by an integer for use in "reference" fields
   /// that are round-tripped to the client.
   int storeData(Object data) => _manager.storeData(this, data);
+
+  /// Converts a URI in the form org-dartlang-sdk:///sdk/lib/collection/hash_set.dart
+  /// to a local file path based on the current SDK.
+  String? _convertOrgDartlangSdkToPath(Uri uri) {
+    // org-dartlang-sdk URIs can be in multiple forms:
+    //
+    //   - org-dartlang-sdk:///sdk/lib/collection/hash_set.dart
+    //   - org-dartlang-sdk:///runtime/lib/convert_patch.dart
+    //
+    // We currently only handle the sdk folder, as we don't know which runtime
+    // is being used (this code is shared) and do not want to map to the wrong
+    // sources.
+    if (uri.pathSegments.isNotEmpty && uri.pathSegments.first == 'sdk') {
+      // TODO(dantup): Do we need to worry about this content not matching
+      //   up with what's local (eg. for Flutter the VM running the app is
+      //   on another device to the VM running this DA).
+      final sdkRoot = _manager.sdkRoot;
+      return path.joinAll([sdkRoot, ...uri.pathSegments.skip(1)]);
+    }
+
+    return null;
+  }
+
+  /// Converts a file path inside the current SDK root into a URI in the form
+  /// org-dartlang-sdk:///sdk/lib/collection/hash_set.dart.
+  Uri? _convertPathToOrgDartlangSdk(String input) {
+    final sdkRoot = _manager.sdkRoot;
+    if (path.isWithin(sdkRoot, input)) {
+      final relative = path.relative(input, from: sdkRoot);
+      return Uri(
+        scheme: 'org-dartlang-sdk',
+        host: '',
+        pathSegments: ['sdk', ...path.split(relative)],
+      );
+    }
+
+    return null;
+  }
+
+  /// Converts a URI to a file path.
+  ///
+  /// Supports file:// URIs and org-dartlang-sdk:// URIs.
+  String? _convertUriToFilePath(Uri? input) {
+    if (input == null) {
+      return null;
+    } else if (input.isScheme('file')) {
+      return input.toFilePath();
+    } else if (input.isScheme('org-dartlang-sdk')) {
+      return _convertOrgDartlangSdkToPath(input);
+    } else {
+      return null;
+    }
+  }
+
+  /// Helper to remove a libraries path from the a file path so it points at the
+  /// lib folder.
+  ///
+  /// [uri] should be the equivalent package: URI and is used to know how many
+  /// segments to remove from the file path to get to the lib folder.
+  String? _trimPathToLibFolder(String? filePath, Uri uri) {
+    if (filePath == null) {
+      return null;
+    }
+
+    final fileUri = Uri.file(filePath);
+
+    // Track how many segments from the path are from the lib folder to the
+    // library that will need to be removed later.
+    final libraryPathSegments = uri.pathSegments.length - 1;
+
+    // It should never be the case that the returned value doesn't have at
+    // least as many segments as the path of the URI.
+    assert(fileUri.pathSegments.length > libraryPathSegments);
+    if (fileUri.pathSegments.length <= libraryPathSegments) {
+      return filePath;
+    }
+
+    // Strip off the correct number of segments to the resulting path points
+    // to the root of the package:/ URI.
+    final keepSegments = fileUri.pathSegments.length - libraryPathSegments;
+    return fileUri
+        .replace(pathSegments: fileUri.pathSegments.sublist(0, keepSegments))
+        .toFilePath();
+  }
 }
 
 class _StoredData {
diff --git a/pkg/dds/lib/src/dap/protocol_converter.dart b/pkg/dds/lib/src/dap/protocol_converter.dart
index a3e836e..0bedd50 100644
--- a/pkg/dds/lib/src/dap/protocol_converter.dart
+++ b/pkg/dds/lib/src/dap/protocol_converter.dart
@@ -6,7 +6,6 @@
 import 'dart:io';
 
 import 'package:collection/collection.dart';
-import 'package:package_config/package_config_types.dart';
 import 'package:path/path.dart' as path;
 import 'package:vm_service/vm_service.dart' as vm;
 
@@ -26,11 +25,6 @@
   /// the debug session.
   final DartDebugAdapter _adapter;
 
-  /// Temporary PackageConfig used for resolving package: URIs.
-  /// TODO(dantup): Replace this implementation with one that calls the VM
-  ///   Service once https://github.com/dart-lang/sdk/issues/45530 is done.
-  PackageConfig packageConfig = PackageConfig.empty;
-
   ProtocolConverter(this._adapter);
 
   /// Converts an absolute path to one relative to the cwd used to launch the
@@ -388,13 +382,15 @@
     final tokenPos = location.tokenPos;
     final scriptRefUri = scriptRef?.uri;
     final uri = scriptRefUri != null ? Uri.parse(scriptRefUri) : null;
+    final uriIsDart = uri?.isScheme('dart') ?? false;
     final uriIsPackage = uri?.isScheme('package') ?? false;
-    final sourcePath = uri != null ? await convertVmUriToSourcePath(uri) : null;
+    final sourcePath = uri != null ? await thread.resolveUriToPath(uri) : null;
     var canShowSource = sourcePath != null && File(sourcePath).existsSync();
 
     // Download the source if from a "dart:" uri.
     int? sourceReference;
-    if (uri != null &&
+    if (!canShowSource &&
+        uri != null &&
         (uri.isScheme('dart') || uri.isScheme('org-dartlang-app')) &&
         scriptRef != null) {
       sourceReference = thread.storeData(scriptRef);
@@ -416,17 +412,18 @@
     // SDK and debugSdkLibraries=false) then we should also mark it as
     // deemphasized so that the editor can jump up the stack to the first frame
     // of debuggable code.
-    final isDebuggable = uri != null && _adapter.libaryIsDebuggable(uri);
+    final isDebuggable =
+        uri != null && await _adapter.libraryIsDebuggable(thread, uri);
     final presentationHint = isDebuggable ? null : 'deemphasize';
     final origin = uri != null && _adapter.isSdkLibrary(uri)
         ? 'from the SDK'
-        : uri != null && _adapter.isExternalPackageLibrary(uri)
+        : uri != null && await _adapter.isExternalPackageLibrary(thread, uri)
             ? 'from external packages'
             : null;
 
     final source = canShowSource
         ? dap.Source(
-            name: uriIsPackage
+            name: uriIsPackage || uriIsDart
                 ? uri!.toString()
                 : sourcePath != null
                     ? convertToRelativePath(sourcePath)
@@ -455,22 +452,6 @@
     );
   }
 
-  /// Converts the source URI from the VM to a file path.
-  ///
-  /// This is required so that when the user stops (or navigates via a stack
-  /// frame) we open the same file on their local disk. If we downloaded the
-  /// source from the VM, they would end up seeing two copies of files (and they
-  /// would each have their own breakpoints) which can be confusing.
-  Future<String?> convertVmUriToSourcePath(Uri uri) async {
-    if (uri.isScheme('file')) {
-      return uri.toFilePath();
-    } else if (uri.isScheme('package')) {
-      return resolvePackageUri(uri);
-    } else {
-      return null;
-    }
-  }
-
   /// Whether [kind] is a simple kind, and does not need to be mapped to a variable.
   bool isSimpleKind(String? kind) {
     return kind == 'String' ||
@@ -482,19 +463,6 @@
         kind == 'Closure';
   }
 
-  /// Resolves a `package: URI` to the real underlying source path.
-  ///
-  /// Returns `null` if no mapping was possible, for example if the package is
-  /// not in the package mapping file.
-  String? resolvePackageUri(Uri uri) {
-    // TODO(dantup): Replace this implementation with one that calls the VM
-    //   Service once https://github.com/dart-lang/sdk/issues/45530 is done.
-    // This implementation makes assumptions about the package file being used
-    // that might not be correct (for example if the user uses the --packages
-    // flag).
-    return packageConfig.resolve(uri)?.toFilePath();
-  }
-
   /// Invokes the toString() method on a [vm.InstanceRef] and converts the
   /// response to a user-friendly display string.
   ///
diff --git a/pkg/dds/lib/src/dap/protocol_stream_transformers.dart b/pkg/dds/lib/src/dap/protocol_stream_transformers.dart
index 424fa84..f166e55 100644
--- a/pkg/dds/lib/src/dap/protocol_stream_transformers.dart
+++ b/pkg/dds/lib/src/dap/protocol_stream_transformers.dart
@@ -87,8 +87,14 @@
 
   /// Decodes [buffer] into a String and returns the 'Content-Length' header value.
   static ProtocolHeaders _parseHeaders(List<int> buffer) {
-    // Headers are specified as always ASCII in LSP.
-    final asString = ascii.decode(buffer);
+    final String asString;
+    try {
+      // Headers are specified as always ASCII in LSP.
+      asString = ascii.decode(buffer);
+    } on FormatException {
+      throw FormatException('Unable to decode headers with ascii. '
+          'The stream has utf8 content:\n${utf8.decode(buffer)}');
+    }
     final headers = asString.split('\r\n');
     final lengthHeader =
         headers.firstWhere((h) => h.startsWith('Content-Length'));
diff --git a/pkg/dds/lib/src/isolate_manager.dart b/pkg/dds/lib/src/isolate_manager.dart
index 7522183..7808b2a 100644
--- a/pkg/dds/lib/src/isolate_manager.dart
+++ b/pkg/dds/lib/src/isolate_manager.dart
@@ -110,13 +110,14 @@
   /// Should always be called after an isolate is resumed.
   void clearResumeApprovals() => _resumeApprovalsByName.clear();
 
-  Map<String, dynamic> getCachedCpuSamples(String userTag) {
+  Future<Map<String, dynamic>> getCachedCpuSamples(String userTag) async {
     final repo = cpuSamplesManager.cpuSamplesCaches[userTag];
     if (repo == null) {
       throw json_rpc.RpcException.invalidParams(
         'CPU sample caching is not enabled for tag: "$userTag"',
       );
     }
+    await repo.populateFunctionDetails(isolateManager.dds, id);
     return repo.toJson();
   }
 
@@ -283,14 +284,15 @@
     );
   }
 
-  Map<String, dynamic> getCachedCpuSamples(json_rpc.Parameters parameters) {
+  Future<Map<String, dynamic>> getCachedCpuSamples(
+      json_rpc.Parameters parameters) async {
     final isolateId = parameters['isolateId'].asString;
     if (!isolates.containsKey(isolateId)) {
       return RPCResponses.collectedSentinel;
     }
     final isolate = isolates[isolateId]!;
     final userTag = parameters['userTag'].asString;
-    return isolate.getCachedCpuSamples(userTag);
+    return await isolate.getCachedCpuSamples(userTag);
   }
 
   /// Forwards a `resume` request to the VM service.
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index bafc2dc..ef5124d 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
 
-version: 2.1.4
+version: 2.1.5
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
 
@@ -16,7 +16,6 @@
   devtools_shared: ^2.3.0
   json_rpc_2: ^3.0.0
   meta: ^1.1.8
-  package_config: ^2.0.0
   path: ^1.8.0
   pedantic: ^1.7.0
   shelf: ^1.0.0
@@ -25,7 +24,7 @@
   shelf_web_socket: ^1.0.0
   sse: ^4.0.0
   stream_channel: ^2.0.0
-  vm_service: ^7.2.0
+  vm_service: ^7.5.0
   web_socket_channel: ^2.0.0
 
 dev_dependencies:
diff --git a/pkg/dds/test/dap/dart_cli_test.dart b/pkg/dds/test/dap/dart_cli_test.dart
new file mode 100644
index 0000000..d07dc37
--- /dev/null
+++ b/pkg/dds/test/dap/dart_cli_test.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:dds/dap.dart';
+import 'package:test/test.dart';
+
+import 'mocks.dart';
+
+main() {
+  group('dart cli adapter', () {
+    test('includes vmAdditionalArgs', () async {
+      final adapter = MockDartCliDebugAdapter();
+      final responseCompleter = Completer<void>();
+      final request = MockRequest();
+      final args = DartLaunchRequestArguments(
+        program: 'foo.dart',
+        vmAdditionalArgs: ['vm_arg'],
+        noDebug: true,
+      );
+
+      await adapter.configurationDoneRequest(request, null, () {});
+      await adapter.launchRequest(request, args, responseCompleter.complete);
+      await responseCompleter.future;
+
+      expect(adapter.executable, equals(Platform.resolvedExecutable));
+      expect(adapter.processArgs, containsAllInOrder(['vm_arg', 'foo.dart']));
+    });
+
+    test('includes toolArgs', () async {
+      final adapter = MockDartCliDebugAdapter();
+      final responseCompleter = Completer<void>();
+      final request = MockRequest();
+      final args = DartLaunchRequestArguments(
+        program: 'foo.dart',
+        toolArgs: ['tool_arg'],
+        noDebug: true,
+      );
+
+      await adapter.configurationDoneRequest(request, null, () {});
+      await adapter.launchRequest(request, args, responseCompleter.complete);
+      await responseCompleter.future;
+
+      expect(adapter.executable, equals(Platform.resolvedExecutable));
+      expect(adapter.processArgs, containsAllInOrder(['tool_arg', 'foo.dart']));
+    });
+
+    test('includes env', () async {
+      final adapter = MockDartCliDebugAdapter();
+      final responseCompleter = Completer<void>();
+      final request = MockRequest();
+      final args = DartLaunchRequestArguments(
+        program: 'foo.dart',
+        env: {
+          'ENV1': 'VAL1',
+          'ENV2': 'VAL2',
+        },
+        noDebug: true,
+      );
+
+      await adapter.configurationDoneRequest(request, null, () {});
+      await adapter.launchRequest(request, args, responseCompleter.complete);
+      await responseCompleter.future;
+
+      expect(adapter.executable, equals(Platform.resolvedExecutable));
+      expect(adapter.env!['ENV1'], 'VAL1');
+      expect(adapter.env!['ENV2'], 'VAL2');
+    });
+
+    group('includes customTool', () {
+      test('with no args replaced', () async {
+        final adapter = MockDartCliDebugAdapter();
+        final responseCompleter = Completer<void>();
+        final request = MockRequest();
+        final args = DartLaunchRequestArguments(
+          program: 'foo.dart',
+          customTool: '/custom/dart',
+          noDebug: true,
+          enableAsserts: true, // to check args are still passed through
+        );
+
+        await adapter.configurationDoneRequest(request, null, () {});
+        await adapter.launchRequest(request, args, responseCompleter.complete);
+        await responseCompleter.future;
+
+        expect(adapter.executable, equals('/custom/dart'));
+        // args should be in-tact
+        expect(adapter.processArgs, contains('--enable-asserts'));
+      });
+
+      test('with all args replaced', () async {
+        final adapter = MockDartCliDebugAdapter();
+        final responseCompleter = Completer<void>();
+        final request = MockRequest();
+        final args = DartLaunchRequestArguments(
+          program: 'foo.dart',
+          customTool: '/custom/dart',
+          customToolReplacesArgs: 9999, // replaces all built-in args
+          noDebug: true,
+          enableAsserts: true, // should not be in args
+          toolArgs: ['tool_args'], // should still be in args
+        );
+
+        await adapter.configurationDoneRequest(request, null, () {});
+        await adapter.launchRequest(request, args, responseCompleter.complete);
+        await responseCompleter.future;
+
+        expect(adapter.executable, equals('/custom/dart'));
+        // normal built-in args are replaced by customToolReplacesArgs, but
+        // user-provided toolArgs are not.
+        expect(adapter.processArgs, isNot(contains('--enable-asserts')));
+        expect(adapter.processArgs, contains('tool_args'));
+      });
+    });
+  });
+}
diff --git a/pkg/dds/test/dap/dart_test_test.dart b/pkg/dds/test/dap/dart_test_test.dart
new file mode 100644
index 0000000..defba7d
--- /dev/null
+++ b/pkg/dds/test/dap/dart_test_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:dds/dap.dart';
+import 'package:test/test.dart';
+
+import 'mocks.dart';
+
+main() {
+  group('dart test adapter', () {
+    test('includes vmAdditionalArgs before run test:test', () async {
+      final adapter = MockDartTestDebugAdapter();
+      final responseCompleter = Completer<void>();
+      final request = MockRequest();
+      final args = DartLaunchRequestArguments(
+        program: 'foo.dart',
+        vmAdditionalArgs: ['vm_arg'],
+        noDebug: true,
+      );
+
+      await adapter.configurationDoneRequest(request, null, () {});
+      await adapter.launchRequest(request, args, responseCompleter.complete);
+      await responseCompleter.future;
+
+      expect(adapter.executable, equals(Platform.resolvedExecutable));
+      expect(
+        adapter.processArgs,
+        containsAllInOrder(['vm_arg', 'run', 'test:test', 'foo.dart']),
+      );
+    });
+
+    test('includes toolArgs after run test:test', () async {
+      final adapter = MockDartTestDebugAdapter();
+      final responseCompleter = Completer<void>();
+      final request = MockRequest();
+      final args = DartLaunchRequestArguments(
+        program: 'foo.dart',
+        toolArgs: ['tool_arg'],
+        noDebug: true,
+      );
+
+      await adapter.configurationDoneRequest(request, null, () {});
+      await adapter.launchRequest(request, args, responseCompleter.complete);
+      await responseCompleter.future;
+
+      expect(adapter.executable, equals(Platform.resolvedExecutable));
+      expect(
+        adapter.processArgs,
+        containsAllInOrder(['run', 'test:test', 'tool_arg', 'foo.dart']),
+      );
+    });
+
+    test('includes env', () async {
+      final adapter = MockDartTestDebugAdapter();
+      final responseCompleter = Completer<void>();
+      final request = MockRequest();
+      final args = DartLaunchRequestArguments(
+        program: 'foo.dart',
+        env: {
+          'ENV1': 'VAL1',
+          'ENV2': 'VAL2',
+        },
+        noDebug: true,
+      );
+
+      await adapter.configurationDoneRequest(request, null, () {});
+      await adapter.launchRequest(request, args, responseCompleter.complete);
+      await responseCompleter.future;
+
+      expect(adapter.executable, equals(Platform.resolvedExecutable));
+      expect(adapter.env!['ENV1'], 'VAL1');
+      expect(adapter.env!['ENV2'], 'VAL2');
+    });
+
+    group('includes customTool', () {
+      test('with no args replaced', () async {
+        final adapter = MockDartTestDebugAdapter();
+        final responseCompleter = Completer<void>();
+        final request = MockRequest();
+        final args = DartLaunchRequestArguments(
+          program: 'foo.dart',
+          customTool: '/custom/dart',
+          noDebug: true,
+        );
+
+        await adapter.configurationDoneRequest(request, null, () {});
+        await adapter.launchRequest(request, args, responseCompleter.complete);
+        await responseCompleter.future;
+
+        expect(adapter.executable, equals('/custom/dart'));
+        // args should be in-tact
+        expect(adapter.processArgs, containsAllInOrder(['run', 'test:test']));
+      });
+
+      test('with all args replaced', () async {
+        final adapter = MockDartTestDebugAdapter();
+        final responseCompleter = Completer<void>();
+        final request = MockRequest();
+        final args = DartLaunchRequestArguments(
+          program: 'foo.dart',
+          customTool: '/custom/dart',
+          customToolReplacesArgs: 9999, // replaces all built-in args
+          noDebug: true,
+          toolArgs: ['tool_args'], // should still be in args
+        );
+
+        await adapter.configurationDoneRequest(request, null, () {});
+        await adapter.launchRequest(request, args, responseCompleter.complete);
+        await responseCompleter.future;
+
+        expect(adapter.executable, equals('/custom/dart'));
+        // normal built-in args are replaced by customToolReplacesArgs, but
+        // user-provided toolArgs are not.
+        expect(
+          adapter.processArgs,
+          isNot(containsAllInOrder(['run', 'test:test'])),
+        );
+        expect(adapter.processArgs, contains('tool_args'));
+      });
+    });
+  });
+}
diff --git a/pkg/dds/test/dap/integration/debug_breakpoints_test.dart b/pkg/dds/test/dap/integration/debug_breakpoints_test.dart
index 8aee55c..03475cb 100644
--- a/pkg/dds/test/dap/integration/debug_breakpoints_test.dart
+++ b/pkg/dds/test/dap/integration/debug_breakpoints_test.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
 import 'test_client.dart';
@@ -24,6 +27,18 @@
       await client.hitBreakpoint(testFile, breakpointLine);
     });
 
+    test('stops at a line breakpoint in the SDK set via local sources',
+        () async {
+      final client = dap.client;
+      final testFile = dap.createTestFile(simpleBreakpointProgram);
+
+      // Add the breakpoint to the first line inside the SDK's print function.
+      final sdkFile = File(path.join(sdkRoot, 'lib', 'core', 'print.dart'));
+      final breakpointLine = lineWith(sdkFile, 'print(Object? object) {') + 1;
+
+      await client.hitBreakpoint(sdkFile, breakpointLine, entryFile: testFile);
+    });
+
     test('stops at a line breakpoint and can be resumed', () async {
       final client = dap.client;
       final testFile = dap.createTestFile(simpleBreakpointProgram);
diff --git a/pkg/dds/test/dap/integration/debug_test.dart b/pkg/dds/test/dap/integration/debug_test.dart
index 6e7565b..6655b58 100644
--- a/pkg/dds/test/dap/integration/debug_test.dart
+++ b/pkg/dds/test/dap/integration/debug_test.dart
@@ -2,9 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:io';
 
 import 'package:dds/src/dap/protocol_generated.dart';
+import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
 import 'test_client.dart';
@@ -158,6 +160,87 @@
       // Source code should contain the implementation/signature of print().
       final source = await client.getValidSource(topFrame.source!);
       expect(source.content, contains('void print(Object? object) {'));
+      // Skipped because this test is not currently valid as source for print
+      // is mapped to local sources.
+    }, skip: true);
+
+    test('can map SDK source code to a local path', () async {
+      final client = dap.client;
+      final testFile = dap.createTestFile(simpleBreakpointProgram);
+      final breakpointLine = lineWith(testFile, breakpointMarker);
+
+      // Hit the initial breakpoint.
+      final stop = await dap.client.hitBreakpoint(
+        testFile,
+        breakpointLine,
+        launch: () => client.launch(
+          testFile.path,
+          debugSdkLibraries: true,
+        ),
+      );
+
+      // Step in to go into print.
+      final responses = await Future.wait([
+        client.expectStop('step', sourceName: 'dart:core/print.dart'),
+        client.stepIn(stop.threadId!),
+      ], eagerError: true);
+      final stopResponse = responses.first as StoppedEventBody;
+
+      // Fetch the top stack frame (which should be inside print).
+      final stack = await client.getValidStack(
+        stopResponse.threadId!,
+        startFrame: 0,
+        numFrames: 1,
+      );
+      final topFrame = stack.stackFrames.first;
+
+      // SDK sources that have been mapped have no sourceReference but a path.
+      expect(
+        topFrame.source!.path,
+        equals(path.join(sdkRoot, 'lib', 'core', 'print.dart')),
+      );
+      expect(topFrame.source!.sourceReference, isNull);
+    });
+
+    test('can shutdown during startup', () async {
+      final testFile = dap.createTestFile(simpleArgPrintingProgram);
+
+      // Terminate the app immediately upon recieving the first Thread event.
+      // The DAP is also responding to this event to configure the isolate (eg.
+      // set breakpoints and exception pause behaviour) and will cause it to
+      // receive "Service has disappeared" responses if these are in-flight as
+      // the process terminates. These should not go unhandled since they are
+      // normal during shutdown.
+      unawaited(dap.client.event('thread').then((_) => dap.client.terminate()));
+      await dap.client.start(file: testFile);
+    });
+
+    test('can hot reload', () async {
+      const originalText = 'ORIGINAL TEXT';
+      const newText = 'NEW TEXT';
+
+      // Create a script that prints 'ORIGINAL TEXT'.
+      final testFile = dap.createTestFile(stringPrintingProgram(originalText));
+
+      // Start the program and wait for 'ORIGINAL TEXT' to be printed.
+      await Future.wait([
+        dap.client.initialize(),
+        dap.client.launch(testFile.path),
+      ], eagerError: true);
+
+      // Expect the original text.
+      await dap.client.outputEvents
+          .firstWhere((event) => event.output.trim() == originalText);
+
+      // Update the file and hot reload.
+      testFile.writeAsStringSync(stringPrintingProgram(newText));
+      await dap.client.hotReload();
+
+      // Expect the new text.
+      await dap.client.outputEvents
+          .firstWhere((event) => event.output.trim() == newText);
+
+      await dap.client.terminate();
     });
     // These tests can be slow due to starting up the external server process.
   }, timeout: Timeout.none);
diff --git a/pkg/dds/test/dap/integration/test_client.dart b/pkg/dds/test/dap/integration/test_client.dart
index 66f44da..d960bec 100644
--- a/pkg/dds/test/dap/integration/test_client.dart
+++ b/pkg/dds/test/dap/integration/test_client.dart
@@ -148,7 +148,7 @@
       sendRequest(ContinueArguments(threadId: threadId));
 
   /// Sends a custom request to the server and waits for a response.
-  Future<Response> custom(String name, Object? args) async {
+  Future<Response> custom(String name, [Object? args]) async {
     return sendRequest(args, overrideCommand: name);
   }
 
@@ -191,6 +191,11 @@
     _serverRequestHandlers[request] = handler;
   }
 
+  /// Send a custom 'hotReload' request to the server.
+  Future<Response> hotReload() async {
+    return custom('hotReload');
+  }
+
   /// Send an initialize request to the server.
   ///
   /// This occurs before the request to start running/debugging a script and is
@@ -399,7 +404,7 @@
       } else {
         completer.completeError(message);
       }
-    } else if (message is Event) {
+    } else if (message is Event && !_eventController.isClosed) {
       _eventController.add(message);
 
       // When we see a terminated event, close the event stream so if any
@@ -483,11 +488,13 @@
   Future<StoppedEventBody> hitBreakpoint(
     File file,
     int line, {
+    File? entryFile,
     String? condition,
     String? cwd,
     List<String>? args,
     Future<Response> Function()? launch,
   }) async {
+    entryFile ??= file;
     final stop = expectStop('breakpoint', file: file, line: line);
 
     await Future.wait([
@@ -498,7 +505,7 @@
           breakpoints: [SourceBreakpoint(line: line, condition: condition)],
         ),
       ),
-      launch?.call() ?? this.launch(file.path, cwd: cwd, args: args),
+      launch?.call() ?? this.launch(entryFile.path, cwd: cwd, args: args),
     ], eagerError: true);
 
     return stop;
diff --git a/pkg/dds/test/dap/integration/test_scripts.dart b/pkg/dds/test/dap/integration/test_scripts.dart
index 2b24727..59bc718 100644
--- a/pkg/dds/test/dap/integration/test_scripts.dart
+++ b/pkg/dds/test/dap/integration/test_scripts.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:convert';
+
 import 'package:test/test.dart';
 
 /// A marker used in some test scripts/tests for where to set breakpoints.
@@ -53,6 +55,24 @@
   }
 ''';
 
+/// Returns a simple Dart script that prints the provided string repeatedly.
+String stringPrintingProgram(String text) {
+  // jsonEncode the string to get it into a quoted/escaped form that can be
+  // embedded in the string.
+  final encodedTextString = jsonEncode(text);
+  return '''
+  import 'dart:async';
+
+  main() async {
+    Timer.periodic(Duration(milliseconds: 10), (_) => printSomething());
+  }
+
+  void printSomething() {
+    print($encodedTextString);
+  }
+''';
+}
+
 /// A simple async Dart script that when stopped at the line of '// BREAKPOINT'
 /// will contain multiple stack frames across some async boundaries.
 const simpleAsyncProgram = '''
diff --git a/pkg/dds/test/dap/integration/test_support.dart b/pkg/dds/test/dap/integration/test_support.dart
index 9201798..d4c2a8b 100644
--- a/pkg/dds/test/dap/integration/test_support.dart
+++ b/pkg/dds/test/dap/integration/test_support.dart
@@ -43,6 +43,9 @@
 /// by the VM when not using --write-service-info.
 final vmServiceBannerPattern = RegExp(r'Observatory listening on ([^\s]+)\s');
 
+/// The root of the SDK containing the current running VM.
+final sdkRoot = path.dirname(path.dirname(Platform.resolvedExecutable));
+
 /// Expects the lines in [actual] to match the relevant matcher in [expected],
 /// ignoring differences in line endings and trailing whitespace.
 void expectLines(String actual, List<Object> expected) {
diff --git a/pkg/dds/test/dap/mocks.dart b/pkg/dds/test/dap/mocks.dart
new file mode 100644
index 0000000..9afe079
--- /dev/null
+++ b/pkg/dds/test/dap/mocks.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:dds/dap.dart';
+import 'package:dds/src/dap/adapters/dart_cli_adapter.dart';
+import 'package:dds/src/dap/adapters/dart_test_adapter.dart';
+
+/// A [DartCliDebugAdapter] that captures information about the process that
+/// will be launched.
+class MockDartCliDebugAdapter extends DartCliDebugAdapter {
+  final StreamSink<List<int>> stdin;
+  final Stream<List<int>> stdout;
+
+  late bool launchedInTerminal;
+  late String executable;
+  late List<String> processArgs;
+  late String? workingDirectory;
+  late Map<String, String>? env;
+
+  factory MockDartCliDebugAdapter() {
+    final stdinController = StreamController<List<int>>();
+    final stdoutController = StreamController<List<int>>();
+    final channel = ByteStreamServerChannel(
+        stdinController.stream, stdoutController.sink, null);
+
+    return MockDartCliDebugAdapter._(
+        stdinController.sink, stdoutController.stream, channel);
+  }
+
+  MockDartCliDebugAdapter._(
+      this.stdin, this.stdout, ByteStreamServerChannel channel)
+      : super(channel);
+
+  Future<void> launchAsProcess(
+    String executable,
+    List<String> processArgs, {
+    required String? workingDirectory,
+    required Map<String, String>? env,
+  }) async {
+    this.launchedInTerminal = false;
+    this.executable = executable;
+    this.processArgs = processArgs;
+    this.workingDirectory = workingDirectory;
+    this.env = env;
+  }
+
+  Future<void> launchInEditorTerminal(
+    bool debug,
+    String terminalKind,
+    String executable,
+    List<String> processArgs, {
+    required String? workingDirectory,
+    required Map<String, String>? env,
+  }) async {
+    this.launchedInTerminal = true;
+    this.executable = executable;
+    this.processArgs = processArgs;
+    this.workingDirectory = workingDirectory;
+    this.env = env;
+  }
+}
+
+/// A [DartTestDebugAdapter] that captures information about the process that
+/// will be launched.
+class MockDartTestDebugAdapter extends DartTestDebugAdapter {
+  final StreamSink<List<int>> stdin;
+  final Stream<List<int>> stdout;
+
+  late String executable;
+  late List<String> processArgs;
+  late String? workingDirectory;
+  late Map<String, String>? env;
+
+  factory MockDartTestDebugAdapter() {
+    final stdinController = StreamController<List<int>>();
+    final stdoutController = StreamController<List<int>>();
+    final channel = ByteStreamServerChannel(
+        stdinController.stream, stdoutController.sink, null);
+
+    return MockDartTestDebugAdapter._(
+      stdinController.sink,
+      stdoutController.stream,
+      channel,
+    );
+  }
+
+  MockDartTestDebugAdapter._(
+      this.stdin, this.stdout, ByteStreamServerChannel channel)
+      : super(channel);
+
+  Future<void> launchAsProcess(
+    String executable,
+    List<String> processArgs, {
+    required String? workingDirectory,
+    required Map<String, String>? env,
+  }) async {
+    this.executable = executable;
+    this.processArgs = processArgs;
+    this.workingDirectory = workingDirectory;
+    this.env = env;
+  }
+}
+
+class MockRequest extends Request {
+  static var _requestId = 1;
+  MockRequest()
+      : super.fromMap({
+          'command': 'mock_command',
+          'type': 'mock_type',
+          'seq': _requestId++,
+        });
+}
diff --git a/pkg/dds/test/get_cached_cpu_samples_test.dart b/pkg/dds/test/get_cached_cpu_samples_test.dart
index 77d2bdb..d8e900e 100644
--- a/pkg/dds/test/get_cached_cpu_samples_test.dart
+++ b/pkg/dds/test/get_cached_cpu_samples_test.dart
@@ -42,8 +42,15 @@
       final availableCaches = await service.getAvailableCachedCpuSamples();
       expect(availableCaches.cacheNames.length, 0);
 
-      final isolate = (await service.getVM()).isolates!.first;
-
+      IsolateRef isolate;
+      while (true) {
+        final vm = await service.getVM();
+        if (vm.isolates!.isNotEmpty) {
+          isolate = vm.isolates!.first;
+          break;
+        }
+        await Future.delayed(const Duration(seconds: 1));
+      }
       try {
         await service.getCachedCpuSamples(isolate.id!, 'Fake');
         fail('Invalid userTag did not cause an exception');
@@ -73,7 +80,18 @@
       expect(availableCaches.cacheNames.length, 1);
       expect(availableCaches.cacheNames.first, kUserTag);
 
-      final isolate = (await service.getVM()).isolates!.first;
+      IsolateRef isolate;
+      while (true) {
+        final vm = await service.getVM();
+        if (vm.isolates!.isNotEmpty) {
+          isolate = vm.isolates!.first;
+          isolate = await service.getIsolate(isolate.id!);
+          if ((isolate as Isolate).runnable!) {
+            break;
+          }
+        }
+        await Future.delayed(const Duration(seconds: 1));
+      }
 
       final completer = Completer<void>();
       int i = 0;
diff --git a/pkg/dds/tool/dap/README.md b/pkg/dds/tool/dap/README.md
index 216d648..26bbeb3 100644
--- a/pkg/dds/tool/dap/README.md
+++ b/pkg/dds/tool/dap/README.md
@@ -15,7 +15,7 @@
 
 For details on the standard DAP functionality, see [the Debug Adapter Protocol Overview](https://microsoft.github.io/debug-adapter-protocol/) and [the Debug Adapter Protocol Specification](https://microsoft.github.io/debug-adapter-protocol/specification). Custom extensions are detailed below.
 
-**Flutter**: To run Flutter apps, the equivalent command should be run through the `flutter` tool. This is unavailable at the time of writing, but details will be linked here once available.
+**Flutter**: Flutter apps should be run using the debug adapter in the `flutter` tool - [see this document](https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/debug_adapters/README.md).
 
 ## Launch/Attach Arguments
 
@@ -29,15 +29,20 @@
 - `int? vmServicePort` - the port to bind the VM Service too
 - `List<String>? additionalProjectPaths` - paths of any projects (outside of `cwd`) that are open in the users workspace
 - `String? cwd` - the working directory for the Dart process to be spawned in
+- `Map<String, String>? env` - environment variables to be passed to any spawned process
 
 Arguments specific to `launchRequest` are:
 
 - `bool? noDebug` - whether to run in debug or noDebug mode (if not supplied, defaults to debug)
 - `String program` - the path of the Dart program to run
-- `List<String>? args` - arguments to be passed to the Dart program
-- `List<String>? toolArgs` - arguments for the Dart VM
+- `List<String>? args` - arguments to be passed to the Dart program (after the `program` on the command line)
+- `List<String>? toolArgs` - arguments passed after the tool that will run `program` (after `dart` for CLI scripts and after `dart run test:test` for test scripts)
+- `List<String>? vmAdditionalArgs` - arguments passed directly to the Dart VM (after `dart` for both CLI scripts and test scripts)
 - `String? console` - if set to `"terminal"` or `"externalTerminal"` will be run using the `runInTerminal` reverse-request; otherwise the debug adapter spawns the Dart process
 - `bool? enableAsserts` - whether to enable asserts (if not supplied, defaults to enabled)
+- `String? customTool` - an optional tool to run instead of `dart` - the custom tool must be completely compatible with the tool/command it is replacing
+- `int? customToolReplacesArgs` - the number of arguments to delete from the beginning of the argument list when invoking `customTool` - e.g. setting `customTool` to `dart_test` and
+  `customToolReplacesArgs` to `2` for a test run would invoke `dart_test foo_test.dart` instead of `dart run test:test foo_test.dart` (if larger than the number of computed arguments all arguments will be removed, if not supplied will default to `0`)
 
 Arguments specific to `attachRequest` are:
 
@@ -74,6 +79,17 @@
 }
 ```
 
+### `hotReload`
+
+`hotReload` calls the VM's `reloadSources` service for each active isolate, reloading all modified source files.
+
+```
+{
+	"method": "hotReload",
+	"params": null
+}
+```
+
 ## Custom Events
 
 The debug adapter may emit several custom events that are useful to clients.
diff --git a/pkg/dev_compiler/analysis_options.yaml b/pkg/dev_compiler/analysis_options.yaml
index c1925c0..f93da08 100644
--- a/pkg/dev_compiler/analysis_options.yaml
+++ b/pkg/dev_compiler/analysis_options.yaml
@@ -1,8 +1,8 @@
 include: package:lints/recommended.yaml
 
 analyzer:
-  strong-mode:
-    implicit-casts: false
+  language:
+    strict-casts: true
   errors:
     todo: ignore
     avoid_function_literals_in_foreach_calls: ignore
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
old mode 100755
new mode 100644
index 4d8d197..09d9ca8
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -1,5 +1,5 @@
 #!/usr/bin/env dart
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -8,106 +8,14 @@
 /// Command line entry point for Dart Development Compiler (dartdevc), used to
 /// compile a collection of dart libraries into a single JS module
 
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
 import 'dart:isolate';
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:dev_compiler/src/compiler/shared_command.dart';
-import 'package:dev_compiler/src/kernel/expression_compiler_worker.dart';
+
+import 'package:dev_compiler/ddc.dart' as ddc;
 
 /// The entry point for the Dart Dev Compiler.
 ///
 /// [sendPort] may be passed in when started in an isolate. If provided, it is
 /// used for bazel worker communication instead of stdin/stdout.
 Future main(List<String> args, [SendPort sendPort]) async {
-  // Always returns a new modifiable list.
-  var parsedArgs = ParsedArguments.from(args);
-
-  if (parsedArgs.isWorker) {
-    var workerConnection = sendPort == null
-        ? StdAsyncWorkerConnection()
-        : SendPortAsyncWorkerConnection(sendPort);
-    await _CompilerWorker(parsedArgs, workerConnection).run();
-  } else if (parsedArgs.isBatch) {
-    await runBatch(parsedArgs);
-  } else if (parsedArgs.isExpressionCompiler) {
-    await ExpressionCompilerWorker.createAndStart(parsedArgs.rest,
-        sendPort: sendPort);
-  } else {
-    var result = await compile(parsedArgs);
-    exitCode = result.exitCode;
-  }
-}
-
-/// Runs the compiler worker loop.
-class _CompilerWorker extends AsyncWorkerLoop {
-  /// The original args supplied to the executable.
-  final ParsedArguments _startupArgs;
-
-  _CompilerWorker(this._startupArgs, AsyncWorkerConnection workerConnection)
-      : super(connection: workerConnection);
-
-  /// Keeps track of our last compilation result so it can potentially be
-  /// re-used in a worker.
-  CompilerResult lastResult;
-
-  /// Performs each individual work request.
-  @override
-  Future<WorkResponse> performRequest(WorkRequest request) async {
-    var args = _startupArgs.merge(request.arguments);
-    var output = StringBuffer();
-    var context = args.reuseResult ? lastResult : null;
-
-    /// Build a map of uris to digests.
-    final inputDigests = <Uri, List<int>>{};
-    for (var input in request.inputs) {
-      inputDigests[sourcePathToUri(input.path)] = input.digest;
-    }
-
-    lastResult = await runZoned(
-        () =>
-            compile(args, previousResult: context, inputDigests: inputDigests),
-        zoneSpecification:
-            ZoneSpecification(print: (self, parent, zone, message) {
-      output.writeln(message.toString());
-    }));
-    return WorkResponse()
-      ..exitCode = lastResult.success ? 0 : 1
-      ..output = output.toString();
-  }
-}
-
-/// Runs DDC in Kernel batch mode for test.dart.
-Future runBatch(ParsedArguments batchArgs) async {
-  var totalTests = 0;
-  var failedTests = 0;
-  var watch = Stopwatch()..start();
-
-  print('>>> BATCH START');
-
-  String line;
-  CompilerResult result;
-
-  while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
-    totalTests++;
-    var args = batchArgs.merge(line.split(RegExp(r'\s+')));
-
-    String outcome;
-    try {
-      result = await compile(args, previousResult: result);
-      outcome = result.success ? 'PASS' : (result.crashed ? 'CRASH' : 'FAIL');
-    } catch (e, s) {
-      outcome = 'CRASH';
-      print('Unhandled exception:');
-      print(e);
-      print(s);
-    }
-
-    stderr.writeln('>>> EOF STDERR');
-    print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms');
-  }
-
-  var time = watch.elapsedMilliseconds;
-  print('>>> BATCH END (${totalTests - failedTests})/$totalTests ${time}ms');
+  return ddc.internalMain(args, sendPort);
 }
diff --git a/pkg/dev_compiler/lib/ddc.dart b/pkg/dev_compiler/lib/ddc.dart
new file mode 100755
index 0000000..5911cd9
--- /dev/null
+++ b/pkg/dev_compiler/lib/ddc.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+/// Command line entry point for Dart Development Compiler (dartdevc), used to
+/// compile a collection of dart libraries into a single JS module
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:isolate';
+import 'package:bazel_worker/bazel_worker.dart';
+
+import 'src/compiler/shared_command.dart';
+import 'src/kernel/expression_compiler_worker.dart';
+
+/// The internal entry point for the Dart Dev Compiler.
+///
+/// [sendPort] may be passed in when started in an isolate. If provided, it is
+/// used for bazel worker communication instead of stdin/stdout.
+Future internalMain(List<String> args, [SendPort sendPort]) async {
+  // Always returns a new modifiable list.
+  var parsedArgs = ParsedArguments.from(args);
+
+  if (parsedArgs.isWorker) {
+    var workerConnection = sendPort == null
+        ? StdAsyncWorkerConnection()
+        : SendPortAsyncWorkerConnection(sendPort);
+    await _CompilerWorker(parsedArgs, workerConnection).run();
+  } else if (parsedArgs.isBatch) {
+    await runBatch(parsedArgs);
+  } else if (parsedArgs.isExpressionCompiler) {
+    await ExpressionCompilerWorker.createAndStart(parsedArgs.rest,
+        sendPort: sendPort);
+  } else {
+    var result = await compile(parsedArgs);
+    exitCode = result.exitCode;
+  }
+}
+
+/// Runs the compiler worker loop.
+class _CompilerWorker extends AsyncWorkerLoop {
+  /// The original args supplied to the executable.
+  final ParsedArguments _startupArgs;
+
+  _CompilerWorker(this._startupArgs, AsyncWorkerConnection workerConnection)
+      : super(connection: workerConnection);
+
+  /// Keeps track of our last compilation result so it can potentially be
+  /// re-used in a worker.
+  CompilerResult lastResult;
+
+  /// Performs each individual work request.
+  @override
+  Future<WorkResponse> performRequest(WorkRequest request) async {
+    var args = _startupArgs.merge(request.arguments);
+    var output = StringBuffer();
+    var context = args.reuseResult ? lastResult : null;
+
+    /// Build a map of uris to digests.
+    final inputDigests = <Uri, List<int>>{};
+    for (var input in request.inputs) {
+      inputDigests[sourcePathToUri(input.path)] = input.digest;
+    }
+
+    lastResult = await runZoned(
+        () =>
+            compile(args, previousResult: context, inputDigests: inputDigests),
+        zoneSpecification:
+            ZoneSpecification(print: (self, parent, zone, message) {
+      output.writeln(message.toString());
+    }));
+    return WorkResponse()
+      ..exitCode = lastResult.success ? 0 : 1
+      ..output = output.toString();
+  }
+}
+
+/// Runs DDC in Kernel batch mode for test.dart.
+Future runBatch(ParsedArguments batchArgs) async {
+  var totalTests = 0;
+  var failedTests = 0;
+  var watch = Stopwatch()..start();
+
+  print('>>> BATCH START');
+
+  String line;
+  CompilerResult result;
+
+  while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
+    totalTests++;
+    var args = batchArgs.merge(line.split(RegExp(r'\s+')));
+
+    String outcome;
+    try {
+      result = await compile(args, previousResult: result);
+      outcome = result.success ? 'PASS' : (result.crashed ? 'CRASH' : 'FAIL');
+    } catch (e, s) {
+      outcome = 'CRASH';
+      print('Unhandled exception:');
+      print(e);
+      print(s);
+    }
+
+    stderr.writeln('>>> EOF STDERR');
+    print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms');
+  }
+
+  var time = watch.elapsedMilliseconds;
+  print('>>> BATCH END (${totalTests - failedTests})/$totalTests ${time}ms');
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index d8435ca..5b514be 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -338,10 +338,16 @@
     result = await fe.compile(compilerState, inputs, diagnosticMessageHandler);
   } else {
     compilerState.options.onDiagnostic = diagnosticMessageHandler;
-    var incrementalComponent = await incrementalCompiler.computeDelta(
-        entryPoints: inputs, fullComponent: true);
-    result = fe.DdcResult(incrementalComponent, cachedSdkInput.component,
-        doneAdditionalDills, incrementalCompiler.userCode.loader.hierarchy);
+    var incrementalCompilerResult = await incrementalCompiler.computeDelta(
+        entryPoints: inputs,
+        fullComponent: true,
+        trackNeededDillLibraries: recordUsedInputs);
+    result = fe.DdcResult(
+        incrementalCompilerResult.component,
+        cachedSdkInput.component,
+        doneAdditionalDills,
+        incrementalCompilerResult.classHierarchy,
+        incrementalCompilerResult.neededDillLibraries);
   }
   compilerState.options.onDiagnostic = null; // See http://dartbug.com/36983.
 
@@ -476,9 +482,10 @@
   if (recordUsedInputs) {
     var usedOutlines = <Uri>{};
     if (useIncrementalCompiler) {
-      compilerState.incrementalCompiler
-          .updateNeededDillLibrariesWithHierarchy(result.classHierarchy, null);
-      for (var lib in compilerState.incrementalCompiler.neededDillLibraries) {
+      var neededDillLibraries = result.neededDillLibraries;
+      compilerState.incrementalCompiler.updateNeededDillLibrariesWithHierarchy(
+          neededDillLibraries, result.classHierarchy);
+      for (var lib in neededDillLibraries) {
         if (lib.importUri.scheme == 'dart') continue;
         var uri = compilerState.libraryToInputDill[lib.importUri];
         if (uri == null) {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 131d308..a25692d 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1612,14 +1612,12 @@
     var fn = node.function;
     var body = _emitArgumentInitializers(fn, node.name.text);
 
-    // Redirecting constructors: these are not allowed to have initializers,
-    // and the redirecting ctor invocation runs before field initializers.
-    var redirectCall = node.initializers
-            .firstWhere((i) => i is RedirectingInitializer, orElse: () => null)
-        as RedirectingInitializer;
-
-    if (redirectCall != null) {
-      body.add(_emitRedirectingConstructor(redirectCall, className));
+    // Redirecting constructors are not allowed to have conventional
+    // initializers but can have variable declarations in the form of
+    // initializers to support named arguments appearing anywhere in the
+    // arguments list.
+    if (node.initializers.any((i) => i is RedirectingInitializer)) {
+      body.add(_emitRedirectingConstructor(node.initializers, className));
       return body;
     }
 
@@ -1652,15 +1650,23 @@
   }
 
   js_ast.Statement _emitRedirectingConstructor(
-      RedirectingInitializer node, js_ast.Expression className) {
-    var ctor = node.target;
-    // We can't dispatch to the constructor with `this.new` as that might hit a
-    // derived class constructor with the same name.
-    return js.statement('#.#.call(this, #);', [
-      className,
-      _constructorName(ctor.name.text),
-      _emitArgumentList(node.arguments, types: false)
-    ]);
+      List<Initializer> initializers, js_ast.Expression className) {
+    var jsInitializers = <js_ast.Statement>[
+      for (var init in initializers)
+        if (init is LocalInitializer)
+          // Temporary locals are created when named arguments don't appear at
+          // the end of the arguments list.
+          visitVariableDeclaration(init.variable)
+        else if (init is RedirectingInitializer)
+          // We can't dispatch to the constructor with `this.new` as that might
+          // hit a derived class constructor with the same name.
+          js.statement('#.#.call(this, #);', [
+            className,
+            _constructorName(init.target.name.text),
+            _emitArgumentList(init.arguments, types: false)
+          ])
+    ];
+    return js_ast.Block(jsInitializers);
   }
 
   js_ast.Statement _emitSuperConstructorCallIfNeeded(
@@ -5373,7 +5379,16 @@
     // setter, or method. For the case of tearing off a `super` method in
     // contexts where `super` isn't allowed, see [_emitSuperTearoff].
     var name = member.name.text;
-    var jsMethod = _superHelpers.putIfAbsent(name, () {
+    var getter = (member is Field && !setter) ||
+        (member is Procedure && member.isGetter);
+    // Prefix applied to the name only used in the compiler for a map key. This
+    // name does not make its way into the compiled program.
+    var lookupPrefix = setter
+        ? r'set$'
+        : getter
+            ? r'get$'
+            : '';
+    var jsMethod = _superHelpers.putIfAbsent('$lookupPrefix$name', () {
       var isAccessor = member is Procedure ? member.isAccessor : true;
       if (isAccessor) {
         assert(member is Procedure
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
index 4e2cd32..a41722c 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
@@ -310,7 +310,7 @@
 
       _log('Compiling expression \n$expression');
 
-      var dartScope = await _findScopeAt(Uri.parse(libraryUri), line, column);
+      var dartScope = _findScopeAt(Uri.parse(libraryUri), line, column);
       if (dartScope == null) {
         _log('Scope not found at $libraryUri:$line:$column');
         return null;
@@ -389,14 +389,14 @@
     }
   }
 
-  Future<DartScope> _findScopeAt(Uri libraryUri, int line, int column) async {
+  DartScope _findScopeAt(Uri libraryUri, int line, int column) {
     if (line < 0) {
       onDiagnostic(_createInternalError(
           libraryUri, line, column, 'Invalid source location'));
       return null;
     }
 
-    var library = await _getLibrary(libraryUri);
+    var library = _getLibrary(libraryUri);
     if (library == null) {
       onDiagnostic(_createInternalError(
           libraryUri, line, column, 'Dart library not found for location'));
@@ -415,19 +415,8 @@
     return scope;
   }
 
-  Future<Library> _getLibrary(Uri libraryUri) async {
-    return await _compiler.context.runInContext((_) async {
-      var builder = _compiler.userCode.loader.lookupLibraryBuilder(libraryUri);
-      if (builder != null) {
-        var library =
-            _compiler.userCode.loader.read(libraryUri, -1, accessor: builder);
-
-        return library.library;
-      }
-
-      _log('Loaded library for expression');
-      return null;
-    });
+  Library _getLibrary(Uri libraryUri) {
+    return _compiler.lookupLibrary(libraryUri);
   }
 
   /// Return a JS function that returns the evaluated results when called.
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
index 1068a8a..6d5c418 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
@@ -357,8 +357,9 @@
     var incrementalCompiler = IncrementalCompiler.forExpressionCompilationOnly(
         CompilerContext(_processedOptions), component, /*resetTicker*/ false);
 
-    var finalComponent = await incrementalCompiler
+    var incrementalCompilerResult = await incrementalCompiler
         .computeDelta(entryPoints: [libraryUri], fullComponent: true);
+    var finalComponent = incrementalCompilerResult.component;
     assert(!duplicateLibrariesReachable(finalComponent.libraries));
     assert(_canSerialize(finalComponent));
 
@@ -374,8 +375,8 @@
       };
     }
 
-    var coreTypes = incrementalCompiler.getCoreTypes();
-    var hierarchy = incrementalCompiler.getClassHierarchy();
+    var coreTypes = incrementalCompilerResult.coreTypes;
+    var hierarchy = incrementalCompilerResult.classHierarchy;
 
     var kernel2jsCompiler = ProgramCompiler(
       finalComponent,
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
index bc5786d..90f0eef 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
@@ -117,17 +117,19 @@
     // compilers/components/names per module.
     setup.options.packagesFileUri = packages;
     var compiler = DevelopmentIncrementalCompiler(setup.options, input);
-    var component = await compiler.computeDelta();
+    var compilerResult = await compiler.computeDelta();
+    var component = compilerResult.component;
     component.computeCanonicalNames();
     // Initialize DDC.
     var moduleName = p.basenameWithoutExtension(output.toFilePath());
 
-    var classHierarchy = compiler.getClassHierarchy();
+    var classHierarchy = compilerResult.classHierarchy;
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
-        soundNullSafety: setup.soundNullSafety);
-    var coreTypes = compiler.getCoreTypes();
+        soundNullSafety: setup.soundNullSafety,
+        emitDebugMetadata: true);
+    var coreTypes = compilerResult.coreTypes;
 
     final importToSummary = Map<Library, Component>.identity();
     final summaryToModule = Map<Component, String>.identity();
@@ -145,10 +147,10 @@
     var code = jsProgramToCode(
       module,
       setup.moduleFormat,
-      inlineSourceMap: true,
-      buildSourceMap: true,
-      emitDebugMetadata: true,
-      emitDebugSymbols: true,
+      inlineSourceMap: compilerOptions.inlineSourceMap,
+      buildSourceMap: compilerOptions.sourceMap,
+      emitDebugMetadata: compilerOptions.emitDebugMetadata,
+      emitDebugSymbols: compilerOptions.emitDebugSymbols,
       jsUrl: '$output',
       mapUrl: '$output.map',
       compiler: kernel2jsCompiler,
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
index 66db5dd..8dc187d 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -76,18 +76,19 @@
     // initialize incremental compiler and create component
     setup.options.packagesFileUri = packages;
     var compiler = DevelopmentIncrementalCompiler(setup.options, input);
-    var component = await compiler.computeDelta();
+    var compilerResult = await compiler.computeDelta();
+    var component = compilerResult.component;
     component.computeCanonicalNames();
 
     // initialize ddc
     var moduleName = 'foo.dart';
-    var classHierarchy = compiler.getClassHierarchy();
+    var classHierarchy = compilerResult.classHierarchy;
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
         soundNullSafety: setup.soundNullSafety,
         moduleFormats: [setup.moduleFormat]);
-    var coreTypes = compiler.getCoreTypes();
+    var coreTypes = compilerResult.coreTypes;
 
     final importToSummary = Map<Library, Component>.identity();
     final summaryToModule = Map<Component, String>.identity();
diff --git a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
index 4fb6eb6..b607f71 100644
--- a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
+++ b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
@@ -21,7 +21,8 @@
     // Initialize incremental compiler and create component.
     setup.options.packagesFileUri = packages;
     var compiler = DevelopmentIncrementalCompiler(setup.options, input);
-    var component = await compiler.computeDelta();
+    var compilerResult = await compiler.computeDelta();
+    var component = compilerResult.component;
     component.computeCanonicalNames();
     var errors = setup.errors.where((e) => e.contains('Error'));
     if (errors.isNotEmpty) {
@@ -30,14 +31,14 @@
 
     // Initialize DDC.
     var moduleName = 'foo.dart';
-    var classHierarchy = compiler.getClassHierarchy();
+    var classHierarchy = compilerResult.classHierarchy;
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
         soundNullSafety: setup.soundNullSafety,
         moduleFormats: [setup.moduleFormat],
         emitDebugSymbols: true);
-    var coreTypes = compiler.getCoreTypes();
+    var coreTypes = compilerResult.coreTypes;
 
     final importToSummary = Map<Library, Component>.identity();
     final summaryToModule = Map<Component, String>.identity();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart
index 82e0be2..ad18584 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart
@@ -5,7 +5,7 @@
 // @dart = 2.9
 
 void main() async {
-  await for (var i in foobar()) {
+  await for (var i in foobar() as Stream) {
     print(i);
   }
   print('Done!');
diff --git a/pkg/front_end/analysis_options_no_lints.yaml b/pkg/front_end/analysis_options_no_lints.yaml
index d699e16..cc832b8 100644
--- a/pkg/front_end/analysis_options_no_lints.yaml
+++ b/pkg/front_end/analysis_options_no_lints.yaml
@@ -4,6 +4,7 @@
 
 analyzer:
   exclude:
+    - outline_extraction_testcases/**
     - parser_testcases/**
     - test/analyser_ignored/**
     - test/class_hierarchy/data/**
@@ -11,6 +12,7 @@
     - test/extensions/data/**
     - test/id_testing/data/**
     - test/language_versioning/data/**
+    - test/macros/data/**
     - test/patching/data/**
     - test/predicates/data/**
     - test/static_types/data/**
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index 4f3c912..50570c9 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -32,25 +32,25 @@
 }
 
 const Version enableAlternativeInvalidationStrategyVersion =
-    const Version(2, 15);
-const Version enableConstFunctionsVersion = const Version(2, 15);
+    const Version(2, 16);
+const Version enableConstFunctionsVersion = const Version(2, 16);
 const Version enableConstantUpdate2018Version = const Version(2, 0);
 const Version enableConstructorTearoffsVersion = const Version(2, 15);
 const Version enableControlFlowCollectionsVersion = const Version(2, 0);
-const Version enableEnhancedEnumsVersion = const Version(2, 15);
+const Version enableEnhancedEnumsVersion = const Version(2, 16);
 const Version enableExtensionMethodsVersion = const Version(2, 6);
-const Version enableExtensionTypesVersion = const Version(2, 15);
+const Version enableExtensionTypesVersion = const Version(2, 16);
 const Version enableGenericMetadataVersion = const Version(2, 14);
-const Version enableNamedArgumentsAnywhereVersion = const Version(2, 15);
+const Version enableNamedArgumentsAnywhereVersion = const Version(2, 16);
 const Version enableNonNullableVersion = const Version(2, 12);
 const Version enableNonfunctionTypeAliasesVersion = const Version(2, 13);
 const Version enableSetLiteralsVersion = const Version(2, 0);
 const Version enableSpreadCollectionsVersion = const Version(2, 0);
-const Version enableSuperParametersVersion = const Version(2, 15);
-const Version enableTestExperimentVersion = const Version(2, 15);
+const Version enableSuperParametersVersion = const Version(2, 16);
+const Version enableTestExperimentVersion = const Version(2, 16);
 const Version enableTripleShiftVersion = const Version(2, 14);
-const Version enableValueClassVersion = const Version(2, 15);
-const Version enableVarianceVersion = const Version(2, 15);
+const Version enableValueClassVersion = const Version(2, 16);
+const Version enableVarianceVersion = const Version(2, 16);
 
 ExperimentalFlag? parseExperimentalFlag(String flag) {
   switch (flag) {
@@ -141,47 +141,47 @@
 };
 
 const Map<ExperimentalFlag, Version> experimentEnabledVersion = {
-  ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 15),
-  ExperimentalFlag.constFunctions: const Version(2, 15),
+  ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 16),
+  ExperimentalFlag.constFunctions: const Version(2, 16),
   ExperimentalFlag.constantUpdate2018: const Version(2, 0),
   ExperimentalFlag.constructorTearoffs: const Version(2, 15),
   ExperimentalFlag.controlFlowCollections: const Version(2, 0),
-  ExperimentalFlag.enhancedEnums: const Version(2, 15),
+  ExperimentalFlag.enhancedEnums: const Version(2, 16),
   ExperimentalFlag.extensionMethods: const Version(2, 6),
-  ExperimentalFlag.extensionTypes: const Version(2, 15),
+  ExperimentalFlag.extensionTypes: const Version(2, 16),
   ExperimentalFlag.genericMetadata: const Version(2, 14),
-  ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 15),
+  ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 16),
   ExperimentalFlag.nonNullable: const Version(2, 12),
   ExperimentalFlag.nonfunctionTypeAliases: const Version(2, 13),
   ExperimentalFlag.setLiterals: const Version(2, 0),
   ExperimentalFlag.spreadCollections: const Version(2, 0),
-  ExperimentalFlag.superParameters: const Version(2, 15),
-  ExperimentalFlag.testExperiment: const Version(2, 15),
+  ExperimentalFlag.superParameters: const Version(2, 16),
+  ExperimentalFlag.testExperiment: const Version(2, 16),
   ExperimentalFlag.tripleShift: const Version(2, 14),
-  ExperimentalFlag.valueClass: const Version(2, 15),
-  ExperimentalFlag.variance: const Version(2, 15),
+  ExperimentalFlag.valueClass: const Version(2, 16),
+  ExperimentalFlag.variance: const Version(2, 16),
 };
 
 const Map<ExperimentalFlag, Version> experimentReleasedVersion = {
-  ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 15),
-  ExperimentalFlag.constFunctions: const Version(2, 15),
+  ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 16),
+  ExperimentalFlag.constFunctions: const Version(2, 16),
   ExperimentalFlag.constantUpdate2018: const Version(2, 0),
   ExperimentalFlag.constructorTearoffs: const Version(2, 15),
   ExperimentalFlag.controlFlowCollections: const Version(2, 0),
-  ExperimentalFlag.enhancedEnums: const Version(2, 15),
+  ExperimentalFlag.enhancedEnums: const Version(2, 16),
   ExperimentalFlag.extensionMethods: const Version(2, 6),
-  ExperimentalFlag.extensionTypes: const Version(2, 15),
+  ExperimentalFlag.extensionTypes: const Version(2, 16),
   ExperimentalFlag.genericMetadata: const Version(2, 14),
-  ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 15),
+  ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 16),
   ExperimentalFlag.nonNullable: const Version(2, 10),
   ExperimentalFlag.nonfunctionTypeAliases: const Version(2, 13),
   ExperimentalFlag.setLiterals: const Version(2, 0),
   ExperimentalFlag.spreadCollections: const Version(2, 0),
-  ExperimentalFlag.superParameters: const Version(2, 15),
-  ExperimentalFlag.testExperiment: const Version(2, 15),
+  ExperimentalFlag.superParameters: const Version(2, 16),
+  ExperimentalFlag.testExperiment: const Version(2, 16),
   ExperimentalFlag.tripleShift: const Version(2, 14),
-  ExperimentalFlag.valueClass: const Version(2, 15),
-  ExperimentalFlag.variance: const Version(2, 15),
+  ExperimentalFlag.valueClass: const Version(2, 16),
+  ExperimentalFlag.variance: const Version(2, 16),
 };
 
 const AllowedExperimentalFlags defaultAllowedExperimentalFlags =
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index d28d71c..ae632ec 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -10,7 +10,7 @@
 import 'package:kernel/core_types.dart' show CoreTypes;
 
 import 'package:kernel/kernel.dart'
-    show Component, Procedure, DartType, TypeParameter;
+    show Component, Library, Procedure, DartType, TypeParameter;
 
 import '../base/processed_options.dart' show ProcessedOptions;
 
@@ -70,17 +70,13 @@
         component);
   }
 
-  /// Returns a component whose libraries are the recompiled libraries,
-  /// or - in the case of [fullComponent] - a full Component.
-  Future<Component> computeDelta({List<Uri>? entryPoints, bool fullComponent});
-
-  /// Returns [CoreTypes] used during compilation.
-  /// Valid after [computeDelta] is called.
-  CoreTypes? getCoreTypes();
-
-  /// Returns [ClassHierarchy] used during compilation.
-  /// Valid after [computeDelta] is called.
-  ClassHierarchy? getClassHierarchy();
+  /// Returns an [IncrementalCompilerResult] with the component whose libraries
+  /// are the recompiled libraries, or - in the case of [fullComponent] - a full
+  /// Component.
+  Future<IncrementalCompilerResult> computeDelta(
+      {List<Uri>? entryPoints,
+      bool fullComponent: false,
+      bool trackNeededDillLibraries: false});
 
   /// Remove the file associated with the given file [uri] from the set of
   /// valid files.  This guarantees that those files will be re-read on the
@@ -149,3 +145,13 @@
 bool isLegalIdentifier(String identifier) {
   return StringScanner.isLegalIdentifier(identifier);
 }
+
+class IncrementalCompilerResult {
+  final Component component;
+  final ClassHierarchy? classHierarchy;
+  final CoreTypes? coreTypes;
+  final Set<Library>? neededDillLibraries;
+
+  IncrementalCompilerResult(this.component,
+      {this.classHierarchy, this.coreTypes, this.neededDillLibraries});
+}
diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
index 1375e06a..85f6052 100644
--- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
+++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
@@ -5,6 +5,11 @@
 import 'package:kernel/ast.dart';
 import '../fasta/kernel/late_lowering.dart';
 import '../fasta/source/source_extension_builder.dart' show extensionThisName;
+export '../fasta/kernel/constructor_tearoff_lowering.dart'
+    show
+        isConstructorTearOffLowering,
+        isTearOffLowering,
+        isTypedefTearOffLowering;
 
 /// Returns `true` if [node] is the field holding the value of a lowered late
 /// field.
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 7d167c4..217bb40 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -137,8 +137,9 @@
 
 Future<CompilerResult> _compile(InitializedCompilerState compilerState,
     List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler,
-    {bool? summaryOnly, bool includeOffsets: true}) {
-  summaryOnly ??= true;
+    {bool? buildSummary, bool? buildComponent, bool includeOffsets: true}) {
+  buildSummary ??= true;
+  buildComponent ??= true;
   CompilerOptions options = compilerState.options;
   options..onDiagnostic = diagnosticMessageHandler;
 
@@ -147,8 +148,8 @@
   processedOpts.inputs.addAll(inputs);
 
   return generateKernel(processedOpts,
-      buildSummary: summaryOnly,
-      buildComponent: !summaryOnly,
+      buildSummary: buildSummary,
+      buildComponent: buildComponent,
       includeOffsets: includeOffsets);
 }
 
@@ -157,15 +158,18 @@
     {bool includeOffsets: false}) async {
   CompilerResult result = await _compile(
       compilerState, inputs, diagnosticMessageHandler,
-      summaryOnly: true, includeOffsets: includeOffsets);
+      buildSummary: true,
+      buildComponent: false,
+      includeOffsets: includeOffsets);
   return result.summary;
 }
 
 Future<Component?> compileComponent(InitializedCompilerState compilerState,
-    List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler) async {
+    List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler,
+    {bool buildSummary: true}) async {
   CompilerResult result = await _compile(
       compilerState, inputs, diagnosticMessageHandler,
-      summaryOnly: false);
+      buildSummary: buildSummary, buildComponent: true);
 
   Component? component = result.component;
   if (component != null) {
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 0d7c334..2ebfdf1 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -85,9 +85,10 @@
   final Component? sdkSummary;
   final List<Component> additionalDills;
   final ClassHierarchy classHierarchy;
+  final Set<Library>? neededDillLibraries;
 
   DdcResult(this.component, this.sdkSummary, this.additionalDills,
-      this.classHierarchy)
+      this.classHierarchy, this.neededDillLibraries)
       // ignore: unnecessary_null_comparison
       : assert(classHierarchy != null);
 
@@ -221,5 +222,5 @@
   Component? sdkSummary = await processedOpts.loadSdkSummary(null);
   List<Component> summaries = await processedOpts.loadAdditionalDills(null);
   return new DdcResult(
-      component, sdkSummary, summaries, compilerResult.classHierarchy!);
+      component, sdkSummary, summaries, compilerResult.classHierarchy!, null);
 }
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
index 65eceae..346a4ae 100644
--- a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
@@ -121,7 +121,6 @@
             new CompilerContext(processedOpts),
             cachedSdkInput.component,
             outlineOnly);
-        incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
       } else {
         options = oldState.options;
         processedOpts = oldState.processedOpts;
@@ -144,7 +143,6 @@
         // Reuse the incremental compiler, but reset as needed.
         incrementalCompiler = oldState.incrementalCompiler!;
         incrementalCompiler.invalidateAllSources();
-        incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
         options.packagesFileUri = packagesFile;
         options.fileSystem = fileSystem;
         processedOpts.clearFileSystemCache();
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 141014c..b9b4ca7 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -24,7 +24,11 @@
 export '../api_prototype/front_end.dart' show CompilerResult;
 
 export '../api_prototype/incremental_kernel_generator.dart'
-    show IncrementalKernelGenerator, IncrementalSerializer, isLegalIdentifier;
+    show
+        IncrementalCompilerResult,
+        IncrementalKernelGenerator,
+        IncrementalSerializer,
+        isLegalIdentifier;
 
 export '../api_prototype/kernel_generator.dart'
     show kernelForModule, kernelForProgram;
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 2a94404..ecc964c 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
@@ -120,7 +120,8 @@
       int startCharOffset,
       int charOffset,
       int charEndOffset,
-      IndexedClass? referencesFromIndexed) {
+      IndexedClass? referencesFromIndexed,
+      Scope scope) {
     assert(enumConstantInfos == null || enumConstantInfos.isNotEmpty);
 
     Uri fileUri = parent.fileUri;
@@ -170,6 +171,7 @@
         reference: referencesFromIndexed?.cls.reference,
         fileUri: fileUri);
     Map<String, MemberBuilder> members = <String, MemberBuilder>{};
+    Map<String, MemberBuilder> setters = <String, MemberBuilder>{};
     Map<String, MemberBuilder> constructors = <String, MemberBuilder>{};
     NamedTypeBuilder selfType = new NamedTypeBuilder(
         name,
@@ -357,11 +359,18 @@
     }
     final int startCharOffsetComputed =
         metadata == null ? startCharOffset : metadata.first.charOffset;
+    scope.forEachLocalMember((name, member) {
+      members[name] = member as MemberBuilder;
+    });
+    scope.forEachLocalSetter((name, member) {
+      setters[name] = member;
+    });
     EnumBuilder enumBuilder = new EnumBuilder.internal(
         metadata,
         name,
         new Scope(
             local: members,
+            setters: setters,
             parent: parent.scope,
             debugName: "enum $name",
             isModifiable: false),
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 73cabf5..1672a7d 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -220,7 +220,7 @@
   bool get isPart => false;
 
   @override
-  String get debugName => "LibraryBuilder";
+  String get debugName => "$runtimeType";
 
   @override
   Loader get loader;
@@ -435,6 +435,11 @@
         ? const NullabilityBuilder.nullable()
         : const NullabilityBuilder.omitted();
   }
+
+  @override
+  StringBuffer printOn(StringBuffer buffer) {
+    return buffer..write(name ?? importUri);
+  }
 }
 
 class LibraryLocalDeclarationIterator implements Iterator<Builder> {
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 0bfffd5..306c9aa 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -285,6 +285,10 @@
       Uri fileUri,
       TypeAliasBuilder aliasBuilder,
       DartType type) {
+    // Don't report the error in case of InvalidType. An error has already been
+    // reported in this case.
+    if (type is InvalidType) return null;
+
     Message message;
     if (declaration!.isTypeVariable) {
       message =
@@ -400,7 +404,7 @@
         // from ClassHierarchyBuilder.
         TypeDeclarationBuilder? unaliasedDeclaration = this.declaration;
         // The following code assumes that the declaration is a TypeAliasBuilder
-        // that through a chain of other TypeAliasBuilders (possibly, the chian
+        // that through a chain of other TypeAliasBuilders (possibly, the chain
         // length is 0) references a ClassBuilder of the Null class.  Otherwise,
         // it won't produce the NullType on the output.
         while (unaliasedDeclaration is TypeAliasBuilder) {
@@ -421,7 +425,7 @@
         // class from ClassHierarchyBuilder.
         TypeDeclarationBuilder? unaliasedDeclaration = this.declaration;
         // The following code assumes that the declaration is a TypeAliasBuilder
-        // that through a chain of other TypeAliasBuilders (possibly, the chian
+        // that through a chain of other TypeAliasBuilders (possibly, the chain
         // length is 0) references a ClassBuilder of the FutureOr class.
         // Otherwise, it won't produce the FutureOrType on the output.
         while (unaliasedDeclaration is TypeAliasBuilder) {
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 61bdb2e..03b4da8 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -9,18 +9,6 @@
 import 'package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart'
     show ScannerConfiguration;
 
-import 'package:front_end/src/api_prototype/experimental_flags.dart';
-
-import 'package:front_end/src/api_prototype/lowering_predicates.dart'
-    show isExtensionThisName;
-
-import 'package:front_end/src/base/nnbd_mode.dart';
-
-import 'package:front_end/src/fasta/builder/member_builder.dart'
-    show MemberBuilder;
-
-import 'package:front_end/src/fasta/fasta_codes.dart';
-import 'package:front_end/src/fasta/source/source_loader.dart';
 import 'package:kernel/binary/ast_from_binary.dart'
     show
         BinaryBuilderWithMetadata,
@@ -33,8 +21,6 @@
 import 'package:kernel/class_hierarchy.dart'
     show ClassHierarchy, ClosedWorldClassHierarchy;
 
-import 'package:kernel/core_types.dart' show CoreTypes;
-
 import 'package:kernel/kernel.dart'
     show
         Class,
@@ -69,13 +55,22 @@
 
 import 'package:package_config/package_config.dart' show Package, PackageConfig;
 
+import '../api_prototype/experimental_flags.dart';
+
 import '../api_prototype/file_system.dart' show FileSystem, FileSystemEntity;
 
 import '../api_prototype/incremental_kernel_generator.dart'
-    show IncrementalKernelGenerator, isLegalIdentifier;
+    show
+        IncrementalCompilerResult,
+        IncrementalKernelGenerator,
+        isLegalIdentifier;
+
+import '../api_prototype/lowering_predicates.dart' show isExtensionThisName;
 
 import '../api_prototype/memory_file_system.dart' show MemoryFileSystem;
 
+import '../base/nnbd_mode.dart';
+
 import 'builder/builder.dart' show Builder;
 
 import 'builder/class_builder.dart' show ClassBuilder;
@@ -86,6 +81,8 @@
 
 import 'builder/library_builder.dart' show LibraryBuilder;
 
+import 'builder/member_builder.dart' show MemberBuilder;
+
 import 'builder/name_iterator.dart' show NameIterator;
 
 import 'builder/type_builder.dart' show TypeBuilder;
@@ -107,6 +104,8 @@
 
 import 'export.dart' show Export;
 
+import 'fasta_codes.dart';
+
 import 'import.dart' show Import;
 
 import 'incremental_serializer.dart' show IncrementalSerializer;
@@ -134,6 +133,8 @@
 import 'source/source_library_builder.dart'
     show ImplicitLanguageVersion, SourceLibraryBuilder;
 
+import 'source/source_loader.dart';
+
 import 'ticker.dart' show Ticker;
 
 import 'uri_translator.dart' show UriTranslator;
@@ -143,78 +144,99 @@
 class IncrementalCompiler implements IncrementalKernelGenerator {
   final CompilerContext context;
 
-  final Ticker ticker;
-  final bool resetTicker;
+  final Ticker _ticker;
+  final bool _resetTicker;
   final bool outlineOnly;
-  bool trackNeededDillLibraries = false;
-  Set<Library>? neededDillLibraries;
 
-  Set<Uri?> invalidatedUris = new Set<Uri?>();
+  Set<Uri?> _invalidatedUris = new Set<Uri?>();
 
-  DillTarget? dillLoadedData;
-  List<LibraryBuilder>? platformBuilders;
-  Map<Uri, LibraryBuilder>? userBuilders;
-  final Uri? initializeFromDillUri;
-  Component? componentToInitializeFrom;
-  bool initializedFromDill = false;
-  bool initializedIncrementalSerializer = false;
-  Uri? previousPackagesUri;
-  Map<String, Package>? previousPackagesMap;
-  Map<String, Package>? currentPackagesMap;
-  bool hasToCheckPackageUris = false;
-  final bool initializedForExpressionCompilationOnly;
-  bool computeDeltaRunOnce = false;
-  Map<Uri, List<DiagnosticMessageFromJson>> remainingComponentProblems =
-      new Map<Uri, List<DiagnosticMessageFromJson>>();
-  List<Component>? modulesToLoad;
-  IncrementalSerializer? incrementalSerializer;
+  DillTarget? _dillLoadedData;
+  List<LibraryBuilder>? _platformBuilders;
+  Map<Uri, LibraryBuilder>? _userBuilders;
+
+  final _InitializationStrategy _initializationStrategy;
+
+  Uri? _previousPackagesUri;
+  Map<String, Package>? _previousPackagesMap;
+  Map<String, Package>? _currentPackagesMap;
+  bool _hasToCheckPackageUris = false;
+  final bool _initializedForExpressionCompilationOnly;
+  bool _computeDeltaRunOnce = false;
+  List<Component>? _modulesToLoad;
+  final IncrementalSerializer? _incrementalSerializer;
+  final _ComponentProblems _componentProblems = new _ComponentProblems();
+
+  RecorderForTesting? get recorderForTesting => null;
 
   static final Uri debugExprUri =
       new Uri(scheme: "org-dartlang-debug", path: "synthetic_debug_expression");
 
-  IncrementalKernelTarget? userCode;
-  Set<Library>? previousSourceBuilders;
+  IncrementalKernelTarget? _lastGoodKernelTarget;
+  Set<Library>? _previousSourceBuilders;
 
   /// Guard against multiple computeDelta calls at the same time (possibly
   /// caused by lacking awaits etc).
-  Completer<dynamic>? currentlyCompiling;
+  Completer<dynamic>? _currentlyCompiling;
 
   IncrementalCompiler.fromComponent(
-      this.context, this.componentToInitializeFrom,
-      [bool? outlineOnly, this.incrementalSerializer])
-      : ticker = context.options.ticker,
-        resetTicker = true,
-        initializeFromDillUri = null,
+      this.context, Component? _componentToInitializeFrom,
+      [bool? outlineOnly, this._incrementalSerializer])
+      : _ticker = context.options.ticker,
+        _resetTicker = true,
+        _initializationStrategy = new _InitializationStrategy.fromComponent(
+            _componentToInitializeFrom),
         this.outlineOnly = outlineOnly ?? false,
-        this.initializedForExpressionCompilationOnly = false {
-    enableExperimentsBasedOnEnvironment();
+        this._initializedForExpressionCompilationOnly = false {
+    _enableExperimentsBasedOnEnvironment();
   }
 
   IncrementalCompiler(this.context,
-      [this.initializeFromDillUri,
+      [Uri? _initializeFromDillUri,
       bool? outlineOnly,
-      this.incrementalSerializer])
-      : ticker = context.options.ticker,
-        resetTicker = true,
-        componentToInitializeFrom = null,
+      this._incrementalSerializer])
+      : _ticker = context.options.ticker,
+        _resetTicker = true,
+        _initializationStrategy =
+            new _InitializationStrategy.fromUri(_initializeFromDillUri),
         this.outlineOnly = outlineOnly ?? false,
-        this.initializedForExpressionCompilationOnly = false {
-    enableExperimentsBasedOnEnvironment();
+        this._initializedForExpressionCompilationOnly = false {
+    _enableExperimentsBasedOnEnvironment();
   }
 
   IncrementalCompiler.forExpressionCompilationOnly(
-      this.context, this.componentToInitializeFrom,
+      this.context, Component? _componentToInitializeFrom,
       [bool? resetTicker])
-      : ticker = context.options.ticker,
-        this.resetTicker = resetTicker ?? true,
-        initializeFromDillUri = null,
+      : _ticker = context.options.ticker,
+        this._resetTicker = resetTicker ?? true,
+        _initializationStrategy = new _InitializationStrategy.fromComponent(
+            _componentToInitializeFrom),
         this.outlineOnly = false,
-        this.incrementalSerializer = null,
-        this.initializedForExpressionCompilationOnly = true {
-    enableExperimentsBasedOnEnvironment();
+        this._incrementalSerializer = null,
+        this._initializedForExpressionCompilationOnly = true {
+    _enableExperimentsBasedOnEnvironment();
   }
 
-  void enableExperimentsBasedOnEnvironment({Set<String>? enabledExperiments}) {
+  bool get initializedFromDillForTesting =>
+      _initializationStrategy.initializedFromDillForTesting;
+
+  bool get initializedIncrementalSerializerForTesting =>
+      _initializationStrategy.initializedIncrementalSerializerForTesting;
+
+  DillTarget? get dillTargetForTesting => _dillLoadedData;
+
+  IncrementalKernelTarget? get kernelTargetForTesting => _lastGoodKernelTarget;
+
+  /// Returns the [Package] used for the package [packageName] in the most
+  /// recent compilation.
+  Package? getPackageForPackageName(String packageName) =>
+      _currentPackagesMap?[packageName];
+
+  /// Returns the [Library] with the given [importUri] from the most recent
+  /// compilation.
+  Library? lookupLibrary(Uri importUri) =>
+      _lastGoodKernelTarget?.loader.lookupLibraryBuilder(importUri)?.library;
+
+  void _enableExperimentsBasedOnEnvironment({Set<String>? enabledExperiments}) {
     // Note that these are all experimental. Use at your own risk.
     enabledExperiments ??= getExperimentEnvironment();
     // Currently there's no live experiments.
@@ -222,36 +244,45 @@
 
   @override
   void setExperimentalFeaturesForTesting(Set<String> features) {
-    enableExperimentsBasedOnEnvironment(enabledExperiments: features);
+    _enableExperimentsBasedOnEnvironment(enabledExperiments: features);
   }
 
   @override
-  Future<Component> computeDelta(
-      {List<Uri>? entryPoints, bool fullComponent: false}) async {
-    while (currentlyCompiling != null) {
-      await currentlyCompiling!.future;
+  Future<IncrementalCompilerResult> computeDelta(
+      {List<Uri>? entryPoints,
+      bool fullComponent: false,
+      bool trackNeededDillLibraries: false}) async {
+    while (_currentlyCompiling != null) {
+      await _currentlyCompiling!.future;
     }
-    currentlyCompiling = new Completer();
-    if (resetTicker) {
-      ticker.reset();
+    _currentlyCompiling = new Completer();
+    if (_resetTicker) {
+      _ticker.reset();
     }
     entryPoints ??= context.options.inputs;
-    return context.runInContext<Component>((CompilerContext c) async {
-      if (computeDeltaRunOnce && initializedForExpressionCompilationOnly) {
+    return context
+        .runInContext<IncrementalCompilerResult>((CompilerContext c) async {
+      if (_computeDeltaRunOnce && _initializedForExpressionCompilationOnly) {
         throw new StateError("Initialized for expression compilation: "
             "cannot do another general compile.");
       }
-      computeDeltaRunOnce = true;
+      _computeDeltaRunOnce = true;
+      IncrementalKernelTarget? lastGoodKernelTarget = _lastGoodKernelTarget;
+
       // Initial setup: Load platform, initialize from dill or component etc.
-      UriTranslator uriTranslator = await setupPackagesAndUriTranslator(c);
+      UriTranslator uriTranslator = await _setupPackagesAndUriTranslator(c);
       IncrementalCompilerData data =
-          await ensurePlatformAndInitialize(uriTranslator, c);
+          await _ensurePlatformAndInitialize(uriTranslator, c);
 
       // Figure out what to keep and what to throw away.
-      Set<Uri?> invalidatedUris = this.invalidatedUris.toSet();
-      invalidateNotKeptUserBuilders(invalidatedUris);
-      ReusageResult? reusedResult =
-          computeReusedLibraries(invalidatedUris, uriTranslator, entryPoints!);
+      Set<Uri?> invalidatedUris = this._invalidatedUris.toSet();
+      _invalidateNotKeptUserBuilders(invalidatedUris);
+      ReusageResult? reusedResult = _computeReusedLibraries(
+          lastGoodKernelTarget,
+          _userBuilders,
+          invalidatedUris,
+          uriTranslator,
+          entryPoints!);
 
       // Use the reused libraries to re-write entry-points.
       if (reusedResult.arePartsUsedAsEntryPoints()) {
@@ -267,43 +298,49 @@
 
       // Experimental invalidation initialization (e.g. figure out if we can).
       ExperimentalInvalidation? experimentalInvalidation =
-          await initializeExperimentalInvalidation(reusedResult, c);
-      recordRebuildBodiesCountForTesting(
+          await _initializeExperimentalInvalidation(reusedResult, c);
+      recorderForTesting?.recordRebuildBodiesCount(
           experimentalInvalidation?.missingSources.length ?? 0);
 
       // Cleanup: After (potentially) removing builders we have stuff to cleanup
       // to not leak, and we might need to re-create the dill target.
-      cleanupRemovedBuilders(reusedResult, uriTranslator);
-      recreateDillTargetIfPackageWasUpdated(uriTranslator, c);
-      ClassHierarchy? hierarchy = userCode?.loader.hierarchy;
-      cleanupHierarchy(hierarchy, experimentalInvalidation, reusedResult);
+      _cleanupRemovedBuilders(
+          lastGoodKernelTarget, reusedResult, uriTranslator);
+      _recreateDillTargetIfPackageWasUpdated(uriTranslator, c);
+      ClassHierarchy? hierarchy = lastGoodKernelTarget?.loader.hierarchy;
+      _cleanupHierarchy(hierarchy, experimentalInvalidation, reusedResult);
       List<LibraryBuilder> reusedLibraries = reusedResult.reusedLibraries;
       reusedResult = null;
 
-      // TODO(jensj): Given the code below, [userCode] is assumed always to be
-      // non-null.
-      if (userCode != null) {
-        ticker.logMs("Decided to reuse ${reusedLibraries.length}"
-            " of ${userCode!.loader.libraryBuilders.length} libraries");
+      if (lastGoodKernelTarget != null) {
+        _ticker.logMs("Decided to reuse ${reusedLibraries.length}"
+            " of ${lastGoodKernelTarget.loader.libraryBuilders.length}"
+            " libraries");
       }
 
       // For modular compilation we can be asked to load components and track
       // which libraries we actually use for the compilation. Set that up now.
-      loadEnsureLoadedComponents(reusedLibraries);
-      resetTrackingOfUsedLibraries(hierarchy);
+      _loadEnsureLoadedComponents(reusedLibraries);
+      if (trackNeededDillLibraries) {
+        _resetTrackingOfUsedLibraries(hierarchy);
+      }
 
-      // For each computeDelta call we create a new userCode object which needs
+      // For each computeDelta call we create a new kernel target which needs
       // to be setup, and in the case of experimental invalidation some of the
       // builders needs to be patched up.
-      IncrementalKernelTarget? userCodeOld = userCode;
-      setupNewUserCode(c, uriTranslator, hierarchy, reusedLibraries,
-          experimentalInvalidation, entryPoints!.first);
+      IncrementalKernelTarget currentKernelTarget = _setupNewKernelTarget(
+          c,
+          uriTranslator,
+          hierarchy,
+          reusedLibraries,
+          experimentalInvalidation,
+          entryPoints!.first);
       Map<LibraryBuilder, List<LibraryBuilder>>? rebuildBodiesMap =
-          experimentalInvalidationCreateRebuildBodiesBuilders(
-              experimentalInvalidation, uriTranslator);
-      entryPoints = userCode!.setEntryPoints(entryPoints!);
-      await userCode!.loader.buildOutlines();
-      experimentalInvalidationPatchUpScopes(
+          _experimentalInvalidationCreateRebuildBodiesBuilders(
+              currentKernelTarget, experimentalInvalidation, uriTranslator);
+      entryPoints = currentKernelTarget.setEntryPoints(entryPoints!);
+      await currentKernelTarget.loader.buildOutlines();
+      _experimentalInvalidationPatchUpScopes(
           experimentalInvalidation, rebuildBodiesMap);
       rebuildBodiesMap = null;
 
@@ -311,50 +348,55 @@
       // Note that the [Component] is not the "full" component.
       // It is a component consisting of all newly compiled libraries and all
       // libraries loaded from .dill files or directly from components.
-      // Technically, it's the combination of userCode.loader.libraries and
-      // dillLoadedData.loader.libraries.
-      Component? componentWithDill = await userCode!.buildOutlines();
+      // Technically, it's the combination of
+      // `currentKernelTarget.loader.libraries` and
+      // `_dillLoadedData.loader.libraries`.
+      Component? componentWithDill = await currentKernelTarget.buildOutlines();
 
       if (!outlineOnly) {
         // Checkpoint: Build the actual bodies.
         componentWithDill =
-            await userCode!.buildComponent(verify: c.options.verify);
+            await currentKernelTarget.buildComponent(verify: c.options.verify);
       }
-      hierarchy ??= userCode!.loader.hierarchy;
-      // ignore: unnecessary_null_comparison
-      if (hierarchy != null) {
-        if (userCode!.classHierarchyChanges != null) {
-          hierarchy.applyTreeChanges([], [], userCode!.classHierarchyChanges!);
-        }
-        if (userCode!.classMemberChanges != null) {
-          hierarchy.applyMemberChanges(userCode!.classMemberChanges!,
-              findDescendants: true);
-        }
+      hierarchy ??= currentKernelTarget.loader.hierarchy;
+      if (currentKernelTarget.classHierarchyChanges != null) {
+        hierarchy.applyTreeChanges(
+            [], [], currentKernelTarget.classHierarchyChanges!);
       }
-      recordNonFullComponentForTesting(componentWithDill!);
+      if (currentKernelTarget.classMemberChanges != null) {
+        hierarchy.applyMemberChanges(currentKernelTarget.classMemberChanges!,
+            findDescendants: true);
+      }
+      recorderForTesting?.recordNonFullComponent(componentWithDill!);
 
-      // Perform actual dill usage tracking.
-      performDillUsageTracking(hierarchy);
+      Set<Library>? neededDillLibraries;
+      if (trackNeededDillLibraries) {
+        // Perform actual dill usage tracking.
+        neededDillLibraries =
+            _performDillUsageTracking(currentKernelTarget, hierarchy);
+      }
 
-      // If we actually got a result we can throw away the old userCode and the
-      // list of invalidated uris.
-      // ignore: unnecessary_null_comparison
+      // If we actually got a result we can throw away the
+      // [lastGoodKernelTarget] and the list of invalidated uris.
+      // TODO(jensj,johnniwinther): Given the code below, [componentWithDill] is
+      // assumed always to be non-null.
       if (componentWithDill != null) {
-        this.invalidatedUris.clear();
-        hasToCheckPackageUris = false;
-        userCodeOld?.loader.releaseAncillaryResources();
-        userCodeOld = null;
+        this._invalidatedUris.clear();
+        _hasToCheckPackageUris = false;
+        lastGoodKernelTarget?.loader.releaseAncillaryResources();
+        lastGoodKernelTarget = null;
       }
 
       // Compute which libraries to output and which (previous) errors/warnings
       // we have to reissue. In the process do some cleanup too.
       List<Library> compiledLibraries =
-          new List<Library>.from(userCode!.loader.libraries);
-      Map<Uri, Source> uriToSource = componentWithDill.uriToSource;
-      experimentalCompilationPostCompilePatchup(
+          new List<Library>.from(currentKernelTarget.loader.libraries);
+      Map<Uri, Source> uriToSource = componentWithDill!.uriToSource;
+      _experimentalCompilationPostCompilePatchup(
           experimentalInvalidation, compiledLibraries, uriToSource);
       List<Library> outputLibraries =
-          calculateOutputLibrariesAndIssueLibraryProblems(
+          _calculateOutputLibrariesAndIssueLibraryProblems(
+              currentKernelTarget,
               data.component != null || fullComponent,
               compiledLibraries,
               entryPoints!,
@@ -363,18 +405,20 @@
               uriTranslator,
               uriToSource,
               c);
-      List<String> problemsAsJson = reissueComponentProblems(componentWithDill);
+      List<String> problemsAsJson = _componentProblems.reissueProblems(
+          context, currentKernelTarget, componentWithDill);
 
       // If we didn't get a result, go back to the previous one so expression
       // calculation has the potential to work.
       // ignore: unnecessary_null_comparison
       if (componentWithDill == null) {
-        userCode!.loader.clearLibraryBuilders();
-        userCode = userCodeOld;
-        dillLoadedData!.loader.currentSourceLoader = userCode!.loader;
+        currentKernelTarget.loader.clearLibraryBuilders();
+        currentKernelTarget = lastGoodKernelTarget!;
+        _dillLoadedData!.loader.currentSourceLoader =
+            currentKernelTarget.loader;
       } else {
-        previousSourceBuilders =
-            convertSourceLibraryBuildersToDill(experimentalInvalidation);
+        _previousSourceBuilders = _convertSourceLibraryBuildersToDill(
+            currentKernelTarget, experimentalInvalidation);
       }
 
       experimentalInvalidation = null;
@@ -394,11 +438,15 @@
         ..problemsAsJson = problemsAsJson;
 
       // We're now done. Allow any waiting compile to start.
-      Completer<dynamic> currentlyCompilingLocal = currentlyCompiling!;
-      currentlyCompiling = null;
+      Completer<dynamic> currentlyCompilingLocal = _currentlyCompiling!;
+      _currentlyCompiling = null;
       currentlyCompilingLocal.complete();
 
-      return result;
+      _lastGoodKernelTarget = currentKernelTarget;
+      return new IncrementalCompilerResult(result,
+          classHierarchy: currentKernelTarget.loader.hierarchy,
+          coreTypes: currentKernelTarget.loader.coreTypes,
+          neededDillLibraries: neededDillLibraries);
     });
   }
 
@@ -410,26 +458,25 @@
   /// source builders and they will thus be patched up here too.
   ///
   /// Returns the set of Libraries that now has new (dill) builders.
-  Set<Library> convertSourceLibraryBuildersToDill(
+  Set<Library> _convertSourceLibraryBuildersToDill(
+      IncrementalKernelTarget nextGoodKernelTarget,
       ExperimentalInvalidation? experimentalInvalidation) {
     bool changed = false;
     Set<Library> newDillLibraryBuilders = new Set<Library>();
-    userBuilders ??= <Uri, LibraryBuilder>{};
+    _userBuilders ??= <Uri, LibraryBuilder>{};
     Map<LibraryBuilder, List<LibraryBuilder>>? convertedLibraries;
-    for (LibraryBuilder builder in userCode!.loader.libraryBuilders) {
+    for (LibraryBuilder builder
+        in nextGoodKernelTarget.loader.libraryBuilders) {
       if (builder is SourceLibraryBuilder) {
         DillLibraryBuilder dillBuilder =
-            dillLoadedData!.loader.appendLibrary(builder.library);
-        userCode!.loader.registerLibraryBuilder(
+            _dillLoadedData!.loader.appendLibrary(builder.library);
+        nextGoodKernelTarget.loader.registerLibraryBuilder(
             // TODO(johnniwinther): Why do we need to create
             //  [DillLibraryBuilder]s for the patch library file uris?
             dillBuilder,
             builder.isPatch ? builder.fileUri : null);
-        userBuilders![builder.importUri] = dillBuilder;
+        _userBuilders![builder.importUri] = dillBuilder;
         newDillLibraryBuilders.add(builder.library);
-        if (userCode!.loader.first == builder) {
-          userCode!.loader.first = dillBuilder;
-        }
         changed = true;
         if (experimentalInvalidation != null) {
           convertedLibraries ??=
@@ -441,8 +488,9 @@
     if (changed) {
       // We suppress finalization errors because they have already been
       // reported.
-      dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
-      assert(_checkEquivalentScopes(userCode!.loader, dillLoadedData!.loader));
+      _dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
+      assert(_checkEquivalentScopes(
+          nextGoodKernelTarget.loader, _dillLoadedData!.loader));
 
       if (experimentalInvalidation != null) {
         /// If doing experimental invalidation that means that some of the old
@@ -455,7 +503,7 @@
         // Maps from old library builder to map of new content.
         Map<LibraryBuilder, Map<String, Builder>>? replacementSettersMap = {};
 
-        experimentalInvalidationFillReplacementMaps(
+        _experimentalInvalidationFillReplacementMaps(
             convertedLibraries!, replacementMap, replacementSettersMap);
 
         for (LibraryBuilder builder
@@ -478,12 +526,12 @@
         replacementSettersMap = null;
       }
     }
-    userCode!.loader.buildersCreatedWithReferences.clear();
-    userCode!.loader.builderHierarchy.clear();
-    userCode!.loader.referenceFromIndex = null;
+    nextGoodKernelTarget.loader.buildersCreatedWithReferences.clear();
+    nextGoodKernelTarget.loader.builderHierarchy.clear();
+    nextGoodKernelTarget.loader.referenceFromIndex = null;
     convertedLibraries = null;
     experimentalInvalidation = null;
-    if (userBuilders!.isEmpty) userBuilders = null;
+    if (_userBuilders!.isEmpty) _userBuilders = null;
     return newDillLibraryBuilders;
   }
 
@@ -565,7 +613,8 @@
 
   /// Compute which libraries to output and which (previous) errors/warnings we
   /// have to reissue. In the process do some cleanup too.
-  List<Library> calculateOutputLibrariesAndIssueLibraryProblems(
+  List<Library> _calculateOutputLibrariesAndIssueLibraryProblems(
+      IncrementalKernelTarget currentKernelTarget,
       bool fullComponent,
       List<Library> compiledLibraries,
       List<Uri> entryPoints,
@@ -577,18 +626,25 @@
     List<Library> outputLibraries;
     Set<Library> allLibraries;
     if (fullComponent) {
-      outputLibraries = computeTransitiveClosure(compiledLibraries, entryPoints,
-          reusedLibraries, hierarchy, uriTranslator, uriToSource);
+      outputLibraries = _computeTransitiveClosure(
+          currentKernelTarget,
+          compiledLibraries,
+          entryPoints,
+          reusedLibraries,
+          hierarchy,
+          uriTranslator,
+          uriToSource);
       allLibraries = outputLibraries.toSet();
       if (!c.options.omitPlatform) {
-        for (int i = 0; i < platformBuilders!.length; i++) {
-          Library lib = platformBuilders![i].library;
+        for (int i = 0; i < _platformBuilders!.length; i++) {
+          Library lib = _platformBuilders![i].library;
           outputLibraries.add(lib);
         }
       }
     } else {
       outputLibraries = <Library>[];
-      allLibraries = computeTransitiveClosure(
+      allLibraries = _computeTransitiveClosure(
+              currentKernelTarget,
               compiledLibraries,
               entryPoints,
               reusedLibraries,
@@ -599,7 +655,7 @@
           .toSet();
     }
 
-    reissueLibraryProblems(allLibraries, compiledLibraries);
+    _reissueLibraryProblems(allLibraries, compiledLibraries);
     return outputLibraries;
   }
 
@@ -610,7 +666,7 @@
   /// contain all the libraries that would normally have been recompiled.
   /// This might be a temporary thing, but we need to figure out if the VM
   /// can (always) work with only getting the actually rebuild stuff.
-  void experimentalCompilationPostCompilePatchup(
+  void _experimentalCompilationPostCompilePatchup(
       ExperimentalInvalidation? experimentalInvalidation,
       List<Library> compiledLibraries,
       Map<Uri, Source> uriToSource) {
@@ -628,32 +684,33 @@
   /// Perform dill usage tracking if asked. Use the marking on dill builders as
   /// well as the class hierarchy to figure out which dill libraries was
   /// actually used by the compilation.
-  void performDillUsageTracking(ClassHierarchy hierarchy) {
-    if (trackNeededDillLibraries) {
-      // Which dill builders were built?
-      neededDillLibraries = new Set<Library>();
+  Set<Library> _performDillUsageTracking(
+      IncrementalKernelTarget target, ClassHierarchy hierarchy) {
+    // Which dill builders were built?
+    Set<Library> neededDillLibraries = {};
 
-      // Propagate data from constant evaluator: Libraries used in the constant
-      // evaluator - that comes from dill - are marked.
-      Set<Library> librariesUsedByConstantEvaluator = userCode!.librariesUsed;
+    // Propagate data from constant evaluator: Libraries used in the constant
+    // evaluator - that comes from dill - are marked.
+    Set<Library> librariesUsedByConstantEvaluator = target.librariesUsed;
 
-      for (LibraryBuilder builder in dillLoadedData!.loader.libraryBuilders) {
-        if (builder is DillLibraryBuilder) {
-          if (builder.isBuiltAndMarked ||
-              librariesUsedByConstantEvaluator.contains(builder.library)) {
-            neededDillLibraries!.add(builder.library);
-          }
+    for (LibraryBuilder builder in _dillLoadedData!.loader.libraryBuilders) {
+      if (builder is DillLibraryBuilder) {
+        if (builder.isBuiltAndMarked ||
+            librariesUsedByConstantEvaluator.contains(builder.library)) {
+          neededDillLibraries.add(builder.library);
         }
       }
-
-      updateNeededDillLibrariesWithHierarchy(
-          hierarchy, userCode!.loader.builderHierarchy);
     }
+
+    updateNeededDillLibrariesWithHierarchy(
+        neededDillLibraries, hierarchy, target.loader.builderHierarchy);
+
+    return neededDillLibraries;
   }
 
   /// Fill in the replacement maps that describe the replacements that need to
   /// happen because of experimental invalidation.
-  void experimentalInvalidationFillReplacementMaps(
+  void _experimentalInvalidationFillReplacementMaps(
       Map<LibraryBuilder, List<LibraryBuilder>> rebuildBodiesMap,
       Map<LibraryBuilder, Map<String, Builder>> replacementMap,
       Map<LibraryBuilder, Map<String, Builder>> replacementSettersMap) {
@@ -687,10 +744,12 @@
   }
 
   /// When doing experimental invalidation, we have some builders that needs to
-  /// be rebuild special, namely they have to be [userCode.loader.read] with
-  /// references from the original [Library] for things to work.
+  /// be rebuild special, namely they have to be
+  /// [currentKernelTarget.loader.read] with references from the original
+  /// [Library] for things to work.
   Map<LibraryBuilder, List<LibraryBuilder>>
-      experimentalInvalidationCreateRebuildBodiesBuilders(
+      _experimentalInvalidationCreateRebuildBodiesBuilders(
+          IncrementalKernelTarget currentKernelTarget,
           ExperimentalInvalidation? experimentalInvalidation,
           UriTranslator uriTranslator) {
     // Any builder(s) in [rebuildBodies] should be semi-reused: Create source
@@ -700,8 +759,9 @@
         new Map<LibraryBuilder, List<LibraryBuilder>>.identity();
     if (experimentalInvalidation != null) {
       for (LibraryBuilder library in experimentalInvalidation.rebuildBodies) {
-        LibraryBuilder newBuilder = userCode!.loader.read(library.importUri, -1,
-            accessor: userCode!.loader.first,
+        LibraryBuilder newBuilder = currentKernelTarget.loader.read(
+            library.importUri, -1,
+            accessorUri: currentKernelTarget.loader.firstUri,
             fileUri: library.fileUri,
             referencesFrom: library.library);
         List<LibraryBuilder> builders = [newBuilder];
@@ -713,8 +773,9 @@
           // libraries.
           Uri partUri = getPartUri(library.importUri, part);
           Uri? fileUri =
-              getPartFileUri(library.library.fileUri, part, uriTranslator);
-          LibraryBuilder newPartBuilder = userCode!.loader.read(partUri, -1,
+              uriTranslator.getPartFileUri(library.library.fileUri, part);
+          LibraryBuilder newPartBuilder = currentKernelTarget.loader.read(
+              partUri, -1,
               accessor: library,
               fileUri: fileUri,
               referencesFrom: library.library,
@@ -729,7 +790,7 @@
   /// When doing experimental invalidation we have to patch up the scopes of the
   /// the libraries we're not recompiling but should have recompiled if we
   /// didn't do anything special.
-  void experimentalInvalidationPatchUpScopes(
+  void _experimentalInvalidationPatchUpScopes(
       ExperimentalInvalidation? experimentalInvalidation,
       Map<LibraryBuilder, List<LibraryBuilder>> rebuildBodiesMap) {
     if (experimentalInvalidation != null) {
@@ -739,7 +800,7 @@
       // Maps from old library builder to map of new content.
       Map<LibraryBuilder, Map<String, Builder>> replacementSettersMap = {};
 
-      experimentalInvalidationFillReplacementMaps(
+      _experimentalInvalidationFillReplacementMaps(
           rebuildBodiesMap, replacementMap, replacementSettersMap);
 
       for (LibraryBuilder builder
@@ -777,20 +838,20 @@
             Builder childBuilder = iterator.current;
             if (childBuilder is SourceClassBuilder) {
               TypeBuilder? typeBuilder = childBuilder.supertypeBuilder;
-              replaceTypeBuilder(
+              _replaceTypeBuilder(
                   replacementMap, replacementSettersMap, typeBuilder);
               typeBuilder = childBuilder.mixedInTypeBuilder;
-              replaceTypeBuilder(
+              _replaceTypeBuilder(
                   replacementMap, replacementSettersMap, typeBuilder);
               if (childBuilder.onTypes != null) {
                 for (typeBuilder in childBuilder.onTypes!) {
-                  replaceTypeBuilder(
+                  _replaceTypeBuilder(
                       replacementMap, replacementSettersMap, typeBuilder);
                 }
               }
               if (childBuilder.interfaceBuilders != null) {
                 for (typeBuilder in childBuilder.interfaceBuilders!) {
-                  replaceTypeBuilder(
+                  _replaceTypeBuilder(
                       replacementMap, replacementSettersMap, typeBuilder);
                 }
               }
@@ -820,30 +881,31 @@
         fileSystem, includeComments, dillTarget, uriTranslator);
   }
 
-  /// Create a new [userCode] object, and add the reused builders to it.
-  void setupNewUserCode(
+  /// Create a new [IncrementalKernelTarget] object, and add the reused builders
+  /// to it.
+  IncrementalKernelTarget _setupNewKernelTarget(
       CompilerContext c,
       UriTranslator uriTranslator,
       ClassHierarchy? hierarchy,
       List<LibraryBuilder> reusedLibraries,
       ExperimentalInvalidation? experimentalInvalidation,
       Uri firstEntryPoint) {
-    userCode = createIncrementalKernelTarget(
+    IncrementalKernelTarget kernelTarget = createIncrementalKernelTarget(
         new HybridFileSystem(
             new MemoryFileSystem(
                 new Uri(scheme: "org-dartlang-debug", path: "/")),
             c.fileSystem),
         false,
-        dillLoadedData!,
+        _dillLoadedData!,
         uriTranslator);
-    userCode!.loader.hierarchy = hierarchy;
-    dillLoadedData!.loader.currentSourceLoader = userCode!.loader;
+    kernelTarget.loader.hierarchy = hierarchy;
+    _dillLoadedData!.loader.currentSourceLoader = kernelTarget.loader;
 
     // Re-use the libraries we've deemed re-usable.
     List<bool> seenModes = [false, false, false, false];
     for (LibraryBuilder library in reusedLibraries) {
       seenModes[library.library.nonNullableByDefaultCompiledMode.index] = true;
-      userCode!.loader.registerLibraryBuilder(library);
+      kernelTarget.loader.registerLibraryBuilder(library);
     }
     // Check compilation mode up against what we've seen here and set
     // `hasInvalidNnbdModeLibrary` accordingly.
@@ -853,14 +915,14 @@
           // Don't expect strong or invalid.
           if (seenModes[NonNullableByDefaultCompiledMode.Strong.index] ||
               seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
-            userCode!.loader.hasInvalidNnbdModeLibrary = true;
+            kernelTarget.loader.hasInvalidNnbdModeLibrary = true;
           }
           break;
         case NnbdMode.Strong:
           // Don't expect weak or invalid.
           if (seenModes[NonNullableByDefaultCompiledMode.Weak.index] ||
               seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
-            userCode!.loader.hasInvalidNnbdModeLibrary = true;
+            kernelTarget.loader.hasInvalidNnbdModeLibrary = true;
           }
           break;
         case NnbdMode.Agnostic:
@@ -868,7 +930,7 @@
           if (seenModes[NonNullableByDefaultCompiledMode.Strong.index] ||
               seenModes[NonNullableByDefaultCompiledMode.Weak.index] ||
               seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
-            userCode!.loader.hasInvalidNnbdModeLibrary = true;
+            kernelTarget.loader.hasInvalidNnbdModeLibrary = true;
           }
           break;
       }
@@ -876,75 +938,46 @@
       // Don't expect strong or invalid.
       if (seenModes[NonNullableByDefaultCompiledMode.Strong.index] ||
           seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
-        userCode!.loader.hasInvalidNnbdModeLibrary = true;
+        kernelTarget.loader.hasInvalidNnbdModeLibrary = true;
       }
     }
 
-    // The entry point(s) has to be set first for loader.first to be setup
-    // correctly. If the first one is in the rebuildBodies, we have to add it
-    // from there first.
-    Uri firstEntryPointImportUri =
-        userCode!.getEntryPointUri(firstEntryPoint, issueProblem: false);
-    bool wasFirstSet = false;
-    if (experimentalInvalidation != null) {
-      for (LibraryBuilder library in experimentalInvalidation.rebuildBodies) {
-        if (library.importUri == firstEntryPointImportUri) {
-          userCode!.loader.read(library.importUri, -1,
-              accessor: userCode!.loader.first,
-              fileUri: library.fileUri,
-              referencesFrom: library.library);
-          wasFirstSet = true;
-          break;
-        }
-      }
-    }
-    if (!wasFirstSet) {
-      userCode!.loader.read(firstEntryPointImportUri, -1,
-          accessor: userCode!.loader.first,
-          fileUri: firstEntryPointImportUri != firstEntryPoint
-              ? firstEntryPoint
-              : null);
-    }
-    if (userCode!.loader.first == null) {
-      LibraryBuilder? libraryBuilder =
-          userCode!.loader.lookupLibraryBuilder(firstEntryPointImportUri);
-      if (libraryBuilder != null) {
-        userCode!.loader.first = libraryBuilder;
-      }
-    }
+    // The entry point(s) has to be set first for loader.firstUri to be setup
+    // correctly.
+    kernelTarget.loader.firstUri =
+        kernelTarget.getEntryPointUri(firstEntryPoint, issueProblem: false);
+    return kernelTarget;
   }
 
   /// When tracking used libraries we mark them when we use them. To track
   /// correctly we have to unmark before the next iteration to not have too much
   /// marked and therefore incorrectly marked something as used when it is not.
-  void resetTrackingOfUsedLibraries(ClassHierarchy? hierarchy) {
-    if (trackNeededDillLibraries) {
-      // Reset dill loaders and kernel class hierarchy.
-      for (LibraryBuilder builder in dillLoadedData!.loader.libraryBuilders) {
-        if (builder is DillLibraryBuilder) {
-          if (builder.isBuiltAndMarked) {
-            // Clear cached calculations in classes which upon calculation can
-            // mark things as needed.
-            for (Builder builder in builder.scope.localMembers) {
-              if (builder is DillClassBuilder) {
-                builder.clearCachedValues();
-              }
+  void _resetTrackingOfUsedLibraries(ClassHierarchy? hierarchy) {
+    // Reset dill loaders and kernel class hierarchy.
+    for (LibraryBuilder builder in _dillLoadedData!.loader.libraryBuilders) {
+      if (builder is DillLibraryBuilder) {
+        if (builder.isBuiltAndMarked) {
+          // Clear cached calculations in classes which upon calculation can
+          // mark things as needed.
+          for (Builder builder in builder.scope.localMembers) {
+            if (builder is DillClassBuilder) {
+              builder.clearCachedValues();
             }
-            builder.isBuiltAndMarked = false;
           }
+          builder.isBuiltAndMarked = false;
         }
       }
+    }
 
-      if (hierarchy is ClosedWorldClassHierarchy) {
-        hierarchy.resetUsed();
-      }
+    if (hierarchy is ClosedWorldClassHierarchy) {
+      hierarchy.resetUsed();
     }
   }
 
   /// Cleanup the hierarchy to no longer reference libraries that we are
   /// invalidating (or would normally have invalidated if we hadn't done any
   /// experimental invalidation).
-  void cleanupHierarchy(
+  void _cleanupHierarchy(
       ClassHierarchy? hierarchy,
       ExperimentalInvalidation? experimentalInvalidation,
       ReusageResult reusedResult) {
@@ -970,19 +1003,20 @@
   /// If the package uris needs to be re-checked the uri translator has changed,
   /// and the [DillTarget] needs to get the new uri translator. We do that
   /// by creating a new one.
-  void recreateDillTargetIfPackageWasUpdated(
+  void _recreateDillTargetIfPackageWasUpdated(
       UriTranslator uriTranslator, CompilerContext c) {
-    if (hasToCheckPackageUris) {
+    if (_hasToCheckPackageUris) {
       // The package file was changed.
       // Make sure the dill loader is on the same page.
-      DillTarget oldDillLoadedData = dillLoadedData!;
-      dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
+      DillTarget oldDillLoadedData = _dillLoadedData!;
+      DillTarget newDillLoadedData = _dillLoadedData =
+          new DillTarget(_ticker, uriTranslator, c.options.target);
       for (DillLibraryBuilder library
           in oldDillLoadedData.loader.libraryBuilders) {
-        dillLoadedData!.loader.registerLibraryBuilder(library);
+        newDillLoadedData.loader.registerLibraryBuilder(library);
       }
-      dillLoadedData!.loader.first = oldDillLoadedData.loader.first;
-      dillLoadedData!.loader.libraries
+      newDillLoadedData.loader.first = oldDillLoadedData.loader.first;
+      newDillLoadedData.loader.libraries
           .addAll(oldDillLoadedData.loader.libraries);
     }
   }
@@ -994,37 +1028,34 @@
   /// We also have to remove any component problems beloning to any such
   /// no-longer-used library (to avoid re-issuing errors about no longer
   /// relevant stuff).
-  void cleanupRemovedBuilders(
+  void _cleanupRemovedBuilders(IncrementalKernelTarget? lastGoodKernelTarget,
       ReusageResult reusedResult, UriTranslator uriTranslator) {
     bool removedDillBuilders = false;
     for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
-      cleanupSourcesForBuilder(reusedResult, builder, uriTranslator,
-          CompilerContext.current.uriToSource);
-      incrementalSerializer?.invalidate(builder.fileUri);
+      _cleanupSourcesForBuilder(lastGoodKernelTarget, reusedResult, builder,
+          uriTranslator, CompilerContext.current.uriToSource);
+      _incrementalSerializer?.invalidate(builder.fileUri);
 
       LibraryBuilder? dillBuilder =
-          dillLoadedData!.loader.deregisterLibraryBuilder(builder.importUri);
+          _dillLoadedData!.loader.deregisterLibraryBuilder(builder.importUri);
       if (dillBuilder != null) {
         removedDillBuilders = true;
-        userBuilders?.remove(builder.importUri);
+        _userBuilders?.remove(builder.importUri);
       }
 
       // Remove component problems for libraries we don't reuse.
-      if (remainingComponentProblems.isNotEmpty) {
-        Library lib = builder.library;
-        removeLibraryFromRemainingComponentProblems(lib, uriTranslator);
-      }
+      _componentProblems.removeLibrary(builder.library, uriTranslator);
     }
 
     if (removedDillBuilders) {
-      makeDillLoaderLibrariesUpToDateWithBuildersMap();
+      _makeDillLoaderLibrariesUpToDateWithBuildersMap();
     }
   }
 
   bool _importsFfi() {
-    if (userBuilders == null) return false;
+    if (_userBuilders == null) return false;
     final Uri dartFfiUri = Uri.parse("dart:ffi");
-    for (LibraryBuilder builder in userBuilders!.values) {
+    for (LibraryBuilder builder in _userBuilders!.values) {
       Library lib = builder.library;
       for (LibraryDependency dependency in lib.dependencies) {
         if (dependency.targetLibrary.importUri == dartFfiUri) {
@@ -1038,7 +1069,7 @@
   /// Figure out if we can (and was asked to) do experimental invalidation.
   /// Note that this returns (future or) [null] if we're not doing experimental
   /// invalidation.
-  Future<ExperimentalInvalidation?> initializeExperimentalInvalidation(
+  Future<ExperimentalInvalidation?> _initializeExperimentalInvalidation(
       ReusageResult reusedResult, CompilerContext c) async {
     Set<LibraryBuilder>? rebuildBodies;
     Set<LibraryBuilder> originalNotReusedLibraries;
@@ -1046,7 +1077,7 @@
 
     if (!context.options.isExperimentEnabledGlobally(
         ExperimentalFlag.alternativeInvalidationStrategy)) return null;
-    if (modulesToLoad != null) return null;
+    if (_modulesToLoad != null) return null;
     if (reusedResult.directlyInvalidated.isEmpty) return null;
     if (reusedResult.invalidatedBecauseOfPackageUpdate) return null;
 
@@ -1185,29 +1216,30 @@
 
   /// Get UriTranslator, and figure out if the packages file was (potentially)
   /// changed.
-  Future<UriTranslator> setupPackagesAndUriTranslator(CompilerContext c) async {
+  Future<UriTranslator> _setupPackagesAndUriTranslator(
+      CompilerContext c) async {
     bool bypassCache = false;
-    if (!identical(previousPackagesUri, c.options.packagesUriRaw)) {
-      previousPackagesUri = c.options.packagesUriRaw;
+    if (!identical(_previousPackagesUri, c.options.packagesUriRaw)) {
+      _previousPackagesUri = c.options.packagesUriRaw;
       bypassCache = true;
-    } else if (this.invalidatedUris.contains(c.options.packagesUri)) {
+    } else if (this._invalidatedUris.contains(c.options.packagesUri)) {
       bypassCache = true;
     }
     UriTranslator uriTranslator =
         await c.options.getUriTranslator(bypassCache: bypassCache);
-    previousPackagesMap = currentPackagesMap;
-    currentPackagesMap = createPackagesMap(uriTranslator.packages);
+    _previousPackagesMap = _currentPackagesMap;
+    _currentPackagesMap = _createPackagesMap(uriTranslator.packages);
     // TODO(jensj): We can probably (from the maps above) figure out if anything
     // changed and only set this to true if it did.
-    hasToCheckPackageUris = hasToCheckPackageUris || bypassCache;
-    ticker.logMs("Read packages file");
-    if (initializedForExpressionCompilationOnly) {
-      hasToCheckPackageUris = false;
+    _hasToCheckPackageUris = _hasToCheckPackageUris || bypassCache;
+    _ticker.logMs("Read packages file");
+    if (_initializedForExpressionCompilationOnly) {
+      _hasToCheckPackageUris = false;
     }
     return uriTranslator;
   }
 
-  Map<String, Package> createPackagesMap(PackageConfig packages) {
+  Map<String, Package> _createPackagesMap(PackageConfig packages) {
     Map<String, Package> result = new Map<String, Package>();
     for (Package package in packages.packages) {
       result[package.name] = package;
@@ -1217,88 +1249,42 @@
 
   /// Load platform and (potentially) initialize from dill,
   /// or initialize from component.
-  Future<IncrementalCompilerData> ensurePlatformAndInitialize(
-      UriTranslator uriTranslator, CompilerContext c) async {
+  Future<IncrementalCompilerData> _ensurePlatformAndInitialize(
+      UriTranslator uriTranslator, CompilerContext context) async {
     IncrementalCompilerData data = new IncrementalCompilerData();
-    if (dillLoadedData == null) {
-      int bytesLength = 0;
-      if (componentToInitializeFrom != null) {
-        // If initializing from a component it has to include the sdk,
-        // so we explicitly don't load it here.
-        initializeFromComponent(uriTranslator, c, data);
-        componentToInitializeFrom = null;
-      } else {
-        List<int>? summaryBytes = await c.options.loadSdkSummaryBytes();
-        bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
-        if (initializeFromDillUri != null) {
-          try {
-            bytesLength += await initializeFromDill(uriTranslator, c, data);
-          } catch (e, st) {
-            // We might have loaded x out of y libraries into the component.
-            // To avoid any unforeseen problems start over.
-            bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
-
-            if (e is InvalidKernelVersionError ||
-                e is InvalidKernelSdkVersionError ||
-                e is PackageChangedError ||
-                e is CanonicalNameSdkError ||
-                e is CompilationModeError) {
-              // Don't report any warning.
-            } else {
-              Uri? gzInitializedFrom;
-              if (c.options.writeFileOnCrashReport) {
-                gzInitializedFrom = saveAsGzip(
-                    data.initializationBytes!, "initialize_from.dill");
-                recordTemporaryFileForTesting(gzInitializedFrom);
-              }
-              if (e is CanonicalNameError) {
-                Message message = gzInitializedFrom != null
-                    ? templateInitializeFromDillNotSelfContained.withArguments(
-                        initializeFromDillUri.toString(), gzInitializedFrom)
-                    : templateInitializeFromDillNotSelfContainedNoDump
-                        .withArguments(initializeFromDillUri.toString());
-                dillLoadedData!.loader
-                    .addProblem(message, TreeNode.noOffset, 1, null);
-              } else {
-                // Unknown error: Report problem as such.
-                Message message = gzInitializedFrom != null
-                    ? templateInitializeFromDillUnknownProblem.withArguments(
-                        initializeFromDillUri.toString(),
-                        "$e",
-                        "$st",
-                        gzInitializedFrom)
-                    : templateInitializeFromDillUnknownProblemNoDump
-                        .withArguments(
-                            initializeFromDillUri.toString(), "$e", "$st");
-                dillLoadedData!.loader
-                    .addProblem(message, TreeNode.noOffset, 1, null);
-              }
-            }
-          }
-        }
-      }
-      appendLibraries(data, bytesLength);
+    if (_dillLoadedData == null) {
+      DillTarget dillLoadedData = _dillLoadedData =
+          new DillTarget(_ticker, uriTranslator, context.options.target);
+      int bytesLength = await _initializationStrategy.initialize(
+          dillLoadedData,
+          uriTranslator,
+          context,
+          data,
+          _componentProblems,
+          _incrementalSerializer,
+          recorderForTesting);
+      _appendLibraries(data, bytesLength);
 
       // We suppress finalization errors because they will reported via
       // problemsAsJson fields (with better precision).
-      dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
-      userBuilders = <Uri, LibraryBuilder>{};
-      platformBuilders = <LibraryBuilder>[];
+      dillLoadedData.buildOutlines(suppressFinalizationErrors: true);
+      _userBuilders = <Uri, LibraryBuilder>{};
+      _platformBuilders = <LibraryBuilder>[];
       for (DillLibraryBuilder builder
-          in dillLoadedData!.loader.libraryBuilders) {
+          in dillLoadedData.loader.libraryBuilders) {
         if (builder.importUri.scheme == "dart") {
-          platformBuilders!.add(builder);
+          _platformBuilders!.add(builder);
         } else {
-          userBuilders![builder.importUri] = builder;
+          _userBuilders![builder.importUri] = builder;
         }
       }
-      if (userBuilders!.isEmpty) userBuilders = null;
+      if (_userBuilders!.isEmpty) _userBuilders = null;
     }
     data.initializationBytes = null;
     return data;
   }
 
-  void replaceTypeBuilder(
+  void _replaceTypeBuilder(
       Map<LibraryBuilder, Map<String, Builder>> replacementMap,
       Map<LibraryBuilder, Map<String, Builder>> replacementSettersMap,
       TypeBuilder? typeBuilder) {
@@ -1319,12 +1305,6 @@
     typeBuilder!.bind(replacement as TypeDeclarationBuilder);
   }
 
-  @override
-  CoreTypes? getCoreTypes() => userCode?.loader.coreTypes;
-
-  @override
-  ClassHierarchy? getClassHierarchy() => userCode?.loader.hierarchy;
-
   /// Allows for updating the list of needed libraries.
   ///
   /// Useful if a class hierarchy has been used externally.
@@ -1337,9 +1317,9 @@
   /// (though handling of the case where all bets are off should probably still
   /// live locally).
   void updateNeededDillLibrariesWithHierarchy(
-      ClassHierarchy hierarchy, ClassHierarchyBuilder? builderHierarchy) {
+      Set<Library> neededDillLibraries, ClassHierarchy hierarchy,
+      [ClassHierarchyBuilder? builderHierarchy]) {
     if (hierarchy is ClosedWorldClassHierarchy && !hierarchy.allBetsOff) {
-      neededDillLibraries ??= new Set<Library>();
       Set<Class> classes = new Set<Class>();
       List<Class> worklist = <Class>[];
       // Get all classes touched by kernel class hierarchy.
@@ -1380,35 +1360,35 @@
         Library library = c.enclosingLibrary;
         // Only add if loaded from a dill file (and wasn't a 'dill' that was
         // converted from source builders to dill builders).
-        if (dillLoadedData!.loader.containsLibraryBuilder(library.importUri) &&
-            (previousSourceBuilders == null ||
-                !previousSourceBuilders!.contains(library))) {
-          neededDillLibraries!.add(library);
+        if (_dillLoadedData!.loader.containsLibraryBuilder(library.importUri) &&
+            (_previousSourceBuilders == null ||
+                !_previousSourceBuilders!.contains(library))) {
+          neededDillLibraries.add(library);
         }
       }
     } else {
       // Cannot track in other kernel class hierarchies or
       // if all bets are off: Add everything (except for the libraries we just
       // converted from source builders to dill builders).
-      neededDillLibraries = new Set<Library>();
+      neededDillLibraries.clear();
       for (DillLibraryBuilder builder
-          in dillLoadedData!.loader.libraryBuilders) {
-        if (previousSourceBuilders == null ||
-            !previousSourceBuilders!.contains(builder.library)) {
-          neededDillLibraries!.add(builder.library);
+          in _dillLoadedData!.loader.libraryBuilders) {
+        if (_previousSourceBuilders == null ||
+            !_previousSourceBuilders!.contains(builder.library)) {
+          neededDillLibraries.add(builder.library);
         }
       }
     }
   }
 
   /// Internal method.
-  void invalidateNotKeptUserBuilders(Set<Uri?> invalidatedUris) {
-    if (modulesToLoad != null && userBuilders != null) {
+  void _invalidateNotKeptUserBuilders(Set<Uri?> invalidatedUris) {
+    if (_modulesToLoad != null && _userBuilders != null) {
       Set<Library> loadedNotKept = new Set<Library>();
-      for (LibraryBuilder builder in userBuilders!.values) {
+      for (LibraryBuilder builder in _userBuilders!.values) {
         loadedNotKept.add(builder.library);
       }
-      for (Component module in modulesToLoad!) {
+      for (Component module in _modulesToLoad!) {
         loadedNotKept.removeAll(module.libraries);
       }
       for (Library lib in loadedNotKept) {
@@ -1418,43 +1398,44 @@
   }
 
   /// Internal method.
-  void loadEnsureLoadedComponents(List<LibraryBuilder> reusedLibraries) {
-    if (modulesToLoad != null) {
+  void _loadEnsureLoadedComponents(List<LibraryBuilder> reusedLibraries) {
+    if (_modulesToLoad != null) {
       bool loadedAnything = false;
-      for (Component module in modulesToLoad!) {
+      for (Component module in _modulesToLoad!) {
         bool usedComponent = false;
         for (Library lib in module.libraries) {
-          if (!dillLoadedData!.loader.containsLibraryBuilder(lib.importUri)) {
-            dillLoadedData!.loader.libraries.add(lib);
-            dillLoadedData!.loader.registerKnownLibrary(lib);
-            reusedLibraries.add(dillLoadedData!.loader.read(lib.importUri, -1));
+          if (!_dillLoadedData!.loader.containsLibraryBuilder(lib.importUri)) {
+            _dillLoadedData!.loader.libraries.add(lib);
+            _dillLoadedData!.loader.registerKnownLibrary(lib);
+            reusedLibraries
+                .add(_dillLoadedData!.loader.read(lib.importUri, -1));
             usedComponent = true;
           }
         }
         if (usedComponent) {
-          dillLoadedData!.uriToSource.addAll(module.uriToSource);
+          _dillLoadedData!.uriToSource.addAll(module.uriToSource);
           loadedAnything = true;
         }
       }
       if (loadedAnything) {
         // We suppress finalization errors because they will reported via
         // problemsAsJson fields (with better precision).
-        dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
-        userBuilders = <Uri, LibraryBuilder>{};
-        platformBuilders = <LibraryBuilder>[];
+        _dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
+        _userBuilders = <Uri, LibraryBuilder>{};
+        _platformBuilders = <LibraryBuilder>[];
         for (DillLibraryBuilder builder
-            in dillLoadedData!.loader.libraryBuilders) {
+            in _dillLoadedData!.loader.libraryBuilders) {
           if (builder.importUri.scheme == "dart") {
-            platformBuilders!.add(builder);
+            _platformBuilders!.add(builder);
           } else {
-            userBuilders![builder.importUri] = builder;
+            _userBuilders![builder.importUri] = builder;
           }
         }
-        if (userBuilders!.isEmpty) {
-          userBuilders = null;
+        if (_userBuilders!.isEmpty) {
+          _userBuilders = null;
         }
       }
-      modulesToLoad = null;
+      _modulesToLoad = null;
     }
   }
 
@@ -1463,7 +1444,7 @@
   }
 
   /// Internal method.
-  void reissueLibraryProblems(
+  void _reissueLibraryProblems(
       Set<Library> allLibraries, List<Library> compiledLibraries) {
     // The newly-compiled libraries have issued problems already. Re-issue
     // problems for the libraries that weren't re-compiled (ignore compile
@@ -1484,75 +1465,12 @@
   }
 
   /// Internal method.
-  /// Re-issue problems on the component and return the filtered list.
-  List<String> reissueComponentProblems(Component componentWithDill) {
-    // These problems have already been reported.
-    Set<String> issuedProblems = new Set<String>();
-    if (componentWithDill.problemsAsJson != null) {
-      issuedProblems.addAll(componentWithDill.problemsAsJson!);
-    }
-
-    // Report old problems that wasn't reported again.
-    Set<Uri>? strongModeNNBDPackageOptOutUris;
-    for (MapEntry<Uri, List<DiagnosticMessageFromJson>> entry
-        in remainingComponentProblems.entries) {
-      List<DiagnosticMessageFromJson> messages = entry.value;
-      for (int i = 0; i < messages.length; i++) {
-        DiagnosticMessageFromJson message = messages[i];
-        if (message.codeName == "StrongModeNNBDPackageOptOut") {
-          // Special case this: Don't issue them here; instead collect them
-          // to get their uris and re-issue a new error.
-          strongModeNNBDPackageOptOutUris ??= {};
-          strongModeNNBDPackageOptOutUris.add(entry.key);
-          continue;
-        }
-        if (issuedProblems.add(message.toJsonString())) {
-          context.options.reportDiagnosticMessage(message);
-        }
-      }
-    }
-    if (strongModeNNBDPackageOptOutUris != null) {
-      // Get the builders for these uris; then call
-      // `SourceLoader.giveCombinedErrorForNonStrongLibraries` on them to issue
-      // a new error.
-      Set<LibraryBuilder> builders = {};
-      SourceLoader loader = userCode!.loader;
-      for (LibraryBuilder builder in loader.libraryBuilders) {
-        if (strongModeNNBDPackageOptOutUris.contains(builder.fileUri)) {
-          builders.add(builder);
-        }
-      }
-      FormattedMessage message = loader.giveCombinedErrorForNonStrongLibraries(
-          builders,
-          emitNonPackageErrors: false)!;
-      issuedProblems.add(message.toJsonString());
-      // The problem was issued by the call so don't re-issue it here.
-    }
-
-    // Save any new component-problems.
-    _addProblemsAsJsonToRemainingProblems(componentWithDill.problemsAsJson);
-    return new List<String>.from(issuedProblems);
-  }
-
-  /// Internal method.
-  Uri? getPartFileUri(
-      Uri parentFileUri, LibraryPart part, UriTranslator uriTranslator) {
-    Uri? fileUri = getPartUri(parentFileUri, part);
-    if (fileUri.scheme == "package") {
-      // Part was specified via package URI and the resolve above thus
-      // did not go as expected. Translate the package URI to get the
-      // actual file URI.
-      fileUri = uriTranslator.translate(fileUri, false);
-    }
-    return fileUri;
-  }
-
-  /// Internal method.
   /// Compute the transitive closure.
   ///
   /// As a side-effect, this also cleans-up now-unreferenced builders as well as
   /// any saved component problems for such builders.
-  List<Library> computeTransitiveClosure(
+  List<Library> _computeTransitiveClosure(
+      IncrementalKernelTarget currentKernelTarget,
       List<Library> inputLibraries,
       List<Uri> entryPoints,
       List<LibraryBuilder> reusedLibraries,
@@ -1622,7 +1540,7 @@
           }
           for (LibraryPart part in library.parts) {
             Uri? partFileUri =
-                getPartFileUri(library.fileUri, part, uriTranslator);
+                uriTranslator.getPartFileUri(library.fileUri, part);
             partsUsed.add(partFileUri);
           }
         }
@@ -1633,26 +1551,32 @@
     bool removedDillBuilders = false;
     for (Uri uri in potentiallyReferencedLibraries.keys) {
       if (uri.scheme == "package") continue;
-      LibraryBuilder? builder = userCode!.loader.deregisterLibraryBuilder(uri);
+      LibraryBuilder? builder =
+          currentKernelTarget.loader.deregisterLibraryBuilder(uri);
       if (builder != null) {
         Library lib = builder.library;
         removedLibraries.add(lib);
-        if (dillLoadedData!.loader.deregisterLibraryBuilder(uri) != null) {
+        if (_dillLoadedData!.loader.deregisterLibraryBuilder(uri) != null) {
           removedDillBuilders = true;
         }
-        cleanupSourcesForBuilder(null, builder, uriTranslator,
-            CompilerContext.current.uriToSource, uriToSource, partsUsed);
-        userBuilders?.remove(uri);
-        removeLibraryFromRemainingComponentProblems(
-            lib, uriTranslator, partsUsed);
+        _cleanupSourcesForBuilder(
+            currentKernelTarget,
+            null,
+            builder,
+            uriTranslator,
+            CompilerContext.current.uriToSource,
+            uriToSource,
+            partsUsed);
+        _userBuilders?.remove(uri);
+        _componentProblems.removeLibrary(lib, uriTranslator, partsUsed);
 
         // Technically this isn't necessary as the uri is not a package-uri.
-        incrementalSerializer?.invalidate(builder.fileUri);
+        _incrementalSerializer?.invalidate(builder.fileUri);
       }
     }
     hierarchy.applyTreeChanges(removedLibraries, const [], const []);
     if (removedDillBuilders) {
-      makeDillLoaderLibrariesUpToDateWithBuildersMap();
+      _makeDillLoaderLibrariesUpToDateWithBuildersMap();
     }
 
     return result;
@@ -1663,10 +1587,10 @@
   /// will still hang around and be linked into the Component created internally
   /// in the compilation process.
   /// This method syncs the [libraries] list with the data in [builders].
-  void makeDillLoaderLibrariesUpToDateWithBuildersMap() {
-    dillLoadedData!.loader.libraries.clear();
-    for (LibraryBuilder builder in dillLoadedData!.loader.libraryBuilders) {
-      dillLoadedData!.loader.libraries.add(builder.library);
+  void _makeDillLoaderLibrariesUpToDateWithBuildersMap() {
+    _dillLoadedData!.loader.libraries.clear();
+    for (LibraryBuilder builder in _dillLoadedData!.loader.libraryBuilders) {
+      _dillLoadedData!.loader.libraries.add(builder.library);
     }
   }
 
@@ -1675,7 +1599,8 @@
   /// [partsUsed] indicates part uris that are used by (other/alive) libraries.
   /// Those parts will not be cleaned up. This is useful when a part has been
   /// "moved" to be part of another library.
-  void cleanupSourcesForBuilder(
+  void _cleanupSourcesForBuilder(
+      IncrementalKernelTarget? lastGoodKernelTarget,
       ReusageResult? reusedResult,
       LibraryBuilder builder,
       UriTranslator uriTranslator,
@@ -1686,20 +1611,21 @@
     uriToSourceExtra?.remove(builder.fileUri);
     Library lib = builder.library;
     for (LibraryPart part in lib.parts) {
-      Uri? partFileUri = getPartFileUri(lib.fileUri, part, uriTranslator);
+      Uri? partFileUri = uriTranslator.getPartFileUri(lib.fileUri, part);
       if (partsUsed != null && partsUsed.contains(partFileUri)) continue;
 
       // If the builders map contain the "parts" import uri, it's a real library
       // (erroneously) used as a part so we don't want to remove that.
-      if (userCode?.loader != null) {
+      if (lastGoodKernelTarget?.loader != null) {
         Uri? partImportUri = uriToSource[partFileUri]?.importUri;
         if (partImportUri != null &&
-            userCode!.loader.containsLibraryBuilder(partImportUri)) {
+            lastGoodKernelTarget!.loader
+                .containsLibraryBuilder(partImportUri)) {
           continue;
         }
       } else if (reusedResult != null) {
-        // We've just launched and don't have userCode yet. Search reusedResult
-        // for a kept library with this uri.
+        // We've just launched and don't have [lastGoodKernelTarget] yet. Search
+        // reusedResult for a kept library with this uri.
         bool found = false;
         for (int i = 0; i < reusedResult.reusedLibraries.length; i++) {
           LibraryBuilder reusedLibrary = reusedResult.reusedLibraries[i];
@@ -1718,195 +1644,12 @@
   }
 
   /// Internal method.
-  ///
-  /// [partsUsed] indicates part uris that are used by (other/alive) libraries.
-  /// Those parts will not be removed from the component problems.
-  /// This is useful when a part has been "moved" to be part of another library.
-  void removeLibraryFromRemainingComponentProblems(
-      Library lib, UriTranslator uriTranslator,
-      [Set<Uri?>? partsUsed]) {
-    remainingComponentProblems.remove(lib.fileUri);
-    // Remove parts too.
-    for (LibraryPart part in lib.parts) {
-      Uri? partFileUri = getPartFileUri(lib.fileUri, part, uriTranslator);
-      remainingComponentProblems.remove(partFileUri);
-    }
-  }
-
-  /// Internal method.
-  int prepareSummary(List<int>? summaryBytes, UriTranslator uriTranslator,
-      CompilerContext c, IncrementalCompilerData data) {
-    dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
-    int bytesLength = 0;
-
-    data.component = c.options.target.configureComponent(new Component());
-    if (summaryBytes != null) {
-      ticker.logMs("Read ${c.options.sdkSummary}");
-      new BinaryBuilderWithMetadata(summaryBytes,
-              disableLazyReading: false, disableLazyClassReading: true)
-          .readComponent(data.component!);
-      ticker.logMs("Deserialized ${c.options.sdkSummary}");
-      bytesLength += summaryBytes.length;
-    }
-
-    return bytesLength;
-  }
-
-  /// Internal method.
-  // This procedure will try to load the dill file and will crash if it cannot.
-  Future<int> initializeFromDill(UriTranslator uriTranslator, CompilerContext c,
-      IncrementalCompilerData data) async {
-    int bytesLength = 0;
-    FileSystemEntity entity =
-        c.options.fileSystem.entityForUri(initializeFromDillUri!);
-    if (await entity.exists()) {
-      List<int> initializationBytes = await entity.readAsBytes();
-      // ignore: unnecessary_null_comparison
-      if (initializationBytes != null && initializationBytes.isNotEmpty) {
-        ticker.logMs("Read $initializeFromDillUri");
-        data.initializationBytes = initializationBytes;
-
-        // We're going to output all we read here so lazy loading it
-        // doesn't make sense.
-        List<SubComponentView> views = new BinaryBuilderWithMetadata(
-                initializationBytes,
-                disableLazyReading: true)
-            .readComponent(data.component!,
-                checkCanonicalNames: true, createView: true)!;
-
-        // Compute "output nnbd mode".
-        NonNullableByDefaultCompiledMode compiledMode;
-        if (c.options
-            .isExperimentEnabledGlobally(ExperimentalFlag.nonNullable)) {
-          switch (c.options.nnbdMode) {
-            case NnbdMode.Weak:
-              compiledMode = NonNullableByDefaultCompiledMode.Weak;
-              break;
-            case NnbdMode.Strong:
-              compiledMode = NonNullableByDefaultCompiledMode.Strong;
-              break;
-            case NnbdMode.Agnostic:
-              compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
-              break;
-          }
-        } else {
-          compiledMode = NonNullableByDefaultCompiledMode.Weak;
-        }
-
-        // Check the any package-urls still point to the same file
-        // (e.g. the package still exists and hasn't been updated).
-        // Also verify NNBD settings.
-        for (Library lib in data.component!.libraries) {
-          if (lib.importUri.scheme == "package" &&
-              uriTranslator.translate(lib.importUri, false) != lib.fileUri) {
-            // Package has been removed or updated.
-            // This library should be thrown away.
-            // Everything that depends on it should be thrown away.
-            // TODO(jensj): Anything that doesn't depend on it can be kept.
-            // For now just don't initialize from this dill.
-            throw const PackageChangedError();
-          }
-          // Note: If a library has a NonNullableByDefaultCompiledMode.invalid
-          // we will throw and we won't initialize from it.
-          // That's wanted behavior.
-          if (compiledMode !=
-              mergeCompilationModeOrThrow(
-                  compiledMode, lib.nonNullableByDefaultCompiledMode)) {
-            throw new CompilationModeError(
-                "Can't compile to $compiledMode with library with mode "
-                "${lib.nonNullableByDefaultCompiledMode}.");
-          }
-        }
-
-        // Only initialize the incremental serializer when we know we'll
-        // actually use the data loaded from dill.
-        initializedIncrementalSerializer =
-            incrementalSerializer?.initialize(initializationBytes, views) ??
-                false;
-
-        initializedFromDill = true;
-        bytesLength += initializationBytes.length;
-        saveComponentProblems(data);
-      }
-    }
-    return bytesLength;
-  }
-
-  /// Internal method.
-  void saveComponentProblems(IncrementalCompilerData data) {
-    List<String>? problemsAsJson = data.component!.problemsAsJson;
-    _addProblemsAsJsonToRemainingProblems(problemsAsJson);
-  }
-
-  void _addProblemsAsJsonToRemainingProblems(List<String>? problemsAsJson) {
-    if (problemsAsJson != null) {
-      for (String jsonString in problemsAsJson) {
-        DiagnosticMessageFromJson message =
-            new DiagnosticMessageFromJson.fromJson(jsonString);
-        assert(message.uri != null ||
-            (message.involvedFiles != null &&
-                message.involvedFiles!.isNotEmpty));
-        if (message.uri != null) {
-          List<DiagnosticMessageFromJson> messages =
-              remainingComponentProblems[message.uri!] ??=
-                  <DiagnosticMessageFromJson>[];
-          messages.add(message);
-        }
-        if (message.involvedFiles != null) {
-          // This indexes the same message under several uris - this way it will
-          // be issued as long as it's a problem. It will because of
-          // deduplication when we re-issue these (in reissueComponentProblems)
-          // only be reported once.
-          for (Uri uri in message.involvedFiles!) {
-            List<DiagnosticMessageFromJson> messages =
-                remainingComponentProblems[uri] ??=
-                    <DiagnosticMessageFromJson>[];
-            messages.add(message);
-          }
-        }
-      }
-    }
-  }
-
-  /// Internal method.
-  // This procedure will set up compiler from [componentToInitializeFrom].
-  void initializeFromComponent(UriTranslator uriTranslator, CompilerContext c,
-      IncrementalCompilerData data) {
-    ticker.logMs("About to initializeFromComponent");
-
-    dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
-    data.component = new Component(
-        libraries: componentToInitializeFrom!.libraries,
-        uriToSource: componentToInitializeFrom!.uriToSource)
-      ..setMainMethodAndMode(componentToInitializeFrom!.mainMethod?.reference,
-          true, componentToInitializeFrom!.mode);
-    saveComponentProblems(data);
-
-    bool foundDartCore = false;
-    for (int i = 0; i < data.component!.libraries.length; i++) {
-      Library library = data.component!.libraries[i];
-      if (library.importUri.scheme == "dart" &&
-          library.importUri.path == "core") {
-        foundDartCore = true;
-        break;
-      }
-    }
-
-    if (!foundDartCore) {
-      throw const InitializeFromComponentError("Did not find dart:core when "
-          "tried to initialize from component.");
-    }
-
-    ticker.logMs("Ran initializeFromComponent");
-  }
-
-  /// Internal method.
-  void appendLibraries(IncrementalCompilerData data, int bytesLength) {
+  void _appendLibraries(IncrementalCompilerData data, int bytesLength) {
     if (data.component != null) {
-      dillLoadedData!.loader
+      _dillLoadedData!.loader
           .appendLibraries(data.component!, byteCount: bytesLength);
     }
-    ticker.logMs("Appended libraries");
+    _ticker.logMs("Appended libraries");
   }
 
   @override
@@ -1919,12 +1662,14 @@
       {String? className,
       String? methodName,
       bool isStatic = false}) async {
-    assert(dillLoadedData != null && userCode != null);
+    IncrementalKernelTarget? lastGoodKernelTarget = this._lastGoodKernelTarget;
+    assert(_dillLoadedData != null && lastGoodKernelTarget != null);
 
     return await context.runInContext((_) async {
-      LibraryBuilder libraryBuilder = userCode!.loader
-          .read(libraryUri, -1, accessor: userCode!.loader.first);
-      ticker.logMs("Loaded library $libraryUri");
+      LibraryBuilder libraryBuilder = lastGoodKernelTarget!.loader.read(
+          libraryUri, -1,
+          accessorUri: lastGoodKernelTarget.loader.firstUri);
+      _ticker.logMs("Loaded library $libraryUri");
 
       Class? cls;
       if (className != null) {
@@ -1954,11 +1699,11 @@
         }
       }
 
-      userCode!.loader.resetSeenMessages();
+      lastGoodKernelTarget.loader.resetSeenMessages();
 
       for (TypeParameter typeParam in typeDefinitions) {
         if (!isLegalIdentifier(typeParam.name!)) {
-          userCode!.loader.addProblem(
+          lastGoodKernelTarget.loader.addProblem(
               templateIncrementalCompilerIllegalTypeParameter
                   .withArguments('$typeParam'),
               typeParam.fileOffset,
@@ -1975,7 +1720,7 @@
                 !isStatic &&
                 index == 1 &&
                 isExtensionThisName(name)))) {
-          userCode!.loader.addProblem(
+          lastGoodKernelTarget.loader.addProblem(
               templateIncrementalCompilerIllegalParameter.withArguments(name),
               // TODO: pass variable declarations instead of
               // parameter names for proper location detection.
@@ -1992,12 +1737,12 @@
         debugExprUri,
         /*packageUri*/ null,
         new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
-        userCode!.loader,
+        lastGoodKernelTarget.loader,
         null,
         scope: libraryBuilder.scope.createNestedScope("expression"),
         nameOrigin: libraryBuilder,
       );
-      ticker.logMs("Created debug library");
+      _ticker.logMs("Created debug library");
 
       if (libraryBuilder is DillLibraryBuilder) {
         for (LibraryDependency dependency
@@ -2030,10 +1775,11 @@
         }
 
         debugLibrary.addImportsToScope();
-        ticker.logMs("Added imports");
+        _ticker.logMs("Added imports");
       }
 
-      HybridFileSystem hfs = userCode!.fileSystem as HybridFileSystem;
+      HybridFileSystem hfs =
+          lastGoodKernelTarget.fileSystem as HybridFileSystem;
       MemoryFileSystem fs = hfs.memory;
       fs.entityForUri(debugExprUri).writeAsStringSync(expression);
 
@@ -2061,13 +1807,15 @@
         }
       }
 
-      debugLibrary.build(userCode!.loader.coreLibrary, modifyTarget: false);
-      Expression compiledExpression = await userCode!.loader.buildExpression(
-          debugLibrary,
-          className ?? extensionName,
-          (className != null && !isStatic) || extensionThis != null,
-          parameters,
-          extensionThis);
+      debugLibrary.build(lastGoodKernelTarget.loader.coreLibrary,
+          modifyTarget: false);
+      Expression compiledExpression = await lastGoodKernelTarget.loader
+          .buildExpression(
+              debugLibrary,
+              className ?? extensionName,
+              (className != null && !isStatic) || extensionThis != null,
+              parameters,
+              extensionThis);
 
       Procedure procedure = new Procedure(
           new Name(syntheticProcedureName), ProcedureKind.Method, parameters,
@@ -2080,21 +1828,21 @@
       procedure.fileUri = debugLibrary.fileUri;
       procedure.parent = cls ?? libraryBuilder.library;
 
-      userCode!.uriToSource.remove(debugExprUri);
-      userCode!.loader.sourceBytes.remove(debugExprUri);
+      lastGoodKernelTarget.uriToSource.remove(debugExprUri);
+      lastGoodKernelTarget.loader.sourceBytes.remove(debugExprUri);
 
       // Make sure the library has a canonical name.
       Component c = new Component(libraries: [debugLibrary.library]);
       c.computeCanonicalNames();
-      ticker.logMs("Built debug library");
+      _ticker.logMs("Built debug library");
 
-      userCode!.runProcedureTransformations(procedure);
+      lastGoodKernelTarget.runProcedureTransformations(procedure);
 
       return procedure;
     });
   }
 
-  bool packagesEqual(Package? a, Package? b) {
+  bool _packagesEqual(Package? a, Package? b) {
     if (a == null || b == null) return false;
     if (a.name != b.name) return false;
     if (a.root != b.root) return false;
@@ -2105,16 +1853,20 @@
   }
 
   /// Internal method.
-  ReusageResult computeReusedLibraries(Set<Uri?> invalidatedUris,
-      UriTranslator uriTranslator, List<Uri> entryPoints) {
+  ReusageResult _computeReusedLibraries(
+      IncrementalKernelTarget? lastGoodKernelTarget,
+      Map<Uri, LibraryBuilder>? _userBuilders,
+      Set<Uri?> invalidatedUris,
+      UriTranslator uriTranslator,
+      List<Uri> entryPoints) {
     Set<Uri> seenUris = new Set<Uri>();
     List<LibraryBuilder> reusedLibraries = <LibraryBuilder>[];
-    for (int i = 0; i < platformBuilders!.length; i++) {
-      LibraryBuilder builder = platformBuilders![i];
+    for (int i = 0; i < _platformBuilders!.length; i++) {
+      LibraryBuilder builder = _platformBuilders![i];
       if (!seenUris.add(builder.importUri)) continue;
       reusedLibraries.add(builder);
     }
-    if (userCode == null && userBuilders == null) {
+    if (lastGoodKernelTarget == null && _userBuilders == null) {
       return new ReusageResult.reusedLibrariesOnly(reusedLibraries);
     }
     bool invalidatedBecauseOfPackageUpdate = false;
@@ -2134,16 +1886,16 @@
       if (importUri != fileUri && invalidatedUris.contains(fileUri)) {
         return true;
       }
-      if (hasToCheckPackageUris && importUri.scheme == "package") {
+      if (_hasToCheckPackageUris && importUri.scheme == "package") {
         // Get package name, check if the base URI has changed for the package,
         // if it has, translate the URI again,
         // otherwise the URI cannot have changed.
         String path = importUri.path;
         int firstSlash = path.indexOf('/');
         String packageName = path.substring(0, firstSlash);
-        if (previousPackagesMap == null ||
-            !packagesEqual(previousPackagesMap![packageName],
-                currentPackagesMap![packageName])) {
+        if (_previousPackagesMap == null ||
+            !_packagesEqual(_previousPackagesMap![packageName],
+                _currentPackagesMap![packageName])) {
           Uri? newFileUri = uriTranslator.translate(importUri, false);
           if (newFileUri != fileUri) {
             invalidatedBecauseOfPackageUpdate = true;
@@ -2179,8 +1931,8 @@
       } else if (libraryBuilder is DillLibraryBuilder) {
         for (LibraryPart part in libraryBuilder.library.parts) {
           Uri partUri = getPartUri(libraryBuilder.importUri, part);
-          Uri? fileUri = getPartFileUri(
-              libraryBuilder.library.fileUri, part, uriTranslator);
+          Uri? fileUri = uriTranslator.getPartFileUri(
+              libraryBuilder.library.fileUri, part);
           partUriToParent[partUri] = libraryBuilder;
           partUriToParent[fileUri] = libraryBuilder;
 
@@ -2198,19 +1950,21 @@
       }
     }
 
-    if (userCode != null) {
-      // userCode already contains the builders from userBuilders.
-      for (LibraryBuilder libraryBuilder in userCode!.loader.libraryBuilders) {
+    if (lastGoodKernelTarget != null) {
+      // [lastGoodKernelTarget] already contains the builders from
+      // [userBuilders].
+      for (LibraryBuilder libraryBuilder
+          in lastGoodKernelTarget.loader.libraryBuilders) {
         addBuilderAndInvalidateUris(libraryBuilder.importUri, libraryBuilder);
       }
     } else {
-      // userCode was null so we explicitly have to add the builders from
-      // userBuilders (which cannot be null as we checked initially that one of
-      // them was non-null).
-      userBuilders!.forEach(addBuilderAndInvalidateUris);
+      // [lastGoodKernelTarget] was null so we explicitly have to add the
+      // builders from [userBuilders] (which cannot be null as we checked
+      // initially that one of them was non-null).
+      _userBuilders!.forEach(addBuilderAndInvalidateUris);
     }
 
-    recordInvalidatedImportUrisForTesting(invalidatedImportUris);
+    recorderForTesting?.recordInvalidatedImportUris(invalidatedImportUris);
     for (Uri uri in invalidatedImportUris) {
       directlyInvalidated.add(builders[uri]!);
     }
@@ -2286,39 +2040,29 @@
 
   @override
   void invalidate(Uri? uri) {
-    invalidatedUris.add(uri);
+    _invalidatedUris.add(uri);
   }
 
   @override
   void invalidateAllSources() {
-    if (userCode != null) {
-      Set<Uri> uris = new Set<Uri>.from(userCode!.loader.libraryImportUris);
-      uris.removeAll(dillLoadedData!.loader.libraryImportUris);
-      if (previousSourceBuilders != null) {
-        for (Library library in previousSourceBuilders!) {
+    IncrementalKernelTarget? lastGoodKernelTarget = this._lastGoodKernelTarget;
+    if (lastGoodKernelTarget != null) {
+      Set<Uri> uris =
+          new Set<Uri>.from(lastGoodKernelTarget.loader.libraryImportUris);
+      uris.removeAll(_dillLoadedData!.loader.libraryImportUris);
+      if (_previousSourceBuilders != null) {
+        for (Library library in _previousSourceBuilders!) {
           uris.add(library.importUri);
         }
       }
-      invalidatedUris.addAll(uris);
+      _invalidatedUris.addAll(uris);
     }
   }
 
   @override
   void setModulesToLoadOnNextComputeDelta(List<Component> components) {
-    modulesToLoad = components.toList();
+    _modulesToLoad = components.toList();
   }
-
-  /// Internal method.
-  void recordNonFullComponentForTesting(Component component) {}
-
-  /// Internal method.
-  void recordInvalidatedImportUrisForTesting(List<Uri> uris) {}
-
-  /// Internal method.
-  void recordRebuildBodiesCountForTesting(int count) {}
-
-  /// Internal method.
-  void recordTemporaryFileForTesting(Uri uri) {}
 }
 
 /// Translate a parts "partUri" to an actual uri with handling of invalid uris.
@@ -2482,3 +2226,412 @@
     librariesUsed.addAll(visitedLibraries);
   }
 }
+
+abstract class _InitializationStrategy {
+  const _InitializationStrategy();
+
+  factory _InitializationStrategy.fromComponent(Component? component) {
+    return component != null
+        ? new _InitializationFromComponent(component)
+        : const _InitializationFromSdkSummary();
+  }
+
+  factory _InitializationStrategy.fromUri(Uri? uri) {
+    return uri != null
+        ? new _InitializationFromUri(uri)
+        : const _InitializationFromSdkSummary();
+  }
+
+  bool get initializedFromDillForTesting => false;
+
+  bool get initializedIncrementalSerializerForTesting => false;
+
+  Future<int> initialize(
+      DillTarget dillLoadedData,
+      UriTranslator uriTranslator,
+      CompilerContext context,
+      IncrementalCompilerData data,
+      _ComponentProblems componentProblems,
+      IncrementalSerializer? incrementalSerializer,
+      RecorderForTesting? recorderForTesting);
+}
+
+class _InitializationFromSdkSummary extends _InitializationStrategy {
+  const _InitializationFromSdkSummary();
+
+  @override
+  Future<int> initialize(
+      DillTarget dillLoadedData,
+      UriTranslator uriTranslator,
+      CompilerContext context,
+      IncrementalCompilerData data,
+      _ComponentProblems componentProblems,
+      IncrementalSerializer? incrementalSerializer,
+      RecorderForTesting? recorderForTesting) async {
+    List<int>? summaryBytes = await context.options.loadSdkSummaryBytes();
+    return _prepareSummary(
+        dillLoadedData, summaryBytes, uriTranslator, context, data);
+  }
+
+  int _prepareSummary(
+      DillTarget dillLoadedTarget,
+      List<int>? summaryBytes,
+      UriTranslator uriTranslator,
+      CompilerContext context,
+      IncrementalCompilerData data) {
+    int bytesLength = 0;
+
+    data.component = context.options.target.configureComponent(new Component());
+    if (summaryBytes != null) {
+      dillLoadedTarget.ticker.logMs("Read ${context.options.sdkSummary}");
+      new BinaryBuilderWithMetadata(summaryBytes,
+              disableLazyReading: false, disableLazyClassReading: true)
+          .readComponent(data.component!);
+      dillLoadedTarget.ticker
+          .logMs("Deserialized ${context.options.sdkSummary}");
+      bytesLength += summaryBytes.length;
+    }
+
+    return bytesLength;
+  }
+}
+
+class _InitializationFromComponent extends _InitializationStrategy {
+  Component componentToInitializeFrom;
+
+  _InitializationFromComponent(this.componentToInitializeFrom);
+
+  @override
+  Future<int> initialize(
+      DillTarget dillLoadedData,
+      UriTranslator uriTranslator,
+      CompilerContext context,
+      IncrementalCompilerData data,
+      _ComponentProblems componentProblems,
+      IncrementalSerializer? incrementalSerializer,
+      RecorderForTesting? recorderForTesting) {
+    dillLoadedData.ticker.logMs("About to initializeFromComponent");
+
+    Component component = data.component = new Component(
+        libraries: componentToInitializeFrom.libraries,
+        uriToSource: componentToInitializeFrom.uriToSource)
+      ..setMainMethodAndMode(componentToInitializeFrom.mainMethod?.reference,
+          true, componentToInitializeFrom.mode);
+    componentProblems.saveComponentProblems(component);
+
+    bool foundDartCore = false;
+    for (int i = 0; i < component.libraries.length; i++) {
+      Library library = component.libraries[i];
+      if (library.importUri.scheme == "dart" &&
+          library.importUri.path == "core") {
+        foundDartCore = true;
+        break;
+      }
+    }
+
+    if (!foundDartCore) {
+      throw const InitializeFromComponentError("Did not find dart:core when "
+          "tried to initialize from component.");
+    }
+
+    dillLoadedData.ticker.logMs("Ran initializeFromComponent");
+    return new Future<int>.value(0);
+  }
+}
+
+class _InitializationFromUri extends _InitializationFromSdkSummary {
+  Uri initializeFromDillUri;
+
+  _InitializationFromUri(this.initializeFromDillUri);
+
+  @override
+  Future<int> initialize(
+      DillTarget dillLoadedData,
+      UriTranslator uriTranslator,
+      CompilerContext context,
+      IncrementalCompilerData data,
+      _ComponentProblems componentProblems,
+      IncrementalSerializer? incrementalSerializer,
+      RecorderForTesting? recorderForTesting) async {
+    List<int>? summaryBytes = await context.options.loadSdkSummaryBytes();
+    int bytesLength = _prepareSummary(
+        dillLoadedData, summaryBytes, uriTranslator, context, data);
+    try {
+      bytesLength += await _initializeFromDill(
+          dillLoadedData,
+          initializeFromDillUri,
+          uriTranslator,
+          context,
+          data,
+          componentProblems,
+          incrementalSerializer);
+    } catch (e, st) {
+      // We might have loaded x out of y libraries into the component.
+      // To avoid any unforeseen problems start over.
+      bytesLength = _prepareSummary(
+          dillLoadedData, summaryBytes, uriTranslator, context, data);
+
+      if (e is InvalidKernelVersionError ||
+          e is InvalidKernelSdkVersionError ||
+          e is PackageChangedError ||
+          e is CanonicalNameSdkError ||
+          e is CompilationModeError) {
+        // Don't report any warning.
+      } else {
+        Uri? gzInitializedFrom;
+        if (context.options.writeFileOnCrashReport) {
+          gzInitializedFrom =
+              saveAsGzip(data.initializationBytes!, "initialize_from.dill");
+          recorderForTesting?.recordTemporaryFile(gzInitializedFrom);
+        }
+        if (e is CanonicalNameError) {
+          Message message = gzInitializedFrom != null
+              ? templateInitializeFromDillNotSelfContained.withArguments(
+                  initializeFromDillUri.toString(), gzInitializedFrom)
+              : templateInitializeFromDillNotSelfContainedNoDump
+                  .withArguments(initializeFromDillUri.toString());
+          dillLoadedData.loader.addProblem(message, TreeNode.noOffset, 1, null);
+        } else {
+          // Unknown error: Report problem as such.
+          Message message = gzInitializedFrom != null
+              ? templateInitializeFromDillUnknownProblem.withArguments(
+                  initializeFromDillUri.toString(),
+                  "$e",
+                  "$st",
+                  gzInitializedFrom)
+              : templateInitializeFromDillUnknownProblemNoDump.withArguments(
+                  initializeFromDillUri.toString(), "$e", "$st");
+          dillLoadedData.loader.addProblem(message, TreeNode.noOffset, 1, null);
+        }
+      }
+    }
+    return bytesLength;
+  }
+
+  bool _initializedFromDill = false;
+  bool _initializedIncrementalSerializer = false;
+
+  @override
+  bool get initializedFromDillForTesting => _initializedFromDill;
+
+  @override
+  bool get initializedIncrementalSerializerForTesting =>
+      _initializedIncrementalSerializer;
+
+  // This procedure will try to load the dill file and will crash if it cannot.
+  Future<int> _initializeFromDill(
+      DillTarget dillLoadedData,
+      Uri initializeFromDillUri,
+      UriTranslator uriTranslator,
+      CompilerContext context,
+      IncrementalCompilerData data,
+      _ComponentProblems _componentProblems,
+      IncrementalSerializer? incrementalSerializer) async {
+    int bytesLength = 0;
+    FileSystemEntity entity =
+        context.options.fileSystem.entityForUri(initializeFromDillUri);
+    if (await entity.exists()) {
+      List<int> initializationBytes = await entity.readAsBytes();
+      // ignore: unnecessary_null_comparison
+      if (initializationBytes != null && initializationBytes.isNotEmpty) {
+        dillLoadedData.ticker.logMs("Read $initializeFromDillUri");
+        data.initializationBytes = initializationBytes;
+
+        // We're going to output all we read here so lazy loading it
+        // doesn't make sense.
+        List<SubComponentView> views = new BinaryBuilderWithMetadata(
+                initializationBytes,
+                disableLazyReading: true)
+            .readComponent(data.component!,
+                checkCanonicalNames: true, createView: true)!;
+
+        // Compute "output nnbd mode".
+        NonNullableByDefaultCompiledMode compiledMode;
+        if (context.options
+            .isExperimentEnabledGlobally(ExperimentalFlag.nonNullable)) {
+          switch (context.options.nnbdMode) {
+            case NnbdMode.Weak:
+              compiledMode = NonNullableByDefaultCompiledMode.Weak;
+              break;
+            case NnbdMode.Strong:
+              compiledMode = NonNullableByDefaultCompiledMode.Strong;
+              break;
+            case NnbdMode.Agnostic:
+              compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
+              break;
+          }
+        } else {
+          compiledMode = NonNullableByDefaultCompiledMode.Weak;
+        }
+
+        // Check the any package-urls still point to the same file
+        // (e.g. the package still exists and hasn't been updated).
+        // Also verify NNBD settings.
+        for (Library lib in data.component!.libraries) {
+          if (lib.importUri.scheme == "package" &&
+              uriTranslator.translate(lib.importUri, false) != lib.fileUri) {
+            // Package has been removed or updated.
+            // This library should be thrown away.
+            // Everything that depends on it should be thrown away.
+            // TODO(jensj): Anything that doesn't depend on it can be kept.
+            // For now just don't initialize from this dill.
+            throw const PackageChangedError();
+          }
+          // Note: If a library has a NonNullableByDefaultCompiledMode.invalid
+          // we will throw and we won't initialize from it.
+          // That's wanted behavior.
+          if (compiledMode !=
+              mergeCompilationModeOrThrow(
+                  compiledMode, lib.nonNullableByDefaultCompiledMode)) {
+            throw new CompilationModeError(
+                "Can't compile to $compiledMode with library with mode "
+                "${lib.nonNullableByDefaultCompiledMode}.");
+          }
+        }
+
+        // Only initialize the incremental serializer when we know we'll
+        // actually use the data loaded from dill.
+        _initializedIncrementalSerializer =
+            incrementalSerializer?.initialize(initializationBytes, views) ??
+                false;
+
+        _initializedFromDill = true;
+        bytesLength += initializationBytes.length;
+        _componentProblems.saveComponentProblems(data.component!);
+      }
+    }
+    return bytesLength;
+  }
+}
+
+class _ComponentProblems {
+  Map<Uri, List<DiagnosticMessageFromJson>> _remainingComponentProblems =
+      new Map<Uri, List<DiagnosticMessageFromJson>>();
+
+  /// [partsUsed] indicates part uris that are used by (other/alive) libraries.
+  /// Those parts will not be removed from the component problems.
+  /// This is useful when a part has been "moved" to be part of another library.
+  void removeLibrary(Library lib, UriTranslator uriTranslator,
+      [Set<Uri?>? partsUsed]) {
+    if (_remainingComponentProblems.isNotEmpty) {
+      _remainingComponentProblems.remove(lib.fileUri);
+      // Remove parts too.
+      for (LibraryPart part in lib.parts) {
+        Uri? partFileUri = uriTranslator.getPartFileUri(lib.fileUri, part);
+        _remainingComponentProblems.remove(partFileUri);
+      }
+    }
+  }
+
+  /// Re-issue problems on the component and return the filtered list.
+  List<String> reissueProblems(
+      CompilerContext context,
+      IncrementalKernelTarget currentKernelTarget,
+      Component componentWithDill) {
+    // These problems have already been reported.
+    Set<String> issuedProblems = new Set<String>();
+    if (componentWithDill.problemsAsJson != null) {
+      issuedProblems.addAll(componentWithDill.problemsAsJson!);
+    }
+
+    // Report old problems that wasn't reported again.
+    Set<Uri>? strongModeNNBDPackageOptOutUris;
+    for (MapEntry<Uri, List<DiagnosticMessageFromJson>> entry
+        in _remainingComponentProblems.entries) {
+      List<DiagnosticMessageFromJson> messages = entry.value;
+      for (int i = 0; i < messages.length; i++) {
+        DiagnosticMessageFromJson message = messages[i];
+        if (message.codeName == "StrongModeNNBDPackageOptOut") {
+          // Special case this: Don't issue them here; instead collect them
+          // to get their uris and re-issue a new error.
+          strongModeNNBDPackageOptOutUris ??= {};
+          strongModeNNBDPackageOptOutUris.add(entry.key);
+          continue;
+        }
+        if (issuedProblems.add(message.toJsonString())) {
+          context.options.reportDiagnosticMessage(message);
+        }
+      }
+    }
+    if (strongModeNNBDPackageOptOutUris != null) {
+      // Get the builders for these uris; then call
+      // `SourceLoader.giveCombinedErrorForNonStrongLibraries` on them to issue
+      // a new error.
+      Set<LibraryBuilder> builders = {};
+      SourceLoader loader = currentKernelTarget.loader;
+      for (LibraryBuilder builder in loader.libraryBuilders) {
+        if (strongModeNNBDPackageOptOutUris.contains(builder.fileUri)) {
+          builders.add(builder);
+        }
+      }
+      FormattedMessage message = loader.giveCombinedErrorForNonStrongLibraries(
+          builders,
+          emitNonPackageErrors: false)!;
+      issuedProblems.add(message.toJsonString());
+      // The problem was issued by the call so don't re-issue it here.
+    }
+
+    // Save any new component-problems.
+    _addProblemsAsJson(componentWithDill.problemsAsJson);
+    return new List<String>.from(issuedProblems);
+  }
+
+  void saveComponentProblems(Component component) {
+    _addProblemsAsJson(component.problemsAsJson);
+  }
+
+  void _addProblemsAsJson(List<String>? problemsAsJson) {
+    if (problemsAsJson != null) {
+      for (String jsonString in problemsAsJson) {
+        DiagnosticMessageFromJson message =
+            new DiagnosticMessageFromJson.fromJson(jsonString);
+        assert(message.uri != null ||
+            (message.involvedFiles != null &&
+                message.involvedFiles!.isNotEmpty));
+        if (message.uri != null) {
+          List<DiagnosticMessageFromJson> messages =
+              _remainingComponentProblems[message.uri!] ??=
+                  <DiagnosticMessageFromJson>[];
+          messages.add(message);
+        }
+        if (message.involvedFiles != null) {
+          // This indexes the same message under several uris - this way it will
+          // be issued as long as it's a problem. It will because of
+          // deduplication when we re-issue these (in reissueComponentProblems)
+          // only be reported once.
+          for (Uri uri in message.involvedFiles!) {
+            List<DiagnosticMessageFromJson> messages =
+                _remainingComponentProblems[uri] ??=
+                    <DiagnosticMessageFromJson>[];
+            messages.add(message);
+          }
+        }
+      }
+    }
+  }
+}
+
+extension on UriTranslator {
+  Uri? getPartFileUri(Uri parentFileUri, LibraryPart part) {
+    Uri? fileUri = getPartUri(parentFileUri, part);
+    if (fileUri.scheme == "package") {
+      // Part was specified via package URI and the resolve above thus
+      // did not go as expected. Translate the package URI to get the
+      // actual file URI.
+      fileUri = translate(fileUri, false);
+    }
+    return fileUri;
+  }
+}
+
+class RecorderForTesting {
+  const RecorderForTesting();
+
+  void recordNonFullComponent(Component component) {}
+
+  void recordInvalidatedImportUris(List<Uri> uris) {}
+
+  void recordRebuildBodiesCount(int count) {}
+
+  void recordTemporaryFile(Uri uri) {}
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index c19ef88..dad946b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -4013,7 +4013,8 @@
   @override
   void endFormalParameter(
       Token? thisKeyword,
-      Token? periodAfterThis,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
       Token nameToken,
       Token? initializerStart,
       Token? initializerEnd,
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 9e0e011..9440adf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -316,7 +316,7 @@
           getEntryPointUri(entryPoint, issueProblem: true);
       result.add(translatedEntryPoint);
       loader.read(translatedEntryPoint, -1,
-          accessor: loader.first,
+          accessorUri: loader.firstUri,
           fileUri: translatedEntryPoint != entryPoint ? entryPoint : null);
     }
     return result;
@@ -402,7 +402,6 @@
     if (loader.first == null) return null;
     return withCrashReporting<Component?>(() async {
       await loader.buildOutlines();
-      loader.createTypeInferenceEngine();
       loader.coreLibrary.becomeCoreLibrary();
       loader.resolveParts();
       loader.computeLibraryScopes();
@@ -411,30 +410,33 @@
       loader.computeVariances();
       loader.computeDefaultTypes(
           dynamicType, nullType, bottomType, objectClassBuilder);
-      List<SourceClassBuilder> myClasses =
+      List<SourceClassBuilder> sourceClassBuilders =
           loader.checkSemantics(objectClassBuilder);
+      loader.computeMacroDeclarations(sourceClassBuilders);
       loader.finishTypeVariables(objectClassBuilder, dynamicType);
+      loader.createTypeInferenceEngine();
       loader.buildComponent();
       installDefaultSupertypes();
-      installSyntheticConstructors(myClasses);
+      installSyntheticConstructors(sourceClassBuilders);
       loader.resolveConstructors();
       component =
           link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
       computeCoreTypes();
-      loader.buildClassHierarchy(myClasses, objectClassBuilder);
+      loader.buildClassHierarchy(sourceClassBuilders, objectClassBuilder);
       loader.computeHierarchy();
       loader.computeShowHideElements();
       loader.installTypedefTearOffs();
-      loader.performTopLevelInference(myClasses);
-      loader.checkSupertypes(myClasses);
-      loader.checkOverrides(myClasses);
-      loader.checkAbstractMembers(myClasses);
-      loader.addNoSuchMethodForwarders(myClasses);
-      loader.checkMixins(myClasses);
+      loader.performTopLevelInference(sourceClassBuilders);
+      loader.checkSupertypes(sourceClassBuilders);
+      loader.checkOverrides(sourceClassBuilders);
+      loader.checkAbstractMembers(sourceClassBuilders);
+      loader.addNoSuchMethodForwarders(sourceClassBuilders);
+      loader.checkMixins(sourceClassBuilders);
       loader.buildOutlineExpressions(
           loader.coreTypes, synthesizedFunctionNodes);
+      loader.computeMacroApplications();
       loader.checkTypes();
-      loader.checkRedirectingFactories(myClasses);
+      loader.checkRedirectingFactories(sourceClassBuilders);
       loader.checkMainMethods();
       installAllComponentProblems(loader.allComponentProblems);
       loader.allComponentProblems.clear();
@@ -809,7 +811,8 @@
         supertype is TypeVariableBuilder ||
         supertype is DynamicTypeDeclarationBuilder ||
         supertype is VoidTypeDeclarationBuilder ||
-        supertype is NeverTypeDeclarationBuilder) {
+        supertype is NeverTypeDeclarationBuilder ||
+        supertype is TypeAliasBuilder) {
       builder.addSyntheticConstructor(_makeDefaultConstructor(
           builder, constructorReference, tearOffReference));
     } else {
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
new file mode 100644
index 0000000..afa9dca
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart';
+
+bool enableMacros = false;
+
+final Uri macroLibraryUri = Uri.parse('package:macro_builder/src/macro.dart');
+const String macroClassName = 'Macro';
+
+class MacroDeclarationData {
+  bool macrosAreAvailable = false;
+  Map<Uri, List<String>> macroDeclarations = {};
+  List<List<Uri>>? compilationSequence;
+}
+
+class MacroApplicationData {
+  Map<Library, LibraryMacroApplicationData> libraryData = {};
+}
+
+class MacroApplications {
+  final List<Class> macros;
+
+  MacroApplications(this.macros);
+}
+
+class LibraryMacroApplicationData {
+  MacroApplications? libraryApplications;
+  Map<Class, ClassMacroApplicationData> classData = {};
+  Map<Typedef, MacroApplications> typedefApplications = {};
+  Map<Member, MacroApplications> memberApplications = {};
+}
+
+class ClassMacroApplicationData {
+  MacroApplications? classApplications;
+  Map<Member, MacroApplications> memberApplications = {};
+}
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index a1e2b88..86edd9f 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -176,6 +176,11 @@
   }
 
   @override
+  void handleNoTypeNameInConstructorReference(Token token) {
+    debugEvent("NoTypeNameInConstructorReference");
+  }
+
+  @override
   void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
     debugEvent("NoConstructorReferenceContinuationAfterTypeArguments");
   }
@@ -212,11 +217,26 @@
   }
 
   @override
+  void handleEnumWithClause(Token withKeyword) {
+    debugEvent("EnumWithClause");
+  }
+
+  @override
+  void handleEnumNoWithClause() {
+    debugEvent("EnumNoWithClause");
+  }
+
+  @override
   void endTypeArguments(int count, Token beginToken, Token endToken) {
     debugEvent("TypeArguments");
   }
 
   @override
+  void endArguments(int count, Token beginToken, Token endToken) {
+    debugEvent("Arguments");
+  }
+
+  @override
   void handleInvalidTypeArguments(Token token) {
     debugEvent("InvalidTypeArguments");
   }
@@ -939,12 +959,103 @@
   }
 
   @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
+  void beginEnum(Token enumKeyword) {
+    assert(checkState(enumKeyword, [ValueKinds.NameOrParserRecovery]));
     debugEvent("Enum");
-    const FixedNullableList<Object>().pop(stack, count * 2);
-    pop(); // Name.
-    pop(); // Annotations begin token.
+    Object? name = pop();
+
+    assert(currentDeclaration == null);
+    assert(memberScope == libraryBuilder.scope);
+
+    if (name is ParserRecovery) {
+      currentClassIsParserRecovery = true;
+      return;
+    }
+
+    currentDeclaration =
+        lookupBuilder(enumKeyword, null, name as String) as DeclarationBuilder;
+    memberScope = currentDeclaration!.scope;
+  }
+
+  @override
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
+    debugEvent("Enum");
     checkEmpty(enumKeyword.charOffset);
+    currentDeclaration = null;
+    memberScope = libraryBuilder.scope;
+  }
+
+  @override
+  void handleEnumElement(Token beginKeyword) {
+    debugEvent("EnumElement");
+  }
+
+  @override
+  void handleEnumElements(Token elementsEndToken, int elementsCount) {
+    debugEvent("EnumElements");
+    const FixedNullableList<Object>().pop(stack, elementsCount * 2);
+    pop(); // Annotations begin token.
+    checkEmpty(elementsEndToken.charOffset);
+  }
+
+  @override
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    debugEvent("EnumHeader");
+  }
+
+  @override
+  void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    // TODO(chloestefantsova): Call endClassConstructor instead.
+    debugEvent("EnumConstructor");
+    pop(); // bodyToken
+    pop(); // name
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    // Skip the declaration. An error as already been produced by the parser.
+  }
+
+  @override
+  void endEnumFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    // TODO(chloestefantsova): Call endClassFactoryMethod instead.
+    debugEvent("EnumFactoryMethod");
+    pop(); // bodyToken
+    pop(); // name
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    // Skip the declaration. An error as already been produced by the parser.
+  }
+
+  @override
+  void endEnumMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    // TODO(chloestefantsova): Call endClassMethod instead.
+    debugEvent("EnumMethod");
+    pop(); // bodyToken
+    pop(); // name
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    // Skip the declaration. An error as already been produced by the parser.
+  }
+
+  @override
+  void endEnumFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    // TODO(chloestefantsova): Call endClassFields instead.
+    debugEvent("EnumFields");
+    const FixedNullableList<String>().pop(stack, count); // names
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    // Skip the declaration. An error as already been produced by the parser.
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 63f5779..0d7fc82 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -309,6 +309,33 @@
   /// This includes type of the declaration but excludes annotations on the
   /// field declaration itself, which are seen in the [ExtensionBody] context.
   ExtensionStaticField,
+
+  /// In a generative constructor declaration inside an enum declaration.
+  EnumConstructor,
+
+  /// In a static method declaration inside an enum declaration.
+  EnumStaticMethod,
+
+  /// In a static field declaration inside an enum declaration.
+  EnumStaticField,
+
+  /// In an instance method declaration inside an enum declaration.
+  EnumInstanceMethod,
+
+  /// In an instance field declaration inside an enum declaration.
+  EnumInstanceField,
+
+  /// In a factory constructor declaration inside an enum declaration. This
+  /// is an error case.
+  ///
+  /// This excludes annotations on the constructor declaration itself, which
+  /// are seen in the [EnumBody] context.
+  EnumFactory,
+
+  /// In an enum declaration body.
+  ///
+  /// This includes annotations on extension member declarations.
+  EnumBody,
 }
 
 extension on DeclarationContext {
@@ -318,7 +345,6 @@
       case DeclarationContext.Typedef:
       case DeclarationContext.TopLevelMethod:
       case DeclarationContext.TopLevelField:
-      case DeclarationContext.Enum:
         return InstanceTypeVariableAccessState.Unexpected;
       case DeclarationContext.ClassOrMixinOrNamedMixinApplication:
       case DeclarationContext.NamedMixinApplication:
@@ -327,6 +353,10 @@
       case DeclarationContext.ClassFactory:
       case DeclarationContext.ClassInstanceMethod:
       case DeclarationContext.ClassInstanceField:
+      case DeclarationContext.Enum:
+      case DeclarationContext.EnumConstructor:
+      case DeclarationContext.EnumInstanceField:
+      case DeclarationContext.EnumInstanceMethod:
       case DeclarationContext.Mixin:
       case DeclarationContext.MixinInstanceMethod:
       case DeclarationContext.MixinInstanceField:
@@ -337,6 +367,9 @@
       case DeclarationContext.ClassBody:
       case DeclarationContext.ClassStaticMethod:
       case DeclarationContext.ClassStaticField:
+      case DeclarationContext.EnumStaticField:
+      case DeclarationContext.EnumStaticMethod:
+      case DeclarationContext.EnumBody:
       case DeclarationContext.MixinBody:
       case DeclarationContext.MixinStaticMethod:
       case DeclarationContext.MixinStaticField:
@@ -349,6 +382,7 @@
       case DeclarationContext.ExtensionConstructor:
       case DeclarationContext.ExtensionFactory:
       case DeclarationContext.ExtensionInstanceField:
+      case DeclarationContext.EnumFactory:
         return InstanceTypeVariableAccessState.Invalid;
     }
   }
@@ -824,6 +858,9 @@
       case DeclarationKind.Extension:
         declarationContext = DeclarationContext.ExtensionBody;
         break;
+      case DeclarationKind.Enum:
+        declarationContext = DeclarationContext.Enum;
+        break;
     }
     pushDeclarationContext(declarationContext);
     if (kind == DeclarationKind.Extension) {
@@ -876,12 +913,21 @@
   }
 
   @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
-    debugEvent("ClassOrMixinImplements");
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
+    debugEvent("Implements");
     push(const FixedNullableList<TypeBuilder>()
             .popNonNullable(stack, interfacesCount, dummyTypeBuilder) ??
         NullValue.TypeBuilderList);
+
+    if (!libraryBuilder.enableEnhancedEnumsInLibrary &&
+        implementsKeyword != null &&
+        declarationContext == DeclarationContext.Enum) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments('enhanced-enums',
+              libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
+          implementsKeyword.charOffset,
+          -1);
+    }
   }
 
   @override
@@ -1457,6 +1503,14 @@
           declarationContext = DeclarationContext.ExtensionInstanceMethod;
         }
         break;
+      case DeclarationKind.Enum:
+        if (inConstructor) {
+          declarationContext = DeclarationContext.EnumConstructor;
+        } else if (staticToken != null) {
+          declarationContext = DeclarationContext.EnumStaticMethod;
+        } else {
+          declarationContext = DeclarationContext.EnumInstanceMethod;
+        }
     }
     pushDeclarationContext(declarationContext);
 
@@ -1910,6 +1964,12 @@
   }
 
   @override
+  void endArguments(int count, Token beginToken, Token endToken) {
+    debugEvent("Arguments");
+    push(NullValue.Arguments);
+  }
+
+  @override
   void handleInvalidTypeArguments(Token token) {
     debugEvent("InvalidTypeArguments");
     pop(NullValue.TypeArguments);
@@ -1959,12 +2019,31 @@
   }
 
   @override
+  void handleNoArguments(Token token) {
+    debugEvent("NoArguments");
+    push(NullValue.Arguments);
+  }
+
+  @override
   void handleNoTypeVariables(Token token) {
     super.handleNoTypeVariables(token);
     inConstructorName = false;
   }
 
   @override
+  void handleNoTypeArguments(Token token) {
+    debugEvent("NoTypeArguments");
+    push(NullValue.TypeArguments);
+  }
+
+  @override
+  void handleNoTypeNameInConstructorReference(Token token) {
+    debugEvent("NoTypeNameInConstructorReference");
+    push(NullValue.Name);
+    push(token.charOffset);
+  }
+
+  @override
   void handleVoidKeyword(Token token) {
     debugEvent("VoidKeyword");
     push(libraryBuilder.addVoidType(token.charOffset));
@@ -1991,13 +2070,26 @@
   @override
   void endFormalParameter(
       Token? thisKeyword,
-      Token? periodAfterThis,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
       Token nameToken,
       Token? initializerStart,
       Token? initializerEnd,
       FormalParameterKind kind,
       MemberKind memberKind) {
     debugEvent("FormalParameter");
+
+    if (superKeyword != null &&
+        !libraryBuilder.enableSuperParametersInLibrary) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments(
+              'super-parameters',
+              libraryBuilder.enableConstructorTearOffsVersionInLibrary
+                  .toText()),
+          superKeyword.charOffset,
+          superKeyword.length);
+    }
+
     int charOffset = popCharOffset();
     Object? name = pop();
     TypeBuilder? type = nullIfParserRecovery(pop()) as TypeBuilder?;
@@ -2155,23 +2247,70 @@
 
   @override
   void beginEnum(Token enumKeyword) {
+    assert(checkState(
+        enumKeyword, [ValueKinds.Integer, ValueKinds.NameOrParserRecovery]));
+    int offset = pop() as int;
+    Object? name = pop();
+    push(name);
+    push(offset);
+
+    String declarationName;
+    if (name is String) {
+      declarationName = name;
+    } else {
+      declarationName = '#enum';
+    }
     pushDeclarationContext(DeclarationContext.Enum);
+    libraryBuilder.beginNestedDeclaration(
+        TypeParameterScopeKind.enumDeclaration, declarationName);
   }
 
   @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
-    debugEvent("Enum");
+  void handleEnumElement(Token beginToken) {
+    debugEvent("EnumElements");
+    pop(); // arguments.
+    pop(); // constructor reference.
+    // Keep on the stack the EnumConstantInfo created in handleIdentifier.
+  }
+
+  @override
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    debugEvent("EnumHeader");
+    push(enumKeyword.charOffset); // start char offset.
+    push(leftBrace.endGroup!.charOffset); // end char offset.
+  }
+
+  @override
+  void handleEnumElements(Token elementsEndToken, int elementsCount) {
+    debugEvent("EnumElements");
     List<EnumConstantInfo?>? enumConstantInfos =
-        const FixedNullableList<EnumConstantInfo>().pop(stack, count);
+        const FixedNullableList<EnumConstantInfo>().pop(stack, elementsCount);
+    int endCharOffset = popCharOffset();
+    int startCharOffset = popCharOffset();
+    pop() as List<TypeBuilder>?; // interfaces.
+    pop() as List<TypeBuilder>?; // mixins.
+    List<TypeVariableBuilder>? typeVariables =
+        pop() as List<TypeVariableBuilder>?;
     int charOffset = popCharOffset(); // identifier char offset.
-    int startCharOffset = enumKeyword.charOffset;
     Object? name = pop();
     List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
-    checkEmpty(enumKeyword.charOffset);
+    checkEmpty(startCharOffset);
+
     if (name is! ParserRecovery) {
       libraryBuilder.addEnum(metadata, name as String, enumConstantInfos,
-          startCharOffset, charOffset, leftBrace.endGroup!.charOffset);
+          startCharOffset, charOffset, endCharOffset);
+    } else {
+      libraryBuilder
+          .endNestedDeclaration(
+              TypeParameterScopeKind.enumDeclaration, "<syntax-error>")
+          .resolveNamedTypes(typeVariables, libraryBuilder);
     }
+  }
+
+  @override
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
+    debugEvent("Enum");
+    checkEmpty(enumKeyword.charOffset);
     popDeclarationContext(DeclarationContext.Enum);
   }
 
@@ -2247,7 +2386,7 @@
     List<TypeVariableBuilder>? typeVariables;
     Object? name;
     int charOffset;
-    TypeBuilder? aliasedType;
+    TypeBuilder aliasedType;
     if (equals == null) {
       List<FormalParameterBuilder>? formals =
           pop() as List<FormalParameterBuilder>?;
@@ -2297,6 +2436,14 @@
           // elsewhere.
           addProblem(
               messageTypedefNullableType, equals.charOffset, equals.length);
+          aliasedType = new NamedTypeBuilder.fromTypeDeclarationBuilder(
+              new InvalidTypeDeclarationBuilder(
+                  "${name}",
+                  messageTypedefNullableType.withLocation(
+                      uri, equals.charOffset, equals.length)),
+              const NullabilityBuilder.omitted(),
+              instanceTypeVariableAccess:
+                  InstanceTypeVariableAccessState.Allowed);
         } else {
           // TODO(ahe): We need to start a nested declaration when parsing the
           // formals and return type so we can correctly bind
@@ -2310,18 +2457,40 @@
           aliasedType = type;
         } else {
           addProblem(messageTypedefNotType, equals.charOffset, equals.length);
+          aliasedType = new NamedTypeBuilder.fromTypeDeclarationBuilder(
+              new InvalidTypeDeclarationBuilder(
+                  "${name}",
+                  messageTypedefNotType.withLocation(
+                      uri, equals.charOffset, equals.length)),
+              const NullabilityBuilder.omitted(),
+              instanceTypeVariableAccess:
+                  InstanceTypeVariableAccessState.Allowed);
         }
       } else {
+        assert(type is! FunctionTypeBuilder);
         // TODO(ahe): Improve this error message.
-        addProblem(messageTypedefNotFunction, equals.charOffset, equals.length);
-        aliasedType = new NamedTypeBuilder.fromTypeDeclarationBuilder(
-            new InvalidTypeDeclarationBuilder(
-                "${name}",
-                messageTypedefNotType.withLocation(
-                    uri, equals.charOffset, equals.length)),
-            const NullabilityBuilder.omitted(),
-            instanceTypeVariableAccess:
-                InstanceTypeVariableAccessState.Allowed);
+        if (type is TypeBuilder) {
+          addProblem(
+              messageTypedefNotFunction, equals.charOffset, equals.length);
+          aliasedType = new NamedTypeBuilder.fromTypeDeclarationBuilder(
+              new InvalidTypeDeclarationBuilder(
+                  "${name}",
+                  messageTypedefNotFunction.withLocation(
+                      uri, equals.charOffset, equals.length)),
+              const NullabilityBuilder.omitted(),
+              instanceTypeVariableAccess:
+                  InstanceTypeVariableAccessState.Allowed);
+        } else {
+          addProblem(messageTypedefNotType, equals.charOffset, equals.length);
+          aliasedType = new NamedTypeBuilder.fromTypeDeclarationBuilder(
+              new InvalidTypeDeclarationBuilder(
+                  "${name}",
+                  messageTypedefNotType.withLocation(
+                      uri, equals.charOffset, equals.length)),
+              const NullabilityBuilder.omitted(),
+              instanceTypeVariableAccess:
+                  InstanceTypeVariableAccessState.Allowed);
+        }
       }
     }
     List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
@@ -2370,6 +2539,12 @@
           declarationContext = DeclarationContext.ExtensionInstanceField;
         }
         break;
+      case DeclarationKind.Enum:
+        if (staticToken != null) {
+          declarationContext = DeclarationContext.EnumStaticMethod;
+        } else {
+          declarationContext = DeclarationContext.EnumInstanceMethod;
+        }
     }
     pushDeclarationContext(declarationContext);
   }
@@ -2545,6 +2720,15 @@
   void endTypeVariables(Token beginToken, Token endToken) {
     debugEvent("endTypeVariables");
 
+    if (!libraryBuilder.enableEnhancedEnumsInLibrary &&
+        declarationContext == DeclarationContext.Enum) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments('enhanced-enums',
+              libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
+          beginToken.charOffset,
+          -1);
+    }
+
     // Peek to leave type parameters on top of stack.
     List<TypeVariableBuilder>? typeParameters =
         peek() as List<TypeVariableBuilder>?;
@@ -2638,12 +2822,44 @@
     String? suffix = popIfNotNull(periodBeforeName) as String?;
     List<TypeBuilder>? typeArguments = pop() as List<TypeBuilder>?;
     int charOffset = popCharOffset();
-    Object name = pop()!;
+    Object? name = pop();
     if (name is ParserRecovery) {
       push(name);
-    } else {
+    } else if (name != null) {
       push(libraryBuilder.addConstructorReference(
           name, typeArguments, suffix, charOffset));
+    } else {
+      assert(name == null);
+      // At the moment, the name of the type in a constructor reference can be
+      // omitted only within an enum element declaration.
+      if (libraryBuilder.currentTypeParameterScopeBuilder.kind ==
+          TypeParameterScopeKind.enumDeclaration) {
+        if (libraryBuilder.enableEnhancedEnumsInLibrary) {
+          push(libraryBuilder.addConstructorReference(
+              libraryBuilder.currentTypeParameterScopeBuilder.name,
+              typeArguments,
+              suffix,
+              charOffset));
+        } else {
+          // For entries that consist of their name only, all of the elements
+          // of the constructor reference should be null.
+          if (typeArguments != null || suffix != null) {
+            addProblem(
+                templateExperimentNotEnabled.withArguments(
+                    'enhanced-enums',
+                    libraryBuilder.enableEnhancedEnumsVersionInLibrary
+                        .toText()),
+                charOffset,
+                -1);
+          }
+          push(NullValue.ConstructorReference);
+        }
+      } else {
+        internalProblem(
+            messageInternalProblemOmittedTypeNameInConstructorReference,
+            charOffset,
+            uri);
+      }
     }
   }
 
@@ -2663,6 +2879,9 @@
       case DeclarationKind.Extension:
         declarationContext = DeclarationContext.ExtensionFactory;
         break;
+      case DeclarationKind.Enum:
+        declarationContext = DeclarationContext.EnumFactory;
+        break;
     }
 
     pushDeclarationContext(declarationContext);
@@ -2737,6 +2956,150 @@
   }
 
   @override
+  void endEnumFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    // TODO(cstefantsova): Call endClassFactoryMethod instead.
+    debugEvent("EnumFactoryMethod");
+    MethodBody bodyKind = pop() as MethodBody;
+    if (bodyKind == MethodBody.RedirectingFactoryBody) {
+      pop(); // reference
+    }
+    pop(); // async marker
+    pop(); // formals
+    popCharOffset(); // formals char offset
+    pop(); // type variables
+    popCharOffset(); // char offset
+    pop(); // name
+    pop(); // modifiers
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    popDeclarationContext();
+    // TODO(cstefantsova): Use actual type parameters.
+    libraryBuilder
+        .endNestedDeclaration(
+            TypeParameterScopeKind.factoryMethod, "#factory_method")
+        .resolveNamedTypes([], libraryBuilder);
+    // Skip the declaration. An error as already been produced by the parser.
+
+    if (libraryBuilder.enableEnhancedEnumsInLibrary) {
+      addProblem(messageEnumDeclaresFactory, beginToken.charOffset, -1);
+    } else {
+      addProblem(
+          templateExperimentNotEnabled.withArguments('enhanced-enums',
+              libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
+          beginToken.charOffset,
+          -1);
+    }
+  }
+
+  @override
+  void endEnumMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    // TODO(cstefantsova): Call endClassMethod instead.
+    debugEvent("EnumMethod");
+    MethodBody bodyKind = pop() as MethodBody;
+    if (bodyKind == MethodBody.RedirectingFactoryBody) {
+      pop(); // reference
+    }
+    pop(); // async marker
+    pop(); // formals
+    popCharOffset(); // formals char offset
+    pop(); // type variables
+    popCharOffset(); // char offset
+    pop(); // name
+    pop(); // return type
+    int modifiers = Modifier.toMask(pop() as List<Modifier>?);
+    popCharOffset(); // final or const offset
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    popDeclarationContext();
+    TypeParameterScopeKind scopeKind;
+    if ((modifiers & staticMask) != 0) {
+      scopeKind = TypeParameterScopeKind.staticMethod;
+    } else {
+      scopeKind = TypeParameterScopeKind.instanceMethod;
+    }
+    // TODO(cstefantsova): Use actual type parameters.
+    libraryBuilder
+        .endNestedDeclaration(scopeKind, "#method")
+        .resolveNamedTypes([], libraryBuilder);
+    // Skip the declaration. An error as already been produced by the parser.
+
+    if (!libraryBuilder.enableEnhancedEnumsInLibrary) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments('enhanced-enums',
+              libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
+          beginToken.charOffset,
+          -1);
+    }
+  }
+
+  @override
+  void endEnumFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    // TODO(cstefantsova): Call endClassFields instead.
+    debugEvent("EnumFields");
+    popFieldInfos(count); // field infos
+    pop(); // type
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    popDeclarationContext();
+    // Skip the declaration. An error as already been produced by the parser.
+
+    if (!libraryBuilder.enableEnhancedEnumsInLibrary) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments('enhanced-enums',
+              libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
+          beginToken.charOffset,
+          -1);
+    }
+  }
+
+  @override
+  void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    // TODO(cstefantsova): Call endClassConstructor instead.
+    debugEvent("EnumMethod");
+    MethodBody bodyKind = pop() as MethodBody;
+    if (bodyKind == MethodBody.RedirectingFactoryBody) {
+      pop(); // reference
+    }
+    pop(); // async marker
+    pop(); // formals
+    popCharOffset(); // formals char offset
+    pop(); // type variables
+    popCharOffset(); // char offset
+    pop(); // name
+    pop(); // return type
+    pop(); // modifiers
+    popCharOffset(); // final or const offset
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    popDeclarationContext();
+    // TODO(cstefantsova): Use actual type parameters.
+    libraryBuilder
+        .endNestedDeclaration(TypeParameterScopeKind.instanceMethod, "#method")
+        .resolveNamedTypes([], libraryBuilder);
+    // Skip the declaration. An error as already been produced by the parser.
+
+    if (!libraryBuilder.enableEnhancedEnumsInLibrary) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments('enhanced-enums',
+              libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
+          beginToken.charOffset,
+          -1);
+    }
+  }
+
+  @override
   void endRedirectingFactoryBody(Token beginToken, Token endToken) {
     debugEvent("RedirectingFactoryBody");
     push(MethodBody.RedirectingFactoryBody);
@@ -2826,6 +3189,33 @@
   }
 
   @override
+  void handleEnumWithClause(Token withKeyword) {
+    debugEvent("EnumWithClause");
+
+    if (!libraryBuilder.enableEnhancedEnumsInLibrary) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments('enhanced-enums',
+              libraryBuilder.enableEnhancedEnumsVersionInLibrary.toText()),
+          withKeyword.charOffset,
+          -1);
+    }
+
+    Object? mixins = pop();
+    if (mixins is ParserRecovery) {
+      push(new ParserRecovery(withKeyword.charOffset));
+    } else {
+      // TODO(cstefantsova): Handle enum mixins here.
+      push(mixins);
+    }
+  }
+
+  @override
+  void handleEnumNoWithClause() {
+    debugEvent("EnumNoWithClause");
+    push(NullValue.TypeBuilderList);
+  }
+
+  @override
   void handleClassHeader(Token begin, Token classKeyword, Token? nativeToken) {
     debugEvent("ClassHeader");
     nativeMethodName = null;
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 da6208a..cf7b0ba 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
@@ -318,12 +318,16 @@
   Version? _enableConstructorTearoffsVersionInLibrary;
   Version? _enableExtensionTypesVersionInLibrary;
   Version? _enableNamedArgumentsAnywhereVersionInLibrary;
+  Version? _enableSuperParametersVersionInLibrary;
+  Version? _enableEnhancedEnumsVersionInLibrary;
   bool? _enableTripleShiftInLibrary;
   bool? _enableExtensionMethodsInLibrary;
   bool? _enableGenericMetadataInLibrary;
   bool? _enableExtensionTypesInLibrary;
+  bool? _enableEnhancedEnumsInLibrary;
   bool? _enableConstructorTearOffsInLibrary;
   bool? _enableNamedArgumentsAnywhereInLibrary;
+  bool? _enableSuperParametersInLibrary;
 
   bool get enableConstFunctionsInLibrary => _enableConstFunctionsInLibrary ??=
       loader.target.isExperimentEnabledInLibraryByVersion(
@@ -411,6 +415,28 @@
               ExperimentalFlag.namedArgumentsAnywhere,
               _packageUri ?? importUri);
 
+  bool get enableSuperParametersInLibrary => _enableSuperParametersInLibrary ??=
+      loader.target.isExperimentEnabledInLibraryByVersion(
+          ExperimentalFlag.superParameters,
+          _packageUri ?? importUri,
+          languageVersion.version);
+
+  Version get enableSuperParametersVersionInLibrary =>
+      _enableSuperParametersVersionInLibrary ??= loader.target
+          .getExperimentEnabledVersionInLibrary(
+              ExperimentalFlag.superParameters, _packageUri ?? importUri);
+
+  bool get enableEnhancedEnumsInLibrary => _enableEnhancedEnumsInLibrary ??=
+      loader.target.isExperimentEnabledInLibraryByVersion(
+          ExperimentalFlag.enhancedEnums,
+          _packageUri ?? importUri,
+          languageVersion.version);
+
+  Version get enableEnhancedEnumsVersionInLibrary =>
+      _enableEnhancedEnumsVersionInLibrary ??= loader.target
+          .getExperimentEnabledVersionInLibrary(
+              ExperimentalFlag.enhancedEnums, _packageUri ?? importUri);
+
   void _updateLibraryNNBDSettings() {
     library.isNonNullableByDefault = isNonNullableByDefault;
     switch (loader.nnbdMode) {
@@ -698,7 +724,7 @@
           resolve(this.importUri,
               new Uri(scheme: "dart", path: "core").toString(), -1),
           -1,
-          accessor: loader.first);
+          accessorUri: loader.firstUri);
       imported = coreLibrary.loader
           .lookupLibraryBuilder(new Uri(scheme: 'dart', path: dottedName));
     }
@@ -774,13 +800,7 @@
     if (uri != null) {
       partOfUri = resolve(this.importUri, uri, uriOffset);
       Uri newFileUri = resolve(fileUri, uri, uriOffset);
-      LibraryBuilder library = loader.read(partOfUri!, uriOffset,
-          fileUri: newFileUri, accessor: this);
-      if (loader.first == this) {
-        // This is a part, and it was the first input. Let the loader know
-        // about that.
-        loader.first = library;
-      }
+      loader.read(partOfUri!, uriOffset, fileUri: newFileUri, accessor: this);
     }
   }
 
@@ -2670,6 +2690,11 @@
       referencesFromIndexedClass =
           referencesFromIndexed!.lookupIndexedClass(name);
     }
+    // Nested declaration began in `OutlineBuilder.beginEnum`.
+    // TODO(cstefantsova): Use actual type variables here.
+    TypeParameterScopeBuilder declaration =
+        endNestedDeclaration(TypeParameterScopeKind.enumDeclaration, name)
+          ..resolveNamedTypes([], this);
     EnumBuilder builder = new EnumBuilder(
         metadata,
         name,
@@ -2678,7 +2703,13 @@
         startCharOffset,
         charOffset,
         charEndOffset,
-        referencesFromIndexedClass);
+        referencesFromIndexedClass,
+        new Scope(
+            local: declaration.members!,
+            setters: declaration.setters!,
+            parent: scope.withTypeVariables(<TypeVariableBuilder>[]),
+            debugName: "enum $name",
+            isModifiable: false));
     addBuilder(name, builder, charOffset,
         getterReference: referencesFromIndexedClass?.cls.reference);
   }
@@ -4579,6 +4610,7 @@
   topLevelMethod,
   factoryMethod,
   functionType,
+  enumDeclaration,
 }
 
 /// A builder object preparing for building declarations that can introduce type
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 29c7861..4043a0a4 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -27,6 +27,7 @@
 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:kernel/util/graph.dart';
 import 'package:package_config/package_config.dart' as package_config;
 
 import '../../api_prototype/experimental_flags.dart';
@@ -34,7 +35,9 @@
 import '../../base/common.dart';
 import '../../base/instrumentation.dart' show Instrumentation;
 import '../../base/nnbd_mode.dart';
+import '../dill/dill_class_builder.dart';
 import '../dill/dill_library_builder.dart';
+import '../builder_graph.dart';
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/constructor_builder.dart';
@@ -64,6 +67,7 @@
 import '../kernel/kernel_helper.dart'
     show SynthesizedFunctionNode, TypeDependency;
 import '../kernel/kernel_target.dart' show KernelTarget;
+import '../kernel/macro.dart';
 import '../kernel/transform_collections.dart' show CollectionTransformer;
 import '../kernel/transform_set_literals.dart' show SetLiteralTransformer;
 import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
@@ -193,12 +197,22 @@
 
   /// 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;
+  Uri? _firstUri;
+
+  LibraryBuilder? get first => _builders[_firstUri];
+
+  Uri? get firstUri => _firstUri;
+
+  void set firstUri(Uri? value) {
+    _firstUri = value;
+  }
 
   int byteCount = 0;
 
   Uri? currentUriForCrashReporting;
 
+  ClassBuilder? _macroClassBuilder;
+
   SourceLoader(this.fileSystem, this.includeComments, this.target)
       : dataForTesting =
             retainDataForTesting ? new SourceLoaderDataForTesting() : null;
@@ -367,7 +381,7 @@
     // firstSourceUri and first library should be done as early as
     // possible.
     firstSourceUri ??= uri;
-    first ??= libraryBuilder;
+    firstUri ??= libraryBuilder.importUri;
 
     _checkForDartCore(uri, libraryBuilder);
 
@@ -467,6 +481,7 @@
   LibraryBuilder read(Uri uri, int charOffset,
       {Uri? fileUri,
       LibraryBuilder? accessor,
+      Uri? accessorUri,
       LibraryBuilder? origin,
       Library? referencesFrom,
       bool? referenceIsPartOwner}) {
@@ -486,6 +501,7 @@
 
       _builders[uri] = libraryBuilder;
     }
+    accessor ??= _builders[accessorUri];
     if (accessor == null) {
       if (libraryBuilder.loader == this && first != libraryBuilder) {
         unhandled("null", "accessor", charOffset, uri);
@@ -505,11 +521,11 @@
 
   void _ensureCoreLibrary() {
     if (_coreLibrary == null) {
-      read(Uri.parse("dart:core"), 0, accessor: first);
+      read(Uri.parse("dart:core"), 0, accessorUri: firstUri);
       // 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);
+      read(Uri.parse("dart:collection"), 0, accessorUri: firstUri);
       assert(_coreLibrary != null);
     }
   }
@@ -828,7 +844,7 @@
     _typeInferenceEngine!.typeDependencies[member] = typeDependency;
   }
 
-  Future<Null> buildOutlines() async {
+  Future<void> buildOutlines() async {
     _ensureCoreLibrary();
     while (_unparsedLibraries.isNotEmpty) {
       LibraryBuilder library = _unparsedLibraries.removeFirst();
@@ -1061,7 +1077,10 @@
     }
     for (Uri uri in parts) {
       if (usedParts.contains(uri)) {
-        _builders.remove(uri);
+        LibraryBuilder? part = _builders.remove(uri);
+        if (_firstUri == uri) {
+          firstUri = part!.partOfLibrary!.importUri;
+        }
       } else {
         SourceLibraryBuilder part =
             lookupLibraryBuilder(uri) as SourceLibraryBuilder;
@@ -1168,6 +1187,191 @@
     ticker.logMs("Resolved $typeCount types");
   }
 
+  void computeMacroDeclarations(List<SourceClassBuilder> sourceClassBuilders) {
+    if (!enableMacros) return;
+
+    LibraryBuilder? macroLibraryBuilder = lookupLibraryBuilder(macroLibraryUri);
+    if (macroLibraryBuilder == null) return;
+
+    Builder? macroClassBuilder =
+        macroLibraryBuilder.lookupLocalMember(macroClassName);
+    if (macroClassBuilder is! ClassBuilder) {
+      // TODO(johnniwinther): Report this when the actual macro builder package
+      // exists. It should at least be a warning.
+      return;
+    }
+
+    _macroClassBuilder = macroClassBuilder;
+    if (retainDataForTesting) {
+      dataForTesting!.macroDeclarationData.macrosAreAvailable = true;
+    }
+
+    Set<ClassBuilder> macroClasses = {macroClassBuilder};
+    Set<Uri> macroLibraries = {macroLibraryBuilder.importUri};
+
+    bool isMacroClass(TypeDeclarationBuilder? typeDeclarationBuilder) {
+      if (typeDeclarationBuilder == null) return false;
+      while (typeDeclarationBuilder is TypeAliasBuilder) {
+        typeDeclarationBuilder =
+            typeDeclarationBuilder.unaliasDeclaration(null);
+      }
+      if (typeDeclarationBuilder is ClassBuilder) {
+        if (macroClasses.contains(typeDeclarationBuilder)) return true;
+        if (typeDeclarationBuilder is DillClassBuilder) {
+          // TODO(johnniwinther): Recognize macro classes from dill.
+        }
+      }
+      return false;
+    }
+
+    for (SourceClassBuilder sourceClassBuilder in sourceClassBuilders) {
+      bool isMacro =
+          isMacroClass(sourceClassBuilder.supertypeBuilder?.declaration);
+      if (!isMacro && sourceClassBuilder.interfaceBuilders != null) {
+        for (TypeBuilder interfaceBuilder
+            in sourceClassBuilder.interfaceBuilders!) {
+          if (isMacroClass(interfaceBuilder.declaration)) {
+            isMacro = true;
+            break;
+          }
+        }
+      }
+      isMacro = isMacro ||
+          isMacroClass(sourceClassBuilder.mixedInTypeBuilder?.declaration);
+      if (isMacro) {
+        macroClasses.add(sourceClassBuilder);
+        macroLibraries.add(sourceClassBuilder.library.importUri);
+        if (retainDataForTesting) {
+          (dataForTesting!.macroDeclarationData.macroDeclarations[
+                  sourceClassBuilder.library.importUri] ??= [])
+              .add(sourceClassBuilder.name);
+        }
+      }
+    }
+
+    bool isDillLibrary(Uri uri) => _builders[uri]?.loader != this;
+
+    List<List<Uri>> computeCompilationSequence(Graph<Uri> libraryGraph,
+        {required bool Function(Uri) filter}) {
+      List<List<Uri>> stronglyConnectedComponents =
+          computeStrongComponents(libraryGraph);
+
+      Graph<List<Uri>> strongGraph =
+          new StrongComponentGraph(libraryGraph, stronglyConnectedComponents);
+      List<List<List<Uri>>> componentLayers =
+          topologicalSort(strongGraph).layers;
+      List<List<Uri>> layeredComponents = [];
+      List<Uri> currentLayer = [];
+      for (List<List<Uri>> layer in componentLayers) {
+        bool declaresMacro = false;
+        for (List<Uri> component in layer) {
+          for (Uri uri in component) {
+            if (filter(uri)) continue;
+            if (macroLibraries.contains(uri)) {
+              declaresMacro = true;
+            }
+            currentLayer.add(uri);
+          }
+        }
+        if (declaresMacro) {
+          layeredComponents.add(currentLayer);
+          currentLayer = [];
+        }
+      }
+      if (currentLayer.isNotEmpty) {
+        layeredComponents.add(currentLayer);
+      }
+      return layeredComponents;
+    }
+
+    List<List<Uri>> compilationSteps = computeCompilationSequence(
+        new BuilderGraph(_builders),
+        filter: isDillLibrary);
+    if (retainDataForTesting) {
+      dataForTesting!.macroDeclarationData.compilationSequence =
+          compilationSteps;
+    }
+  }
+
+  void computeMacroApplications() {
+    if (!enableMacros || _macroClassBuilder == null) return;
+    Class macroClass = _macroClassBuilder!.cls;
+
+    Class? computeApplication(Expression expression) {
+      if (expression is ConstructorInvocation) {
+        Class cls = expression.target.enclosingClass;
+        if (hierarchy.isSubtypeOf(cls, macroClass)) {
+          return cls;
+        }
+      }
+      return null;
+    }
+
+    MacroApplications? computeApplications(List<Expression> annotations) {
+      List<Class> macros = [];
+      for (Expression annotation in annotations) {
+        Class? cls = computeApplication(annotation);
+        if (cls != null) {
+          macros.add(cls);
+        }
+      }
+      return macros.isNotEmpty ? new MacroApplications(macros) : null;
+    }
+
+    for (LibraryBuilder libraryBuilder in libraryBuilders) {
+      if (libraryBuilder.loader != this) continue;
+      LibraryMacroApplicationData libraryMacroApplicationData =
+          new LibraryMacroApplicationData();
+      Library library = libraryBuilder.library;
+      libraryMacroApplicationData.libraryApplications =
+          computeApplications(library.annotations);
+      for (Class cls in library.classes) {
+        ClassMacroApplicationData classMacroApplicationData =
+            new ClassMacroApplicationData();
+        classMacroApplicationData.classApplications =
+            computeApplications(cls.annotations);
+        for (Member member in cls.members) {
+          MacroApplications? macroApplications =
+              computeApplications(member.annotations);
+          if (macroApplications != null) {
+            classMacroApplicationData.memberApplications[member] =
+                macroApplications;
+          }
+        }
+        if (classMacroApplicationData.classApplications != null ||
+            classMacroApplicationData.memberApplications.isNotEmpty) {
+          libraryMacroApplicationData.classData[cls] =
+              classMacroApplicationData;
+        }
+      }
+      for (Member member in library.members) {
+        MacroApplications? macroApplications =
+            computeApplications(member.annotations);
+        if (macroApplications != null) {
+          libraryMacroApplicationData.memberApplications[member] =
+              macroApplications;
+        }
+      }
+      for (Typedef typedef in library.typedefs) {
+        MacroApplications? macroApplications =
+            computeApplications(typedef.annotations);
+        if (macroApplications != null) {
+          libraryMacroApplicationData.typedefApplications[typedef] =
+              macroApplications;
+        }
+      }
+      if (libraryMacroApplicationData.libraryApplications != null ||
+          libraryMacroApplicationData.classData.isNotEmpty ||
+          libraryMacroApplicationData.typedefApplications.isNotEmpty ||
+          libraryMacroApplicationData.memberApplications.isNotEmpty) {
+        if (retainDataForTesting) {
+          dataForTesting!.macroApplicationData.libraryData[library] =
+              libraryMacroApplicationData;
+        }
+      }
+    }
+  }
+
   void finishDeferredLoadTearoffs() {
     int count = 0;
     for (LibraryBuilder library in libraryBuilders) {
@@ -1289,20 +1493,6 @@
   /// pipeline (including backends) can assume that there are no hierarchy
   /// cycles.
   List<SourceClassBuilder> handleHierarchyCycles(ClassBuilder objectClass) {
-    // Compute the initial work list of all classes declared in this loader.
-    List<SourceClassBuilder> workList = <SourceClassBuilder>[];
-    for (LibraryBuilder library in libraryBuilders) {
-      if (library.loader == this) {
-        Iterator<Builder> members = library.iterator;
-        while (members.moveNext()) {
-          Builder member = members.current;
-          if (member is SourceClassBuilder) {
-            workList.add(member);
-          }
-        }
-      }
-    }
-
     Set<ClassBuilder> denyListedClasses = new Set<ClassBuilder>();
     for (int i = 0; i < denylistedCoreClasses.length; i++) {
       denyListedClasses.add(coreLibrary.lookupLocalMember(
@@ -1319,42 +1509,16 @@
     }
 
     // Sort the classes topologically.
-    Set<SourceClassBuilder> topologicallySortedClasses =
-        new Set<SourceClassBuilder>();
-    List<SourceClassBuilder> previousWorkList;
-    do {
-      previousWorkList = workList;
-      workList = <SourceClassBuilder>[];
-      for (int i = 0; i < previousWorkList.length; i++) {
-        SourceClassBuilder cls = previousWorkList[i];
-        Map<TypeDeclarationBuilder?, TypeAliasBuilder?> directSupertypeMap =
-            cls.computeDirectSupertypes(objectClass);
-        List<TypeDeclarationBuilder?> directSupertypes =
-            directSupertypeMap.keys.toList();
-        bool allSupertypesProcessed = true;
-        for (int i = 0; i < directSupertypes.length; i++) {
-          Builder? supertype = directSupertypes[i];
-          if (supertype is SourceClassBuilder &&
-              supertype.library.loader == this &&
-              !topologicallySortedClasses.contains(supertype)) {
-            allSupertypesProcessed = false;
-            break;
-          }
-        }
-        if (allSupertypesProcessed && cls.isPatch) {
-          allSupertypesProcessed =
-              topologicallySortedClasses.contains(cls.origin);
-        }
-        if (allSupertypesProcessed) {
-          topologicallySortedClasses.add(cls);
-          checkClassSupertypes(cls, directSupertypeMap, denyListedClasses);
-        } else {
-          workList.add(cls);
-        }
-      }
-    } while (previousWorkList.length != workList.length);
-    List<SourceClassBuilder> classes = topologicallySortedClasses.toList();
-    List<SourceClassBuilder> classesWithCycles = previousWorkList;
+    _SourceClassGraph classGraph = new _SourceClassGraph(this, objectClass);
+    TopologicalSortResult<SourceClassBuilder> result =
+        topologicalSort(classGraph);
+    List<SourceClassBuilder> classes = result.sortedVertices;
+    for (SourceClassBuilder cls in classes) {
+      checkClassSupertypes(
+          cls, classGraph.directSupertypeMap[cls]!, denyListedClasses);
+    }
+
+    List<SourceClassBuilder> classesWithCycles = result.cyclicVertices;
 
     // Once the work list doesn't change in size, it's either empty, or
     // contains all classes with cycles.
@@ -1970,7 +2134,7 @@
     _typeInferenceEngine = null;
     _builders.clear();
     libraries.clear();
-    first = null;
+    firstUri = null;
     sourceBytes.clear();
     target.releaseAncillaryResources();
     _coreTypes = null;
@@ -2269,4 +2433,49 @@
   TreeNode toOriginal(TreeNode alias) {
     return _aliasMap[alias] ?? alias;
   }
+
+  final MacroDeclarationData macroDeclarationData = new MacroDeclarationData();
+
+  final MacroApplicationData macroApplicationData = new MacroApplicationData();
+}
+
+class _SourceClassGraph implements Graph<SourceClassBuilder> {
+  @override
+  final List<SourceClassBuilder> vertices = [];
+  final ClassBuilder _objectClass;
+  final Map<SourceClassBuilder, Map<TypeDeclarationBuilder?, TypeAliasBuilder?>>
+      directSupertypeMap = {};
+  final Map<SourceClassBuilder, List<SourceClassBuilder>> _supertypeMap = {};
+
+  _SourceClassGraph(SourceLoader loader, this._objectClass) {
+    // Compute the vertices as all classes declared in this loader.
+    for (LibraryBuilder library in loader.libraryBuilders) {
+      if (library.loader == loader) {
+        Iterator<Builder> members = library.iterator;
+        while (members.moveNext()) {
+          Builder member = members.current;
+          if (member is SourceClassBuilder && !member.isPatch) {
+            vertices.add(member);
+          }
+        }
+      }
+    }
+  }
+
+  List<SourceClassBuilder> computeSuperClasses(SourceClassBuilder cls) {
+    Map<TypeDeclarationBuilder?, TypeAliasBuilder?> directSupertypes =
+        directSupertypeMap[cls] = cls.computeDirectSupertypes(_objectClass);
+    List<SourceClassBuilder> superClasses = [];
+    for (TypeDeclarationBuilder? directSupertype in directSupertypes.keys) {
+      if (directSupertype is SourceClassBuilder) {
+        superClasses.add(directSupertype);
+      }
+    }
+    return superClasses;
+  }
+
+  @override
+  Iterable<SourceClassBuilder> neighborsOf(SourceClassBuilder vertex) {
+    return _supertypeMap[vertex] ??= computeSuperClasses(vertex);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/util/abstracted_ast_nodes.dart b/pkg/front_end/lib/src/fasta/util/abstracted_ast_nodes.dart
new file mode 100644
index 0000000..e731acd
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/util/abstracted_ast_nodes.dart
@@ -0,0 +1,864 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:front_end/src/fasta/util/parser_ast_helper.dart';
+
+enum Coloring { Untouched, Marked }
+
+abstract class AstNode {
+  Map<String, List<AstNode>> scope = {};
+  Container? parent;
+  ParserAstNode get node;
+  Token get startInclusive;
+  Token get endInclusive;
+
+  Coloring marked = Coloring.Untouched;
+
+  StringBuffer toStringInternal(StringBuffer sb, int indent);
+
+  void buildScope();
+  Map<String, AstNode> selfScope();
+
+  List<AstNode>? findInScope(String name) {
+    return scope[name] ?? parent?.findInScope(name);
+  }
+}
+
+abstract class Container extends AstNode {
+  List<AstNode> _children = [];
+  Iterable<AstNode> get children => _children;
+
+  void addChild(AstNode child, Map<ParserAstNode, AstNode> map) {
+    child.parent = this;
+    _children.add(child);
+    map[child.node] = child;
+  }
+}
+
+class TopLevel extends Container {
+  final String sourceText;
+  final Uri uri;
+
+  @override
+  final ParserAstNode node;
+
+  final Map<ParserAstNode, AstNode> map;
+
+  TopLevel(this.sourceText, this.uri, this.node, this.map);
+
+  @override
+  String toString() => toStringInternal(new StringBuffer(), 0).toString();
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    if (_children.isEmpty) {
+      String stringIndent = " " * ((indent + 1) * 2);
+      sb.write(stringIndent);
+      sb.writeln("(empty)");
+    } else {
+      for (AstNode node in _children) {
+        sb.write(stringIndent);
+        node.toStringInternal(sb, indent + 1);
+      }
+    }
+    return sb;
+  }
+
+  @override
+  void buildScope() {
+    for (AstNode child in _children) {
+      child.buildScope();
+      for (MapEntry<String, AstNode> entry in child.selfScope().entries) {
+        (scope[entry.key] ??= []).add(entry.value);
+      }
+    }
+  }
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return const {};
+  }
+
+  @override
+  Token get endInclusive => throw new UnimplementedError();
+
+  @override
+  Token get startInclusive => throw new UnimplementedError();
+}
+
+class Class extends Container {
+  @override
+  final TopLevelDeclarationEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Class(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Class $name");
+    if (_children.isEmpty) {
+      String stringIndent = " " * ((indent + 1) * 2);
+      sb.write(stringIndent);
+      sb.writeln("(empty)");
+    } else {
+      for (AstNode node in _children) {
+        node.toStringInternal(sb, indent + 1);
+      }
+    }
+    return sb;
+  }
+
+  @override
+  void buildScope() {
+    for (AstNode child in _children) {
+      child.buildScope();
+      for (MapEntry<String, AstNode> entry in child.selfScope().entries) {
+        (scope[entry.key] ??= []).add(entry.value);
+      }
+    }
+  }
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class Mixin extends Container {
+  @override
+  final TopLevelDeclarationEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Mixin(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Mixin $name");
+    if (_children.isEmpty) {
+      String stringIndent = " " * ((indent + 1) * 2);
+      sb.write(stringIndent);
+      sb.writeln("(empty)");
+    } else {
+      for (AstNode node in _children) {
+        node.toStringInternal(sb, indent + 1);
+      }
+    }
+    return sb;
+  }
+
+  @override
+  void buildScope() {
+    for (AstNode child in _children) {
+      child.buildScope();
+      for (MapEntry<String, AstNode> entry in child.selfScope().entries) {
+        (scope[entry.key] ??= []).add(entry.value);
+      }
+    }
+  }
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class Extension extends Container {
+  @override
+  final TopLevelDeclarationEnd node;
+  final String? name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Extension(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Extension $name");
+    if (_children.isEmpty) {
+      String stringIndent = " " * ((indent + 1) * 2);
+      sb.write(stringIndent);
+      sb.writeln("(empty)");
+    } else {
+      for (AstNode node in _children) {
+        node.toStringInternal(sb, indent + 1);
+      }
+    }
+    return sb;
+  }
+
+  @override
+  void buildScope() {
+    for (AstNode child in _children) {
+      child.buildScope();
+      for (MapEntry<String, AstNode> entry in child.selfScope().entries) {
+        (scope[entry.key] ??= []).add(entry.value);
+      }
+    }
+  }
+
+  @override
+  Map<String, AstNode> selfScope() {
+    if (name != null) {
+      return {name!: this};
+    } else {
+      return const {};
+    }
+  }
+}
+
+class ClassConstructor extends AstNode {
+  @override
+  final ClassConstructorEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  ClassConstructor(
+      this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Class constructor $name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    // TODO: Possibly this should be different...
+    return {name: this};
+  }
+}
+
+class ClassFactoryMethod extends AstNode {
+  @override
+  final ClassFactoryMethodEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  ClassFactoryMethod(
+      this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Class factory constructor $name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    // TODO: Possibly this should be different...
+    return {name: this};
+  }
+}
+
+class ClassMethod extends AstNode {
+  @override
+  final ClassMethodEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  ClassMethod(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Class method $name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class ExtensionMethod extends AstNode {
+  @override
+  final ExtensionMethodEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  ExtensionMethod(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Extension method $name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class MixinMethod extends AstNode {
+  @override
+  final MixinMethodEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  MixinMethod(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Mixin method $name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class Enum extends AstNode {
+  @override
+  final EnumEnd node;
+  final String name;
+  final List<String> members;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Enum(this.node, this.name, this.members, this.startInclusive,
+      this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Enum $name with members $members");
+    return sb;
+  }
+
+  @override
+  void buildScope() {
+    for (String child in members) {
+      scope[child] = [this];
+    }
+  }
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class Import extends AstNode {
+  @override
+  final ImportEnd node;
+  final Uri firstUri;
+  final List<Uri>? conditionalUris;
+  final String? asName;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Import(this.node, this.firstUri, this.conditionalUris, this.asName,
+      this.startInclusive, this.endInclusive);
+
+  List<Uri> get uris => [firstUri, ...?conditionalUris];
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    if (asName == null) {
+      sb.writeln("Import of $uris");
+    } else {
+      sb.writeln("Import of $uris as '$asName'");
+    }
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    if (asName != null) {
+      return {asName!: this};
+    }
+    return const {};
+  }
+}
+
+class Export extends AstNode {
+  @override
+  final ExportEnd node;
+  final Uri firstUri;
+  final List<Uri>? conditionalUris;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Export(this.node, this.firstUri, this.conditionalUris, this.startInclusive,
+      this.endInclusive);
+
+  List<Uri> get uris => [firstUri, ...?conditionalUris];
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Export of $uris");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return const {};
+  }
+}
+
+class Part extends AstNode {
+  @override
+  final PartEnd node;
+  final Uri uri;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Part(this.node, this.uri, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Part $uri");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return const {};
+  }
+}
+
+class TopLevelFields extends AstNode {
+  @override
+  final TopLevelFieldsEnd node;
+  final List<String> names;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  TopLevelFields(this.node, this.names, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Top level field(s) ${names.join(", ")}");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    Map<String, AstNode> scope = {};
+    for (String name in names) {
+      scope[name] = this;
+    }
+    return scope;
+  }
+}
+
+class TopLevelMethod extends AstNode {
+  @override
+  final TopLevelMethodEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  TopLevelMethod(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Top level method $name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class Typedef extends AstNode {
+  @override
+  final TypedefEnd node;
+  final String name;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Typedef(this.node, this.name, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Top level method $name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return {name: this};
+  }
+}
+
+class ClassFields extends AstNode {
+  @override
+  final ClassFieldsEnd node;
+  final List<String> names;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  ClassFields(this.node, this.names, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Class field(s) ${names.join(", ")}");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    Map<String, AstNode> scope = {};
+    for (String name in names) {
+      scope[name] = this;
+    }
+    return scope;
+  }
+}
+
+class MixinFields extends AstNode {
+  @override
+  final MixinFieldsEnd node;
+  final List<String> names;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  MixinFields(this.node, this.names, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Mixin field(s) ${names.join(", ")}");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    Map<String, AstNode> scope = {};
+    for (String name in names) {
+      scope[name] = this;
+    }
+    return scope;
+  }
+}
+
+class ExtensionFields extends AstNode {
+  @override
+  final ExtensionFieldsEnd node;
+  final List<String> names;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  ExtensionFields(
+      this.node, this.names, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("Extension field(s) ${names.join(", ")}");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    Map<String, AstNode> scope = {};
+    for (String name in names) {
+      scope[name] = this;
+    }
+    return scope;
+  }
+}
+
+class Metadata extends AstNode {
+  @override
+  final MetadataEnd node;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  Metadata(this.node, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("metadata");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return const {};
+  }
+}
+
+class LibraryName extends AstNode {
+  @override
+  final LibraryNameEnd node;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  LibraryName(this.node, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("library name");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return const {};
+  }
+}
+
+class PartOf extends AstNode {
+  @override
+  final PartOfEnd node;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+  final Uri partOfUri;
+
+  PartOf(this.node, this.partOfUri, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("part of");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return const {};
+  }
+}
+
+class LanguageVersion extends AstNode {
+  @override
+  final ParserAstNode node;
+  @override
+  final Token startInclusive;
+  @override
+  final Token endInclusive;
+
+  LanguageVersion(this.node, this.startInclusive, this.endInclusive);
+
+  @override
+  StringBuffer toStringInternal(StringBuffer sb, int indent) {
+    String stringIndent = " " * (indent * 2);
+    sb.write(stringIndent);
+    if (marked != Coloring.Untouched) {
+      sb.write("(marked) ");
+    }
+    sb.writeln("$startInclusive");
+    return sb;
+  }
+
+  @override
+  void buildScope() {}
+
+  @override
+  Map<String, AstNode> selfScope() {
+    return const {};
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
deleted file mode 100644
index 94a1865..0000000
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
+++ /dev/null
@@ -1,1292 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:typed_data' show Uint8List;
-
-import 'dart:io' show File;
-
-import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
-    show ScannerConfiguration;
-
-import 'package:_fe_analyzer_shared/src/parser/parser.dart'
-    show ClassMemberParser, Parser;
-
-import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
-    show Utf8BytesScanner;
-
-import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
-import '../source/diet_parser.dart';
-
-import 'direct_parser_ast_helper.dart';
-
-DirectParserASTContentCompilationUnitEnd getAST(List<int> rawBytes,
-    {bool includeBody: true,
-    bool includeComments: false,
-    bool enableExtensionMethods: false,
-    bool enableNonNullable: false,
-    bool enableTripleShift: false}) {
-  Uint8List bytes = new Uint8List(rawBytes.length + 1);
-  bytes.setRange(0, rawBytes.length, rawBytes);
-
-  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
-      enableExtensionMethods: enableExtensionMethods,
-      enableNonNullable: enableNonNullable,
-      enableTripleShift: enableTripleShift);
-
-  Utf8BytesScanner scanner = new Utf8BytesScanner(
-    bytes,
-    includeComments: includeComments,
-    configuration: scannerConfiguration,
-    languageVersionChanged: (scanner, languageVersion) {
-      // For now don't do anything, but having it (making it non-null) means the
-      // configuration won't be reset.
-    },
-  );
-  Token firstToken = scanner.tokenize();
-  // ignore: unnecessary_null_comparison
-  if (firstToken == null) {
-    throw "firstToken is null";
-  }
-
-  DirectParserASTListener listener = new DirectParserASTListener();
-  Parser parser;
-  if (includeBody) {
-    parser = new Parser(listener,
-        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
-  } else {
-    parser = new ClassMemberParser(listener,
-        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
-  }
-  parser.parseUnit(firstToken);
-  return listener.data.single as DirectParserASTContentCompilationUnitEnd;
-}
-
-/// Best-effort visitor for DirectParserASTContent that visits top-level entries
-/// and class members only (i.e. no bodies, no field initializer content, no
-/// names etc).
-class DirectParserASTContentVisitor {
-  void accept(DirectParserASTContent node) {
-    if (node is DirectParserASTContentCompilationUnitEnd ||
-        node is DirectParserASTContentTopLevelDeclarationEnd ||
-        node is DirectParserASTContentClassOrMixinOrExtensionBodyEnd ||
-        node is DirectParserASTContentMemberEnd) {
-      visitChildren(node);
-      return;
-    }
-
-    if (node.type == DirectParserASTType.BEGIN) {
-      // Ignored. These are basically just dummy nodes anyway.
-      assert(node.children == null);
-      return;
-    }
-    if (node.type == DirectParserASTType.HANDLE) {
-      // Ignored at least for know.
-      assert(node.children == null);
-      return;
-    }
-    if (node is DirectParserASTContentTypeVariablesEnd ||
-        node is DirectParserASTContentTypeArgumentsEnd ||
-        node is DirectParserASTContentTypeListEnd ||
-        node is DirectParserASTContentFunctionTypeEnd ||
-        node is DirectParserASTContentBlockEnd) {
-      // Ignored at least for know.
-      return;
-    }
-    if (node is DirectParserASTContentMetadataStarEnd) {
-      DirectParserASTContentMetadataStarEnd metadata = node;
-      visitMetadataStar(metadata);
-      return;
-    }
-    if (node is DirectParserASTContentTypedefEnd) {
-      DirectParserASTContentTypedefEnd typedefDecl = node;
-      visitTypedef(
-          typedefDecl, typedefDecl.typedefKeyword, typedefDecl.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentClassDeclarationEnd) {
-      DirectParserASTContentClassDeclarationEnd cls = node;
-      visitClass(cls, cls.beginToken, cls.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentTopLevelMethodEnd) {
-      DirectParserASTContentTopLevelMethodEnd method = node;
-      visitTopLevelMethod(method, method.beginToken, method.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentClassMethodEnd) {
-      DirectParserASTContentClassMethodEnd method = node;
-      visitClassMethod(method, method.beginToken, method.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentExtensionMethodEnd) {
-      DirectParserASTContentExtensionMethodEnd method = node;
-      visitExtensionMethod(method, method.beginToken, method.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentMixinMethodEnd) {
-      DirectParserASTContentMixinMethodEnd method = node;
-      visitMixinMethod(method, method.beginToken, method.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentImportEnd) {
-      DirectParserASTContentImportEnd import = node;
-      visitImport(import, import.importKeyword, import.semicolon);
-      return;
-    }
-    if (node is DirectParserASTContentExportEnd) {
-      DirectParserASTContentExportEnd export = node;
-      visitExport(export, export.exportKeyword, export.semicolon);
-      return;
-    }
-    if (node is DirectParserASTContentTopLevelFieldsEnd) {
-      // TODO(jensj): Possibly this could go into more details too
-      // (e.g. to split up a field declaration).
-      DirectParserASTContentTopLevelFieldsEnd fields = node;
-      visitTopLevelFields(fields, fields.beginToken, fields.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentClassFieldsEnd) {
-      // TODO(jensj): Possibly this could go into more details too
-      // (e.g. to split up a field declaration).
-      DirectParserASTContentClassFieldsEnd fields = node;
-      visitClassFields(fields, fields.beginToken, fields.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentExtensionFieldsEnd) {
-      // TODO(jensj): Possibly this could go into more details too
-      // (e.g. to split up a field declaration).
-      DirectParserASTContentExtensionFieldsEnd fields = node;
-      visitExtensionFields(fields, fields.beginToken, fields.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentMixinFieldsEnd) {
-      // TODO(jensj): Possibly this could go into more details too
-      // (e.g. to split up a field declaration).
-      DirectParserASTContentMixinFieldsEnd fields = node;
-      visitMixinFields(fields, fields.beginToken, fields.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentNamedMixinApplicationEnd) {
-      DirectParserASTContentNamedMixinApplicationEnd namedMixin = node;
-      visitNamedMixin(namedMixin, namedMixin.begin, namedMixin.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentMixinDeclarationEnd) {
-      DirectParserASTContentMixinDeclarationEnd declaration = node;
-      visitMixin(declaration, declaration.mixinKeyword, declaration.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentEnumEnd) {
-      DirectParserASTContentEnumEnd declaration = node;
-      visitEnum(declaration, declaration.enumKeyword,
-          declaration.leftBrace.endGroup!);
-      return;
-    }
-    if (node is DirectParserASTContentLibraryNameEnd) {
-      DirectParserASTContentLibraryNameEnd name = node;
-      visitLibraryName(name, name.libraryKeyword, name.semicolon);
-      return;
-    }
-    if (node is DirectParserASTContentPartEnd) {
-      DirectParserASTContentPartEnd part = node;
-      visitPart(part, part.partKeyword, part.semicolon);
-      return;
-    }
-    if (node is DirectParserASTContentPartOfEnd) {
-      DirectParserASTContentPartOfEnd partOf = node;
-      visitPartOf(partOf, partOf.partKeyword, partOf.semicolon);
-      return;
-    }
-    if (node is DirectParserASTContentExtensionDeclarationEnd) {
-      DirectParserASTContentExtensionDeclarationEnd ext = node;
-      visitExtension(ext, ext.extensionKeyword, ext.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentClassConstructorEnd) {
-      DirectParserASTContentClassConstructorEnd decl = node;
-      visitClassConstructor(decl, decl.beginToken, decl.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentExtensionConstructorEnd) {
-      DirectParserASTContentExtensionConstructorEnd decl = node;
-      visitExtensionConstructor(decl, decl.beginToken, decl.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentClassFactoryMethodEnd) {
-      DirectParserASTContentClassFactoryMethodEnd decl = node;
-      visitClassFactoryMethod(decl, decl.beginToken, decl.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentExtensionFactoryMethodEnd) {
-      DirectParserASTContentExtensionFactoryMethodEnd decl = node;
-      visitExtensionFactoryMethod(decl, decl.beginToken, decl.endToken);
-      return;
-    }
-    if (node is DirectParserASTContentMetadataEnd) {
-      DirectParserASTContentMetadataEnd decl = node;
-      // TODO(jensj): endToken is not part of the metadata! It's the first token
-      // of the next thing.
-      visitMetadata(decl, decl.beginToken, decl.endToken.previous!);
-      return;
-    }
-
-    throw "Unknown: $node (${node.runtimeType} @ ${node.what})";
-  }
-
-  void visitChildren(DirectParserASTContent node) {
-    if (node.children == null) return;
-    final int numChildren = node.children!.length;
-    for (int i = 0; i < numChildren; i++) {
-      DirectParserASTContent child = node.children![i];
-      accept(child);
-    }
-  }
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitImport(DirectParserASTContentImportEnd node, Token startInclusive,
-      Token? endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitExport(DirectParserASTContentExportEnd node, Token startInclusive,
-      Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitTypedef(DirectParserASTContentTypedefEnd node, Token startInclusive,
-      Token endInclusive) {}
-
-  /// Note: Implementers can call visitChildren on this node.
-  void visitMetadataStar(DirectParserASTContentMetadataStarEnd node) {
-    visitChildren(node);
-  }
-
-  /// Note: Implementers can call visitChildren on this node.
-  void visitClass(DirectParserASTContentClassDeclarationEnd node,
-      Token startInclusive, Token endInclusive) {
-    visitChildren(node);
-  }
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitTopLevelMethod(DirectParserASTContentTopLevelMethodEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitClassMethod(DirectParserASTContentClassMethodEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitExtensionMethod(DirectParserASTContentExtensionMethodEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitMixinMethod(DirectParserASTContentMixinMethodEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitTopLevelFields(DirectParserASTContentTopLevelFieldsEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitClassFields(DirectParserASTContentClassFieldsEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitExtensionFields(DirectParserASTContentExtensionFieldsEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitMixinFields(DirectParserASTContentMixinFieldsEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers can call visitChildren on this node.
-  void visitNamedMixin(DirectParserASTContentNamedMixinApplicationEnd node,
-      Token startInclusive, Token endInclusive) {
-    visitChildren(node);
-  }
-
-  /// Note: Implementers can call visitChildren on this node.
-  void visitMixin(DirectParserASTContentMixinDeclarationEnd node,
-      Token startInclusive, Token endInclusive) {
-    visitChildren(node);
-  }
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitEnum(DirectParserASTContentEnumEnd node, Token startInclusive,
-      Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitLibraryName(DirectParserASTContentLibraryNameEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitPart(DirectParserASTContentPartEnd node, Token startInclusive,
-      Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitPartOf(DirectParserASTContentPartOfEnd node, Token startInclusive,
-      Token endInclusive) {}
-
-  /// Note: Implementers can call visitChildren on this node.
-  void visitExtension(DirectParserASTContentExtensionDeclarationEnd node,
-      Token startInclusive, Token endInclusive) {
-    visitChildren(node);
-  }
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitClassConstructor(DirectParserASTContentClassConstructorEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitExtensionConstructor(
-      DirectParserASTContentExtensionConstructorEnd node,
-      Token startInclusive,
-      Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitClassFactoryMethod(DirectParserASTContentClassFactoryMethodEnd node,
-      Token startInclusive, Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitExtensionFactoryMethod(
-      DirectParserASTContentExtensionFactoryMethodEnd node,
-      Token startInclusive,
-      Token endInclusive) {}
-
-  /// Note: Implementers are NOT expected to call visitChildren on this node.
-  void visitMetadata(DirectParserASTContentMetadataEnd node,
-      Token startInclusive, Token endInclusive) {}
-}
-
-extension GeneralASTContentExtension on DirectParserASTContent {
-  bool isClass() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        // ignore: lines_longer_than_80_chars
-        is! DirectParserASTContentClassOrMixinOrNamedMixinApplicationPreludeBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentClassDeclarationEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentClassDeclarationEnd asClass() {
-    if (!isClass()) throw "Not class";
-    return children!.last as DirectParserASTContentClassDeclarationEnd;
-  }
-
-  bool isImport() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentImportEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentImportEnd asImport() {
-    if (!isImport()) throw "Not import";
-    return children!.last as DirectParserASTContentImportEnd;
-  }
-
-  bool isExport() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentExportEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentExportEnd asExport() {
-    if (!isExport()) throw "Not export";
-    return children!.last as DirectParserASTContentExportEnd;
-  }
-
-  bool isEnum() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentEnumEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentEnumEnd asEnum() {
-    if (!isEnum()) throw "Not enum";
-    return children!.last as DirectParserASTContentEnumEnd;
-  }
-
-  bool isTypedef() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentTypedefEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentTypedefEnd asTypedef() {
-    if (!isTypedef()) throw "Not typedef";
-    return children!.last as DirectParserASTContentTypedefEnd;
-  }
-
-  bool isScript() {
-    if (this is! DirectParserASTContentScriptHandle) {
-      return false;
-    }
-    return true;
-  }
-
-  DirectParserASTContentScriptHandle asScript() {
-    if (!isScript()) throw "Not script";
-    return this as DirectParserASTContentScriptHandle;
-  }
-
-  bool isExtension() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentExtensionDeclarationPreludeBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentExtensionDeclarationEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentExtensionDeclarationEnd asExtension() {
-    if (!isExtension()) throw "Not extension";
-    return children!.last as DirectParserASTContentExtensionDeclarationEnd;
-  }
-
-  bool isInvalidTopLevelDeclaration() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first is! DirectParserASTContentTopLevelMemberBegin) {
-      return false;
-    }
-    if (children!.last
-        is! DirectParserASTContentInvalidTopLevelDeclarationHandle) {
-      return false;
-    }
-
-    return true;
-  }
-
-  bool isRecoverableError() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentRecoverableErrorHandle) {
-      return false;
-    }
-
-    return true;
-  }
-
-  bool isRecoverImport() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentRecoverImportHandle) {
-      return false;
-    }
-
-    return true;
-  }
-
-  bool isMixinDeclaration() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        // ignore: lines_longer_than_80_chars
-        is! DirectParserASTContentClassOrMixinOrNamedMixinApplicationPreludeBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentMixinDeclarationEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentMixinDeclarationEnd asMixinDeclaration() {
-    if (!isMixinDeclaration()) throw "Not mixin declaration";
-    return children!.last as DirectParserASTContentMixinDeclarationEnd;
-  }
-
-  bool isNamedMixinDeclaration() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        // ignore: lines_longer_than_80_chars
-        is! DirectParserASTContentClassOrMixinOrNamedMixinApplicationPreludeBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentNamedMixinApplicationEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentNamedMixinApplicationEnd asNamedMixinDeclaration() {
-    if (!isNamedMixinDeclaration()) throw "Not named mixin declaration";
-    return children!.last as DirectParserASTContentNamedMixinApplicationEnd;
-  }
-
-  bool isTopLevelMethod() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first is! DirectParserASTContentTopLevelMemberBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentTopLevelMethodEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentTopLevelMethodEnd asTopLevelMethod() {
-    if (!isTopLevelMethod()) throw "Not top level method";
-    return children!.last as DirectParserASTContentTopLevelMethodEnd;
-  }
-
-  bool isTopLevelFields() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first is! DirectParserASTContentTopLevelMemberBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentTopLevelFieldsEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentTopLevelFieldsEnd asTopLevelFields() {
-    if (!isTopLevelFields()) throw "Not top level fields";
-    return children!.last as DirectParserASTContentTopLevelFieldsEnd;
-  }
-
-  bool isLibraryName() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentLibraryNameEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentLibraryNameEnd asLibraryName() {
-    if (!isLibraryName()) throw "Not library name";
-    return children!.last as DirectParserASTContentLibraryNameEnd;
-  }
-
-  bool isPart() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentPartEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentPartEnd asPart() {
-    if (!isPart()) throw "Not part";
-    return children!.last as DirectParserASTContentPartEnd;
-  }
-
-  bool isPartOf() {
-    if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
-      return false;
-    }
-    if (children!.first
-        is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
-      return false;
-    }
-    if (children!.last is! DirectParserASTContentPartOfEnd) {
-      return false;
-    }
-
-    return true;
-  }
-
-  DirectParserASTContentPartOfEnd asPartOf() {
-    if (!isPartOf()) throw "Not part of";
-    return children!.last as DirectParserASTContentPartOfEnd;
-  }
-
-  bool isMetadata() {
-    if (this is! DirectParserASTContentMetadataStarEnd) {
-      return false;
-    }
-    if (children!.first is! DirectParserASTContentMetadataStarBegin) {
-      return false;
-    }
-    return true;
-  }
-
-  DirectParserASTContentMetadataStarEnd asMetadata() {
-    if (!isMetadata()) throw "Not metadata";
-    return this as DirectParserASTContentMetadataStarEnd;
-  }
-
-  bool isFunctionBody() {
-    if (this is DirectParserASTContentBlockFunctionBodyEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentBlockFunctionBodyEnd asFunctionBody() {
-    if (!isFunctionBody()) throw "Not function body";
-    return this as DirectParserASTContentBlockFunctionBodyEnd;
-  }
-
-  List<E> recursivelyFind<E extends DirectParserASTContent>() {
-    Set<E> result = {};
-    _recursivelyFindInternal(this, result);
-    return result.toList();
-  }
-
-  static void _recursivelyFindInternal<E extends DirectParserASTContent>(
-      DirectParserASTContent node, Set<E> result) {
-    if (node is E) {
-      result.add(node);
-      return;
-    }
-    if (node.children == null) return;
-    for (DirectParserASTContent child in node.children!) {
-      _recursivelyFindInternal(child, result);
-    }
-  }
-
-  void debugDumpNodeRecursively({String indent = ""}) {
-    print("$indent${runtimeType} (${what}) "
-        "(${deprecatedArguments})");
-    if (children == null) return;
-    for (DirectParserASTContent child in children!) {
-      child.debugDumpNodeRecursively(indent: "  $indent");
-    }
-  }
-}
-
-extension MetadataStarExtension on DirectParserASTContentMetadataStarEnd {
-  List<DirectParserASTContentMetadataEnd> getMetadataEntries() {
-    List<DirectParserASTContentMetadataEnd> result = [];
-    for (DirectParserASTContent topLevel in children!) {
-      if (topLevel is! DirectParserASTContentMetadataEnd) continue;
-      result.add(topLevel);
-    }
-    return result;
-  }
-}
-
-extension CompilationUnitExtension on DirectParserASTContentCompilationUnitEnd {
-  List<DirectParserASTContentTopLevelDeclarationEnd> getClasses() {
-    List<DirectParserASTContentTopLevelDeclarationEnd> result = [];
-    for (DirectParserASTContent topLevel in children!) {
-      if (!topLevel.isClass()) continue;
-      result.add(topLevel as DirectParserASTContentTopLevelDeclarationEnd);
-    }
-    return result;
-  }
-
-  List<DirectParserASTContentTopLevelDeclarationEnd> getMixinDeclarations() {
-    List<DirectParserASTContentTopLevelDeclarationEnd> result = [];
-    for (DirectParserASTContent topLevel in children!) {
-      if (!topLevel.isMixinDeclaration()) continue;
-      result.add(topLevel as DirectParserASTContentTopLevelDeclarationEnd);
-    }
-    return result;
-  }
-
-  List<DirectParserASTContentImportEnd> getImports() {
-    List<DirectParserASTContentImportEnd> result = [];
-    for (DirectParserASTContent topLevel in children!) {
-      if (!topLevel.isImport()) continue;
-      result.add(topLevel.children!.last as DirectParserASTContentImportEnd);
-    }
-    return result;
-  }
-
-  List<DirectParserASTContentExportEnd> getExports() {
-    List<DirectParserASTContentExportEnd> result = [];
-    for (DirectParserASTContent topLevel in children!) {
-      if (!topLevel.isExport()) continue;
-      result.add(topLevel.children!.last as DirectParserASTContentExportEnd);
-    }
-    return result;
-  }
-
-  // List<DirectParserASTContentMetadataStarEnd> getMetadata() {
-  //   List<DirectParserASTContentMetadataStarEnd> result = [];
-  //   for (DirectParserASTContent topLevel in children) {
-  //     if (!topLevel.isMetadata()) continue;
-  //     result.add(topLevel);
-  //   }
-  //   return result;
-  // }
-
-  // List<DirectParserASTContentEnumEnd> getEnums() {
-  //   List<DirectParserASTContentEnumEnd> result = [];
-  //   for (DirectParserASTContent topLevel in children) {
-  //     if (!topLevel.isEnum()) continue;
-  //     result.add(topLevel.children.last);
-  //   }
-  //   return result;
-  // }
-
-  // List<DirectParserASTContentFunctionTypeAliasEnd> getTypedefs() {
-  //   List<DirectParserASTContentFunctionTypeAliasEnd> result = [];
-  //   for (DirectParserASTContent topLevel in children) {
-  //     if (!topLevel.isTypedef()) continue;
-  //     result.add(topLevel.children.last);
-  //   }
-  //   return result;
-  // }
-
-  // List<DirectParserASTContentMixinDeclarationEnd> getMixinDeclarations() {
-  //   List<DirectParserASTContentMixinDeclarationEnd> result = [];
-  //   for (DirectParserASTContent topLevel in children) {
-  //     if (!topLevel.isMixinDeclaration()) continue;
-  //     result.add(topLevel.children.last);
-  //   }
-  //   return result;
-  // }
-
-  // List<DirectParserASTContentTopLevelMethodEnd> getTopLevelMethods() {
-  //   List<DirectParserASTContentTopLevelMethodEnd> result = [];
-  //   for (DirectParserASTContent topLevel in children) {
-  //     if (!topLevel.isTopLevelMethod()) continue;
-  //     result.add(topLevel.children.last);
-  //   }
-  //   return result;
-  // }
-
-  DirectParserASTContentCompilationUnitBegin getBegin() {
-    return children!.first as DirectParserASTContentCompilationUnitBegin;
-  }
-}
-
-extension TopLevelDeclarationExtension
-    on DirectParserASTContentTopLevelDeclarationEnd {
-  DirectParserASTContentIdentifierHandle getIdentifier() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentIdentifierHandle) return child;
-    }
-    throw "Not found.";
-  }
-
-  DirectParserASTContentClassDeclarationEnd getClassDeclaration() {
-    if (!isClass()) {
-      throw "Not a class";
-    }
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentClassDeclarationEnd) {
-        return child;
-      }
-    }
-    throw "Not found.";
-  }
-}
-
-extension MixinDeclarationExtension
-    on DirectParserASTContentMixinDeclarationEnd {
-  DirectParserASTContentClassOrMixinOrExtensionBodyEnd
-      getClassOrMixinOrExtensionBody() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentClassOrMixinOrExtensionBodyEnd) {
-        return child;
-      }
-    }
-    throw "Not found.";
-  }
-}
-
-extension ClassDeclarationExtension
-    on DirectParserASTContentClassDeclarationEnd {
-  DirectParserASTContentClassOrMixinOrExtensionBodyEnd
-      getClassOrMixinOrExtensionBody() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentClassOrMixinOrExtensionBodyEnd) {
-        return child;
-      }
-    }
-    throw "Not found.";
-  }
-
-  DirectParserASTContentClassExtendsHandle getClassExtends() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentClassExtendsHandle) return child;
-    }
-    throw "Not found.";
-  }
-
-  DirectParserASTContentClassOrMixinImplementsHandle getClassImplements() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentClassOrMixinImplementsHandle) {
-        return child;
-      }
-    }
-    throw "Not found.";
-  }
-
-  DirectParserASTContentClassWithClauseHandle? getClassWithClause() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentClassWithClauseHandle) {
-        return child;
-      }
-    }
-    return null;
-  }
-}
-
-extension ClassOrMixinBodyExtension
-    on DirectParserASTContentClassOrMixinOrExtensionBodyEnd {
-  List<DirectParserASTContentMemberEnd> getMembers() {
-    List<DirectParserASTContentMemberEnd> members = [];
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentMemberEnd) {
-        members.add(child);
-      }
-    }
-    return members;
-  }
-}
-
-extension MemberExtension on DirectParserASTContentMemberEnd {
-  bool isClassConstructor() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassConstructorEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentClassConstructorEnd getClassConstructor() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassConstructorEnd) return child;
-    throw "Not found";
-  }
-
-  bool isClassFactoryMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassFactoryMethodEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentClassFactoryMethodEnd getClassFactoryMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassFactoryMethodEnd) return child;
-    throw "Not found";
-  }
-
-  bool isClassFields() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassFieldsEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentClassFieldsEnd getClassFields() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassFieldsEnd) return child;
-    throw "Not found";
-  }
-
-  bool isMixinFields() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinFieldsEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentMixinFieldsEnd getMixinFields() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinFieldsEnd) return child;
-    throw "Not found";
-  }
-
-  bool isMixinMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinMethodEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentMixinMethodEnd getMixinMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinMethodEnd) return child;
-    throw "Not found";
-  }
-
-  bool isMixinFactoryMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinFactoryMethodEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentMixinFactoryMethodEnd getMixinFactoryMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinFactoryMethodEnd) return child;
-    throw "Not found";
-  }
-
-  bool isMixinConstructor() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinConstructorEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentMixinConstructorEnd getMixinConstructor() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentMixinConstructorEnd) return child;
-    throw "Not found";
-  }
-
-  bool isClassMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassMethodEnd) return true;
-    return false;
-  }
-
-  DirectParserASTContentClassMethodEnd getClassMethod() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentClassMethodEnd) return child;
-    throw "Not found";
-  }
-
-  bool isClassRecoverableError() {
-    DirectParserASTContent child = children![1];
-    if (child is DirectParserASTContentRecoverableErrorHandle) return true;
-    return false;
-  }
-}
-
-extension ClassFieldsExtension on DirectParserASTContentClassFieldsEnd {
-  List<DirectParserASTContentIdentifierHandle?> getFieldIdentifiers() {
-    // For now blindly assume that the last count identifiers are the names
-    // of the fields.
-    int countLeft = count;
-    List<DirectParserASTContentIdentifierHandle>? identifiers;
-    for (int i = children!.length - 1; i >= 0; i--) {
-      DirectParserASTContent child = children![i];
-      if (child is DirectParserASTContentIdentifierHandle) {
-        countLeft--;
-        if (identifiers == null) {
-          identifiers = new List<DirectParserASTContentIdentifierHandle>.filled(
-              count, child);
-        } else {
-          identifiers[countLeft] = child;
-        }
-        if (countLeft == 0) break;
-      }
-    }
-    if (countLeft != 0) throw "Didn't find the expected number of identifiers";
-    return identifiers ?? [];
-  }
-
-  DirectParserASTContentTypeHandle? getFirstType() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentTypeHandle) return child;
-    }
-    return null;
-  }
-
-  DirectParserASTContentFieldInitializerEnd? getFieldInitializer() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentFieldInitializerEnd) return child;
-    }
-    return null;
-  }
-}
-
-extension ClassMethodExtension on DirectParserASTContentClassMethodEnd {
-  DirectParserASTContentBlockFunctionBodyEnd? getBlockFunctionBody() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentBlockFunctionBodyEnd) {
-        return child;
-      }
-    }
-    return null;
-  }
-}
-
-extension ClassConstructorExtension
-    on DirectParserASTContentClassConstructorEnd {
-  DirectParserASTContentFormalParametersEnd getFormalParameters() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentFormalParametersEnd) {
-        return child;
-      }
-    }
-    throw "Not found";
-  }
-
-  DirectParserASTContentInitializersEnd? getInitializers() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentInitializersEnd) {
-        return child;
-      }
-    }
-    return null;
-  }
-
-  DirectParserASTContentBlockFunctionBodyEnd? getBlockFunctionBody() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentBlockFunctionBodyEnd) {
-        return child;
-      }
-    }
-    return null;
-  }
-}
-
-extension FormalParametersExtension
-    on DirectParserASTContentFormalParametersEnd {
-  List<DirectParserASTContentFormalParameterEnd> getFormalParameters() {
-    List<DirectParserASTContentFormalParameterEnd> result = [];
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentFormalParameterEnd) {
-        result.add(child);
-      }
-    }
-    return result;
-  }
-
-  DirectParserASTContentOptionalFormalParametersEnd?
-      getOptionalFormalParameters() {
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentOptionalFormalParametersEnd) {
-        return child;
-      }
-    }
-    return null;
-  }
-}
-
-extension FormalParameterExtension on DirectParserASTContentFormalParameterEnd {
-  DirectParserASTContentFormalParameterBegin getBegin() {
-    return children!.first as DirectParserASTContentFormalParameterBegin;
-  }
-}
-
-extension OptionalFormalParametersExtension
-    on DirectParserASTContentOptionalFormalParametersEnd {
-  List<DirectParserASTContentFormalParameterEnd> getFormalParameters() {
-    List<DirectParserASTContentFormalParameterEnd> result = [];
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentFormalParameterEnd) {
-        result.add(child);
-      }
-    }
-    return result;
-  }
-}
-
-extension InitializersExtension on DirectParserASTContentInitializersEnd {
-  List<DirectParserASTContentInitializerEnd> getInitializers() {
-    List<DirectParserASTContentInitializerEnd> result = [];
-    for (DirectParserASTContent child in children!) {
-      if (child is DirectParserASTContentInitializerEnd) {
-        result.add(child);
-      }
-    }
-    return result;
-  }
-
-  DirectParserASTContentInitializersBegin getBegin() {
-    return children!.first as DirectParserASTContentInitializersBegin;
-  }
-}
-
-extension InitializerExtension on DirectParserASTContentInitializerEnd {
-  DirectParserASTContentInitializerBegin getBegin() {
-    return children!.first as DirectParserASTContentInitializerBegin;
-  }
-}
-
-void main(List<String> args) {
-  File f = new File(args[0]);
-  Uint8List data = f.readAsBytesSync();
-  DirectParserASTContent ast = getAST(data);
-  if (args.length > 1 && args[1] == "--benchmark") {
-    Stopwatch stopwatch = new Stopwatch()..start();
-    int numRuns = 100;
-    for (int i = 0; i < numRuns; i++) {
-      DirectParserASTContent ast2 = getAST(data);
-      if (ast.what != ast2.what) {
-        throw "Not the same result every time";
-      }
-    }
-    stopwatch.stop();
-    print("First $numRuns took ${stopwatch.elapsedMilliseconds} ms "
-        "(i.e. ${stopwatch.elapsedMilliseconds / numRuns}ms/iteration)");
-    stopwatch = new Stopwatch()..start();
-    numRuns = 2500;
-    for (int i = 0; i < numRuns; i++) {
-      DirectParserASTContent ast2 = getAST(data);
-      if (ast.what != ast2.what) {
-        throw "Not the same result every time";
-      }
-    }
-    stopwatch.stop();
-    print("Next $numRuns took ${stopwatch.elapsedMilliseconds} ms "
-        "(i.e. ${stopwatch.elapsedMilliseconds / numRuns}ms/iteration)");
-  } else {
-    print(ast);
-  }
-}
-
-class DirectParserASTListener extends AbstractDirectParserASTListener {
-  @override
-  void seen(DirectParserASTContent entry) {
-    switch (entry.type) {
-      case DirectParserASTType.BEGIN:
-      case DirectParserASTType.HANDLE:
-        // This just adds stuff.
-        data.add(entry);
-        break;
-      case DirectParserASTType.END:
-        // End should gobble up everything until the corresponding begin (which
-        // should be the latest begin).
-        int? beginIndex;
-        for (int i = data.length - 1; i >= 0; i--) {
-          if (data[i].type == DirectParserASTType.BEGIN) {
-            beginIndex = i;
-            break;
-          }
-        }
-        if (beginIndex == null) {
-          throw "Couldn't find a begin for ${entry.what}. Has:\n"
-              "${data.map((e) => "${e.what}: ${e.type}").join("\n")}";
-        }
-        String begin = data[beginIndex].what;
-        String end = entry.what;
-        if (begin == end) {
-          // Exact match.
-        } else if (end == "TopLevelDeclaration" &&
-            (begin == "ExtensionDeclarationPrelude" ||
-                begin == "ClassOrMixinOrNamedMixinApplicationPrelude" ||
-                begin == "TopLevelMember" ||
-                begin == "UncategorizedTopLevelDeclaration")) {
-          // endTopLevelDeclaration is started by one of
-          // beginExtensionDeclarationPrelude,
-          // beginClassOrNamedMixinApplicationPrelude
-          // beginTopLevelMember or beginUncategorizedTopLevelDeclaration.
-        } else if (begin == "Method" &&
-            (end == "ClassConstructor" ||
-                end == "ClassMethod" ||
-                end == "ExtensionConstructor" ||
-                end == "ExtensionMethod" ||
-                end == "MixinConstructor" ||
-                end == "MixinMethod")) {
-          // beginMethod is ended by one of endClassConstructor, endClassMethod,
-          // endExtensionMethod, endMixinConstructor or endMixinMethod.
-        } else if (begin == "Fields" &&
-            (end == "TopLevelFields" ||
-                end == "ClassFields" ||
-                end == "MixinFields" ||
-                end == "ExtensionFields")) {
-          // beginFields is ended by one of endTopLevelFields, endMixinFields or
-          // endExtensionFields.
-        } else if (begin == "ForStatement" && end == "ForIn") {
-          // beginForStatement is ended by either endForStatement or endForIn.
-        } else if (begin == "FactoryMethod" &&
-            (end == "ClassFactoryMethod" ||
-                end == "MixinFactoryMethod" ||
-                end == "ExtensionFactoryMethod")) {
-          // beginFactoryMethod is ended by either endClassFactoryMethod,
-          // endMixinFactoryMethod or endExtensionFactoryMethod.
-        } else if (begin == "ForControlFlow" && (end == "ForInControlFlow")) {
-          // beginForControlFlow is ended by either endForControlFlow or
-          // endForInControlFlow.
-        } else if (begin == "IfControlFlow" && (end == "IfElseControlFlow")) {
-          // beginIfControlFlow is ended by either endIfControlFlow or
-          // endIfElseControlFlow.
-        } else if (begin == "AwaitExpression" &&
-            (end == "InvalidAwaitExpression")) {
-          // beginAwaitExpression is ended by either endAwaitExpression or
-          // endInvalidAwaitExpression.
-        } else if (begin == "YieldStatement" &&
-            (end == "InvalidYieldStatement")) {
-          // beginYieldStatement is ended by either endYieldStatement or
-          // endInvalidYieldStatement.
-        } else {
-          throw "Unknown combination: begin$begin and end$end";
-        }
-        List<DirectParserASTContent> children = data.sublist(beginIndex);
-        data.length = beginIndex;
-        data.add(entry..children = children);
-        break;
-    }
-  }
-
-  @override
-  void reportVarianceModifierNotEnabled(Token? variance) {
-    throw new UnimplementedError();
-  }
-
-  @override
-  Uri get uri => throw new UnimplementedError();
-
-  @override
-  void logEvent(String name) {
-    throw new UnimplementedError();
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
deleted file mode 100644
index 4fedb0b..0000000
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
+++ /dev/null
@@ -1,7636 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:_fe_analyzer_shared/src/parser/assert.dart';
-import 'package:_fe_analyzer_shared/src/parser/block_kind.dart';
-import 'package:_fe_analyzer_shared/src/parser/constructor_reference_context.dart';
-import 'package:_fe_analyzer_shared/src/parser/declaration_kind.dart';
-import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
-import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
-import 'package:_fe_analyzer_shared/src/parser/listener.dart';
-import 'package:_fe_analyzer_shared/src/parser/member_kind.dart';
-import 'package:_fe_analyzer_shared/src/scanner/error_token.dart';
-import 'package:_fe_analyzer_shared/src/scanner/token.dart';
-import 'package:front_end/src/fasta/messages.dart';
-
-// ignore_for_file: lines_longer_than_80_chars
-
-// THIS FILE IS AUTO GENERATED BY
-// 'tool/_fasta/direct_parser_ast_helper_creator.dart'
-// Run this command to update it:
-// 'dart pkg/front_end/tool/_fasta/direct_parser_ast_helper_creator.dart'
-
-abstract class DirectParserASTContent {
-  final String what;
-  final DirectParserASTType type;
-  Map<String, Object?> get deprecatedArguments;
-  List<DirectParserASTContent>? children;
-
-  DirectParserASTContent(this.what, this.type);
-
-  // TODO(jensj): Compare two ASTs.
-}
-
-enum DirectParserASTType { BEGIN, END, HANDLE }
-
-abstract class AbstractDirectParserASTListener implements Listener {
-  List<DirectParserASTContent> data = [];
-
-  void seen(DirectParserASTContent entry);
-
-  @override
-  void beginArguments(Token token) {
-    DirectParserASTContentArgumentsBegin data =
-        new DirectParserASTContentArgumentsBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endArguments(int count, Token beginToken, Token endToken) {
-    DirectParserASTContentArgumentsEnd data =
-        new DirectParserASTContentArgumentsEnd(DirectParserASTType.END,
-            count: count, beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleAsyncModifier(Token? asyncToken, Token? starToken) {
-    DirectParserASTContentAsyncModifierHandle data =
-        new DirectParserASTContentAsyncModifierHandle(
-            DirectParserASTType.HANDLE,
-            asyncToken: asyncToken,
-            starToken: starToken);
-    seen(data);
-  }
-
-  @override
-  void beginAwaitExpression(Token token) {
-    DirectParserASTContentAwaitExpressionBegin data =
-        new DirectParserASTContentAwaitExpressionBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endAwaitExpression(Token beginToken, Token endToken) {
-    DirectParserASTContentAwaitExpressionEnd data =
-        new DirectParserASTContentAwaitExpressionEnd(DirectParserASTType.END,
-            beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endInvalidAwaitExpression(
-      Token beginToken, Token endToken, MessageCode errorCode) {
-    DirectParserASTContentInvalidAwaitExpressionEnd data =
-        new DirectParserASTContentInvalidAwaitExpressionEnd(
-            DirectParserASTType.END,
-            beginToken: beginToken,
-            endToken: endToken,
-            errorCode: errorCode);
-    seen(data);
-  }
-
-  @override
-  void beginBlock(Token token, BlockKind blockKind) {
-    DirectParserASTContentBlockBegin data =
-        new DirectParserASTContentBlockBegin(DirectParserASTType.BEGIN,
-            token: token, blockKind: blockKind);
-    seen(data);
-  }
-
-  @override
-  void endBlock(
-      int count, Token beginToken, Token endToken, BlockKind blockKind) {
-    DirectParserASTContentBlockEnd data = new DirectParserASTContentBlockEnd(
-        DirectParserASTType.END,
-        count: count,
-        beginToken: beginToken,
-        endToken: endToken,
-        blockKind: blockKind);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidTopLevelBlock(Token token) {
-    DirectParserASTContentInvalidTopLevelBlockHandle data =
-        new DirectParserASTContentInvalidTopLevelBlockHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginCascade(Token token) {
-    DirectParserASTContentCascadeBegin data =
-        new DirectParserASTContentCascadeBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endCascade() {
-    DirectParserASTContentCascadeEnd data =
-        new DirectParserASTContentCascadeEnd(DirectParserASTType.END);
-    seen(data);
-  }
-
-  @override
-  void beginCaseExpression(Token caseKeyword) {
-    DirectParserASTContentCaseExpressionBegin data =
-        new DirectParserASTContentCaseExpressionBegin(DirectParserASTType.BEGIN,
-            caseKeyword: caseKeyword);
-    seen(data);
-  }
-
-  @override
-  void endCaseExpression(Token colon) {
-    DirectParserASTContentCaseExpressionEnd data =
-        new DirectParserASTContentCaseExpressionEnd(DirectParserASTType.END,
-            colon: colon);
-    seen(data);
-  }
-
-  @override
-  void beginClassOrMixinOrExtensionBody(DeclarationKind kind, Token token) {
-    DirectParserASTContentClassOrMixinOrExtensionBodyBegin data =
-        new DirectParserASTContentClassOrMixinOrExtensionBodyBegin(
-            DirectParserASTType.BEGIN,
-            kind: kind,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endClassOrMixinOrExtensionBody(
-      DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
-    DirectParserASTContentClassOrMixinOrExtensionBodyEnd data =
-        new DirectParserASTContentClassOrMixinOrExtensionBodyEnd(
-            DirectParserASTType.END,
-            kind: kind,
-            memberCount: memberCount,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginClassOrMixinOrNamedMixinApplicationPrelude(Token token) {
-    DirectParserASTContentClassOrMixinOrNamedMixinApplicationPreludeBegin data =
-        new DirectParserASTContentClassOrMixinOrNamedMixinApplicationPreludeBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginClassDeclaration(Token begin, Token? abstractToken, Token name) {
-    DirectParserASTContentClassDeclarationBegin data =
-        new DirectParserASTContentClassDeclarationBegin(
-            DirectParserASTType.BEGIN,
-            begin: begin,
-            abstractToken: abstractToken,
-            name: name);
-    seen(data);
-  }
-
-  @override
-  void handleClassExtends(Token? extendsKeyword, int typeCount) {
-    DirectParserASTContentClassExtendsHandle data =
-        new DirectParserASTContentClassExtendsHandle(DirectParserASTType.HANDLE,
-            extendsKeyword: extendsKeyword, typeCount: typeCount);
-    seen(data);
-  }
-
-  @override
-  void handleClassOrMixinImplements(
-      Token? implementsKeyword, int interfacesCount) {
-    DirectParserASTContentClassOrMixinImplementsHandle data =
-        new DirectParserASTContentClassOrMixinImplementsHandle(
-            DirectParserASTType.HANDLE,
-            implementsKeyword: implementsKeyword,
-            interfacesCount: interfacesCount);
-    seen(data);
-  }
-
-  @override
-  void handleExtensionShowHide(Token? showKeyword, int showElementCount,
-      Token? hideKeyword, int hideElementCount) {
-    DirectParserASTContentExtensionShowHideHandle data =
-        new DirectParserASTContentExtensionShowHideHandle(
-            DirectParserASTType.HANDLE,
-            showKeyword: showKeyword,
-            showElementCount: showElementCount,
-            hideKeyword: hideKeyword,
-            hideElementCount: hideElementCount);
-    seen(data);
-  }
-
-  @override
-  void handleClassHeader(Token begin, Token classKeyword, Token? nativeToken) {
-    DirectParserASTContentClassHeaderHandle data =
-        new DirectParserASTContentClassHeaderHandle(DirectParserASTType.HANDLE,
-            begin: begin, classKeyword: classKeyword, nativeToken: nativeToken);
-    seen(data);
-  }
-
-  @override
-  void handleRecoverClassHeader() {
-    DirectParserASTContentRecoverClassHeaderHandle data =
-        new DirectParserASTContentRecoverClassHeaderHandle(
-            DirectParserASTType.HANDLE);
-    seen(data);
-  }
-
-  @override
-  void endClassDeclaration(Token beginToken, Token endToken) {
-    DirectParserASTContentClassDeclarationEnd data =
-        new DirectParserASTContentClassDeclarationEnd(DirectParserASTType.END,
-            beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginMixinDeclaration(Token mixinKeyword, Token name) {
-    DirectParserASTContentMixinDeclarationBegin data =
-        new DirectParserASTContentMixinDeclarationBegin(
-            DirectParserASTType.BEGIN,
-            mixinKeyword: mixinKeyword,
-            name: name);
-    seen(data);
-  }
-
-  @override
-  void handleMixinOn(Token? onKeyword, int typeCount) {
-    DirectParserASTContentMixinOnHandle data =
-        new DirectParserASTContentMixinOnHandle(DirectParserASTType.HANDLE,
-            onKeyword: onKeyword, typeCount: typeCount);
-    seen(data);
-  }
-
-  @override
-  void handleMixinHeader(Token mixinKeyword) {
-    DirectParserASTContentMixinHeaderHandle data =
-        new DirectParserASTContentMixinHeaderHandle(DirectParserASTType.HANDLE,
-            mixinKeyword: mixinKeyword);
-    seen(data);
-  }
-
-  @override
-  void handleRecoverMixinHeader() {
-    DirectParserASTContentRecoverMixinHeaderHandle data =
-        new DirectParserASTContentRecoverMixinHeaderHandle(
-            DirectParserASTType.HANDLE);
-    seen(data);
-  }
-
-  @override
-  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
-    DirectParserASTContentMixinDeclarationEnd data =
-        new DirectParserASTContentMixinDeclarationEnd(DirectParserASTType.END,
-            mixinKeyword: mixinKeyword, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginUncategorizedTopLevelDeclaration(Token token) {
-    DirectParserASTContentUncategorizedTopLevelDeclarationBegin data =
-        new DirectParserASTContentUncategorizedTopLevelDeclarationBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginExtensionDeclarationPrelude(Token extensionKeyword) {
-    DirectParserASTContentExtensionDeclarationPreludeBegin data =
-        new DirectParserASTContentExtensionDeclarationPreludeBegin(
-            DirectParserASTType.BEGIN,
-            extensionKeyword: extensionKeyword);
-    seen(data);
-  }
-
-  @override
-  void beginExtensionDeclaration(Token extensionKeyword, Token? name) {
-    DirectParserASTContentExtensionDeclarationBegin data =
-        new DirectParserASTContentExtensionDeclarationBegin(
-            DirectParserASTType.BEGIN,
-            extensionKeyword: extensionKeyword,
-            name: name);
-    seen(data);
-  }
-
-  @override
-  void endExtensionDeclaration(Token extensionKeyword, Token? typeKeyword,
-      Token onKeyword, Token? showKeyword, Token? hideKeyword, Token endToken) {
-    DirectParserASTContentExtensionDeclarationEnd data =
-        new DirectParserASTContentExtensionDeclarationEnd(
-            DirectParserASTType.END,
-            extensionKeyword: extensionKeyword,
-            typeKeyword: typeKeyword,
-            onKeyword: onKeyword,
-            showKeyword: showKeyword,
-            hideKeyword: hideKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginCombinators(Token token) {
-    DirectParserASTContentCombinatorsBegin data =
-        new DirectParserASTContentCombinatorsBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endCombinators(int count) {
-    DirectParserASTContentCombinatorsEnd data =
-        new DirectParserASTContentCombinatorsEnd(DirectParserASTType.END,
-            count: count);
-    seen(data);
-  }
-
-  @override
-  void beginCompilationUnit(Token token) {
-    DirectParserASTContentCompilationUnitBegin data =
-        new DirectParserASTContentCompilationUnitBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleDirectivesOnly() {
-    DirectParserASTContentDirectivesOnlyHandle data =
-        new DirectParserASTContentDirectivesOnlyHandle(
-            DirectParserASTType.HANDLE);
-    seen(data);
-  }
-
-  @override
-  void endCompilationUnit(int count, Token token) {
-    DirectParserASTContentCompilationUnitEnd data =
-        new DirectParserASTContentCompilationUnitEnd(DirectParserASTType.END,
-            count: count, token: token);
-    seen(data);
-  }
-
-  @override
-  void beginConstLiteral(Token token) {
-    DirectParserASTContentConstLiteralBegin data =
-        new DirectParserASTContentConstLiteralBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endConstLiteral(Token token) {
-    DirectParserASTContentConstLiteralEnd data =
-        new DirectParserASTContentConstLiteralEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginConstructorReference(Token start) {
-    DirectParserASTContentConstructorReferenceBegin data =
-        new DirectParserASTContentConstructorReferenceBegin(
-            DirectParserASTType.BEGIN,
-            start: start);
-    seen(data);
-  }
-
-  @override
-  void endConstructorReference(Token start, Token? periodBeforeName,
-      Token endToken, ConstructorReferenceContext constructorReferenceContext) {
-    DirectParserASTContentConstructorReferenceEnd data =
-        new DirectParserASTContentConstructorReferenceEnd(
-            DirectParserASTType.END,
-            start: start,
-            periodBeforeName: periodBeforeName,
-            endToken: endToken,
-            constructorReferenceContext: constructorReferenceContext);
-    seen(data);
-  }
-
-  @override
-  void beginDoWhileStatement(Token token) {
-    DirectParserASTContentDoWhileStatementBegin data =
-        new DirectParserASTContentDoWhileStatementBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endDoWhileStatement(
-      Token doKeyword, Token whileKeyword, Token endToken) {
-    DirectParserASTContentDoWhileStatementEnd data =
-        new DirectParserASTContentDoWhileStatementEnd(DirectParserASTType.END,
-            doKeyword: doKeyword,
-            whileKeyword: whileKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginDoWhileStatementBody(Token token) {
-    DirectParserASTContentDoWhileStatementBodyBegin data =
-        new DirectParserASTContentDoWhileStatementBodyBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endDoWhileStatementBody(Token token) {
-    DirectParserASTContentDoWhileStatementBodyEnd data =
-        new DirectParserASTContentDoWhileStatementBodyEnd(
-            DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginWhileStatementBody(Token token) {
-    DirectParserASTContentWhileStatementBodyBegin data =
-        new DirectParserASTContentWhileStatementBodyBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endWhileStatementBody(Token token) {
-    DirectParserASTContentWhileStatementBodyEnd data =
-        new DirectParserASTContentWhileStatementBodyEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginEnum(Token enumKeyword) {
-    DirectParserASTContentEnumBegin data = new DirectParserASTContentEnumBegin(
-        DirectParserASTType.BEGIN,
-        enumKeyword: enumKeyword);
-    seen(data);
-  }
-
-  @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
-    DirectParserASTContentEnumEnd data = new DirectParserASTContentEnumEnd(
-        DirectParserASTType.END,
-        enumKeyword: enumKeyword,
-        leftBrace: leftBrace,
-        count: count);
-    seen(data);
-  }
-
-  @override
-  void beginExport(Token token) {
-    DirectParserASTContentExportBegin data =
-        new DirectParserASTContentExportBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endExport(Token exportKeyword, Token semicolon) {
-    DirectParserASTContentExportEnd data = new DirectParserASTContentExportEnd(
-        DirectParserASTType.END,
-        exportKeyword: exportKeyword,
-        semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void handleExtraneousExpression(Token token, Message message) {
-    DirectParserASTContentExtraneousExpressionHandle data =
-        new DirectParserASTContentExtraneousExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            message: message);
-    seen(data);
-  }
-
-  @override
-  void handleExpressionStatement(Token token) {
-    DirectParserASTContentExpressionStatementHandle data =
-        new DirectParserASTContentExpressionStatementHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginFactoryMethod(DeclarationKind declarationKind, Token lastConsumed,
-      Token? externalToken, Token? constToken) {
-    DirectParserASTContentFactoryMethodBegin data =
-        new DirectParserASTContentFactoryMethodBegin(DirectParserASTType.BEGIN,
-            declarationKind: declarationKind,
-            lastConsumed: lastConsumed,
-            externalToken: externalToken,
-            constToken: constToken);
-    seen(data);
-  }
-
-  @override
-  void endClassFactoryMethod(
-      Token beginToken, Token factoryKeyword, Token endToken) {
-    DirectParserASTContentClassFactoryMethodEnd data =
-        new DirectParserASTContentClassFactoryMethodEnd(DirectParserASTType.END,
-            beginToken: beginToken,
-            factoryKeyword: factoryKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endMixinFactoryMethod(
-      Token beginToken, Token factoryKeyword, Token endToken) {
-    DirectParserASTContentMixinFactoryMethodEnd data =
-        new DirectParserASTContentMixinFactoryMethodEnd(DirectParserASTType.END,
-            beginToken: beginToken,
-            factoryKeyword: factoryKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endExtensionFactoryMethod(
-      Token beginToken, Token factoryKeyword, Token endToken) {
-    DirectParserASTContentExtensionFactoryMethodEnd data =
-        new DirectParserASTContentExtensionFactoryMethodEnd(
-            DirectParserASTType.END,
-            beginToken: beginToken,
-            factoryKeyword: factoryKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginFormalParameter(Token token, MemberKind kind, Token? requiredToken,
-      Token? covariantToken, Token? varFinalOrConst) {
-    DirectParserASTContentFormalParameterBegin data =
-        new DirectParserASTContentFormalParameterBegin(
-            DirectParserASTType.BEGIN,
-            token: token,
-            kind: kind,
-            requiredToken: requiredToken,
-            covariantToken: covariantToken,
-            varFinalOrConst: varFinalOrConst);
-    seen(data);
-  }
-
-  @override
-  void endFormalParameter(
-      Token? thisKeyword,
-      Token? periodAfterThis,
-      Token nameToken,
-      Token? initializerStart,
-      Token? initializerEnd,
-      FormalParameterKind kind,
-      MemberKind memberKind) {
-    DirectParserASTContentFormalParameterEnd data =
-        new DirectParserASTContentFormalParameterEnd(DirectParserASTType.END,
-            thisKeyword: thisKeyword,
-            periodAfterThis: periodAfterThis,
-            nameToken: nameToken,
-            initializerStart: initializerStart,
-            initializerEnd: initializerEnd,
-            kind: kind,
-            memberKind: memberKind);
-    seen(data);
-  }
-
-  @override
-  void handleNoFormalParameters(Token token, MemberKind kind) {
-    DirectParserASTContentNoFormalParametersHandle data =
-        new DirectParserASTContentNoFormalParametersHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            kind: kind);
-    seen(data);
-  }
-
-  @override
-  void beginFormalParameters(Token token, MemberKind kind) {
-    DirectParserASTContentFormalParametersBegin data =
-        new DirectParserASTContentFormalParametersBegin(
-            DirectParserASTType.BEGIN,
-            token: token,
-            kind: kind);
-    seen(data);
-  }
-
-  @override
-  void endFormalParameters(
-      int count, Token beginToken, Token endToken, MemberKind kind) {
-    DirectParserASTContentFormalParametersEnd data =
-        new DirectParserASTContentFormalParametersEnd(DirectParserASTType.END,
-            count: count,
-            beginToken: beginToken,
-            endToken: endToken,
-            kind: kind);
-    seen(data);
-  }
-
-  @override
-  void endClassFields(
-      Token? abstractToken,
-      Token? externalToken,
-      Token? staticToken,
-      Token? covariantToken,
-      Token? lateToken,
-      Token? varFinalOrConst,
-      int count,
-      Token beginToken,
-      Token endToken) {
-    DirectParserASTContentClassFieldsEnd data =
-        new DirectParserASTContentClassFieldsEnd(DirectParserASTType.END,
-            abstractToken: abstractToken,
-            externalToken: externalToken,
-            staticToken: staticToken,
-            covariantToken: covariantToken,
-            lateToken: lateToken,
-            varFinalOrConst: varFinalOrConst,
-            count: count,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endMixinFields(
-      Token? abstractToken,
-      Token? externalToken,
-      Token? staticToken,
-      Token? covariantToken,
-      Token? lateToken,
-      Token? varFinalOrConst,
-      int count,
-      Token beginToken,
-      Token endToken) {
-    DirectParserASTContentMixinFieldsEnd data =
-        new DirectParserASTContentMixinFieldsEnd(DirectParserASTType.END,
-            abstractToken: abstractToken,
-            externalToken: externalToken,
-            staticToken: staticToken,
-            covariantToken: covariantToken,
-            lateToken: lateToken,
-            varFinalOrConst: varFinalOrConst,
-            count: count,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endExtensionFields(
-      Token? abstractToken,
-      Token? externalToken,
-      Token? staticToken,
-      Token? covariantToken,
-      Token? lateToken,
-      Token? varFinalOrConst,
-      int count,
-      Token beginToken,
-      Token endToken) {
-    DirectParserASTContentExtensionFieldsEnd data =
-        new DirectParserASTContentExtensionFieldsEnd(DirectParserASTType.END,
-            abstractToken: abstractToken,
-            externalToken: externalToken,
-            staticToken: staticToken,
-            covariantToken: covariantToken,
-            lateToken: lateToken,
-            varFinalOrConst: varFinalOrConst,
-            count: count,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleForInitializerEmptyStatement(Token token) {
-    DirectParserASTContentForInitializerEmptyStatementHandle data =
-        new DirectParserASTContentForInitializerEmptyStatementHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleForInitializerExpressionStatement(Token token, bool forIn) {
-    DirectParserASTContentForInitializerExpressionStatementHandle data =
-        new DirectParserASTContentForInitializerExpressionStatementHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            forIn: forIn);
-    seen(data);
-  }
-
-  @override
-  void handleForInitializerLocalVariableDeclaration(Token token, bool forIn) {
-    DirectParserASTContentForInitializerLocalVariableDeclarationHandle data =
-        new DirectParserASTContentForInitializerLocalVariableDeclarationHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            forIn: forIn);
-    seen(data);
-  }
-
-  @override
-  void beginForStatement(Token token) {
-    DirectParserASTContentForStatementBegin data =
-        new DirectParserASTContentForStatementBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleForLoopParts(Token forKeyword, Token leftParen,
-      Token leftSeparator, int updateExpressionCount) {
-    DirectParserASTContentForLoopPartsHandle data =
-        new DirectParserASTContentForLoopPartsHandle(DirectParserASTType.HANDLE,
-            forKeyword: forKeyword,
-            leftParen: leftParen,
-            leftSeparator: leftSeparator,
-            updateExpressionCount: updateExpressionCount);
-    seen(data);
-  }
-
-  @override
-  void endForStatement(Token endToken) {
-    DirectParserASTContentForStatementEnd data =
-        new DirectParserASTContentForStatementEnd(DirectParserASTType.END,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginForStatementBody(Token token) {
-    DirectParserASTContentForStatementBodyBegin data =
-        new DirectParserASTContentForStatementBodyBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endForStatementBody(Token token) {
-    DirectParserASTContentForStatementBodyEnd data =
-        new DirectParserASTContentForStatementBodyEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleForInLoopParts(Token? awaitToken, Token forToken,
-      Token leftParenthesis, Token inKeyword) {
-    DirectParserASTContentForInLoopPartsHandle data =
-        new DirectParserASTContentForInLoopPartsHandle(
-            DirectParserASTType.HANDLE,
-            awaitToken: awaitToken,
-            forToken: forToken,
-            leftParenthesis: leftParenthesis,
-            inKeyword: inKeyword);
-    seen(data);
-  }
-
-  @override
-  void endForIn(Token endToken) {
-    DirectParserASTContentForInEnd data = new DirectParserASTContentForInEnd(
-        DirectParserASTType.END,
-        endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginForInExpression(Token token) {
-    DirectParserASTContentForInExpressionBegin data =
-        new DirectParserASTContentForInExpressionBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endForInExpression(Token token) {
-    DirectParserASTContentForInExpressionEnd data =
-        new DirectParserASTContentForInExpressionEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginForInBody(Token token) {
-    DirectParserASTContentForInBodyBegin data =
-        new DirectParserASTContentForInBodyBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endForInBody(Token token) {
-    DirectParserASTContentForInBodyEnd data =
-        new DirectParserASTContentForInBodyEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginNamedFunctionExpression(Token token) {
-    DirectParserASTContentNamedFunctionExpressionBegin data =
-        new DirectParserASTContentNamedFunctionExpressionBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endNamedFunctionExpression(Token endToken) {
-    DirectParserASTContentNamedFunctionExpressionEnd data =
-        new DirectParserASTContentNamedFunctionExpressionEnd(
-            DirectParserASTType.END,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginLocalFunctionDeclaration(Token token) {
-    DirectParserASTContentLocalFunctionDeclarationBegin data =
-        new DirectParserASTContentLocalFunctionDeclarationBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endLocalFunctionDeclaration(Token endToken) {
-    DirectParserASTContentLocalFunctionDeclarationEnd data =
-        new DirectParserASTContentLocalFunctionDeclarationEnd(
-            DirectParserASTType.END,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginBlockFunctionBody(Token token) {
-    DirectParserASTContentBlockFunctionBodyBegin data =
-        new DirectParserASTContentBlockFunctionBodyBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
-    DirectParserASTContentBlockFunctionBodyEnd data =
-        new DirectParserASTContentBlockFunctionBodyEnd(DirectParserASTType.END,
-            count: count, beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleNoFunctionBody(Token token) {
-    DirectParserASTContentNoFunctionBodyHandle data =
-        new DirectParserASTContentNoFunctionBodyHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
-    DirectParserASTContentFunctionBodySkippedHandle data =
-        new DirectParserASTContentFunctionBodySkippedHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            isExpressionBody: isExpressionBody);
-    seen(data);
-  }
-
-  @override
-  void beginFunctionName(Token token) {
-    DirectParserASTContentFunctionNameBegin data =
-        new DirectParserASTContentFunctionNameBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endFunctionName(Token beginToken, Token token) {
-    DirectParserASTContentFunctionNameEnd data =
-        new DirectParserASTContentFunctionNameEnd(DirectParserASTType.END,
-            beginToken: beginToken, token: token);
-    seen(data);
-  }
-
-  @override
-  void beginTypedef(Token token) {
-    DirectParserASTContentTypedefBegin data =
-        new DirectParserASTContentTypedefBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endTypedef(Token typedefKeyword, Token? equals, Token endToken) {
-    DirectParserASTContentTypedefEnd data =
-        new DirectParserASTContentTypedefEnd(DirectParserASTType.END,
-            typedefKeyword: typedefKeyword, equals: equals, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleClassWithClause(Token withKeyword) {
-    DirectParserASTContentClassWithClauseHandle data =
-        new DirectParserASTContentClassWithClauseHandle(
-            DirectParserASTType.HANDLE,
-            withKeyword: withKeyword);
-    seen(data);
-  }
-
-  @override
-  void handleClassNoWithClause() {
-    DirectParserASTContentClassNoWithClauseHandle data =
-        new DirectParserASTContentClassNoWithClauseHandle(
-            DirectParserASTType.HANDLE);
-    seen(data);
-  }
-
-  @override
-  void beginNamedMixinApplication(
-      Token begin, Token? abstractToken, Token name) {
-    DirectParserASTContentNamedMixinApplicationBegin data =
-        new DirectParserASTContentNamedMixinApplicationBegin(
-            DirectParserASTType.BEGIN,
-            begin: begin,
-            abstractToken: abstractToken,
-            name: name);
-    seen(data);
-  }
-
-  @override
-  void handleNamedMixinApplicationWithClause(Token withKeyword) {
-    DirectParserASTContentNamedMixinApplicationWithClauseHandle data =
-        new DirectParserASTContentNamedMixinApplicationWithClauseHandle(
-            DirectParserASTType.HANDLE,
-            withKeyword: withKeyword);
-    seen(data);
-  }
-
-  @override
-  void endNamedMixinApplication(Token begin, Token classKeyword, Token equals,
-      Token? implementsKeyword, Token endToken) {
-    DirectParserASTContentNamedMixinApplicationEnd data =
-        new DirectParserASTContentNamedMixinApplicationEnd(
-            DirectParserASTType.END,
-            begin: begin,
-            classKeyword: classKeyword,
-            equals: equals,
-            implementsKeyword: implementsKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginHide(Token hideKeyword) {
-    DirectParserASTContentHideBegin data = new DirectParserASTContentHideBegin(
-        DirectParserASTType.BEGIN,
-        hideKeyword: hideKeyword);
-    seen(data);
-  }
-
-  @override
-  void endHide(Token hideKeyword) {
-    DirectParserASTContentHideEnd data = new DirectParserASTContentHideEnd(
-        DirectParserASTType.END,
-        hideKeyword: hideKeyword);
-    seen(data);
-  }
-
-  @override
-  void handleIdentifierList(int count) {
-    DirectParserASTContentIdentifierListHandle data =
-        new DirectParserASTContentIdentifierListHandle(
-            DirectParserASTType.HANDLE,
-            count: count);
-    seen(data);
-  }
-
-  @override
-  void beginTypeList(Token token) {
-    DirectParserASTContentTypeListBegin data =
-        new DirectParserASTContentTypeListBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endTypeList(int count) {
-    DirectParserASTContentTypeListEnd data =
-        new DirectParserASTContentTypeListEnd(DirectParserASTType.END,
-            count: count);
-    seen(data);
-  }
-
-  @override
-  void beginIfStatement(Token token) {
-    DirectParserASTContentIfStatementBegin data =
-        new DirectParserASTContentIfStatementBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endIfStatement(Token ifToken, Token? elseToken) {
-    DirectParserASTContentIfStatementEnd data =
-        new DirectParserASTContentIfStatementEnd(DirectParserASTType.END,
-            ifToken: ifToken, elseToken: elseToken);
-    seen(data);
-  }
-
-  @override
-  void beginThenStatement(Token token) {
-    DirectParserASTContentThenStatementBegin data =
-        new DirectParserASTContentThenStatementBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endThenStatement(Token token) {
-    DirectParserASTContentThenStatementEnd data =
-        new DirectParserASTContentThenStatementEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginElseStatement(Token token) {
-    DirectParserASTContentElseStatementBegin data =
-        new DirectParserASTContentElseStatementBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endElseStatement(Token token) {
-    DirectParserASTContentElseStatementEnd data =
-        new DirectParserASTContentElseStatementEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginImport(Token importKeyword) {
-    DirectParserASTContentImportBegin data =
-        new DirectParserASTContentImportBegin(DirectParserASTType.BEGIN,
-            importKeyword: importKeyword);
-    seen(data);
-  }
-
-  @override
-  void handleImportPrefix(Token? deferredKeyword, Token? asKeyword) {
-    DirectParserASTContentImportPrefixHandle data =
-        new DirectParserASTContentImportPrefixHandle(DirectParserASTType.HANDLE,
-            deferredKeyword: deferredKeyword, asKeyword: asKeyword);
-    seen(data);
-  }
-
-  @override
-  void endImport(Token importKeyword, Token? semicolon) {
-    DirectParserASTContentImportEnd data = new DirectParserASTContentImportEnd(
-        DirectParserASTType.END,
-        importKeyword: importKeyword,
-        semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void handleRecoverImport(Token? semicolon) {
-    DirectParserASTContentRecoverImportHandle data =
-        new DirectParserASTContentRecoverImportHandle(
-            DirectParserASTType.HANDLE,
-            semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void beginConditionalUris(Token token) {
-    DirectParserASTContentConditionalUrisBegin data =
-        new DirectParserASTContentConditionalUrisBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endConditionalUris(int count) {
-    DirectParserASTContentConditionalUrisEnd data =
-        new DirectParserASTContentConditionalUrisEnd(DirectParserASTType.END,
-            count: count);
-    seen(data);
-  }
-
-  @override
-  void beginConditionalUri(Token ifKeyword) {
-    DirectParserASTContentConditionalUriBegin data =
-        new DirectParserASTContentConditionalUriBegin(DirectParserASTType.BEGIN,
-            ifKeyword: ifKeyword);
-    seen(data);
-  }
-
-  @override
-  void endConditionalUri(Token ifKeyword, Token leftParen, Token? equalSign) {
-    DirectParserASTContentConditionalUriEnd data =
-        new DirectParserASTContentConditionalUriEnd(DirectParserASTType.END,
-            ifKeyword: ifKeyword, leftParen: leftParen, equalSign: equalSign);
-    seen(data);
-  }
-
-  @override
-  void handleDottedName(int count, Token firstIdentifier) {
-    DirectParserASTContentDottedNameHandle data =
-        new DirectParserASTContentDottedNameHandle(DirectParserASTType.HANDLE,
-            count: count, firstIdentifier: firstIdentifier);
-    seen(data);
-  }
-
-  @override
-  void beginImplicitCreationExpression(Token token) {
-    DirectParserASTContentImplicitCreationExpressionBegin data =
-        new DirectParserASTContentImplicitCreationExpressionBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endImplicitCreationExpression(Token token, Token openAngleBracket) {
-    DirectParserASTContentImplicitCreationExpressionEnd data =
-        new DirectParserASTContentImplicitCreationExpressionEnd(
-            DirectParserASTType.END,
-            token: token,
-            openAngleBracket: openAngleBracket);
-    seen(data);
-  }
-
-  @override
-  void beginInitializedIdentifier(Token token) {
-    DirectParserASTContentInitializedIdentifierBegin data =
-        new DirectParserASTContentInitializedIdentifierBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endInitializedIdentifier(Token nameToken) {
-    DirectParserASTContentInitializedIdentifierEnd data =
-        new DirectParserASTContentInitializedIdentifierEnd(
-            DirectParserASTType.END,
-            nameToken: nameToken);
-    seen(data);
-  }
-
-  @override
-  void beginFieldInitializer(Token token) {
-    DirectParserASTContentFieldInitializerBegin data =
-        new DirectParserASTContentFieldInitializerBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endFieldInitializer(Token assignment, Token token) {
-    DirectParserASTContentFieldInitializerEnd data =
-        new DirectParserASTContentFieldInitializerEnd(DirectParserASTType.END,
-            assignment: assignment, token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNoFieldInitializer(Token token) {
-    DirectParserASTContentNoFieldInitializerHandle data =
-        new DirectParserASTContentNoFieldInitializerHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginVariableInitializer(Token token) {
-    DirectParserASTContentVariableInitializerBegin data =
-        new DirectParserASTContentVariableInitializerBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endVariableInitializer(Token assignmentOperator) {
-    DirectParserASTContentVariableInitializerEnd data =
-        new DirectParserASTContentVariableInitializerEnd(
-            DirectParserASTType.END,
-            assignmentOperator: assignmentOperator);
-    seen(data);
-  }
-
-  @override
-  void handleNoVariableInitializer(Token token) {
-    DirectParserASTContentNoVariableInitializerHandle data =
-        new DirectParserASTContentNoVariableInitializerHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginInitializer(Token token) {
-    DirectParserASTContentInitializerBegin data =
-        new DirectParserASTContentInitializerBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endInitializer(Token token) {
-    DirectParserASTContentInitializerEnd data =
-        new DirectParserASTContentInitializerEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginInitializers(Token token) {
-    DirectParserASTContentInitializersBegin data =
-        new DirectParserASTContentInitializersBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endInitializers(int count, Token beginToken, Token endToken) {
-    DirectParserASTContentInitializersEnd data =
-        new DirectParserASTContentInitializersEnd(DirectParserASTType.END,
-            count: count, beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleNoInitializers() {
-    DirectParserASTContentNoInitializersHandle data =
-        new DirectParserASTContentNoInitializersHandle(
-            DirectParserASTType.HANDLE);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidExpression(Token token) {
-    DirectParserASTContentInvalidExpressionHandle data =
-        new DirectParserASTContentInvalidExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidFunctionBody(Token token) {
-    DirectParserASTContentInvalidFunctionBodyHandle data =
-        new DirectParserASTContentInvalidFunctionBodyHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidTypeReference(Token token) {
-    DirectParserASTContentInvalidTypeReferenceHandle data =
-        new DirectParserASTContentInvalidTypeReferenceHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleLabel(Token token) {
-    DirectParserASTContentLabelHandle data =
-        new DirectParserASTContentLabelHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginLabeledStatement(Token token, int labelCount) {
-    DirectParserASTContentLabeledStatementBegin data =
-        new DirectParserASTContentLabeledStatementBegin(
-            DirectParserASTType.BEGIN,
-            token: token,
-            labelCount: labelCount);
-    seen(data);
-  }
-
-  @override
-  void endLabeledStatement(int labelCount) {
-    DirectParserASTContentLabeledStatementEnd data =
-        new DirectParserASTContentLabeledStatementEnd(DirectParserASTType.END,
-            labelCount: labelCount);
-    seen(data);
-  }
-
-  @override
-  void beginLibraryName(Token token) {
-    DirectParserASTContentLibraryNameBegin data =
-        new DirectParserASTContentLibraryNameBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endLibraryName(Token libraryKeyword, Token semicolon) {
-    DirectParserASTContentLibraryNameEnd data =
-        new DirectParserASTContentLibraryNameEnd(DirectParserASTType.END,
-            libraryKeyword: libraryKeyword, semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void handleLiteralMapEntry(Token colon, Token endToken) {
-    DirectParserASTContentLiteralMapEntryHandle data =
-        new DirectParserASTContentLiteralMapEntryHandle(
-            DirectParserASTType.HANDLE,
-            colon: colon,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginLiteralString(Token token) {
-    DirectParserASTContentLiteralStringBegin data =
-        new DirectParserASTContentLiteralStringBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleInterpolationExpression(Token leftBracket, Token? rightBracket) {
-    DirectParserASTContentInterpolationExpressionHandle data =
-        new DirectParserASTContentInterpolationExpressionHandle(
-            DirectParserASTType.HANDLE,
-            leftBracket: leftBracket,
-            rightBracket: rightBracket);
-    seen(data);
-  }
-
-  @override
-  void endLiteralString(int interpolationCount, Token endToken) {
-    DirectParserASTContentLiteralStringEnd data =
-        new DirectParserASTContentLiteralStringEnd(DirectParserASTType.END,
-            interpolationCount: interpolationCount, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleStringJuxtaposition(Token startToken, int literalCount) {
-    DirectParserASTContentStringJuxtapositionHandle data =
-        new DirectParserASTContentStringJuxtapositionHandle(
-            DirectParserASTType.HANDLE,
-            startToken: startToken,
-            literalCount: literalCount);
-    seen(data);
-  }
-
-  @override
-  void beginMember() {
-    DirectParserASTContentMemberBegin data =
-        new DirectParserASTContentMemberBegin(DirectParserASTType.BEGIN);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidMember(Token endToken) {
-    DirectParserASTContentInvalidMemberHandle data =
-        new DirectParserASTContentInvalidMemberHandle(
-            DirectParserASTType.HANDLE,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endMember() {
-    DirectParserASTContentMemberEnd data =
-        new DirectParserASTContentMemberEnd(DirectParserASTType.END);
-    seen(data);
-  }
-
-  @override
-  void beginMethod(
-      DeclarationKind declarationKind,
-      Token? externalToken,
-      Token? staticToken,
-      Token? covariantToken,
-      Token? varFinalOrConst,
-      Token? getOrSet,
-      Token name) {
-    DirectParserASTContentMethodBegin data =
-        new DirectParserASTContentMethodBegin(DirectParserASTType.BEGIN,
-            declarationKind: declarationKind,
-            externalToken: externalToken,
-            staticToken: staticToken,
-            covariantToken: covariantToken,
-            varFinalOrConst: varFinalOrConst,
-            getOrSet: getOrSet,
-            name: name);
-    seen(data);
-  }
-
-  @override
-  void endClassMethod(Token? getOrSet, Token beginToken, Token beginParam,
-      Token? beginInitializers, Token endToken) {
-    DirectParserASTContentClassMethodEnd data =
-        new DirectParserASTContentClassMethodEnd(DirectParserASTType.END,
-            getOrSet: getOrSet,
-            beginToken: beginToken,
-            beginParam: beginParam,
-            beginInitializers: beginInitializers,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endMixinMethod(Token? getOrSet, Token beginToken, Token beginParam,
-      Token? beginInitializers, Token endToken) {
-    DirectParserASTContentMixinMethodEnd data =
-        new DirectParserASTContentMixinMethodEnd(DirectParserASTType.END,
-            getOrSet: getOrSet,
-            beginToken: beginToken,
-            beginParam: beginParam,
-            beginInitializers: beginInitializers,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endExtensionMethod(Token? getOrSet, Token beginToken, Token beginParam,
-      Token? beginInitializers, Token endToken) {
-    DirectParserASTContentExtensionMethodEnd data =
-        new DirectParserASTContentExtensionMethodEnd(DirectParserASTType.END,
-            getOrSet: getOrSet,
-            beginToken: beginToken,
-            beginParam: beginParam,
-            beginInitializers: beginInitializers,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endClassConstructor(Token? getOrSet, Token beginToken, Token beginParam,
-      Token? beginInitializers, Token endToken) {
-    DirectParserASTContentClassConstructorEnd data =
-        new DirectParserASTContentClassConstructorEnd(DirectParserASTType.END,
-            getOrSet: getOrSet,
-            beginToken: beginToken,
-            beginParam: beginParam,
-            beginInitializers: beginInitializers,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endMixinConstructor(Token? getOrSet, Token beginToken, Token beginParam,
-      Token? beginInitializers, Token endToken) {
-    DirectParserASTContentMixinConstructorEnd data =
-        new DirectParserASTContentMixinConstructorEnd(DirectParserASTType.END,
-            getOrSet: getOrSet,
-            beginToken: beginToken,
-            beginParam: beginParam,
-            beginInitializers: beginInitializers,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endExtensionConstructor(Token? getOrSet, Token beginToken,
-      Token beginParam, Token? beginInitializers, Token endToken) {
-    DirectParserASTContentExtensionConstructorEnd data =
-        new DirectParserASTContentExtensionConstructorEnd(
-            DirectParserASTType.END,
-            getOrSet: getOrSet,
-            beginToken: beginToken,
-            beginParam: beginParam,
-            beginInitializers: beginInitializers,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginMetadataStar(Token token) {
-    DirectParserASTContentMetadataStarBegin data =
-        new DirectParserASTContentMetadataStarBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endMetadataStar(int count) {
-    DirectParserASTContentMetadataStarEnd data =
-        new DirectParserASTContentMetadataStarEnd(DirectParserASTType.END,
-            count: count);
-    seen(data);
-  }
-
-  @override
-  void beginMetadata(Token token) {
-    DirectParserASTContentMetadataBegin data =
-        new DirectParserASTContentMetadataBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endMetadata(Token beginToken, Token? periodBeforeName, Token endToken) {
-    DirectParserASTContentMetadataEnd data =
-        new DirectParserASTContentMetadataEnd(DirectParserASTType.END,
-            beginToken: beginToken,
-            periodBeforeName: periodBeforeName,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginOptionalFormalParameters(Token token) {
-    DirectParserASTContentOptionalFormalParametersBegin data =
-        new DirectParserASTContentOptionalFormalParametersBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endOptionalFormalParameters(
-      int count, Token beginToken, Token endToken) {
-    DirectParserASTContentOptionalFormalParametersEnd data =
-        new DirectParserASTContentOptionalFormalParametersEnd(
-            DirectParserASTType.END,
-            count: count,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginPart(Token token) {
-    DirectParserASTContentPartBegin data = new DirectParserASTContentPartBegin(
-        DirectParserASTType.BEGIN,
-        token: token);
-    seen(data);
-  }
-
-  @override
-  void endPart(Token partKeyword, Token semicolon) {
-    DirectParserASTContentPartEnd data = new DirectParserASTContentPartEnd(
-        DirectParserASTType.END,
-        partKeyword: partKeyword,
-        semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void beginPartOf(Token token) {
-    DirectParserASTContentPartOfBegin data =
-        new DirectParserASTContentPartOfBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endPartOf(
-      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
-    DirectParserASTContentPartOfEnd data = new DirectParserASTContentPartOfEnd(
-        DirectParserASTType.END,
-        partKeyword: partKeyword,
-        ofKeyword: ofKeyword,
-        semicolon: semicolon,
-        hasName: hasName);
-    seen(data);
-  }
-
-  @override
-  void beginRedirectingFactoryBody(Token token) {
-    DirectParserASTContentRedirectingFactoryBodyBegin data =
-        new DirectParserASTContentRedirectingFactoryBodyBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endRedirectingFactoryBody(Token beginToken, Token endToken) {
-    DirectParserASTContentRedirectingFactoryBodyEnd data =
-        new DirectParserASTContentRedirectingFactoryBodyEnd(
-            DirectParserASTType.END,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginReturnStatement(Token token) {
-    DirectParserASTContentReturnStatementBegin data =
-        new DirectParserASTContentReturnStatementBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
-    DirectParserASTContentNativeFunctionBodyHandle data =
-        new DirectParserASTContentNativeFunctionBodyHandle(
-            DirectParserASTType.HANDLE,
-            nativeToken: nativeToken,
-            semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
-    DirectParserASTContentNativeFunctionBodyIgnoredHandle data =
-        new DirectParserASTContentNativeFunctionBodyIgnoredHandle(
-            DirectParserASTType.HANDLE,
-            nativeToken: nativeToken,
-            semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
-    DirectParserASTContentNativeFunctionBodySkippedHandle data =
-        new DirectParserASTContentNativeFunctionBodySkippedHandle(
-            DirectParserASTType.HANDLE,
-            nativeToken: nativeToken,
-            semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void handleEmptyFunctionBody(Token semicolon) {
-    DirectParserASTContentEmptyFunctionBodyHandle data =
-        new DirectParserASTContentEmptyFunctionBodyHandle(
-            DirectParserASTType.HANDLE,
-            semicolon: semicolon);
-    seen(data);
-  }
-
-  @override
-  void handleExpressionFunctionBody(Token arrowToken, Token? endToken) {
-    DirectParserASTContentExpressionFunctionBodyHandle data =
-        new DirectParserASTContentExpressionFunctionBodyHandle(
-            DirectParserASTType.HANDLE,
-            arrowToken: arrowToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endReturnStatement(
-      bool hasExpression, Token beginToken, Token endToken) {
-    DirectParserASTContentReturnStatementEnd data =
-        new DirectParserASTContentReturnStatementEnd(DirectParserASTType.END,
-            hasExpression: hasExpression,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleSend(Token beginToken, Token endToken) {
-    DirectParserASTContentSendHandle data =
-        new DirectParserASTContentSendHandle(DirectParserASTType.HANDLE,
-            beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginShow(Token showKeyword) {
-    DirectParserASTContentShowBegin data = new DirectParserASTContentShowBegin(
-        DirectParserASTType.BEGIN,
-        showKeyword: showKeyword);
-    seen(data);
-  }
-
-  @override
-  void endShow(Token showKeyword) {
-    DirectParserASTContentShowEnd data = new DirectParserASTContentShowEnd(
-        DirectParserASTType.END,
-        showKeyword: showKeyword);
-    seen(data);
-  }
-
-  @override
-  void beginSwitchStatement(Token token) {
-    DirectParserASTContentSwitchStatementBegin data =
-        new DirectParserASTContentSwitchStatementBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endSwitchStatement(Token switchKeyword, Token endToken) {
-    DirectParserASTContentSwitchStatementEnd data =
-        new DirectParserASTContentSwitchStatementEnd(DirectParserASTType.END,
-            switchKeyword: switchKeyword, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginSwitchBlock(Token token) {
-    DirectParserASTContentSwitchBlockBegin data =
-        new DirectParserASTContentSwitchBlockBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
-    DirectParserASTContentSwitchBlockEnd data =
-        new DirectParserASTContentSwitchBlockEnd(DirectParserASTType.END,
-            caseCount: caseCount, beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginLiteralSymbol(Token token) {
-    DirectParserASTContentLiteralSymbolBegin data =
-        new DirectParserASTContentLiteralSymbolBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endLiteralSymbol(Token hashToken, int identifierCount) {
-    DirectParserASTContentLiteralSymbolEnd data =
-        new DirectParserASTContentLiteralSymbolEnd(DirectParserASTType.END,
-            hashToken: hashToken, identifierCount: identifierCount);
-    seen(data);
-  }
-
-  @override
-  void handleThrowExpression(Token throwToken, Token endToken) {
-    DirectParserASTContentThrowExpressionHandle data =
-        new DirectParserASTContentThrowExpressionHandle(
-            DirectParserASTType.HANDLE,
-            throwToken: throwToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginRethrowStatement(Token token) {
-    DirectParserASTContentRethrowStatementBegin data =
-        new DirectParserASTContentRethrowStatementBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endRethrowStatement(Token rethrowToken, Token endToken) {
-    DirectParserASTContentRethrowStatementEnd data =
-        new DirectParserASTContentRethrowStatementEnd(DirectParserASTType.END,
-            rethrowToken: rethrowToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endTopLevelDeclaration(Token nextToken) {
-    DirectParserASTContentTopLevelDeclarationEnd data =
-        new DirectParserASTContentTopLevelDeclarationEnd(
-            DirectParserASTType.END,
-            nextToken: nextToken);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidTopLevelDeclaration(Token endToken) {
-    DirectParserASTContentInvalidTopLevelDeclarationHandle data =
-        new DirectParserASTContentInvalidTopLevelDeclarationHandle(
-            DirectParserASTType.HANDLE,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginTopLevelMember(Token token) {
-    DirectParserASTContentTopLevelMemberBegin data =
-        new DirectParserASTContentTopLevelMemberBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginFields(
-      DeclarationKind declarationKind,
-      Token? abstractToken,
-      Token? externalToken,
-      Token? staticToken,
-      Token? covariantToken,
-      Token? lateToken,
-      Token? varFinalOrConst,
-      Token lastConsumed) {
-    DirectParserASTContentFieldsBegin data =
-        new DirectParserASTContentFieldsBegin(DirectParserASTType.BEGIN,
-            declarationKind: declarationKind,
-            abstractToken: abstractToken,
-            externalToken: externalToken,
-            staticToken: staticToken,
-            covariantToken: covariantToken,
-            lateToken: lateToken,
-            varFinalOrConst: varFinalOrConst,
-            lastConsumed: lastConsumed);
-    seen(data);
-  }
-
-  @override
-  void endTopLevelFields(
-      Token? externalToken,
-      Token? staticToken,
-      Token? covariantToken,
-      Token? lateToken,
-      Token? varFinalOrConst,
-      int count,
-      Token beginToken,
-      Token endToken) {
-    DirectParserASTContentTopLevelFieldsEnd data =
-        new DirectParserASTContentTopLevelFieldsEnd(DirectParserASTType.END,
-            externalToken: externalToken,
-            staticToken: staticToken,
-            covariantToken: covariantToken,
-            lateToken: lateToken,
-            varFinalOrConst: varFinalOrConst,
-            count: count,
-            beginToken: beginToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginTopLevelMethod(Token lastConsumed, Token? externalToken) {
-    DirectParserASTContentTopLevelMethodBegin data =
-        new DirectParserASTContentTopLevelMethodBegin(DirectParserASTType.BEGIN,
-            lastConsumed: lastConsumed, externalToken: externalToken);
-    seen(data);
-  }
-
-  @override
-  void endTopLevelMethod(Token beginToken, Token? getOrSet, Token endToken) {
-    DirectParserASTContentTopLevelMethodEnd data =
-        new DirectParserASTContentTopLevelMethodEnd(DirectParserASTType.END,
-            beginToken: beginToken, getOrSet: getOrSet, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginTryStatement(Token token) {
-    DirectParserASTContentTryStatementBegin data =
-        new DirectParserASTContentTryStatementBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleCaseMatch(Token caseKeyword, Token colon) {
-    DirectParserASTContentCaseMatchHandle data =
-        new DirectParserASTContentCaseMatchHandle(DirectParserASTType.HANDLE,
-            caseKeyword: caseKeyword, colon: colon);
-    seen(data);
-  }
-
-  @override
-  void beginCatchClause(Token token) {
-    DirectParserASTContentCatchClauseBegin data =
-        new DirectParserASTContentCatchClauseBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endCatchClause(Token token) {
-    DirectParserASTContentCatchClauseEnd data =
-        new DirectParserASTContentCatchClauseEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleCatchBlock(Token? onKeyword, Token? catchKeyword, Token? comma) {
-    DirectParserASTContentCatchBlockHandle data =
-        new DirectParserASTContentCatchBlockHandle(DirectParserASTType.HANDLE,
-            onKeyword: onKeyword, catchKeyword: catchKeyword, comma: comma);
-    seen(data);
-  }
-
-  @override
-  void handleFinallyBlock(Token finallyKeyword) {
-    DirectParserASTContentFinallyBlockHandle data =
-        new DirectParserASTContentFinallyBlockHandle(DirectParserASTType.HANDLE,
-            finallyKeyword: finallyKeyword);
-    seen(data);
-  }
-
-  @override
-  void endTryStatement(
-      int catchCount, Token tryKeyword, Token? finallyKeyword) {
-    DirectParserASTContentTryStatementEnd data =
-        new DirectParserASTContentTryStatementEnd(DirectParserASTType.END,
-            catchCount: catchCount,
-            tryKeyword: tryKeyword,
-            finallyKeyword: finallyKeyword);
-    seen(data);
-  }
-
-  @override
-  void handleType(Token beginToken, Token? questionMark) {
-    DirectParserASTContentTypeHandle data =
-        new DirectParserASTContentTypeHandle(DirectParserASTType.HANDLE,
-            beginToken: beginToken, questionMark: questionMark);
-    seen(data);
-  }
-
-  @override
-  void handleNonNullAssertExpression(Token bang) {
-    DirectParserASTContentNonNullAssertExpressionHandle data =
-        new DirectParserASTContentNonNullAssertExpressionHandle(
-            DirectParserASTType.HANDLE,
-            bang: bang);
-    seen(data);
-  }
-
-  @override
-  void handleNoName(Token token) {
-    DirectParserASTContentNoNameHandle data =
-        new DirectParserASTContentNoNameHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginFunctionType(Token beginToken) {
-    DirectParserASTContentFunctionTypeBegin data =
-        new DirectParserASTContentFunctionTypeBegin(DirectParserASTType.BEGIN,
-            beginToken: beginToken);
-    seen(data);
-  }
-
-  @override
-  void endFunctionType(Token functionToken, Token? questionMark) {
-    DirectParserASTContentFunctionTypeEnd data =
-        new DirectParserASTContentFunctionTypeEnd(DirectParserASTType.END,
-            functionToken: functionToken, questionMark: questionMark);
-    seen(data);
-  }
-
-  @override
-  void beginTypeArguments(Token token) {
-    DirectParserASTContentTypeArgumentsBegin data =
-        new DirectParserASTContentTypeArgumentsBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endTypeArguments(int count, Token beginToken, Token endToken) {
-    DirectParserASTContentTypeArgumentsEnd data =
-        new DirectParserASTContentTypeArgumentsEnd(DirectParserASTType.END,
-            count: count, beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidTypeArguments(Token token) {
-    DirectParserASTContentInvalidTypeArgumentsHandle data =
-        new DirectParserASTContentInvalidTypeArgumentsHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNoTypeArguments(Token token) {
-    DirectParserASTContentNoTypeArgumentsHandle data =
-        new DirectParserASTContentNoTypeArgumentsHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginTypeVariable(Token token) {
-    DirectParserASTContentTypeVariableBegin data =
-        new DirectParserASTContentTypeVariableBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleTypeVariablesDefined(Token token, int count) {
-    DirectParserASTContentTypeVariablesDefinedHandle data =
-        new DirectParserASTContentTypeVariablesDefinedHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            count: count);
-    seen(data);
-  }
-
-  @override
-  void endTypeVariable(
-      Token token, int index, Token? extendsOrSuper, Token? variance) {
-    DirectParserASTContentTypeVariableEnd data =
-        new DirectParserASTContentTypeVariableEnd(DirectParserASTType.END,
-            token: token,
-            index: index,
-            extendsOrSuper: extendsOrSuper,
-            variance: variance);
-    seen(data);
-  }
-
-  @override
-  void beginTypeVariables(Token token) {
-    DirectParserASTContentTypeVariablesBegin data =
-        new DirectParserASTContentTypeVariablesBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endTypeVariables(Token beginToken, Token endToken) {
-    DirectParserASTContentTypeVariablesEnd data =
-        new DirectParserASTContentTypeVariablesEnd(DirectParserASTType.END,
-            beginToken: beginToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginFunctionExpression(Token token) {
-    DirectParserASTContentFunctionExpressionBegin data =
-        new DirectParserASTContentFunctionExpressionBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endFunctionExpression(Token beginToken, Token token) {
-    DirectParserASTContentFunctionExpressionEnd data =
-        new DirectParserASTContentFunctionExpressionEnd(DirectParserASTType.END,
-            beginToken: beginToken, token: token);
-    seen(data);
-  }
-
-  @override
-  void beginVariablesDeclaration(
-      Token token, Token? lateToken, Token? varFinalOrConst) {
-    DirectParserASTContentVariablesDeclarationBegin data =
-        new DirectParserASTContentVariablesDeclarationBegin(
-            DirectParserASTType.BEGIN,
-            token: token,
-            lateToken: lateToken,
-            varFinalOrConst: varFinalOrConst);
-    seen(data);
-  }
-
-  @override
-  void endVariablesDeclaration(int count, Token? endToken) {
-    DirectParserASTContentVariablesDeclarationEnd data =
-        new DirectParserASTContentVariablesDeclarationEnd(
-            DirectParserASTType.END,
-            count: count,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginWhileStatement(Token token) {
-    DirectParserASTContentWhileStatementBegin data =
-        new DirectParserASTContentWhileStatementBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endWhileStatement(Token whileKeyword, Token endToken) {
-    DirectParserASTContentWhileStatementEnd data =
-        new DirectParserASTContentWhileStatementEnd(DirectParserASTType.END,
-            whileKeyword: whileKeyword, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void beginAsOperatorType(Token operator) {
-    DirectParserASTContentAsOperatorTypeBegin data =
-        new DirectParserASTContentAsOperatorTypeBegin(DirectParserASTType.BEGIN,
-            operator: operator);
-    seen(data);
-  }
-
-  @override
-  void endAsOperatorType(Token operator) {
-    DirectParserASTContentAsOperatorTypeEnd data =
-        new DirectParserASTContentAsOperatorTypeEnd(DirectParserASTType.END,
-            operator: operator);
-    seen(data);
-  }
-
-  @override
-  void handleAsOperator(Token operator) {
-    DirectParserASTContentAsOperatorHandle data =
-        new DirectParserASTContentAsOperatorHandle(DirectParserASTType.HANDLE,
-            operator: operator);
-    seen(data);
-  }
-
-  @override
-  void handleAssignmentExpression(Token token) {
-    DirectParserASTContentAssignmentExpressionHandle data =
-        new DirectParserASTContentAssignmentExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginBinaryExpression(Token token) {
-    DirectParserASTContentBinaryExpressionBegin data =
-        new DirectParserASTContentBinaryExpressionBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endBinaryExpression(Token token) {
-    DirectParserASTContentBinaryExpressionEnd data =
-        new DirectParserASTContentBinaryExpressionEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleEndingBinaryExpression(Token token) {
-    DirectParserASTContentEndingBinaryExpressionHandle data =
-        new DirectParserASTContentEndingBinaryExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginConditionalExpression(Token question) {
-    DirectParserASTContentConditionalExpressionBegin data =
-        new DirectParserASTContentConditionalExpressionBegin(
-            DirectParserASTType.BEGIN,
-            question: question);
-    seen(data);
-  }
-
-  @override
-  void handleConditionalExpressionColon() {
-    DirectParserASTContentConditionalExpressionColonHandle data =
-        new DirectParserASTContentConditionalExpressionColonHandle(
-            DirectParserASTType.HANDLE);
-    seen(data);
-  }
-
-  @override
-  void endConditionalExpression(Token question, Token colon) {
-    DirectParserASTContentConditionalExpressionEnd data =
-        new DirectParserASTContentConditionalExpressionEnd(
-            DirectParserASTType.END,
-            question: question,
-            colon: colon);
-    seen(data);
-  }
-
-  @override
-  void beginConstExpression(Token constKeyword) {
-    DirectParserASTContentConstExpressionBegin data =
-        new DirectParserASTContentConstExpressionBegin(
-            DirectParserASTType.BEGIN,
-            constKeyword: constKeyword);
-    seen(data);
-  }
-
-  @override
-  void endConstExpression(Token token) {
-    DirectParserASTContentConstExpressionEnd data =
-        new DirectParserASTContentConstExpressionEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleConstFactory(Token constKeyword) {
-    DirectParserASTContentConstFactoryHandle data =
-        new DirectParserASTContentConstFactoryHandle(DirectParserASTType.HANDLE,
-            constKeyword: constKeyword);
-    seen(data);
-  }
-
-  @override
-  void beginForControlFlow(Token? awaitToken, Token forToken) {
-    DirectParserASTContentForControlFlowBegin data =
-        new DirectParserASTContentForControlFlowBegin(DirectParserASTType.BEGIN,
-            awaitToken: awaitToken, forToken: forToken);
-    seen(data);
-  }
-
-  @override
-  void endForControlFlow(Token token) {
-    DirectParserASTContentForControlFlowEnd data =
-        new DirectParserASTContentForControlFlowEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endForInControlFlow(Token token) {
-    DirectParserASTContentForInControlFlowEnd data =
-        new DirectParserASTContentForInControlFlowEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginIfControlFlow(Token ifToken) {
-    DirectParserASTContentIfControlFlowBegin data =
-        new DirectParserASTContentIfControlFlowBegin(DirectParserASTType.BEGIN,
-            ifToken: ifToken);
-    seen(data);
-  }
-
-  @override
-  void handleThenControlFlow(Token token) {
-    DirectParserASTContentThenControlFlowHandle data =
-        new DirectParserASTContentThenControlFlowHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleElseControlFlow(Token elseToken) {
-    DirectParserASTContentElseControlFlowHandle data =
-        new DirectParserASTContentElseControlFlowHandle(
-            DirectParserASTType.HANDLE,
-            elseToken: elseToken);
-    seen(data);
-  }
-
-  @override
-  void endIfControlFlow(Token token) {
-    DirectParserASTContentIfControlFlowEnd data =
-        new DirectParserASTContentIfControlFlowEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endIfElseControlFlow(Token token) {
-    DirectParserASTContentIfElseControlFlowEnd data =
-        new DirectParserASTContentIfElseControlFlowEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleSpreadExpression(Token spreadToken) {
-    DirectParserASTContentSpreadExpressionHandle data =
-        new DirectParserASTContentSpreadExpressionHandle(
-            DirectParserASTType.HANDLE,
-            spreadToken: spreadToken);
-    seen(data);
-  }
-
-  @override
-  void beginFunctionTypedFormalParameter(Token token) {
-    DirectParserASTContentFunctionTypedFormalParameterBegin data =
-        new DirectParserASTContentFunctionTypedFormalParameterBegin(
-            DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endFunctionTypedFormalParameter(Token nameToken, Token? question) {
-    DirectParserASTContentFunctionTypedFormalParameterEnd data =
-        new DirectParserASTContentFunctionTypedFormalParameterEnd(
-            DirectParserASTType.END,
-            nameToken: nameToken,
-            question: question);
-    seen(data);
-  }
-
-  @override
-  void handleIdentifier(Token token, IdentifierContext context) {
-    DirectParserASTContentIdentifierHandle data =
-        new DirectParserASTContentIdentifierHandle(DirectParserASTType.HANDLE,
-            token: token, context: context);
-    seen(data);
-  }
-
-  @override
-  void handleShowHideIdentifier(Token? modifier, Token identifier) {
-    DirectParserASTContentShowHideIdentifierHandle data =
-        new DirectParserASTContentShowHideIdentifierHandle(
-            DirectParserASTType.HANDLE,
-            modifier: modifier,
-            identifier: identifier);
-    seen(data);
-  }
-
-  @override
-  void handleIndexedExpression(
-      Token? question, Token openSquareBracket, Token closeSquareBracket) {
-    DirectParserASTContentIndexedExpressionHandle data =
-        new DirectParserASTContentIndexedExpressionHandle(
-            DirectParserASTType.HANDLE,
-            question: question,
-            openSquareBracket: openSquareBracket,
-            closeSquareBracket: closeSquareBracket);
-    seen(data);
-  }
-
-  @override
-  void beginIsOperatorType(Token operator) {
-    DirectParserASTContentIsOperatorTypeBegin data =
-        new DirectParserASTContentIsOperatorTypeBegin(DirectParserASTType.BEGIN,
-            operator: operator);
-    seen(data);
-  }
-
-  @override
-  void endIsOperatorType(Token operator) {
-    DirectParserASTContentIsOperatorTypeEnd data =
-        new DirectParserASTContentIsOperatorTypeEnd(DirectParserASTType.END,
-            operator: operator);
-    seen(data);
-  }
-
-  @override
-  void handleIsOperator(Token isOperator, Token? not) {
-    DirectParserASTContentIsOperatorHandle data =
-        new DirectParserASTContentIsOperatorHandle(DirectParserASTType.HANDLE,
-            isOperator: isOperator, not: not);
-    seen(data);
-  }
-
-  @override
-  void handleLiteralBool(Token token) {
-    DirectParserASTContentLiteralBoolHandle data =
-        new DirectParserASTContentLiteralBoolHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleBreakStatement(
-      bool hasTarget, Token breakKeyword, Token endToken) {
-    DirectParserASTContentBreakStatementHandle data =
-        new DirectParserASTContentBreakStatementHandle(
-            DirectParserASTType.HANDLE,
-            hasTarget: hasTarget,
-            breakKeyword: breakKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleContinueStatement(
-      bool hasTarget, Token continueKeyword, Token endToken) {
-    DirectParserASTContentContinueStatementHandle data =
-        new DirectParserASTContentContinueStatementHandle(
-            DirectParserASTType.HANDLE,
-            hasTarget: hasTarget,
-            continueKeyword: continueKeyword,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleEmptyStatement(Token token) {
-    DirectParserASTContentEmptyStatementHandle data =
-        new DirectParserASTContentEmptyStatementHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginAssert(Token assertKeyword, Assert kind) {
-    DirectParserASTContentAssertBegin data =
-        new DirectParserASTContentAssertBegin(DirectParserASTType.BEGIN,
-            assertKeyword: assertKeyword, kind: kind);
-    seen(data);
-  }
-
-  @override
-  void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis,
-      Token? commaToken, Token semicolonToken) {
-    DirectParserASTContentAssertEnd data = new DirectParserASTContentAssertEnd(
-        DirectParserASTType.END,
-        assertKeyword: assertKeyword,
-        kind: kind,
-        leftParenthesis: leftParenthesis,
-        commaToken: commaToken,
-        semicolonToken: semicolonToken);
-    seen(data);
-  }
-
-  @override
-  void handleLiteralDouble(Token token) {
-    DirectParserASTContentLiteralDoubleHandle data =
-        new DirectParserASTContentLiteralDoubleHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleLiteralInt(Token token) {
-    DirectParserASTContentLiteralIntHandle data =
-        new DirectParserASTContentLiteralIntHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleLiteralList(
-      int count, Token leftBracket, Token? constKeyword, Token rightBracket) {
-    DirectParserASTContentLiteralListHandle data =
-        new DirectParserASTContentLiteralListHandle(DirectParserASTType.HANDLE,
-            count: count,
-            leftBracket: leftBracket,
-            constKeyword: constKeyword,
-            rightBracket: rightBracket);
-    seen(data);
-  }
-
-  @override
-  void handleLiteralSetOrMap(
-    int count,
-    Token leftBrace,
-    Token? constKeyword,
-    Token rightBrace,
-    bool hasSetEntry,
-  ) {
-    DirectParserASTContentLiteralSetOrMapHandle data =
-        new DirectParserASTContentLiteralSetOrMapHandle(
-            DirectParserASTType.HANDLE,
-            count: count,
-            leftBrace: leftBrace,
-            constKeyword: constKeyword,
-            rightBrace: rightBrace,
-            hasSetEntry: hasSetEntry);
-    seen(data);
-  }
-
-  @override
-  void handleLiteralNull(Token token) {
-    DirectParserASTContentLiteralNullHandle data =
-        new DirectParserASTContentLiteralNullHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNativeClause(Token nativeToken, bool hasName) {
-    DirectParserASTContentNativeClauseHandle data =
-        new DirectParserASTContentNativeClauseHandle(DirectParserASTType.HANDLE,
-            nativeToken: nativeToken, hasName: hasName);
-    seen(data);
-  }
-
-  @override
-  void handleNamedArgument(Token colon) {
-    DirectParserASTContentNamedArgumentHandle data =
-        new DirectParserASTContentNamedArgumentHandle(
-            DirectParserASTType.HANDLE,
-            colon: colon);
-    seen(data);
-  }
-
-  @override
-  void beginNewExpression(Token token) {
-    DirectParserASTContentNewExpressionBegin data =
-        new DirectParserASTContentNewExpressionBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endNewExpression(Token token) {
-    DirectParserASTContentNewExpressionEnd data =
-        new DirectParserASTContentNewExpressionEnd(DirectParserASTType.END,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNoArguments(Token token) {
-    DirectParserASTContentNoArgumentsHandle data =
-        new DirectParserASTContentNoArgumentsHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
-    DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle
-        data =
-        new DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNoType(Token lastConsumed) {
-    DirectParserASTContentNoTypeHandle data =
-        new DirectParserASTContentNoTypeHandle(DirectParserASTType.HANDLE,
-            lastConsumed: lastConsumed);
-    seen(data);
-  }
-
-  @override
-  void handleNoTypeVariables(Token token) {
-    DirectParserASTContentNoTypeVariablesHandle data =
-        new DirectParserASTContentNoTypeVariablesHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleOperator(Token token) {
-    DirectParserASTContentOperatorHandle data =
-        new DirectParserASTContentOperatorHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleSymbolVoid(Token token) {
-    DirectParserASTContentSymbolVoidHandle data =
-        new DirectParserASTContentSymbolVoidHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleOperatorName(Token operatorKeyword, Token token) {
-    DirectParserASTContentOperatorNameHandle data =
-        new DirectParserASTContentOperatorNameHandle(DirectParserASTType.HANDLE,
-            operatorKeyword: operatorKeyword, token: token);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidOperatorName(Token operatorKeyword, Token token) {
-    DirectParserASTContentInvalidOperatorNameHandle data =
-        new DirectParserASTContentInvalidOperatorNameHandle(
-            DirectParserASTType.HANDLE,
-            operatorKeyword: operatorKeyword,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleParenthesizedCondition(Token token) {
-    DirectParserASTContentParenthesizedConditionHandle data =
-        new DirectParserASTContentParenthesizedConditionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleParenthesizedExpression(Token token) {
-    DirectParserASTContentParenthesizedExpressionHandle data =
-        new DirectParserASTContentParenthesizedExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleQualified(Token period) {
-    DirectParserASTContentQualifiedHandle data =
-        new DirectParserASTContentQualifiedHandle(DirectParserASTType.HANDLE,
-            period: period);
-    seen(data);
-  }
-
-  @override
-  void handleStringPart(Token token) {
-    DirectParserASTContentStringPartHandle data =
-        new DirectParserASTContentStringPartHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleSuperExpression(Token token, IdentifierContext context) {
-    DirectParserASTContentSuperExpressionHandle data =
-        new DirectParserASTContentSuperExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            context: context);
-    seen(data);
-  }
-
-  @override
-  void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
-    DirectParserASTContentSwitchCaseBegin data =
-        new DirectParserASTContentSwitchCaseBegin(DirectParserASTType.BEGIN,
-            labelCount: labelCount,
-            expressionCount: expressionCount,
-            firstToken: firstToken);
-    seen(data);
-  }
-
-  @override
-  void endSwitchCase(
-      int labelCount,
-      int expressionCount,
-      Token? defaultKeyword,
-      Token? colonAfterDefault,
-      int statementCount,
-      Token firstToken,
-      Token endToken) {
-    DirectParserASTContentSwitchCaseEnd data =
-        new DirectParserASTContentSwitchCaseEnd(DirectParserASTType.END,
-            labelCount: labelCount,
-            expressionCount: expressionCount,
-            defaultKeyword: defaultKeyword,
-            colonAfterDefault: colonAfterDefault,
-            statementCount: statementCount,
-            firstToken: firstToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleThisExpression(Token token, IdentifierContext context) {
-    DirectParserASTContentThisExpressionHandle data =
-        new DirectParserASTContentThisExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            context: context);
-    seen(data);
-  }
-
-  @override
-  void handleUnaryPostfixAssignmentExpression(Token token) {
-    DirectParserASTContentUnaryPostfixAssignmentExpressionHandle data =
-        new DirectParserASTContentUnaryPostfixAssignmentExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleUnaryPrefixExpression(Token token) {
-    DirectParserASTContentUnaryPrefixExpressionHandle data =
-        new DirectParserASTContentUnaryPrefixExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleUnaryPrefixAssignmentExpression(Token token) {
-    DirectParserASTContentUnaryPrefixAssignmentExpressionHandle data =
-        new DirectParserASTContentUnaryPrefixAssignmentExpressionHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginFormalParameterDefaultValueExpression() {
-    DirectParserASTContentFormalParameterDefaultValueExpressionBegin data =
-        new DirectParserASTContentFormalParameterDefaultValueExpressionBegin(
-            DirectParserASTType.BEGIN);
-    seen(data);
-  }
-
-  @override
-  void endFormalParameterDefaultValueExpression() {
-    DirectParserASTContentFormalParameterDefaultValueExpressionEnd data =
-        new DirectParserASTContentFormalParameterDefaultValueExpressionEnd(
-            DirectParserASTType.END);
-    seen(data);
-  }
-
-  @override
-  void handleValuedFormalParameter(Token equals, Token token) {
-    DirectParserASTContentValuedFormalParameterHandle data =
-        new DirectParserASTContentValuedFormalParameterHandle(
-            DirectParserASTType.HANDLE,
-            equals: equals,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleFormalParameterWithoutValue(Token token) {
-    DirectParserASTContentFormalParameterWithoutValueHandle data =
-        new DirectParserASTContentFormalParameterWithoutValueHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleVoidKeyword(Token token) {
-    DirectParserASTContentVoidKeywordHandle data =
-        new DirectParserASTContentVoidKeywordHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleVoidKeywordWithTypeArguments(Token token) {
-    DirectParserASTContentVoidKeywordWithTypeArgumentsHandle data =
-        new DirectParserASTContentVoidKeywordWithTypeArgumentsHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void beginYieldStatement(Token token) {
-    DirectParserASTContentYieldStatementBegin data =
-        new DirectParserASTContentYieldStatementBegin(DirectParserASTType.BEGIN,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void endYieldStatement(Token yieldToken, Token? starToken, Token endToken) {
-    DirectParserASTContentYieldStatementEnd data =
-        new DirectParserASTContentYieldStatementEnd(DirectParserASTType.END,
-            yieldToken: yieldToken, starToken: starToken, endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void endInvalidYieldStatement(Token beginToken, Token? starToken,
-      Token endToken, MessageCode errorCode) {
-    DirectParserASTContentInvalidYieldStatementEnd data =
-        new DirectParserASTContentInvalidYieldStatementEnd(
-            DirectParserASTType.END,
-            beginToken: beginToken,
-            starToken: starToken,
-            endToken: endToken,
-            errorCode: errorCode);
-    seen(data);
-  }
-
-  @override
-  void handleRecoverableError(
-      Message message, Token startToken, Token endToken) {
-    DirectParserASTContentRecoverableErrorHandle data =
-        new DirectParserASTContentRecoverableErrorHandle(
-            DirectParserASTType.HANDLE,
-            message: message,
-            startToken: startToken,
-            endToken: endToken);
-    seen(data);
-  }
-
-  @override
-  void handleErrorToken(ErrorToken token) {
-    DirectParserASTContentErrorTokenHandle data =
-        new DirectParserASTContentErrorTokenHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleUnescapeError(
-      Message message, Token location, int stringOffset, int length) {
-    DirectParserASTContentUnescapeErrorHandle data =
-        new DirectParserASTContentUnescapeErrorHandle(
-            DirectParserASTType.HANDLE,
-            message: message,
-            location: location,
-            stringOffset: stringOffset,
-            length: length);
-    seen(data);
-  }
-
-  @override
-  void handleInvalidStatement(Token token, Message message) {
-    DirectParserASTContentInvalidStatementHandle data =
-        new DirectParserASTContentInvalidStatementHandle(
-            DirectParserASTType.HANDLE,
-            token: token,
-            message: message);
-    seen(data);
-  }
-
-  @override
-  void handleScript(Token token) {
-    DirectParserASTContentScriptHandle data =
-        new DirectParserASTContentScriptHandle(DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleCommentReferenceText(String referenceSource, int referenceOffset) {
-    DirectParserASTContentCommentReferenceTextHandle data =
-        new DirectParserASTContentCommentReferenceTextHandle(
-            DirectParserASTType.HANDLE,
-            referenceSource: referenceSource,
-            referenceOffset: referenceOffset);
-    seen(data);
-  }
-
-  @override
-  void handleCommentReference(
-      Token? newKeyword, Token? prefix, Token? period, Token token) {
-    DirectParserASTContentCommentReferenceHandle data =
-        new DirectParserASTContentCommentReferenceHandle(
-            DirectParserASTType.HANDLE,
-            newKeyword: newKeyword,
-            prefix: prefix,
-            period: period,
-            token: token);
-    seen(data);
-  }
-
-  @override
-  void handleNoCommentReference() {
-    DirectParserASTContentNoCommentReferenceHandle data =
-        new DirectParserASTContentNoCommentReferenceHandle(
-            DirectParserASTType.HANDLE);
-    seen(data);
-  }
-
-  @override
-  void handleTypeArgumentApplication(Token openAngleBracket) {
-    DirectParserASTContentTypeArgumentApplicationHandle data =
-        new DirectParserASTContentTypeArgumentApplicationHandle(
-            DirectParserASTType.HANDLE,
-            openAngleBracket: openAngleBracket);
-    seen(data);
-  }
-
-  @override
-  void handleNewAsIdentifier(Token token) {
-    DirectParserASTContentNewAsIdentifierHandle data =
-        new DirectParserASTContentNewAsIdentifierHandle(
-            DirectParserASTType.HANDLE,
-            token: token);
-    seen(data);
-  }
-}
-
-class DirectParserASTContentArgumentsBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentArgumentsBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Arguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentArgumentsEnd extends DirectParserASTContent {
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentArgumentsEnd(DirectParserASTType type,
-      {required this.count, required this.beginToken, required this.endToken})
-      : super("Arguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentAsyncModifierHandle extends DirectParserASTContent {
-  final Token? asyncToken;
-  final Token? starToken;
-
-  DirectParserASTContentAsyncModifierHandle(DirectParserASTType type,
-      {this.asyncToken, this.starToken})
-      : super("AsyncModifier", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "asyncToken": asyncToken,
-        "starToken": starToken,
-      };
-}
-
-class DirectParserASTContentAwaitExpressionBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentAwaitExpressionBegin(DirectParserASTType type,
-      {required this.token})
-      : super("AwaitExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentAwaitExpressionEnd extends DirectParserASTContent {
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentAwaitExpressionEnd(DirectParserASTType type,
-      {required this.beginToken, required this.endToken})
-      : super("AwaitExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentInvalidAwaitExpressionEnd
-    extends DirectParserASTContent {
-  final Token beginToken;
-  final Token endToken;
-  final MessageCode errorCode;
-
-  DirectParserASTContentInvalidAwaitExpressionEnd(DirectParserASTType type,
-      {required this.beginToken,
-      required this.endToken,
-      required this.errorCode})
-      : super("InvalidAwaitExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "endToken": endToken,
-        "errorCode": errorCode,
-      };
-}
-
-class DirectParserASTContentBlockBegin extends DirectParserASTContent {
-  final Token token;
-  final BlockKind blockKind;
-
-  DirectParserASTContentBlockBegin(DirectParserASTType type,
-      {required this.token, required this.blockKind})
-      : super("Block", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "blockKind": blockKind,
-      };
-}
-
-class DirectParserASTContentBlockEnd extends DirectParserASTContent {
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-  final BlockKind blockKind;
-
-  DirectParserASTContentBlockEnd(DirectParserASTType type,
-      {required this.count,
-      required this.beginToken,
-      required this.endToken,
-      required this.blockKind})
-      : super("Block", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-        "blockKind": blockKind,
-      };
-}
-
-class DirectParserASTContentInvalidTopLevelBlockHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInvalidTopLevelBlockHandle(DirectParserASTType type,
-      {required this.token})
-      : super("InvalidTopLevelBlock", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentCascadeBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentCascadeBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Cascade", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentCascadeEnd extends DirectParserASTContent {
-  DirectParserASTContentCascadeEnd(DirectParserASTType type)
-      : super("Cascade", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentCaseExpressionBegin extends DirectParserASTContent {
-  final Token caseKeyword;
-
-  DirectParserASTContentCaseExpressionBegin(DirectParserASTType type,
-      {required this.caseKeyword})
-      : super("CaseExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "caseKeyword": caseKeyword,
-      };
-}
-
-class DirectParserASTContentCaseExpressionEnd extends DirectParserASTContent {
-  final Token colon;
-
-  DirectParserASTContentCaseExpressionEnd(DirectParserASTType type,
-      {required this.colon})
-      : super("CaseExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "colon": colon,
-      };
-}
-
-class DirectParserASTContentClassOrMixinOrExtensionBodyBegin
-    extends DirectParserASTContent {
-  final DeclarationKind kind;
-  final Token token;
-
-  DirectParserASTContentClassOrMixinOrExtensionBodyBegin(
-      DirectParserASTType type,
-      {required this.kind,
-      required this.token})
-      : super("ClassOrMixinOrExtensionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "kind": kind,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentClassOrMixinOrExtensionBodyEnd
-    extends DirectParserASTContent {
-  final DeclarationKind kind;
-  final int memberCount;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentClassOrMixinOrExtensionBodyEnd(DirectParserASTType type,
-      {required this.kind,
-      required this.memberCount,
-      required this.beginToken,
-      required this.endToken})
-      : super("ClassOrMixinOrExtensionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "kind": kind,
-        "memberCount": memberCount,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentClassOrMixinOrNamedMixinApplicationPreludeBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentClassOrMixinOrNamedMixinApplicationPreludeBegin(
-      DirectParserASTType type,
-      {required this.token})
-      : super("ClassOrMixinOrNamedMixinApplicationPrelude", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentClassDeclarationBegin
-    extends DirectParserASTContent {
-  final Token begin;
-  final Token? abstractToken;
-  final Token name;
-
-  DirectParserASTContentClassDeclarationBegin(DirectParserASTType type,
-      {required this.begin, this.abstractToken, required this.name})
-      : super("ClassDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "begin": begin,
-        "abstractToken": abstractToken,
-        "name": name,
-      };
-}
-
-class DirectParserASTContentClassExtendsHandle extends DirectParserASTContent {
-  final Token? extendsKeyword;
-  final int typeCount;
-
-  DirectParserASTContentClassExtendsHandle(DirectParserASTType type,
-      {this.extendsKeyword, required this.typeCount})
-      : super("ClassExtends", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "extendsKeyword": extendsKeyword,
-        "typeCount": typeCount,
-      };
-}
-
-class DirectParserASTContentClassOrMixinImplementsHandle
-    extends DirectParserASTContent {
-  final Token? implementsKeyword;
-  final int interfacesCount;
-
-  DirectParserASTContentClassOrMixinImplementsHandle(DirectParserASTType type,
-      {this.implementsKeyword, required this.interfacesCount})
-      : super("ClassOrMixinImplements", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "implementsKeyword": implementsKeyword,
-        "interfacesCount": interfacesCount,
-      };
-}
-
-class DirectParserASTContentExtensionShowHideHandle
-    extends DirectParserASTContent {
-  final Token? showKeyword;
-  final int showElementCount;
-  final Token? hideKeyword;
-  final int hideElementCount;
-
-  DirectParserASTContentExtensionShowHideHandle(DirectParserASTType type,
-      {this.showKeyword,
-      required this.showElementCount,
-      this.hideKeyword,
-      required this.hideElementCount})
-      : super("ExtensionShowHide", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "showKeyword": showKeyword,
-        "showElementCount": showElementCount,
-        "hideKeyword": hideKeyword,
-        "hideElementCount": hideElementCount,
-      };
-}
-
-class DirectParserASTContentClassHeaderHandle extends DirectParserASTContent {
-  final Token begin;
-  final Token classKeyword;
-  final Token? nativeToken;
-
-  DirectParserASTContentClassHeaderHandle(DirectParserASTType type,
-      {required this.begin, required this.classKeyword, this.nativeToken})
-      : super("ClassHeader", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "begin": begin,
-        "classKeyword": classKeyword,
-        "nativeToken": nativeToken,
-      };
-}
-
-class DirectParserASTContentRecoverClassHeaderHandle
-    extends DirectParserASTContent {
-  DirectParserASTContentRecoverClassHeaderHandle(DirectParserASTType type)
-      : super("RecoverClassHeader", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentClassDeclarationEnd extends DirectParserASTContent {
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentClassDeclarationEnd(DirectParserASTType type,
-      {required this.beginToken, required this.endToken})
-      : super("ClassDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentMixinDeclarationBegin
-    extends DirectParserASTContent {
-  final Token mixinKeyword;
-  final Token name;
-
-  DirectParserASTContentMixinDeclarationBegin(DirectParserASTType type,
-      {required this.mixinKeyword, required this.name})
-      : super("MixinDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "mixinKeyword": mixinKeyword,
-        "name": name,
-      };
-}
-
-class DirectParserASTContentMixinOnHandle extends DirectParserASTContent {
-  final Token? onKeyword;
-  final int typeCount;
-
-  DirectParserASTContentMixinOnHandle(DirectParserASTType type,
-      {this.onKeyword, required this.typeCount})
-      : super("MixinOn", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "onKeyword": onKeyword,
-        "typeCount": typeCount,
-      };
-}
-
-class DirectParserASTContentMixinHeaderHandle extends DirectParserASTContent {
-  final Token mixinKeyword;
-
-  DirectParserASTContentMixinHeaderHandle(DirectParserASTType type,
-      {required this.mixinKeyword})
-      : super("MixinHeader", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "mixinKeyword": mixinKeyword,
-      };
-}
-
-class DirectParserASTContentRecoverMixinHeaderHandle
-    extends DirectParserASTContent {
-  DirectParserASTContentRecoverMixinHeaderHandle(DirectParserASTType type)
-      : super("RecoverMixinHeader", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentMixinDeclarationEnd extends DirectParserASTContent {
-  final Token mixinKeyword;
-  final Token endToken;
-
-  DirectParserASTContentMixinDeclarationEnd(DirectParserASTType type,
-      {required this.mixinKeyword, required this.endToken})
-      : super("MixinDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "mixinKeyword": mixinKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentUncategorizedTopLevelDeclarationBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentUncategorizedTopLevelDeclarationBegin(
-      DirectParserASTType type,
-      {required this.token})
-      : super("UncategorizedTopLevelDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentExtensionDeclarationPreludeBegin
-    extends DirectParserASTContent {
-  final Token extensionKeyword;
-
-  DirectParserASTContentExtensionDeclarationPreludeBegin(
-      DirectParserASTType type,
-      {required this.extensionKeyword})
-      : super("ExtensionDeclarationPrelude", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "extensionKeyword": extensionKeyword,
-      };
-}
-
-class DirectParserASTContentExtensionDeclarationBegin
-    extends DirectParserASTContent {
-  final Token extensionKeyword;
-  final Token? name;
-
-  DirectParserASTContentExtensionDeclarationBegin(DirectParserASTType type,
-      {required this.extensionKeyword, this.name})
-      : super("ExtensionDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "extensionKeyword": extensionKeyword,
-        "name": name,
-      };
-}
-
-class DirectParserASTContentExtensionDeclarationEnd
-    extends DirectParserASTContent {
-  final Token extensionKeyword;
-  final Token? typeKeyword;
-  final Token onKeyword;
-  final Token? showKeyword;
-  final Token? hideKeyword;
-  final Token endToken;
-
-  DirectParserASTContentExtensionDeclarationEnd(DirectParserASTType type,
-      {required this.extensionKeyword,
-      this.typeKeyword,
-      required this.onKeyword,
-      this.showKeyword,
-      this.hideKeyword,
-      required this.endToken})
-      : super("ExtensionDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "extensionKeyword": extensionKeyword,
-        "typeKeyword": typeKeyword,
-        "onKeyword": onKeyword,
-        "showKeyword": showKeyword,
-        "hideKeyword": hideKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentCombinatorsBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentCombinatorsBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Combinators", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentCombinatorsEnd extends DirectParserASTContent {
-  final int count;
-
-  DirectParserASTContentCombinatorsEnd(DirectParserASTType type,
-      {required this.count})
-      : super("Combinators", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-      };
-}
-
-class DirectParserASTContentCompilationUnitBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentCompilationUnitBegin(DirectParserASTType type,
-      {required this.token})
-      : super("CompilationUnit", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentDirectivesOnlyHandle
-    extends DirectParserASTContent {
-  DirectParserASTContentDirectivesOnlyHandle(DirectParserASTType type)
-      : super("DirectivesOnly", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentCompilationUnitEnd extends DirectParserASTContent {
-  final int count;
-  final Token token;
-
-  DirectParserASTContentCompilationUnitEnd(DirectParserASTType type,
-      {required this.count, required this.token})
-      : super("CompilationUnit", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentConstLiteralBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentConstLiteralBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ConstLiteral", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentConstLiteralEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentConstLiteralEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ConstLiteral", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentConstructorReferenceBegin
-    extends DirectParserASTContent {
-  final Token start;
-
-  DirectParserASTContentConstructorReferenceBegin(DirectParserASTType type,
-      {required this.start})
-      : super("ConstructorReference", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "start": start,
-      };
-}
-
-class DirectParserASTContentConstructorReferenceEnd
-    extends DirectParserASTContent {
-  final Token start;
-  final Token? periodBeforeName;
-  final Token endToken;
-  final ConstructorReferenceContext constructorReferenceContext;
-
-  DirectParserASTContentConstructorReferenceEnd(DirectParserASTType type,
-      {required this.start,
-      this.periodBeforeName,
-      required this.endToken,
-      required this.constructorReferenceContext})
-      : super("ConstructorReference", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "start": start,
-        "periodBeforeName": periodBeforeName,
-        "endToken": endToken,
-        "constructorReferenceContext": constructorReferenceContext,
-      };
-}
-
-class DirectParserASTContentDoWhileStatementBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentDoWhileStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("DoWhileStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentDoWhileStatementEnd extends DirectParserASTContent {
-  final Token doKeyword;
-  final Token whileKeyword;
-  final Token endToken;
-
-  DirectParserASTContentDoWhileStatementEnd(DirectParserASTType type,
-      {required this.doKeyword,
-      required this.whileKeyword,
-      required this.endToken})
-      : super("DoWhileStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "doKeyword": doKeyword,
-        "whileKeyword": whileKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentDoWhileStatementBodyBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentDoWhileStatementBodyBegin(DirectParserASTType type,
-      {required this.token})
-      : super("DoWhileStatementBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentDoWhileStatementBodyEnd
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentDoWhileStatementBodyEnd(DirectParserASTType type,
-      {required this.token})
-      : super("DoWhileStatementBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentWhileStatementBodyBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentWhileStatementBodyBegin(DirectParserASTType type,
-      {required this.token})
-      : super("WhileStatementBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentWhileStatementBodyEnd
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentWhileStatementBodyEnd(DirectParserASTType type,
-      {required this.token})
-      : super("WhileStatementBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentEnumBegin extends DirectParserASTContent {
-  final Token enumKeyword;
-
-  DirectParserASTContentEnumBegin(DirectParserASTType type,
-      {required this.enumKeyword})
-      : super("Enum", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "enumKeyword": enumKeyword,
-      };
-}
-
-class DirectParserASTContentEnumEnd extends DirectParserASTContent {
-  final Token enumKeyword;
-  final Token leftBrace;
-  final int count;
-
-  DirectParserASTContentEnumEnd(DirectParserASTType type,
-      {required this.enumKeyword, required this.leftBrace, required this.count})
-      : super("Enum", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "enumKeyword": enumKeyword,
-        "leftBrace": leftBrace,
-        "count": count,
-      };
-}
-
-class DirectParserASTContentExportBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentExportBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Export", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentExportEnd extends DirectParserASTContent {
-  final Token exportKeyword;
-  final Token semicolon;
-
-  DirectParserASTContentExportEnd(DirectParserASTType type,
-      {required this.exportKeyword, required this.semicolon})
-      : super("Export", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "exportKeyword": exportKeyword,
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentExtraneousExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final Message message;
-
-  DirectParserASTContentExtraneousExpressionHandle(DirectParserASTType type,
-      {required this.token, required this.message})
-      : super("ExtraneousExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "message": message,
-      };
-}
-
-class DirectParserASTContentExpressionStatementHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentExpressionStatementHandle(DirectParserASTType type,
-      {required this.token})
-      : super("ExpressionStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFactoryMethodBegin extends DirectParserASTContent {
-  final DeclarationKind declarationKind;
-  final Token lastConsumed;
-  final Token? externalToken;
-  final Token? constToken;
-
-  DirectParserASTContentFactoryMethodBegin(DirectParserASTType type,
-      {required this.declarationKind,
-      required this.lastConsumed,
-      this.externalToken,
-      this.constToken})
-      : super("FactoryMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "declarationKind": declarationKind,
-        "lastConsumed": lastConsumed,
-        "externalToken": externalToken,
-        "constToken": constToken,
-      };
-}
-
-class DirectParserASTContentClassFactoryMethodEnd
-    extends DirectParserASTContent {
-  final Token beginToken;
-  final Token factoryKeyword;
-  final Token endToken;
-
-  DirectParserASTContentClassFactoryMethodEnd(DirectParserASTType type,
-      {required this.beginToken,
-      required this.factoryKeyword,
-      required this.endToken})
-      : super("ClassFactoryMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "factoryKeyword": factoryKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentMixinFactoryMethodEnd
-    extends DirectParserASTContent {
-  final Token beginToken;
-  final Token factoryKeyword;
-  final Token endToken;
-
-  DirectParserASTContentMixinFactoryMethodEnd(DirectParserASTType type,
-      {required this.beginToken,
-      required this.factoryKeyword,
-      required this.endToken})
-      : super("MixinFactoryMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "factoryKeyword": factoryKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentExtensionFactoryMethodEnd
-    extends DirectParserASTContent {
-  final Token beginToken;
-  final Token factoryKeyword;
-  final Token endToken;
-
-  DirectParserASTContentExtensionFactoryMethodEnd(DirectParserASTType type,
-      {required this.beginToken,
-      required this.factoryKeyword,
-      required this.endToken})
-      : super("ExtensionFactoryMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "factoryKeyword": factoryKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentFormalParameterBegin
-    extends DirectParserASTContent {
-  final Token token;
-  final MemberKind kind;
-  final Token? requiredToken;
-  final Token? covariantToken;
-  final Token? varFinalOrConst;
-
-  DirectParserASTContentFormalParameterBegin(DirectParserASTType type,
-      {required this.token,
-      required this.kind,
-      this.requiredToken,
-      this.covariantToken,
-      this.varFinalOrConst})
-      : super("FormalParameter", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "kind": kind,
-        "requiredToken": requiredToken,
-        "covariantToken": covariantToken,
-        "varFinalOrConst": varFinalOrConst,
-      };
-}
-
-class DirectParserASTContentFormalParameterEnd extends DirectParserASTContent {
-  final Token? thisKeyword;
-  final Token? periodAfterThis;
-  final Token nameToken;
-  final Token? initializerStart;
-  final Token? initializerEnd;
-  final FormalParameterKind kind;
-  final MemberKind memberKind;
-
-  DirectParserASTContentFormalParameterEnd(DirectParserASTType type,
-      {this.thisKeyword,
-      this.periodAfterThis,
-      required this.nameToken,
-      this.initializerStart,
-      this.initializerEnd,
-      required this.kind,
-      required this.memberKind})
-      : super("FormalParameter", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "thisKeyword": thisKeyword,
-        "periodAfterThis": periodAfterThis,
-        "nameToken": nameToken,
-        "initializerStart": initializerStart,
-        "initializerEnd": initializerEnd,
-        "kind": kind,
-        "memberKind": memberKind,
-      };
-}
-
-class DirectParserASTContentNoFormalParametersHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final MemberKind kind;
-
-  DirectParserASTContentNoFormalParametersHandle(DirectParserASTType type,
-      {required this.token, required this.kind})
-      : super("NoFormalParameters", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "kind": kind,
-      };
-}
-
-class DirectParserASTContentFormalParametersBegin
-    extends DirectParserASTContent {
-  final Token token;
-  final MemberKind kind;
-
-  DirectParserASTContentFormalParametersBegin(DirectParserASTType type,
-      {required this.token, required this.kind})
-      : super("FormalParameters", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "kind": kind,
-      };
-}
-
-class DirectParserASTContentFormalParametersEnd extends DirectParserASTContent {
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-  final MemberKind kind;
-
-  DirectParserASTContentFormalParametersEnd(DirectParserASTType type,
-      {required this.count,
-      required this.beginToken,
-      required this.endToken,
-      required this.kind})
-      : super("FormalParameters", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-        "kind": kind,
-      };
-}
-
-class DirectParserASTContentClassFieldsEnd extends DirectParserASTContent {
-  final Token? abstractToken;
-  final Token? externalToken;
-  final Token? staticToken;
-  final Token? covariantToken;
-  final Token? lateToken;
-  final Token? varFinalOrConst;
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentClassFieldsEnd(DirectParserASTType type,
-      {this.abstractToken,
-      this.externalToken,
-      this.staticToken,
-      this.covariantToken,
-      this.lateToken,
-      this.varFinalOrConst,
-      required this.count,
-      required this.beginToken,
-      required this.endToken})
-      : super("ClassFields", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "abstractToken": abstractToken,
-        "externalToken": externalToken,
-        "staticToken": staticToken,
-        "covariantToken": covariantToken,
-        "lateToken": lateToken,
-        "varFinalOrConst": varFinalOrConst,
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentMixinFieldsEnd extends DirectParserASTContent {
-  final Token? abstractToken;
-  final Token? externalToken;
-  final Token? staticToken;
-  final Token? covariantToken;
-  final Token? lateToken;
-  final Token? varFinalOrConst;
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentMixinFieldsEnd(DirectParserASTType type,
-      {this.abstractToken,
-      this.externalToken,
-      this.staticToken,
-      this.covariantToken,
-      this.lateToken,
-      this.varFinalOrConst,
-      required this.count,
-      required this.beginToken,
-      required this.endToken})
-      : super("MixinFields", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "abstractToken": abstractToken,
-        "externalToken": externalToken,
-        "staticToken": staticToken,
-        "covariantToken": covariantToken,
-        "lateToken": lateToken,
-        "varFinalOrConst": varFinalOrConst,
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentExtensionFieldsEnd extends DirectParserASTContent {
-  final Token? abstractToken;
-  final Token? externalToken;
-  final Token? staticToken;
-  final Token? covariantToken;
-  final Token? lateToken;
-  final Token? varFinalOrConst;
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentExtensionFieldsEnd(DirectParserASTType type,
-      {this.abstractToken,
-      this.externalToken,
-      this.staticToken,
-      this.covariantToken,
-      this.lateToken,
-      this.varFinalOrConst,
-      required this.count,
-      required this.beginToken,
-      required this.endToken})
-      : super("ExtensionFields", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "abstractToken": abstractToken,
-        "externalToken": externalToken,
-        "staticToken": staticToken,
-        "covariantToken": covariantToken,
-        "lateToken": lateToken,
-        "varFinalOrConst": varFinalOrConst,
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentForInitializerEmptyStatementHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForInitializerEmptyStatementHandle(
-      DirectParserASTType type,
-      {required this.token})
-      : super("ForInitializerEmptyStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForInitializerExpressionStatementHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final bool forIn;
-
-  DirectParserASTContentForInitializerExpressionStatementHandle(
-      DirectParserASTType type,
-      {required this.token,
-      required this.forIn})
-      : super("ForInitializerExpressionStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "forIn": forIn,
-      };
-}
-
-class DirectParserASTContentForInitializerLocalVariableDeclarationHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final bool forIn;
-
-  DirectParserASTContentForInitializerLocalVariableDeclarationHandle(
-      DirectParserASTType type,
-      {required this.token,
-      required this.forIn})
-      : super("ForInitializerLocalVariableDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "forIn": forIn,
-      };
-}
-
-class DirectParserASTContentForStatementBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ForStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForLoopPartsHandle extends DirectParserASTContent {
-  final Token forKeyword;
-  final Token leftParen;
-  final Token leftSeparator;
-  final int updateExpressionCount;
-
-  DirectParserASTContentForLoopPartsHandle(DirectParserASTType type,
-      {required this.forKeyword,
-      required this.leftParen,
-      required this.leftSeparator,
-      required this.updateExpressionCount})
-      : super("ForLoopParts", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "forKeyword": forKeyword,
-        "leftParen": leftParen,
-        "leftSeparator": leftSeparator,
-        "updateExpressionCount": updateExpressionCount,
-      };
-}
-
-class DirectParserASTContentForStatementEnd extends DirectParserASTContent {
-  final Token endToken;
-
-  DirectParserASTContentForStatementEnd(DirectParserASTType type,
-      {required this.endToken})
-      : super("ForStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentForStatementBodyBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForStatementBodyBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ForStatementBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForStatementBodyEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForStatementBodyEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ForStatementBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForInLoopPartsHandle
-    extends DirectParserASTContent {
-  final Token? awaitToken;
-  final Token forToken;
-  final Token leftParenthesis;
-  final Token inKeyword;
-
-  DirectParserASTContentForInLoopPartsHandle(DirectParserASTType type,
-      {this.awaitToken,
-      required this.forToken,
-      required this.leftParenthesis,
-      required this.inKeyword})
-      : super("ForInLoopParts", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "awaitToken": awaitToken,
-        "forToken": forToken,
-        "leftParenthesis": leftParenthesis,
-        "inKeyword": inKeyword,
-      };
-}
-
-class DirectParserASTContentForInEnd extends DirectParserASTContent {
-  final Token endToken;
-
-  DirectParserASTContentForInEnd(DirectParserASTType type,
-      {required this.endToken})
-      : super("ForIn", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentForInExpressionBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForInExpressionBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ForInExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForInExpressionEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForInExpressionEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ForInExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForInBodyBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForInBodyBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ForInBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForInBodyEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForInBodyEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ForInBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNamedFunctionExpressionBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNamedFunctionExpressionBegin(DirectParserASTType type,
-      {required this.token})
-      : super("NamedFunctionExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNamedFunctionExpressionEnd
-    extends DirectParserASTContent {
-  final Token endToken;
-
-  DirectParserASTContentNamedFunctionExpressionEnd(DirectParserASTType type,
-      {required this.endToken})
-      : super("NamedFunctionExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentLocalFunctionDeclarationBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLocalFunctionDeclarationBegin(DirectParserASTType type,
-      {required this.token})
-      : super("LocalFunctionDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentLocalFunctionDeclarationEnd
-    extends DirectParserASTContent {
-  final Token endToken;
-
-  DirectParserASTContentLocalFunctionDeclarationEnd(DirectParserASTType type,
-      {required this.endToken})
-      : super("LocalFunctionDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentBlockFunctionBodyBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentBlockFunctionBodyBegin(DirectParserASTType type,
-      {required this.token})
-      : super("BlockFunctionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentBlockFunctionBodyEnd
-    extends DirectParserASTContent {
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentBlockFunctionBodyEnd(DirectParserASTType type,
-      {required this.count, required this.beginToken, required this.endToken})
-      : super("BlockFunctionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentNoFunctionBodyHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoFunctionBodyHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NoFunctionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFunctionBodySkippedHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final bool isExpressionBody;
-
-  DirectParserASTContentFunctionBodySkippedHandle(DirectParserASTType type,
-      {required this.token, required this.isExpressionBody})
-      : super("FunctionBodySkipped", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "isExpressionBody": isExpressionBody,
-      };
-}
-
-class DirectParserASTContentFunctionNameBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentFunctionNameBegin(DirectParserASTType type,
-      {required this.token})
-      : super("FunctionName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFunctionNameEnd extends DirectParserASTContent {
-  final Token beginToken;
-  final Token token;
-
-  DirectParserASTContentFunctionNameEnd(DirectParserASTType type,
-      {required this.beginToken, required this.token})
-      : super("FunctionName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentTypedefBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentTypedefBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Typedef", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentTypedefEnd extends DirectParserASTContent {
-  final Token typedefKeyword;
-  final Token? equals;
-  final Token endToken;
-
-  DirectParserASTContentTypedefEnd(DirectParserASTType type,
-      {required this.typedefKeyword, this.equals, required this.endToken})
-      : super("Typedef", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "typedefKeyword": typedefKeyword,
-        "equals": equals,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentClassWithClauseHandle
-    extends DirectParserASTContent {
-  final Token withKeyword;
-
-  DirectParserASTContentClassWithClauseHandle(DirectParserASTType type,
-      {required this.withKeyword})
-      : super("ClassWithClause", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "withKeyword": withKeyword,
-      };
-}
-
-class DirectParserASTContentClassNoWithClauseHandle
-    extends DirectParserASTContent {
-  DirectParserASTContentClassNoWithClauseHandle(DirectParserASTType type)
-      : super("ClassNoWithClause", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentNamedMixinApplicationBegin
-    extends DirectParserASTContent {
-  final Token begin;
-  final Token? abstractToken;
-  final Token name;
-
-  DirectParserASTContentNamedMixinApplicationBegin(DirectParserASTType type,
-      {required this.begin, this.abstractToken, required this.name})
-      : super("NamedMixinApplication", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "begin": begin,
-        "abstractToken": abstractToken,
-        "name": name,
-      };
-}
-
-class DirectParserASTContentNamedMixinApplicationWithClauseHandle
-    extends DirectParserASTContent {
-  final Token withKeyword;
-
-  DirectParserASTContentNamedMixinApplicationWithClauseHandle(
-      DirectParserASTType type,
-      {required this.withKeyword})
-      : super("NamedMixinApplicationWithClause", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "withKeyword": withKeyword,
-      };
-}
-
-class DirectParserASTContentNamedMixinApplicationEnd
-    extends DirectParserASTContent {
-  final Token begin;
-  final Token classKeyword;
-  final Token equals;
-  final Token? implementsKeyword;
-  final Token endToken;
-
-  DirectParserASTContentNamedMixinApplicationEnd(DirectParserASTType type,
-      {required this.begin,
-      required this.classKeyword,
-      required this.equals,
-      this.implementsKeyword,
-      required this.endToken})
-      : super("NamedMixinApplication", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "begin": begin,
-        "classKeyword": classKeyword,
-        "equals": equals,
-        "implementsKeyword": implementsKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentHideBegin extends DirectParserASTContent {
-  final Token hideKeyword;
-
-  DirectParserASTContentHideBegin(DirectParserASTType type,
-      {required this.hideKeyword})
-      : super("Hide", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "hideKeyword": hideKeyword,
-      };
-}
-
-class DirectParserASTContentHideEnd extends DirectParserASTContent {
-  final Token hideKeyword;
-
-  DirectParserASTContentHideEnd(DirectParserASTType type,
-      {required this.hideKeyword})
-      : super("Hide", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "hideKeyword": hideKeyword,
-      };
-}
-
-class DirectParserASTContentIdentifierListHandle
-    extends DirectParserASTContent {
-  final int count;
-
-  DirectParserASTContentIdentifierListHandle(DirectParserASTType type,
-      {required this.count})
-      : super("IdentifierList", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-      };
-}
-
-class DirectParserASTContentTypeListBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentTypeListBegin(DirectParserASTType type,
-      {required this.token})
-      : super("TypeList", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentTypeListEnd extends DirectParserASTContent {
-  final int count;
-
-  DirectParserASTContentTypeListEnd(DirectParserASTType type,
-      {required this.count})
-      : super("TypeList", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-      };
-}
-
-class DirectParserASTContentIfStatementBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentIfStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("IfStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentIfStatementEnd extends DirectParserASTContent {
-  final Token ifToken;
-  final Token? elseToken;
-
-  DirectParserASTContentIfStatementEnd(DirectParserASTType type,
-      {required this.ifToken, this.elseToken})
-      : super("IfStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "ifToken": ifToken,
-        "elseToken": elseToken,
-      };
-}
-
-class DirectParserASTContentThenStatementBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentThenStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ThenStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentThenStatementEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentThenStatementEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ThenStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentElseStatementBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentElseStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ElseStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentElseStatementEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentElseStatementEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ElseStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentImportBegin extends DirectParserASTContent {
-  final Token importKeyword;
-
-  DirectParserASTContentImportBegin(DirectParserASTType type,
-      {required this.importKeyword})
-      : super("Import", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "importKeyword": importKeyword,
-      };
-}
-
-class DirectParserASTContentImportPrefixHandle extends DirectParserASTContent {
-  final Token? deferredKeyword;
-  final Token? asKeyword;
-
-  DirectParserASTContentImportPrefixHandle(DirectParserASTType type,
-      {this.deferredKeyword, this.asKeyword})
-      : super("ImportPrefix", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "deferredKeyword": deferredKeyword,
-        "asKeyword": asKeyword,
-      };
-}
-
-class DirectParserASTContentImportEnd extends DirectParserASTContent {
-  final Token importKeyword;
-  final Token? semicolon;
-
-  DirectParserASTContentImportEnd(DirectParserASTType type,
-      {required this.importKeyword, this.semicolon})
-      : super("Import", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "importKeyword": importKeyword,
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentRecoverImportHandle extends DirectParserASTContent {
-  final Token? semicolon;
-
-  DirectParserASTContentRecoverImportHandle(DirectParserASTType type,
-      {this.semicolon})
-      : super("RecoverImport", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentConditionalUrisBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentConditionalUrisBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ConditionalUris", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentConditionalUrisEnd extends DirectParserASTContent {
-  final int count;
-
-  DirectParserASTContentConditionalUrisEnd(DirectParserASTType type,
-      {required this.count})
-      : super("ConditionalUris", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-      };
-}
-
-class DirectParserASTContentConditionalUriBegin extends DirectParserASTContent {
-  final Token ifKeyword;
-
-  DirectParserASTContentConditionalUriBegin(DirectParserASTType type,
-      {required this.ifKeyword})
-      : super("ConditionalUri", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "ifKeyword": ifKeyword,
-      };
-}
-
-class DirectParserASTContentConditionalUriEnd extends DirectParserASTContent {
-  final Token ifKeyword;
-  final Token leftParen;
-  final Token? equalSign;
-
-  DirectParserASTContentConditionalUriEnd(DirectParserASTType type,
-      {required this.ifKeyword, required this.leftParen, this.equalSign})
-      : super("ConditionalUri", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "ifKeyword": ifKeyword,
-        "leftParen": leftParen,
-        "equalSign": equalSign,
-      };
-}
-
-class DirectParserASTContentDottedNameHandle extends DirectParserASTContent {
-  final int count;
-  final Token firstIdentifier;
-
-  DirectParserASTContentDottedNameHandle(DirectParserASTType type,
-      {required this.count, required this.firstIdentifier})
-      : super("DottedName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "firstIdentifier": firstIdentifier,
-      };
-}
-
-class DirectParserASTContentImplicitCreationExpressionBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentImplicitCreationExpressionBegin(
-      DirectParserASTType type,
-      {required this.token})
-      : super("ImplicitCreationExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentImplicitCreationExpressionEnd
-    extends DirectParserASTContent {
-  final Token token;
-  final Token openAngleBracket;
-
-  DirectParserASTContentImplicitCreationExpressionEnd(DirectParserASTType type,
-      {required this.token, required this.openAngleBracket})
-      : super("ImplicitCreationExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "openAngleBracket": openAngleBracket,
-      };
-}
-
-class DirectParserASTContentInitializedIdentifierBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInitializedIdentifierBegin(DirectParserASTType type,
-      {required this.token})
-      : super("InitializedIdentifier", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInitializedIdentifierEnd
-    extends DirectParserASTContent {
-  final Token nameToken;
-
-  DirectParserASTContentInitializedIdentifierEnd(DirectParserASTType type,
-      {required this.nameToken})
-      : super("InitializedIdentifier", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "nameToken": nameToken,
-      };
-}
-
-class DirectParserASTContentFieldInitializerBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentFieldInitializerBegin(DirectParserASTType type,
-      {required this.token})
-      : super("FieldInitializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFieldInitializerEnd extends DirectParserASTContent {
-  final Token assignment;
-  final Token token;
-
-  DirectParserASTContentFieldInitializerEnd(DirectParserASTType type,
-      {required this.assignment, required this.token})
-      : super("FieldInitializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "assignment": assignment,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNoFieldInitializerHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoFieldInitializerHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NoFieldInitializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentVariableInitializerBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentVariableInitializerBegin(DirectParserASTType type,
-      {required this.token})
-      : super("VariableInitializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentVariableInitializerEnd
-    extends DirectParserASTContent {
-  final Token assignmentOperator;
-
-  DirectParserASTContentVariableInitializerEnd(DirectParserASTType type,
-      {required this.assignmentOperator})
-      : super("VariableInitializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "assignmentOperator": assignmentOperator,
-      };
-}
-
-class DirectParserASTContentNoVariableInitializerHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoVariableInitializerHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NoVariableInitializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInitializerBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInitializerBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Initializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInitializerEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInitializerEnd(DirectParserASTType type,
-      {required this.token})
-      : super("Initializer", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInitializersBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInitializersBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Initializers", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInitializersEnd extends DirectParserASTContent {
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentInitializersEnd(DirectParserASTType type,
-      {required this.count, required this.beginToken, required this.endToken})
-      : super("Initializers", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentNoInitializersHandle
-    extends DirectParserASTContent {
-  DirectParserASTContentNoInitializersHandle(DirectParserASTType type)
-      : super("NoInitializers", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentInvalidExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInvalidExpressionHandle(DirectParserASTType type,
-      {required this.token})
-      : super("InvalidExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInvalidFunctionBodyHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInvalidFunctionBodyHandle(DirectParserASTType type,
-      {required this.token})
-      : super("InvalidFunctionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInvalidTypeReferenceHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInvalidTypeReferenceHandle(DirectParserASTType type,
-      {required this.token})
-      : super("InvalidTypeReference", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentLabelHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLabelHandle(DirectParserASTType type,
-      {required this.token})
-      : super("Label", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentLabeledStatementBegin
-    extends DirectParserASTContent {
-  final Token token;
-  final int labelCount;
-
-  DirectParserASTContentLabeledStatementBegin(DirectParserASTType type,
-      {required this.token, required this.labelCount})
-      : super("LabeledStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "labelCount": labelCount,
-      };
-}
-
-class DirectParserASTContentLabeledStatementEnd extends DirectParserASTContent {
-  final int labelCount;
-
-  DirectParserASTContentLabeledStatementEnd(DirectParserASTType type,
-      {required this.labelCount})
-      : super("LabeledStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "labelCount": labelCount,
-      };
-}
-
-class DirectParserASTContentLibraryNameBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLibraryNameBegin(DirectParserASTType type,
-      {required this.token})
-      : super("LibraryName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentLibraryNameEnd extends DirectParserASTContent {
-  final Token libraryKeyword;
-  final Token semicolon;
-
-  DirectParserASTContentLibraryNameEnd(DirectParserASTType type,
-      {required this.libraryKeyword, required this.semicolon})
-      : super("LibraryName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "libraryKeyword": libraryKeyword,
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentLiteralMapEntryHandle
-    extends DirectParserASTContent {
-  final Token colon;
-  final Token endToken;
-
-  DirectParserASTContentLiteralMapEntryHandle(DirectParserASTType type,
-      {required this.colon, required this.endToken})
-      : super("LiteralMapEntry", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "colon": colon,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentLiteralStringBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLiteralStringBegin(DirectParserASTType type,
-      {required this.token})
-      : super("LiteralString", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInterpolationExpressionHandle
-    extends DirectParserASTContent {
-  final Token leftBracket;
-  final Token? rightBracket;
-
-  DirectParserASTContentInterpolationExpressionHandle(DirectParserASTType type,
-      {required this.leftBracket, this.rightBracket})
-      : super("InterpolationExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "leftBracket": leftBracket,
-        "rightBracket": rightBracket,
-      };
-}
-
-class DirectParserASTContentLiteralStringEnd extends DirectParserASTContent {
-  final int interpolationCount;
-  final Token endToken;
-
-  DirectParserASTContentLiteralStringEnd(DirectParserASTType type,
-      {required this.interpolationCount, required this.endToken})
-      : super("LiteralString", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "interpolationCount": interpolationCount,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentStringJuxtapositionHandle
-    extends DirectParserASTContent {
-  final Token startToken;
-  final int literalCount;
-
-  DirectParserASTContentStringJuxtapositionHandle(DirectParserASTType type,
-      {required this.startToken, required this.literalCount})
-      : super("StringJuxtaposition", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "startToken": startToken,
-        "literalCount": literalCount,
-      };
-}
-
-class DirectParserASTContentMemberBegin extends DirectParserASTContent {
-  DirectParserASTContentMemberBegin(DirectParserASTType type)
-      : super("Member", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentInvalidMemberHandle extends DirectParserASTContent {
-  final Token endToken;
-
-  DirectParserASTContentInvalidMemberHandle(DirectParserASTType type,
-      {required this.endToken})
-      : super("InvalidMember", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentMemberEnd extends DirectParserASTContent {
-  DirectParserASTContentMemberEnd(DirectParserASTType type)
-      : super("Member", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentMethodBegin extends DirectParserASTContent {
-  final DeclarationKind declarationKind;
-  final Token? externalToken;
-  final Token? staticToken;
-  final Token? covariantToken;
-  final Token? varFinalOrConst;
-  final Token? getOrSet;
-  final Token name;
-
-  DirectParserASTContentMethodBegin(DirectParserASTType type,
-      {required this.declarationKind,
-      this.externalToken,
-      this.staticToken,
-      this.covariantToken,
-      this.varFinalOrConst,
-      this.getOrSet,
-      required this.name})
-      : super("Method", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "declarationKind": declarationKind,
-        "externalToken": externalToken,
-        "staticToken": staticToken,
-        "covariantToken": covariantToken,
-        "varFinalOrConst": varFinalOrConst,
-        "getOrSet": getOrSet,
-        "name": name,
-      };
-}
-
-class DirectParserASTContentClassMethodEnd extends DirectParserASTContent {
-  final Token? getOrSet;
-  final Token beginToken;
-  final Token beginParam;
-  final Token? beginInitializers;
-  final Token endToken;
-
-  DirectParserASTContentClassMethodEnd(DirectParserASTType type,
-      {this.getOrSet,
-      required this.beginToken,
-      required this.beginParam,
-      this.beginInitializers,
-      required this.endToken})
-      : super("ClassMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "getOrSet": getOrSet,
-        "beginToken": beginToken,
-        "beginParam": beginParam,
-        "beginInitializers": beginInitializers,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentMixinMethodEnd extends DirectParserASTContent {
-  final Token? getOrSet;
-  final Token beginToken;
-  final Token beginParam;
-  final Token? beginInitializers;
-  final Token endToken;
-
-  DirectParserASTContentMixinMethodEnd(DirectParserASTType type,
-      {this.getOrSet,
-      required this.beginToken,
-      required this.beginParam,
-      this.beginInitializers,
-      required this.endToken})
-      : super("MixinMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "getOrSet": getOrSet,
-        "beginToken": beginToken,
-        "beginParam": beginParam,
-        "beginInitializers": beginInitializers,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentExtensionMethodEnd extends DirectParserASTContent {
-  final Token? getOrSet;
-  final Token beginToken;
-  final Token beginParam;
-  final Token? beginInitializers;
-  final Token endToken;
-
-  DirectParserASTContentExtensionMethodEnd(DirectParserASTType type,
-      {this.getOrSet,
-      required this.beginToken,
-      required this.beginParam,
-      this.beginInitializers,
-      required this.endToken})
-      : super("ExtensionMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "getOrSet": getOrSet,
-        "beginToken": beginToken,
-        "beginParam": beginParam,
-        "beginInitializers": beginInitializers,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentClassConstructorEnd extends DirectParserASTContent {
-  final Token? getOrSet;
-  final Token beginToken;
-  final Token beginParam;
-  final Token? beginInitializers;
-  final Token endToken;
-
-  DirectParserASTContentClassConstructorEnd(DirectParserASTType type,
-      {this.getOrSet,
-      required this.beginToken,
-      required this.beginParam,
-      this.beginInitializers,
-      required this.endToken})
-      : super("ClassConstructor", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "getOrSet": getOrSet,
-        "beginToken": beginToken,
-        "beginParam": beginParam,
-        "beginInitializers": beginInitializers,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentMixinConstructorEnd extends DirectParserASTContent {
-  final Token? getOrSet;
-  final Token beginToken;
-  final Token beginParam;
-  final Token? beginInitializers;
-  final Token endToken;
-
-  DirectParserASTContentMixinConstructorEnd(DirectParserASTType type,
-      {this.getOrSet,
-      required this.beginToken,
-      required this.beginParam,
-      this.beginInitializers,
-      required this.endToken})
-      : super("MixinConstructor", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "getOrSet": getOrSet,
-        "beginToken": beginToken,
-        "beginParam": beginParam,
-        "beginInitializers": beginInitializers,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentExtensionConstructorEnd
-    extends DirectParserASTContent {
-  final Token? getOrSet;
-  final Token beginToken;
-  final Token beginParam;
-  final Token? beginInitializers;
-  final Token endToken;
-
-  DirectParserASTContentExtensionConstructorEnd(DirectParserASTType type,
-      {this.getOrSet,
-      required this.beginToken,
-      required this.beginParam,
-      this.beginInitializers,
-      required this.endToken})
-      : super("ExtensionConstructor", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "getOrSet": getOrSet,
-        "beginToken": beginToken,
-        "beginParam": beginParam,
-        "beginInitializers": beginInitializers,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentMetadataStarBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentMetadataStarBegin(DirectParserASTType type,
-      {required this.token})
-      : super("MetadataStar", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentMetadataStarEnd extends DirectParserASTContent {
-  final int count;
-
-  DirectParserASTContentMetadataStarEnd(DirectParserASTType type,
-      {required this.count})
-      : super("MetadataStar", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-      };
-}
-
-class DirectParserASTContentMetadataBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentMetadataBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Metadata", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentMetadataEnd extends DirectParserASTContent {
-  final Token beginToken;
-  final Token? periodBeforeName;
-  final Token endToken;
-
-  DirectParserASTContentMetadataEnd(DirectParserASTType type,
-      {required this.beginToken, this.periodBeforeName, required this.endToken})
-      : super("Metadata", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "periodBeforeName": periodBeforeName,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentOptionalFormalParametersBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentOptionalFormalParametersBegin(DirectParserASTType type,
-      {required this.token})
-      : super("OptionalFormalParameters", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentOptionalFormalParametersEnd
-    extends DirectParserASTContent {
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentOptionalFormalParametersEnd(DirectParserASTType type,
-      {required this.count, required this.beginToken, required this.endToken})
-      : super("OptionalFormalParameters", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentPartBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentPartBegin(DirectParserASTType type,
-      {required this.token})
-      : super("Part", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentPartEnd extends DirectParserASTContent {
-  final Token partKeyword;
-  final Token semicolon;
-
-  DirectParserASTContentPartEnd(DirectParserASTType type,
-      {required this.partKeyword, required this.semicolon})
-      : super("Part", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "partKeyword": partKeyword,
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentPartOfBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentPartOfBegin(DirectParserASTType type,
-      {required this.token})
-      : super("PartOf", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentPartOfEnd extends DirectParserASTContent {
-  final Token partKeyword;
-  final Token ofKeyword;
-  final Token semicolon;
-  final bool hasName;
-
-  DirectParserASTContentPartOfEnd(DirectParserASTType type,
-      {required this.partKeyword,
-      required this.ofKeyword,
-      required this.semicolon,
-      required this.hasName})
-      : super("PartOf", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "partKeyword": partKeyword,
-        "ofKeyword": ofKeyword,
-        "semicolon": semicolon,
-        "hasName": hasName,
-      };
-}
-
-class DirectParserASTContentRedirectingFactoryBodyBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentRedirectingFactoryBodyBegin(DirectParserASTType type,
-      {required this.token})
-      : super("RedirectingFactoryBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentRedirectingFactoryBodyEnd
-    extends DirectParserASTContent {
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentRedirectingFactoryBodyEnd(DirectParserASTType type,
-      {required this.beginToken, required this.endToken})
-      : super("RedirectingFactoryBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentReturnStatementBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentReturnStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("ReturnStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNativeFunctionBodyHandle
-    extends DirectParserASTContent {
-  final Token nativeToken;
-  final Token semicolon;
-
-  DirectParserASTContentNativeFunctionBodyHandle(DirectParserASTType type,
-      {required this.nativeToken, required this.semicolon})
-      : super("NativeFunctionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "nativeToken": nativeToken,
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentNativeFunctionBodyIgnoredHandle
-    extends DirectParserASTContent {
-  final Token nativeToken;
-  final Token semicolon;
-
-  DirectParserASTContentNativeFunctionBodyIgnoredHandle(
-      DirectParserASTType type,
-      {required this.nativeToken,
-      required this.semicolon})
-      : super("NativeFunctionBodyIgnored", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "nativeToken": nativeToken,
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentNativeFunctionBodySkippedHandle
-    extends DirectParserASTContent {
-  final Token nativeToken;
-  final Token semicolon;
-
-  DirectParserASTContentNativeFunctionBodySkippedHandle(
-      DirectParserASTType type,
-      {required this.nativeToken,
-      required this.semicolon})
-      : super("NativeFunctionBodySkipped", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "nativeToken": nativeToken,
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentEmptyFunctionBodyHandle
-    extends DirectParserASTContent {
-  final Token semicolon;
-
-  DirectParserASTContentEmptyFunctionBodyHandle(DirectParserASTType type,
-      {required this.semicolon})
-      : super("EmptyFunctionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "semicolon": semicolon,
-      };
-}
-
-class DirectParserASTContentExpressionFunctionBodyHandle
-    extends DirectParserASTContent {
-  final Token arrowToken;
-  final Token? endToken;
-
-  DirectParserASTContentExpressionFunctionBodyHandle(DirectParserASTType type,
-      {required this.arrowToken, this.endToken})
-      : super("ExpressionFunctionBody", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "arrowToken": arrowToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentReturnStatementEnd extends DirectParserASTContent {
-  final bool hasExpression;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentReturnStatementEnd(DirectParserASTType type,
-      {required this.hasExpression,
-      required this.beginToken,
-      required this.endToken})
-      : super("ReturnStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "hasExpression": hasExpression,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentSendHandle extends DirectParserASTContent {
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentSendHandle(DirectParserASTType type,
-      {required this.beginToken, required this.endToken})
-      : super("Send", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentShowBegin extends DirectParserASTContent {
-  final Token showKeyword;
-
-  DirectParserASTContentShowBegin(DirectParserASTType type,
-      {required this.showKeyword})
-      : super("Show", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "showKeyword": showKeyword,
-      };
-}
-
-class DirectParserASTContentShowEnd extends DirectParserASTContent {
-  final Token showKeyword;
-
-  DirectParserASTContentShowEnd(DirectParserASTType type,
-      {required this.showKeyword})
-      : super("Show", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "showKeyword": showKeyword,
-      };
-}
-
-class DirectParserASTContentSwitchStatementBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentSwitchStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("SwitchStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentSwitchStatementEnd extends DirectParserASTContent {
-  final Token switchKeyword;
-  final Token endToken;
-
-  DirectParserASTContentSwitchStatementEnd(DirectParserASTType type,
-      {required this.switchKeyword, required this.endToken})
-      : super("SwitchStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "switchKeyword": switchKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentSwitchBlockBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentSwitchBlockBegin(DirectParserASTType type,
-      {required this.token})
-      : super("SwitchBlock", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentSwitchBlockEnd extends DirectParserASTContent {
-  final int caseCount;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentSwitchBlockEnd(DirectParserASTType type,
-      {required this.caseCount,
-      required this.beginToken,
-      required this.endToken})
-      : super("SwitchBlock", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "caseCount": caseCount,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentLiteralSymbolBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLiteralSymbolBegin(DirectParserASTType type,
-      {required this.token})
-      : super("LiteralSymbol", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentLiteralSymbolEnd extends DirectParserASTContent {
-  final Token hashToken;
-  final int identifierCount;
-
-  DirectParserASTContentLiteralSymbolEnd(DirectParserASTType type,
-      {required this.hashToken, required this.identifierCount})
-      : super("LiteralSymbol", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "hashToken": hashToken,
-        "identifierCount": identifierCount,
-      };
-}
-
-class DirectParserASTContentThrowExpressionHandle
-    extends DirectParserASTContent {
-  final Token throwToken;
-  final Token endToken;
-
-  DirectParserASTContentThrowExpressionHandle(DirectParserASTType type,
-      {required this.throwToken, required this.endToken})
-      : super("ThrowExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "throwToken": throwToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentRethrowStatementBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentRethrowStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("RethrowStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentRethrowStatementEnd extends DirectParserASTContent {
-  final Token rethrowToken;
-  final Token endToken;
-
-  DirectParserASTContentRethrowStatementEnd(DirectParserASTType type,
-      {required this.rethrowToken, required this.endToken})
-      : super("RethrowStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "rethrowToken": rethrowToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentTopLevelDeclarationEnd
-    extends DirectParserASTContent {
-  final Token nextToken;
-
-  DirectParserASTContentTopLevelDeclarationEnd(DirectParserASTType type,
-      {required this.nextToken})
-      : super("TopLevelDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "nextToken": nextToken,
-      };
-}
-
-class DirectParserASTContentInvalidTopLevelDeclarationHandle
-    extends DirectParserASTContent {
-  final Token endToken;
-
-  DirectParserASTContentInvalidTopLevelDeclarationHandle(
-      DirectParserASTType type,
-      {required this.endToken})
-      : super("InvalidTopLevelDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentTopLevelMemberBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentTopLevelMemberBegin(DirectParserASTType type,
-      {required this.token})
-      : super("TopLevelMember", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFieldsBegin extends DirectParserASTContent {
-  final DeclarationKind declarationKind;
-  final Token? abstractToken;
-  final Token? externalToken;
-  final Token? staticToken;
-  final Token? covariantToken;
-  final Token? lateToken;
-  final Token? varFinalOrConst;
-  final Token lastConsumed;
-
-  DirectParserASTContentFieldsBegin(DirectParserASTType type,
-      {required this.declarationKind,
-      this.abstractToken,
-      this.externalToken,
-      this.staticToken,
-      this.covariantToken,
-      this.lateToken,
-      this.varFinalOrConst,
-      required this.lastConsumed})
-      : super("Fields", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "declarationKind": declarationKind,
-        "abstractToken": abstractToken,
-        "externalToken": externalToken,
-        "staticToken": staticToken,
-        "covariantToken": covariantToken,
-        "lateToken": lateToken,
-        "varFinalOrConst": varFinalOrConst,
-        "lastConsumed": lastConsumed,
-      };
-}
-
-class DirectParserASTContentTopLevelFieldsEnd extends DirectParserASTContent {
-  final Token? externalToken;
-  final Token? staticToken;
-  final Token? covariantToken;
-  final Token? lateToken;
-  final Token? varFinalOrConst;
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentTopLevelFieldsEnd(DirectParserASTType type,
-      {this.externalToken,
-      this.staticToken,
-      this.covariantToken,
-      this.lateToken,
-      this.varFinalOrConst,
-      required this.count,
-      required this.beginToken,
-      required this.endToken})
-      : super("TopLevelFields", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "externalToken": externalToken,
-        "staticToken": staticToken,
-        "covariantToken": covariantToken,
-        "lateToken": lateToken,
-        "varFinalOrConst": varFinalOrConst,
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentTopLevelMethodBegin extends DirectParserASTContent {
-  final Token lastConsumed;
-  final Token? externalToken;
-
-  DirectParserASTContentTopLevelMethodBegin(DirectParserASTType type,
-      {required this.lastConsumed, this.externalToken})
-      : super("TopLevelMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "lastConsumed": lastConsumed,
-        "externalToken": externalToken,
-      };
-}
-
-class DirectParserASTContentTopLevelMethodEnd extends DirectParserASTContent {
-  final Token beginToken;
-  final Token? getOrSet;
-  final Token endToken;
-
-  DirectParserASTContentTopLevelMethodEnd(DirectParserASTType type,
-      {required this.beginToken, this.getOrSet, required this.endToken})
-      : super("TopLevelMethod", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "getOrSet": getOrSet,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentTryStatementBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentTryStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("TryStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentCaseMatchHandle extends DirectParserASTContent {
-  final Token caseKeyword;
-  final Token colon;
-
-  DirectParserASTContentCaseMatchHandle(DirectParserASTType type,
-      {required this.caseKeyword, required this.colon})
-      : super("CaseMatch", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "caseKeyword": caseKeyword,
-        "colon": colon,
-      };
-}
-
-class DirectParserASTContentCatchClauseBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentCatchClauseBegin(DirectParserASTType type,
-      {required this.token})
-      : super("CatchClause", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentCatchClauseEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentCatchClauseEnd(DirectParserASTType type,
-      {required this.token})
-      : super("CatchClause", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentCatchBlockHandle extends DirectParserASTContent {
-  final Token? onKeyword;
-  final Token? catchKeyword;
-  final Token? comma;
-
-  DirectParserASTContentCatchBlockHandle(DirectParserASTType type,
-      {this.onKeyword, this.catchKeyword, this.comma})
-      : super("CatchBlock", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "onKeyword": onKeyword,
-        "catchKeyword": catchKeyword,
-        "comma": comma,
-      };
-}
-
-class DirectParserASTContentFinallyBlockHandle extends DirectParserASTContent {
-  final Token finallyKeyword;
-
-  DirectParserASTContentFinallyBlockHandle(DirectParserASTType type,
-      {required this.finallyKeyword})
-      : super("FinallyBlock", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "finallyKeyword": finallyKeyword,
-      };
-}
-
-class DirectParserASTContentTryStatementEnd extends DirectParserASTContent {
-  final int catchCount;
-  final Token tryKeyword;
-  final Token? finallyKeyword;
-
-  DirectParserASTContentTryStatementEnd(DirectParserASTType type,
-      {required this.catchCount, required this.tryKeyword, this.finallyKeyword})
-      : super("TryStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "catchCount": catchCount,
-        "tryKeyword": tryKeyword,
-        "finallyKeyword": finallyKeyword,
-      };
-}
-
-class DirectParserASTContentTypeHandle extends DirectParserASTContent {
-  final Token beginToken;
-  final Token? questionMark;
-
-  DirectParserASTContentTypeHandle(DirectParserASTType type,
-      {required this.beginToken, this.questionMark})
-      : super("Type", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "questionMark": questionMark,
-      };
-}
-
-class DirectParserASTContentNonNullAssertExpressionHandle
-    extends DirectParserASTContent {
-  final Token bang;
-
-  DirectParserASTContentNonNullAssertExpressionHandle(DirectParserASTType type,
-      {required this.bang})
-      : super("NonNullAssertExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "bang": bang,
-      };
-}
-
-class DirectParserASTContentNoNameHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoNameHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NoName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFunctionTypeBegin extends DirectParserASTContent {
-  final Token beginToken;
-
-  DirectParserASTContentFunctionTypeBegin(DirectParserASTType type,
-      {required this.beginToken})
-      : super("FunctionType", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-      };
-}
-
-class DirectParserASTContentFunctionTypeEnd extends DirectParserASTContent {
-  final Token functionToken;
-  final Token? questionMark;
-
-  DirectParserASTContentFunctionTypeEnd(DirectParserASTType type,
-      {required this.functionToken, this.questionMark})
-      : super("FunctionType", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "functionToken": functionToken,
-        "questionMark": questionMark,
-      };
-}
-
-class DirectParserASTContentTypeArgumentsBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentTypeArgumentsBegin(DirectParserASTType type,
-      {required this.token})
-      : super("TypeArguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentTypeArgumentsEnd extends DirectParserASTContent {
-  final int count;
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentTypeArgumentsEnd(DirectParserASTType type,
-      {required this.count, required this.beginToken, required this.endToken})
-      : super("TypeArguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentInvalidTypeArgumentsHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentInvalidTypeArgumentsHandle(DirectParserASTType type,
-      {required this.token})
-      : super("InvalidTypeArguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNoTypeArgumentsHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoTypeArgumentsHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NoTypeArguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentTypeVariableBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentTypeVariableBegin(DirectParserASTType type,
-      {required this.token})
-      : super("TypeVariable", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentTypeVariablesDefinedHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final int count;
-
-  DirectParserASTContentTypeVariablesDefinedHandle(DirectParserASTType type,
-      {required this.token, required this.count})
-      : super("TypeVariablesDefined", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "count": count,
-      };
-}
-
-class DirectParserASTContentTypeVariableEnd extends DirectParserASTContent {
-  final Token token;
-  final int index;
-  final Token? extendsOrSuper;
-  final Token? variance;
-
-  DirectParserASTContentTypeVariableEnd(DirectParserASTType type,
-      {required this.token,
-      required this.index,
-      this.extendsOrSuper,
-      this.variance})
-      : super("TypeVariable", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "index": index,
-        "extendsOrSuper": extendsOrSuper,
-        "variance": variance,
-      };
-}
-
-class DirectParserASTContentTypeVariablesBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentTypeVariablesBegin(DirectParserASTType type,
-      {required this.token})
-      : super("TypeVariables", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentTypeVariablesEnd extends DirectParserASTContent {
-  final Token beginToken;
-  final Token endToken;
-
-  DirectParserASTContentTypeVariablesEnd(DirectParserASTType type,
-      {required this.beginToken, required this.endToken})
-      : super("TypeVariables", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentFunctionExpressionBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentFunctionExpressionBegin(DirectParserASTType type,
-      {required this.token})
-      : super("FunctionExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFunctionExpressionEnd
-    extends DirectParserASTContent {
-  final Token beginToken;
-  final Token token;
-
-  DirectParserASTContentFunctionExpressionEnd(DirectParserASTType type,
-      {required this.beginToken, required this.token})
-      : super("FunctionExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentVariablesDeclarationBegin
-    extends DirectParserASTContent {
-  final Token token;
-  final Token? lateToken;
-  final Token? varFinalOrConst;
-
-  DirectParserASTContentVariablesDeclarationBegin(DirectParserASTType type,
-      {required this.token, this.lateToken, this.varFinalOrConst})
-      : super("VariablesDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "lateToken": lateToken,
-        "varFinalOrConst": varFinalOrConst,
-      };
-}
-
-class DirectParserASTContentVariablesDeclarationEnd
-    extends DirectParserASTContent {
-  final int count;
-  final Token? endToken;
-
-  DirectParserASTContentVariablesDeclarationEnd(DirectParserASTType type,
-      {required this.count, this.endToken})
-      : super("VariablesDeclaration", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentWhileStatementBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentWhileStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("WhileStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentWhileStatementEnd extends DirectParserASTContent {
-  final Token whileKeyword;
-  final Token endToken;
-
-  DirectParserASTContentWhileStatementEnd(DirectParserASTType type,
-      {required this.whileKeyword, required this.endToken})
-      : super("WhileStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "whileKeyword": whileKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentAsOperatorTypeBegin extends DirectParserASTContent {
-  final Token operator;
-
-  DirectParserASTContentAsOperatorTypeBegin(DirectParserASTType type,
-      {required this.operator})
-      : super("AsOperatorType", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "operator": operator,
-      };
-}
-
-class DirectParserASTContentAsOperatorTypeEnd extends DirectParserASTContent {
-  final Token operator;
-
-  DirectParserASTContentAsOperatorTypeEnd(DirectParserASTType type,
-      {required this.operator})
-      : super("AsOperatorType", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "operator": operator,
-      };
-}
-
-class DirectParserASTContentAsOperatorHandle extends DirectParserASTContent {
-  final Token operator;
-
-  DirectParserASTContentAsOperatorHandle(DirectParserASTType type,
-      {required this.operator})
-      : super("AsOperator", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "operator": operator,
-      };
-}
-
-class DirectParserASTContentAssignmentExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentAssignmentExpressionHandle(DirectParserASTType type,
-      {required this.token})
-      : super("AssignmentExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentBinaryExpressionBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentBinaryExpressionBegin(DirectParserASTType type,
-      {required this.token})
-      : super("BinaryExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentBinaryExpressionEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentBinaryExpressionEnd(DirectParserASTType type,
-      {required this.token})
-      : super("BinaryExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentEndingBinaryExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentEndingBinaryExpressionHandle(DirectParserASTType type,
-      {required this.token})
-      : super("EndingBinaryExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentConditionalExpressionBegin
-    extends DirectParserASTContent {
-  final Token question;
-
-  DirectParserASTContentConditionalExpressionBegin(DirectParserASTType type,
-      {required this.question})
-      : super("ConditionalExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "question": question,
-      };
-}
-
-class DirectParserASTContentConditionalExpressionColonHandle
-    extends DirectParserASTContent {
-  DirectParserASTContentConditionalExpressionColonHandle(
-      DirectParserASTType type)
-      : super("ConditionalExpressionColon", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentConditionalExpressionEnd
-    extends DirectParserASTContent {
-  final Token question;
-  final Token colon;
-
-  DirectParserASTContentConditionalExpressionEnd(DirectParserASTType type,
-      {required this.question, required this.colon})
-      : super("ConditionalExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "question": question,
-        "colon": colon,
-      };
-}
-
-class DirectParserASTContentConstExpressionBegin
-    extends DirectParserASTContent {
-  final Token constKeyword;
-
-  DirectParserASTContentConstExpressionBegin(DirectParserASTType type,
-      {required this.constKeyword})
-      : super("ConstExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "constKeyword": constKeyword,
-      };
-}
-
-class DirectParserASTContentConstExpressionEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentConstExpressionEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ConstExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentConstFactoryHandle extends DirectParserASTContent {
-  final Token constKeyword;
-
-  DirectParserASTContentConstFactoryHandle(DirectParserASTType type,
-      {required this.constKeyword})
-      : super("ConstFactory", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "constKeyword": constKeyword,
-      };
-}
-
-class DirectParserASTContentForControlFlowBegin extends DirectParserASTContent {
-  final Token? awaitToken;
-  final Token forToken;
-
-  DirectParserASTContentForControlFlowBegin(DirectParserASTType type,
-      {this.awaitToken, required this.forToken})
-      : super("ForControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "awaitToken": awaitToken,
-        "forToken": forToken,
-      };
-}
-
-class DirectParserASTContentForControlFlowEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForControlFlowEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ForControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentForInControlFlowEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentForInControlFlowEnd(DirectParserASTType type,
-      {required this.token})
-      : super("ForInControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentIfControlFlowBegin extends DirectParserASTContent {
-  final Token ifToken;
-
-  DirectParserASTContentIfControlFlowBegin(DirectParserASTType type,
-      {required this.ifToken})
-      : super("IfControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "ifToken": ifToken,
-      };
-}
-
-class DirectParserASTContentThenControlFlowHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentThenControlFlowHandle(DirectParserASTType type,
-      {required this.token})
-      : super("ThenControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentElseControlFlowHandle
-    extends DirectParserASTContent {
-  final Token elseToken;
-
-  DirectParserASTContentElseControlFlowHandle(DirectParserASTType type,
-      {required this.elseToken})
-      : super("ElseControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "elseToken": elseToken,
-      };
-}
-
-class DirectParserASTContentIfControlFlowEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentIfControlFlowEnd(DirectParserASTType type,
-      {required this.token})
-      : super("IfControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentIfElseControlFlowEnd
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentIfElseControlFlowEnd(DirectParserASTType type,
-      {required this.token})
-      : super("IfElseControlFlow", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentSpreadExpressionHandle
-    extends DirectParserASTContent {
-  final Token spreadToken;
-
-  DirectParserASTContentSpreadExpressionHandle(DirectParserASTType type,
-      {required this.spreadToken})
-      : super("SpreadExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "spreadToken": spreadToken,
-      };
-}
-
-class DirectParserASTContentFunctionTypedFormalParameterBegin
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentFunctionTypedFormalParameterBegin(
-      DirectParserASTType type,
-      {required this.token})
-      : super("FunctionTypedFormalParameter", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFunctionTypedFormalParameterEnd
-    extends DirectParserASTContent {
-  final Token nameToken;
-  final Token? question;
-
-  DirectParserASTContentFunctionTypedFormalParameterEnd(
-      DirectParserASTType type,
-      {required this.nameToken,
-      this.question})
-      : super("FunctionTypedFormalParameter", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "nameToken": nameToken,
-        "question": question,
-      };
-}
-
-class DirectParserASTContentIdentifierHandle extends DirectParserASTContent {
-  final Token token;
-  final IdentifierContext context;
-
-  DirectParserASTContentIdentifierHandle(DirectParserASTType type,
-      {required this.token, required this.context})
-      : super("Identifier", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "context": context,
-      };
-}
-
-class DirectParserASTContentShowHideIdentifierHandle
-    extends DirectParserASTContent {
-  final Token? modifier;
-  final Token identifier;
-
-  DirectParserASTContentShowHideIdentifierHandle(DirectParserASTType type,
-      {this.modifier, required this.identifier})
-      : super("ShowHideIdentifier", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "modifier": modifier,
-        "identifier": identifier,
-      };
-}
-
-class DirectParserASTContentIndexedExpressionHandle
-    extends DirectParserASTContent {
-  final Token? question;
-  final Token openSquareBracket;
-  final Token closeSquareBracket;
-
-  DirectParserASTContentIndexedExpressionHandle(DirectParserASTType type,
-      {this.question,
-      required this.openSquareBracket,
-      required this.closeSquareBracket})
-      : super("IndexedExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "question": question,
-        "openSquareBracket": openSquareBracket,
-        "closeSquareBracket": closeSquareBracket,
-      };
-}
-
-class DirectParserASTContentIsOperatorTypeBegin extends DirectParserASTContent {
-  final Token operator;
-
-  DirectParserASTContentIsOperatorTypeBegin(DirectParserASTType type,
-      {required this.operator})
-      : super("IsOperatorType", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "operator": operator,
-      };
-}
-
-class DirectParserASTContentIsOperatorTypeEnd extends DirectParserASTContent {
-  final Token operator;
-
-  DirectParserASTContentIsOperatorTypeEnd(DirectParserASTType type,
-      {required this.operator})
-      : super("IsOperatorType", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "operator": operator,
-      };
-}
-
-class DirectParserASTContentIsOperatorHandle extends DirectParserASTContent {
-  final Token isOperator;
-  final Token? not;
-
-  DirectParserASTContentIsOperatorHandle(DirectParserASTType type,
-      {required this.isOperator, this.not})
-      : super("IsOperator", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "isOperator": isOperator,
-        "not": not,
-      };
-}
-
-class DirectParserASTContentLiteralBoolHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLiteralBoolHandle(DirectParserASTType type,
-      {required this.token})
-      : super("LiteralBool", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentBreakStatementHandle
-    extends DirectParserASTContent {
-  final bool hasTarget;
-  final Token breakKeyword;
-  final Token endToken;
-
-  DirectParserASTContentBreakStatementHandle(DirectParserASTType type,
-      {required this.hasTarget,
-      required this.breakKeyword,
-      required this.endToken})
-      : super("BreakStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "hasTarget": hasTarget,
-        "breakKeyword": breakKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentContinueStatementHandle
-    extends DirectParserASTContent {
-  final bool hasTarget;
-  final Token continueKeyword;
-  final Token endToken;
-
-  DirectParserASTContentContinueStatementHandle(DirectParserASTType type,
-      {required this.hasTarget,
-      required this.continueKeyword,
-      required this.endToken})
-      : super("ContinueStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "hasTarget": hasTarget,
-        "continueKeyword": continueKeyword,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentEmptyStatementHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentEmptyStatementHandle(DirectParserASTType type,
-      {required this.token})
-      : super("EmptyStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentAssertBegin extends DirectParserASTContent {
-  final Token assertKeyword;
-  final Assert kind;
-
-  DirectParserASTContentAssertBegin(DirectParserASTType type,
-      {required this.assertKeyword, required this.kind})
-      : super("Assert", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "assertKeyword": assertKeyword,
-        "kind": kind,
-      };
-}
-
-class DirectParserASTContentAssertEnd extends DirectParserASTContent {
-  final Token assertKeyword;
-  final Assert kind;
-  final Token leftParenthesis;
-  final Token? commaToken;
-  final Token semicolonToken;
-
-  DirectParserASTContentAssertEnd(DirectParserASTType type,
-      {required this.assertKeyword,
-      required this.kind,
-      required this.leftParenthesis,
-      this.commaToken,
-      required this.semicolonToken})
-      : super("Assert", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "assertKeyword": assertKeyword,
-        "kind": kind,
-        "leftParenthesis": leftParenthesis,
-        "commaToken": commaToken,
-        "semicolonToken": semicolonToken,
-      };
-}
-
-class DirectParserASTContentLiteralDoubleHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLiteralDoubleHandle(DirectParserASTType type,
-      {required this.token})
-      : super("LiteralDouble", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentLiteralIntHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLiteralIntHandle(DirectParserASTType type,
-      {required this.token})
-      : super("LiteralInt", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentLiteralListHandle extends DirectParserASTContent {
-  final int count;
-  final Token leftBracket;
-  final Token? constKeyword;
-  final Token rightBracket;
-
-  DirectParserASTContentLiteralListHandle(DirectParserASTType type,
-      {required this.count,
-      required this.leftBracket,
-      this.constKeyword,
-      required this.rightBracket})
-      : super("LiteralList", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "leftBracket": leftBracket,
-        "constKeyword": constKeyword,
-        "rightBracket": rightBracket,
-      };
-}
-
-class DirectParserASTContentLiteralSetOrMapHandle
-    extends DirectParserASTContent {
-  final int count;
-  final Token leftBrace;
-  final Token? constKeyword;
-  final Token rightBrace;
-  final bool hasSetEntry;
-
-  DirectParserASTContentLiteralSetOrMapHandle(DirectParserASTType type,
-      {required this.count,
-      required this.leftBrace,
-      this.constKeyword,
-      required this.rightBrace,
-      required this.hasSetEntry})
-      : super("LiteralSetOrMap", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "count": count,
-        "leftBrace": leftBrace,
-        "constKeyword": constKeyword,
-        "rightBrace": rightBrace,
-        "hasSetEntry": hasSetEntry,
-      };
-}
-
-class DirectParserASTContentLiteralNullHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentLiteralNullHandle(DirectParserASTType type,
-      {required this.token})
-      : super("LiteralNull", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNativeClauseHandle extends DirectParserASTContent {
-  final Token nativeToken;
-  final bool hasName;
-
-  DirectParserASTContentNativeClauseHandle(DirectParserASTType type,
-      {required this.nativeToken, required this.hasName})
-      : super("NativeClause", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "nativeToken": nativeToken,
-        "hasName": hasName,
-      };
-}
-
-class DirectParserASTContentNamedArgumentHandle extends DirectParserASTContent {
-  final Token colon;
-
-  DirectParserASTContentNamedArgumentHandle(DirectParserASTType type,
-      {required this.colon})
-      : super("NamedArgument", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "colon": colon,
-      };
-}
-
-class DirectParserASTContentNewExpressionBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNewExpressionBegin(DirectParserASTType type,
-      {required this.token})
-      : super("NewExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNewExpressionEnd extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNewExpressionEnd(DirectParserASTType type,
-      {required this.token})
-      : super("NewExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNoArgumentsHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoArgumentsHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NoArguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoConstructorReferenceContinuationAfterTypeArgumentsHandle(
-      DirectParserASTType type,
-      {required this.token})
-      : super("NoConstructorReferenceContinuationAfterTypeArguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNoTypeHandle extends DirectParserASTContent {
-  final Token lastConsumed;
-
-  DirectParserASTContentNoTypeHandle(DirectParserASTType type,
-      {required this.lastConsumed})
-      : super("NoType", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "lastConsumed": lastConsumed,
-      };
-}
-
-class DirectParserASTContentNoTypeVariablesHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNoTypeVariablesHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NoTypeVariables", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentOperatorHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentOperatorHandle(DirectParserASTType type,
-      {required this.token})
-      : super("Operator", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentSymbolVoidHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentSymbolVoidHandle(DirectParserASTType type,
-      {required this.token})
-      : super("SymbolVoid", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentOperatorNameHandle extends DirectParserASTContent {
-  final Token operatorKeyword;
-  final Token token;
-
-  DirectParserASTContentOperatorNameHandle(DirectParserASTType type,
-      {required this.operatorKeyword, required this.token})
-      : super("OperatorName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "operatorKeyword": operatorKeyword,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentInvalidOperatorNameHandle
-    extends DirectParserASTContent {
-  final Token operatorKeyword;
-  final Token token;
-
-  DirectParserASTContentInvalidOperatorNameHandle(DirectParserASTType type,
-      {required this.operatorKeyword, required this.token})
-      : super("InvalidOperatorName", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "operatorKeyword": operatorKeyword,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentParenthesizedConditionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentParenthesizedConditionHandle(DirectParserASTType type,
-      {required this.token})
-      : super("ParenthesizedCondition", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentParenthesizedExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentParenthesizedExpressionHandle(DirectParserASTType type,
-      {required this.token})
-      : super("ParenthesizedExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentQualifiedHandle extends DirectParserASTContent {
-  final Token period;
-
-  DirectParserASTContentQualifiedHandle(DirectParserASTType type,
-      {required this.period})
-      : super("Qualified", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "period": period,
-      };
-}
-
-class DirectParserASTContentStringPartHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentStringPartHandle(DirectParserASTType type,
-      {required this.token})
-      : super("StringPart", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentSuperExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final IdentifierContext context;
-
-  DirectParserASTContentSuperExpressionHandle(DirectParserASTType type,
-      {required this.token, required this.context})
-      : super("SuperExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "context": context,
-      };
-}
-
-class DirectParserASTContentSwitchCaseBegin extends DirectParserASTContent {
-  final int labelCount;
-  final int expressionCount;
-  final Token firstToken;
-
-  DirectParserASTContentSwitchCaseBegin(DirectParserASTType type,
-      {required this.labelCount,
-      required this.expressionCount,
-      required this.firstToken})
-      : super("SwitchCase", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "labelCount": labelCount,
-        "expressionCount": expressionCount,
-        "firstToken": firstToken,
-      };
-}
-
-class DirectParserASTContentSwitchCaseEnd extends DirectParserASTContent {
-  final int labelCount;
-  final int expressionCount;
-  final Token? defaultKeyword;
-  final Token? colonAfterDefault;
-  final int statementCount;
-  final Token firstToken;
-  final Token endToken;
-
-  DirectParserASTContentSwitchCaseEnd(DirectParserASTType type,
-      {required this.labelCount,
-      required this.expressionCount,
-      this.defaultKeyword,
-      this.colonAfterDefault,
-      required this.statementCount,
-      required this.firstToken,
-      required this.endToken})
-      : super("SwitchCase", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "labelCount": labelCount,
-        "expressionCount": expressionCount,
-        "defaultKeyword": defaultKeyword,
-        "colonAfterDefault": colonAfterDefault,
-        "statementCount": statementCount,
-        "firstToken": firstToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentThisExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final IdentifierContext context;
-
-  DirectParserASTContentThisExpressionHandle(DirectParserASTType type,
-      {required this.token, required this.context})
-      : super("ThisExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "context": context,
-      };
-}
-
-class DirectParserASTContentUnaryPostfixAssignmentExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentUnaryPostfixAssignmentExpressionHandle(
-      DirectParserASTType type,
-      {required this.token})
-      : super("UnaryPostfixAssignmentExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentUnaryPrefixExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentUnaryPrefixExpressionHandle(DirectParserASTType type,
-      {required this.token})
-      : super("UnaryPrefixExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentUnaryPrefixAssignmentExpressionHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentUnaryPrefixAssignmentExpressionHandle(
-      DirectParserASTType type,
-      {required this.token})
-      : super("UnaryPrefixAssignmentExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFormalParameterDefaultValueExpressionBegin
-    extends DirectParserASTContent {
-  DirectParserASTContentFormalParameterDefaultValueExpressionBegin(
-      DirectParserASTType type)
-      : super("FormalParameterDefaultValueExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentFormalParameterDefaultValueExpressionEnd
-    extends DirectParserASTContent {
-  DirectParserASTContentFormalParameterDefaultValueExpressionEnd(
-      DirectParserASTType type)
-      : super("FormalParameterDefaultValueExpression", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentValuedFormalParameterHandle
-    extends DirectParserASTContent {
-  final Token equals;
-  final Token token;
-
-  DirectParserASTContentValuedFormalParameterHandle(DirectParserASTType type,
-      {required this.equals, required this.token})
-      : super("ValuedFormalParameter", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "equals": equals,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentFormalParameterWithoutValueHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentFormalParameterWithoutValueHandle(
-      DirectParserASTType type,
-      {required this.token})
-      : super("FormalParameterWithoutValue", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentVoidKeywordHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentVoidKeywordHandle(DirectParserASTType type,
-      {required this.token})
-      : super("VoidKeyword", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentVoidKeywordWithTypeArgumentsHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentVoidKeywordWithTypeArgumentsHandle(
-      DirectParserASTType type,
-      {required this.token})
-      : super("VoidKeywordWithTypeArguments", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentYieldStatementBegin extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentYieldStatementBegin(DirectParserASTType type,
-      {required this.token})
-      : super("YieldStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentYieldStatementEnd extends DirectParserASTContent {
-  final Token yieldToken;
-  final Token? starToken;
-  final Token endToken;
-
-  DirectParserASTContentYieldStatementEnd(DirectParserASTType type,
-      {required this.yieldToken, this.starToken, required this.endToken})
-      : super("YieldStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "yieldToken": yieldToken,
-        "starToken": starToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentInvalidYieldStatementEnd
-    extends DirectParserASTContent {
-  final Token beginToken;
-  final Token? starToken;
-  final Token endToken;
-  final MessageCode errorCode;
-
-  DirectParserASTContentInvalidYieldStatementEnd(DirectParserASTType type,
-      {required this.beginToken,
-      this.starToken,
-      required this.endToken,
-      required this.errorCode})
-      : super("InvalidYieldStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "beginToken": beginToken,
-        "starToken": starToken,
-        "endToken": endToken,
-        "errorCode": errorCode,
-      };
-}
-
-class DirectParserASTContentRecoverableErrorHandle
-    extends DirectParserASTContent {
-  final Message message;
-  final Token startToken;
-  final Token endToken;
-
-  DirectParserASTContentRecoverableErrorHandle(DirectParserASTType type,
-      {required this.message, required this.startToken, required this.endToken})
-      : super("RecoverableError", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "message": message,
-        "startToken": startToken,
-        "endToken": endToken,
-      };
-}
-
-class DirectParserASTContentErrorTokenHandle extends DirectParserASTContent {
-  final ErrorToken token;
-
-  DirectParserASTContentErrorTokenHandle(DirectParserASTType type,
-      {required this.token})
-      : super("ErrorToken", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentUnescapeErrorHandle extends DirectParserASTContent {
-  final Message message;
-  final Token location;
-  final int stringOffset;
-  final int length;
-
-  DirectParserASTContentUnescapeErrorHandle(DirectParserASTType type,
-      {required this.message,
-      required this.location,
-      required this.stringOffset,
-      required this.length})
-      : super("UnescapeError", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "message": message,
-        "location": location,
-        "stringOffset": stringOffset,
-        "length": length,
-      };
-}
-
-class DirectParserASTContentInvalidStatementHandle
-    extends DirectParserASTContent {
-  final Token token;
-  final Message message;
-
-  DirectParserASTContentInvalidStatementHandle(DirectParserASTType type,
-      {required this.token, required this.message})
-      : super("InvalidStatement", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-        "message": message,
-      };
-}
-
-class DirectParserASTContentScriptHandle extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentScriptHandle(DirectParserASTType type,
-      {required this.token})
-      : super("Script", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
-
-class DirectParserASTContentCommentReferenceTextHandle
-    extends DirectParserASTContent {
-  final String referenceSource;
-  final int referenceOffset;
-
-  DirectParserASTContentCommentReferenceTextHandle(DirectParserASTType type,
-      {required this.referenceSource, required this.referenceOffset})
-      : super("CommentReferenceText", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "referenceSource": referenceSource,
-        "referenceOffset": referenceOffset,
-      };
-}
-
-class DirectParserASTContentCommentReferenceHandle
-    extends DirectParserASTContent {
-  final Token? newKeyword;
-  final Token? prefix;
-  final Token? period;
-  final Token token;
-
-  DirectParserASTContentCommentReferenceHandle(DirectParserASTType type,
-      {this.newKeyword, this.prefix, this.period, required this.token})
-      : super("CommentReference", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "newKeyword": newKeyword,
-        "prefix": prefix,
-        "period": period,
-        "token": token,
-      };
-}
-
-class DirectParserASTContentNoCommentReferenceHandle
-    extends DirectParserASTContent {
-  DirectParserASTContentNoCommentReferenceHandle(DirectParserASTType type)
-      : super("NoCommentReference", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {};
-}
-
-class DirectParserASTContentTypeArgumentApplicationHandle
-    extends DirectParserASTContent {
-  final Token openAngleBracket;
-
-  DirectParserASTContentTypeArgumentApplicationHandle(DirectParserASTType type,
-      {required this.openAngleBracket})
-      : super("TypeArgumentApplication", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "openAngleBracket": openAngleBracket,
-      };
-}
-
-class DirectParserASTContentNewAsIdentifierHandle
-    extends DirectParserASTContent {
-  final Token token;
-
-  DirectParserASTContentNewAsIdentifierHandle(DirectParserASTType type,
-      {required this.token})
-      : super("NewAsIdentifier", type);
-
-  @override
-  Map<String, Object?> get deprecatedArguments => {
-        "token": token,
-      };
-}
diff --git a/pkg/front_end/lib/src/fasta/util/outline_extractor.dart b/pkg/front_end/lib/src/fasta/util/outline_extractor.dart
new file mode 100644
index 0000000..8caa3f6
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/util/outline_extractor.dart
@@ -0,0 +1,941 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:_fe_analyzer_shared/src/scanner/abstract_scanner.dart'
+    show ScannerConfiguration;
+import 'package:front_end/src/api_prototype/compiler_options.dart';
+import 'package:front_end/src/api_prototype/file_system.dart';
+import 'package:front_end/src/base/processed_options.dart';
+import 'package:front_end/src/fasta/compiler_context.dart';
+import 'package:front_end/src/fasta/uri_translator.dart';
+import 'package:front_end/src/fasta/util/parser_ast_helper.dart';
+import 'package:front_end/src/fasta/util/textual_outline.dart';
+import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
+import 'package:kernel/target/targets.dart';
+
+import "parser_ast.dart";
+import "abstracted_ast_nodes.dart";
+
+// Overall TODO(s):
+// * If entry is given as fileuri but exists as different import uri...
+//   Does that matter?
+// * Setters vs non-setters with naming conflicts.
+// * -> also these might be found on "different levels", e.g. the setter might
+//      be in the class and the getter might be in an import.
+// * show/hide on imports and exports.
+// * Handle importing/exporting non-existing files.
+// * Tests.
+// * Maybe bypass the direct-from-parser-ast stuff for speed?
+// * Probably some of the special classes can be combined if we want to
+//   (e.g. Class and Mixin).
+// * Extensions --- we currently basically mark all we see.
+//    => Could be perhaps only include them if the class they're talking about
+//       is included? (or we don't know).
+// * E.g. "factory Abc.b() => Abc3();" is the same as
+//   "factory Abc.b() { return Abc3(); }" and Abc3 shouldn't be marked by it.
+//    -> This is basically a rough edge on the textual outline though.
+//    -> Also, the same applies to other instances of "=>".
+// * It shouldn't lookup private stuff in other libraries.
+// * Could there be made a distinction between for instance
+//   `IdentifierContext.typeReference` and `IdentifierContext.expression`?
+//   => one might not have to include content of classes that only talk about
+//      typeReference I think.
+
+Future<void> main(List<String> args) async {
+  if (args.length != 2) {
+    throw "Needs 2 arguments: packages file/dir and file to process.";
+  }
+  Uri packages = Uri.base.resolve(args[0]);
+  Uri file = Uri.base.resolve(args[1]);
+  for (int i = 0; i < 1; i++) {
+    Stopwatch stopwatch = new Stopwatch()..start();
+    await extractOutline([file], packages: packages, verbosityLevel: 40);
+    print("Finished in ${stopwatch.elapsedMilliseconds} ms "
+        "(textual outline was "
+        "${latestProcessor!.textualOutlineStopwatch.elapsedMilliseconds} ms)"
+        "(get ast was "
+        "${latestProcessor!.getAstStopwatch.elapsedMilliseconds} ms)"
+        "(extract identifier was "
+        "${latestProcessor!.extractIdentifierStopwatch.elapsedMilliseconds} ms)"
+        "");
+  }
+}
+
+_Processor? latestProcessor;
+
+Future<Map<Uri, String>> extractOutline(List<Uri> entryPointUris,
+    {Uri? sdk,
+    required Uri? packages,
+    Uri? platform,
+    Target? target,
+    int verbosityLevel: 0}) {
+  CompilerOptions options = new CompilerOptions()
+    ..target = target
+    ..packagesFileUri = packages
+    ..sdkSummary = platform
+    ..sdkRoot = sdk;
+  ProcessedOptions pOptions =
+      new ProcessedOptions(options: options, inputs: entryPointUris);
+  return CompilerContext.runWithOptions(pOptions, (CompilerContext c) async {
+    FileSystem fileSystem = c.options.fileSystem;
+    UriTranslator uriTranslator = await c.options.getUriTranslator();
+    _Processor processor =
+        new _Processor(verbosityLevel, fileSystem, uriTranslator);
+    latestProcessor = processor;
+    List<TopLevel> entryPoints = [];
+    for (Uri entryPointUri in entryPointUris) {
+      TopLevel entryPoint = await processor.preprocessUri(entryPointUri);
+      entryPoints.add(entryPoint);
+    }
+    return await processor.calculate(entryPoints);
+  });
+}
+
+class _Processor {
+  final FileSystem fileSystem;
+  final UriTranslator uriTranslator;
+  final int verbosityLevel;
+
+  final Stopwatch textualOutlineStopwatch = new Stopwatch();
+  final Stopwatch getAstStopwatch = new Stopwatch();
+  final Stopwatch extractIdentifierStopwatch = new Stopwatch();
+
+  Map<Uri, TopLevel> parsed = {};
+
+  _Processor(this.verbosityLevel, this.fileSystem, this.uriTranslator);
+
+  void log(String s) {
+    if (verbosityLevel <= 0) return;
+    print(s);
+  }
+
+  Future<TopLevel> preprocessUri(Uri importUri, {Uri? partOf}) async {
+    if (verbosityLevel >= 20) log("$importUri =>");
+    Uri fileUri = importUri;
+    if (importUri.scheme == "package") {
+      fileUri = uriTranslator.translate(importUri)!;
+    }
+    if (verbosityLevel >= 20) log("$fileUri");
+    final List<int> bytes =
+        await fileSystem.entityForUri(fileUri).readAsBytes();
+    // TODO: Support updating the configuration; also default it to match
+    // the package version.
+    final ScannerConfiguration configuration = new ScannerConfiguration(
+        enableExtensionMethods: true,
+        enableNonNullable: true,
+        enableTripleShift: true);
+    textualOutlineStopwatch.start();
+    final String? outlined = textualOutline(bytes, configuration);
+    textualOutlineStopwatch.stop();
+    if (outlined == null) throw "Textual outline returned null";
+    final List<int> bytes2 = utf8.encode(outlined);
+    getAstStopwatch.start();
+    List<Token> languageVersionsSeen = [];
+    final ParserAstNode ast = getAST(bytes2,
+        enableExtensionMethods: configuration.enableExtensionMethods,
+        enableNonNullable: configuration.enableNonNullable,
+        enableTripleShift: configuration.enableTripleShift,
+        languageVersionsSeen: languageVersionsSeen);
+    getAstStopwatch.stop();
+
+    _ParserAstVisitor visitor = new _ParserAstVisitor(
+        verbosityLevel, outlined, importUri, partOf, ast, languageVersionsSeen);
+    TopLevel topLevel = visitor.currentContainer as TopLevel;
+    if (parsed[importUri] != null) throw "$importUri already set?!?";
+    parsed[importUri] = topLevel;
+    visitor.accept(ast);
+    topLevel.buildScope();
+
+    _IdentifierExtractor identifierExtractor = new _IdentifierExtractor();
+    extractIdentifierStopwatch.start();
+    identifierExtractor.extract(ast);
+    extractIdentifierStopwatch.stop();
+    for (IdentifierHandle identifier in identifierExtractor.identifiers) {
+      if (identifier.context == IdentifierContext.typeVariableDeclaration) {
+        // Hack: Put type variable declarations into scope so any overlap in
+        // name doesn't mark usages (e.g. a class E shouldn't be marked if we're
+        // talking about the type variable E).
+        ParserAstNode content = identifier;
+        AstNode? nearestAstNode = visitor.map[content];
+        while (nearestAstNode == null && content.parent != null) {
+          content = content.parent!;
+          nearestAstNode = visitor.map[content];
+        }
+        if (nearestAstNode == null) {
+          content = identifier;
+          nearestAstNode = visitor.map[content];
+          while (nearestAstNode == null && content.parent != null) {
+            content = content.parent!;
+            nearestAstNode = visitor.map[content];
+          }
+
+          StringBuffer sb = new StringBuffer();
+          Token t = identifier.token;
+          // for(int i = 0; i < 10; i++) {
+          //   t = t.previous!;
+          // }
+          for (int i = 0; i < 20; i++) {
+            sb.write("$t ");
+            t = t.next!;
+          }
+          throw "$fileUri --- couldn't even find nearest ast node for "
+              "${identifier.token} :( -- context $sb";
+        }
+        (nearestAstNode.scope[identifier.token.lexeme] ??= [])
+            .add(nearestAstNode);
+      }
+    }
+
+    return topLevel;
+  }
+
+  Future<void> _premarkTopLevel(List<_TopLevelAndAstNode> worklist,
+      Set<TopLevel> closed, TopLevel entrypointish) async {
+    if (!closed.add(entrypointish)) return;
+
+    for (AstNode child in entrypointish.children) {
+      child.marked = Coloring.Marked;
+      worklist.add(new _TopLevelAndAstNode(entrypointish, child));
+
+      if (child is Part) {
+        if (child.uri.scheme != "dart") {
+          TopLevel partTopLevel = parsed[child.uri] ??
+              await preprocessUri(child.uri, partOf: entrypointish.uri);
+          await _premarkTopLevel(worklist, closed, partTopLevel);
+        }
+      } else if (child is Export) {
+        for (Uri importedUri in child.uris) {
+          if (importedUri.scheme != "dart") {
+            TopLevel exportTopLevel =
+                parsed[importedUri] ?? await preprocessUri(importedUri);
+            await _premarkTopLevel(worklist, closed, exportTopLevel);
+          }
+        }
+      }
+    }
+  }
+
+  Future<List<TopLevel>> _preprocessImportsAsNeeded(
+      Map<TopLevel, List<TopLevel>> imports, TopLevel topLevel) async {
+    List<TopLevel>? imported = imports[topLevel];
+    if (imported == null) {
+      // Process all imports.
+      imported = [];
+      imports[topLevel] = imported;
+      for (AstNode child in topLevel.children) {
+        if (child is Import) {
+          child.marked = Coloring.Marked;
+          for (Uri importedUri in child.uris) {
+            if (importedUri.scheme != "dart") {
+              TopLevel importedTopLevel =
+                  parsed[importedUri] ?? await preprocessUri(importedUri);
+              imported.add(importedTopLevel);
+            }
+          }
+        } else if (child is PartOf) {
+          child.marked = Coloring.Marked;
+          if (child.partOfUri.scheme != "dart") {
+            TopLevel part = parsed[child.partOfUri]!;
+            List<TopLevel> importsFromPart =
+                await _preprocessImportsAsNeeded(imports, part);
+            imported.addAll(importsFromPart);
+          }
+        }
+      }
+    }
+    return imported;
+  }
+
+  Future<Map<Uri, String>> calculate(List<TopLevel> entryPoints) async {
+    List<_TopLevelAndAstNode> worklist = [];
+    Map<TopLevel, List<TopLevel>> imports = {};
+
+    // Mark all top-level in entry point. Also include parts and exports (and
+    // exports exports etc) of the entry point.
+    Set<TopLevel> closed = {};
+    for (TopLevel entryPoint in entryPoints) {
+      await _premarkTopLevel(worklist, closed, entryPoint);
+    }
+
+    Map<TopLevel, Set<String>> lookupsAll = {};
+    Map<TopLevel, List<String>> lookupsWorklist = {};
+    while (worklist.isNotEmpty || lookupsWorklist.isNotEmpty) {
+      while (worklist.isNotEmpty) {
+        _TopLevelAndAstNode entry = worklist.removeLast();
+        if (verbosityLevel >= 20) {
+          log("\n-----\nProcessing ${entry.entry.node.toString()}");
+        }
+        _IdentifierExtractor identifierExtractor = new _IdentifierExtractor();
+        identifierExtractor.extract(entry.entry.node);
+        if (verbosityLevel >= 20) {
+          log("Found ${identifierExtractor.identifiers}");
+        }
+        List<AstNode>? prevLookupResult;
+        nextIdentifier:
+        for (IdentifierHandle identifier in identifierExtractor.identifiers) {
+          ParserAstNode content = identifier;
+          AstNode? nearestAstNode = entry.topLevel.map[content];
+          while (nearestAstNode == null && content.parent != null) {
+            content = content.parent!;
+            nearestAstNode = entry.topLevel.map[content];
+          }
+          if (nearestAstNode == null) {
+            throw "couldn't even find nearest ast node for "
+                "${identifier.token} :(";
+          }
+
+          if (identifier.context == IdentifierContext.typeReference ||
+              identifier.context == IdentifierContext.prefixedTypeReference ||
+              identifier.context ==
+                  IdentifierContext.typeReferenceContinuation ||
+              identifier.context == IdentifierContext.constructorReference ||
+              identifier.context ==
+                  IdentifierContext.constructorReferenceContinuation ||
+              identifier.context == IdentifierContext.expression ||
+              identifier.context == IdentifierContext.expressionContinuation ||
+              identifier.context == IdentifierContext.metadataReference ||
+              identifier.context == IdentifierContext.metadataContinuation) {
+            bool lookupInThisScope = true;
+            if (!identifier.context.isContinuation) {
+              prevLookupResult = null;
+            } else if (prevLookupResult != null) {
+              // In continuation.
+              // either 0 or all should be imports.
+              for (AstNode prevResult in prevLookupResult) {
+                if (prevResult is Import) {
+                  lookupInThisScope = false;
+                } else {
+                  continue nextIdentifier;
+                }
+              }
+            } else {
+              // Still in continuation --- but prev lookup didn't yield
+              // anything. We shouldn't search for the continuation part in this
+              // scope (and thus skip looking in imports).
+              lookupInThisScope = false;
+            }
+            if (verbosityLevel >= 20) {
+              log("${identifier.token} (${identifier.context})");
+            }
+
+            // Now we need parts at this point. Either we're in the entry point
+            // in which case parts was read by [_premarkTopLevel], or we're here
+            // via lookups on an import, where parts were read too.
+            List<AstNode>? lookedUp;
+            if (lookupInThisScope) {
+              lookedUp = findInScope(
+                  identifier.token.lexeme, nearestAstNode, entry.topLevel);
+              prevLookupResult = lookedUp;
+            }
+            if (lookedUp != null) {
+              for (AstNode found in lookedUp) {
+                if (verbosityLevel >= 20) log(" => found $found");
+                if (found.marked == Coloring.Untouched) {
+                  found.marked = Coloring.Marked;
+                  TopLevel foundTopLevel = entry.topLevel;
+                  if (found.parent is TopLevel) {
+                    foundTopLevel = found.parent as TopLevel;
+                  }
+                  worklist.add(new _TopLevelAndAstNode(foundTopLevel, found));
+                }
+              }
+            } else {
+              if (verbosityLevel >= 20) {
+                log("=> Should find this via an import probably?");
+              }
+
+              List<TopLevel> imported =
+                  await _preprocessImportsAsNeeded(imports, entry.topLevel);
+
+              Set<Uri>? wantedImportUrls;
+              if (!lookupInThisScope && prevLookupResult != null) {
+                for (AstNode castMeAsImport in prevLookupResult) {
+                  Import import = castMeAsImport as Import;
+                  assert(import.asName != null);
+                  (wantedImportUrls ??= {}).addAll(import.uris);
+                }
+              }
+
+              for (TopLevel other in imported) {
+                if (!lookupInThisScope && prevLookupResult != null) {
+                  assert(wantedImportUrls != null);
+                  if (!wantedImportUrls!.contains(other.uri)) continue;
+                }
+
+                Set<String> lookupStrings = lookupsAll[other] ??= {};
+                if (lookupStrings.add(identifier.token.lexeme)) {
+                  List<String> lookupStringsWorklist =
+                      lookupsWorklist[other] ??= [];
+                  lookupStringsWorklist.add(identifier.token.lexeme);
+                }
+              }
+            }
+          } else {
+            if (verbosityLevel >= 30) {
+              log("Ignoring ${identifier.token} as it's a "
+                  "${identifier.context}");
+            }
+          }
+        }
+      }
+      Map<TopLevel, List<String>> lookupsWorklistTmp = {};
+      for (MapEntry<TopLevel, List<String>> lookups
+          in lookupsWorklist.entries) {
+        TopLevel topLevel = lookups.key;
+        // We have to make the same lookups in parts and exports too.
+        for (AstNode child in topLevel.children) {
+          TopLevel? other;
+          if (child is Part) {
+            child.marked = Coloring.Marked;
+            // do stuff to part.
+            if (child.uri.scheme != "dart") {
+              other = parsed[child.uri] ??
+                  await preprocessUri(child.uri, partOf: topLevel.uri);
+            }
+          } else if (child is Export) {
+            child.marked = Coloring.Marked;
+            // do stuff to export.
+            for (Uri importedUri in child.uris) {
+              if (importedUri.scheme != "dart") {
+                other = parsed[importedUri] ?? await preprocessUri(importedUri);
+              }
+            }
+          } else if (child is Extension) {
+            // TODO: Maybe put on a list to process later and only include if
+            // the on-class is included?
+            if (child.marked == Coloring.Untouched) {
+              child.marked = Coloring.Marked;
+              worklist.add(new _TopLevelAndAstNode(topLevel, child));
+            }
+          }
+          if (other != null) {
+            Set<String> lookupStrings = lookupsAll[other] ??= {};
+            for (String identifier in lookups.value) {
+              if (lookupStrings.add(identifier)) {
+                List<String> lookupStringsWorklist =
+                    lookupsWorklistTmp[other] ??= [];
+                lookupStringsWorklist.add(identifier);
+              }
+            }
+          }
+        }
+
+        for (String identifier in lookups.value) {
+          List<AstNode>? foundInScope = topLevel.findInScope(identifier);
+          if (foundInScope != null) {
+            for (AstNode found in foundInScope) {
+              if (found.marked == Coloring.Untouched) {
+                found.marked = Coloring.Marked;
+                worklist.add(new _TopLevelAndAstNode(topLevel, found));
+              }
+              if (verbosityLevel >= 20) {
+                log(" => found $found via import (${found.marked})");
+              }
+            }
+          }
+        }
+      }
+      lookupsWorklist = lookupsWorklistTmp;
+    }
+
+    if (verbosityLevel >= 40) {
+      log("\n\n---------\n\n");
+      log(parsed.toString());
+      log("\n\n---------\n\n");
+    }
+
+    // Extract.
+    int count = 0;
+    Map<Uri, String> result = {};
+    // We only read imports if we need to lookup in them, but if a import
+    // statement is included in the output the file has to exist if it actually
+    // exists to not get a compilation error.
+    Set<Uri> imported = {};
+    for (MapEntry<Uri, TopLevel> entry in parsed.entries) {
+      if (verbosityLevel >= 40) log("${entry.key}:");
+      StringBuffer sb = new StringBuffer();
+      for (AstNode child in entry.value.children) {
+        if (child.marked == Coloring.Marked) {
+          String substring = entry.value.sourceText.substring(
+              child.startInclusive.charOffset, child.endInclusive.charEnd);
+          sb.writeln(substring);
+          if (verbosityLevel >= 40) {
+            log(substring);
+          }
+          if (child is Import) {
+            for (Uri importedUri in child.uris) {
+              if (importedUri.scheme != "dart") {
+                imported.add(importedUri);
+              }
+            }
+          }
+        }
+      }
+      if (sb.isNotEmpty) count++;
+      Uri uri = entry.key;
+      Uri fileUri = uri;
+      if (uri.scheme == "package") {
+        fileUri = uriTranslator.translate(uri)!;
+      }
+      result[fileUri] = sb.toString();
+    }
+    for (Uri uri in imported) {
+      TopLevel? topLevel = parsed[uri];
+      if (topLevel != null) continue;
+      // uri imports a file we haven't read. Check if it exists and include it
+      // as an empty file if it does.
+      Uri fileUri = uri;
+      if (uri.scheme == "package") {
+        fileUri = uriTranslator.translate(uri)!;
+      }
+      if (await fileSystem.entityForUri(fileUri).exists()) {
+        result[fileUri] = "";
+      }
+    }
+
+    print("=> Long story short got it to $count non-empty files...");
+
+    return result;
+  }
+
+  List<AstNode>? findInScope(
+      String name, AstNode nearestAstNode, TopLevel topLevel,
+      {Set<TopLevel>? visited}) {
+    List<AstNode>? result;
+    result = nearestAstNode.findInScope(name);
+    if (result != null) return result;
+    for (AstNode child in topLevel.children) {
+      if (child is Part) {
+        visited ??= {topLevel};
+        TopLevel partTopLevel = parsed[child.uri]!;
+        if (visited.add(partTopLevel)) {
+          result =
+              findInScope(name, partTopLevel, partTopLevel, visited: visited);
+          if (result != null) return result;
+        }
+      } else if (child is PartOf) {
+        visited ??= {topLevel};
+        TopLevel partOwnerTopLevel = parsed[child.partOfUri]!;
+        if (visited.add(partOwnerTopLevel)) {
+          result = findInScope(name, partOwnerTopLevel, partOwnerTopLevel,
+              visited: visited);
+          if (result != null) return result;
+        }
+      }
+    }
+  }
+}
+
+class _TopLevelAndAstNode {
+  final TopLevel topLevel;
+  final AstNode entry;
+
+  _TopLevelAndAstNode(this.topLevel, this.entry);
+}
+
+class _IdentifierExtractor {
+  List<IdentifierHandle> identifiers = [];
+
+  void extract(ParserAstNode ast) {
+    if (ast is IdentifierHandle) {
+      identifiers.add(ast);
+    }
+    List<ParserAstNode>? children = ast.children;
+    if (children != null) {
+      for (ParserAstNode child in children) {
+        extract(child);
+      }
+    }
+  }
+}
+
+class _ParserAstVisitor extends ParserAstVisitor {
+  final Uri uri;
+  final Uri? partOfUri;
+  late Container currentContainer;
+  final Map<ParserAstNode, AstNode> map = {};
+  final int verbosityLevel;
+  final List<Token> languageVersionsSeen;
+
+  _ParserAstVisitor(this.verbosityLevel, String sourceText, this.uri,
+      this.partOfUri, ParserAstNode rootAst, this.languageVersionsSeen) {
+    currentContainer = new TopLevel(sourceText, uri, rootAst, map);
+    if (languageVersionsSeen.isNotEmpty) {
+      // Use first one.
+      Token languageVersion = languageVersionsSeen.first;
+      ParserAstNode dummyNode = new NoInitializersHandle(ParserAstType.HANDLE);
+      LanguageVersion version =
+          new LanguageVersion(dummyNode, languageVersion, languageVersion);
+      version.marked = Coloring.Marked;
+      currentContainer.addChild(version, map);
+    }
+  }
+
+  void log(String s) {
+    if (verbosityLevel <= 0) return;
+    Container? x = currentContainer.parent;
+    int level = 0;
+    while (x != null) {
+      level++;
+      x = x.parent;
+    }
+    print(" " * level + s);
+  }
+
+  @override
+  void visitClass(
+      ClassDeclarationEnd node, Token startInclusive, Token endInclusive) {
+    TopLevelDeclarationEnd parent = node.parent! as TopLevelDeclarationEnd;
+    IdentifierHandle identifier = parent.getIdentifier();
+
+    log("Hello from class ${identifier.token}");
+
+    Class cls = new Class(
+        parent, identifier.token.lexeme, startInclusive, endInclusive);
+    currentContainer.addChild(cls, map);
+
+    Container previousContainer = currentContainer;
+    currentContainer = cls;
+    super.visitClass(node, startInclusive, endInclusive);
+    currentContainer = previousContainer;
+  }
+
+  @override
+  void visitClassConstructor(
+      ClassConstructorEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Class);
+    List<IdentifierHandle> ids = node.getIdentifiers();
+    if (ids.length == 1) {
+      ClassConstructor classConstructor = new ClassConstructor(
+          node, ids.single.token.lexeme, startInclusive, endInclusive);
+      currentContainer.addChild(classConstructor, map);
+      log("Hello from constructor ${ids.single.token}");
+    } else if (ids.length == 2) {
+      ClassConstructor classConstructor = new ClassConstructor(node,
+          "${ids.first.token}.${ids.last.token}", startInclusive, endInclusive);
+      map[node] = classConstructor;
+      currentContainer.addChild(classConstructor, map);
+      log("Hello from constructor ${ids.first.token}.${ids.last.token}");
+    } else {
+      throw "Unexpected identifiers in class constructor";
+    }
+
+    super.visitClassConstructor(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitClassFactoryMethod(
+      ClassFactoryMethodEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Class);
+    List<IdentifierHandle> ids = node.getIdentifiers();
+    if (ids.length == 1) {
+      ClassFactoryMethod classFactoryMethod = new ClassFactoryMethod(
+          node, ids.single.token.lexeme, startInclusive, endInclusive);
+      currentContainer.addChild(classFactoryMethod, map);
+      log("Hello from factory method ${ids.single.token}");
+    } else if (ids.length == 2) {
+      ClassFactoryMethod classFactoryMethod = new ClassFactoryMethod(node,
+          "${ids.first.token}.${ids.last.token}", startInclusive, endInclusive);
+      map[node] = classFactoryMethod;
+      currentContainer.addChild(classFactoryMethod, map);
+      log("Hello from factory method ${ids.first.token}.${ids.last.token}");
+    } else {
+      Container findTopLevel = currentContainer;
+      while (findTopLevel is! TopLevel) {
+        findTopLevel = findTopLevel.parent!;
+      }
+      String src = findTopLevel.sourceText
+          .substring(startInclusive.charOffset, endInclusive.charEnd);
+      throw "Unexpected identifiers in class factory method: $ids "
+          "(${ids.map((e) => e.token.lexeme).toList()}) --- "
+          "error on source ${src} --- "
+          "${node.children}";
+    }
+
+    super.visitClassFactoryMethod(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitClassFields(
+      ClassFieldsEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Class);
+    List<String> fields =
+        node.getFieldIdentifiers().map((e) => e.token.lexeme).toList();
+    ClassFields classFields =
+        new ClassFields(node, fields, startInclusive, endInclusive);
+    currentContainer.addChild(classFields, map);
+    log("Hello from class fields ${fields.join(", ")}");
+    super.visitClassFields(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitClassMethod(
+      ClassMethodEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Class);
+
+    String identifier;
+    try {
+      identifier = node.getNameIdentifier();
+    } catch (e) {
+      Container findTopLevel = currentContainer;
+      while (findTopLevel is! TopLevel) {
+        findTopLevel = findTopLevel.parent!;
+      }
+      String src = findTopLevel.sourceText
+          .substring(startInclusive.charOffset, endInclusive.charEnd);
+      throw "Unexpected identifiers in visitClassMethod --- "
+          "error on source ${src} --- "
+          "${node.children}";
+    }
+    ClassMethod classMethod =
+        new ClassMethod(node, identifier, startInclusive, endInclusive);
+    currentContainer.addChild(classMethod, map);
+    log("Hello from class method $identifier");
+    super.visitClassMethod(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitEnum(EnumEnd node, Token startInclusive, Token endInclusive) {
+    List<IdentifierHandle> ids = node.getIdentifiers();
+
+    Enum e = new Enum(
+        node,
+        ids.first.token.lexeme,
+        ids.skip(1).map((e) => e.token.lexeme).toList(),
+        startInclusive,
+        endInclusive);
+    currentContainer.addChild(e, map);
+
+    log("Hello from enum ${ids.first.token} with content "
+        "${ids.skip(1).map((e) => e.token).join(", ")}");
+    super.visitEnum(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitExport(ExportEnd node, Token startInclusive, Token endInclusive) {
+    String uriString = node.getExportUriString();
+    Uri exportUri = uri.resolve(uriString);
+    List<String>? conditionalUriStrings = node.getConditionalExportUriStrings();
+    List<Uri>? conditionalUris;
+    if (conditionalUriStrings != null) {
+      conditionalUris = [];
+      for (String conditionalUri in conditionalUriStrings) {
+        conditionalUris.add(uri.resolve(conditionalUri));
+      }
+    }
+    // TODO: Use 'show' and 'hide' stuff.
+    Export e = new Export(
+        node, exportUri, conditionalUris, startInclusive, endInclusive);
+    currentContainer.addChild(e, map);
+    log("Hello export");
+  }
+
+  @override
+  void visitExtension(
+      ExtensionDeclarationEnd node, Token startInclusive, Token endInclusive) {
+    ExtensionDeclarationBegin begin =
+        node.children!.first as ExtensionDeclarationBegin;
+    TopLevelDeclarationEnd parent = node.parent! as TopLevelDeclarationEnd;
+    log("Hello from extension ${begin.name}");
+    Extension extension =
+        new Extension(parent, begin.name?.lexeme, startInclusive, endInclusive);
+    currentContainer.addChild(extension, map);
+
+    Container previousContainer = currentContainer;
+    currentContainer = extension;
+    super.visitExtension(node, startInclusive, endInclusive);
+    currentContainer = previousContainer;
+  }
+
+  @override
+  void visitExtensionConstructor(
+      ExtensionConstructorEnd node, Token startInclusive, Token endInclusive) {
+    // TODO: implement visitExtensionConstructor
+    throw node;
+  }
+
+  @override
+  void visitExtensionFactoryMethod(ExtensionFactoryMethodEnd node,
+      Token startInclusive, Token endInclusive) {
+    // TODO: implement visitExtensionFactoryMethod
+    throw node;
+  }
+
+  @override
+  void visitExtensionFields(
+      ExtensionFieldsEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Extension);
+    List<String> fields =
+        node.getFieldIdentifiers().map((e) => e.token.lexeme).toList();
+    ExtensionFields classFields =
+        new ExtensionFields(node, fields, startInclusive, endInclusive);
+    currentContainer.addChild(classFields, map);
+    log("Hello from extension fields ${fields.join(", ")}");
+    super.visitExtensionFields(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitExtensionMethod(
+      ExtensionMethodEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Extension);
+    ExtensionMethod extensionMethod = new ExtensionMethod(
+        node, node.getNameIdentifier(), startInclusive, endInclusive);
+    currentContainer.addChild(extensionMethod, map);
+    log("Hello from extension method ${node.getNameIdentifier()}");
+    super.visitExtensionMethod(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitImport(ImportEnd node, Token startInclusive, Token? endInclusive) {
+    IdentifierHandle? prefix = node.getImportPrefix();
+    String uriString = node.getImportUriString();
+    Uri importUri = uri.resolve(uriString);
+    List<String>? conditionalUriStrings = node.getConditionalImportUriStrings();
+    List<Uri>? conditionalUris;
+    if (conditionalUriStrings != null) {
+      conditionalUris = [];
+      for (String conditionalUri in conditionalUriStrings) {
+        conditionalUris.add(uri.resolve(conditionalUri));
+      }
+    }
+    // TODO: Use 'show' and 'hide' stuff.
+
+    // endInclusive can be null on syntax errors and there's recovery of the
+    // import. For now we'll ignore this.
+    Import i = new Import(node, importUri, conditionalUris,
+        prefix?.token.lexeme, startInclusive, endInclusive!);
+    currentContainer.addChild(i, map);
+    if (prefix == null) {
+      log("Hello import");
+    } else {
+      log("Hello import as '${prefix.token}'");
+    }
+  }
+
+  @override
+  void visitLibraryName(
+      LibraryNameEnd node, Token startInclusive, Token endInclusive) {
+    LibraryName name = new LibraryName(node, startInclusive, endInclusive);
+    name.marked = Coloring.Marked;
+    currentContainer.addChild(name, map);
+  }
+
+  @override
+  void visitMetadata(
+      MetadataEnd node, Token startInclusive, Token endInclusive) {
+    Metadata m = new Metadata(node, startInclusive, endInclusive);
+    currentContainer.addChild(m, map);
+  }
+
+  @override
+  void visitMixin(
+      MixinDeclarationEnd node, Token startInclusive, Token endInclusive) {
+    TopLevelDeclarationEnd parent = node.parent! as TopLevelDeclarationEnd;
+    IdentifierHandle identifier = parent.getIdentifier();
+    log("Hello from mixin ${identifier.token}");
+
+    Mixin mixin = new Mixin(
+        parent, identifier.token.lexeme, startInclusive, endInclusive);
+    currentContainer.addChild(mixin, map);
+
+    Container previousContainer = currentContainer;
+    currentContainer = mixin;
+    super.visitMixin(node, startInclusive, endInclusive);
+    currentContainer = previousContainer;
+  }
+
+  @override
+  void visitMixinFields(
+      MixinFieldsEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Mixin);
+    List<String> fields =
+        node.getFieldIdentifiers().map((e) => e.token.lexeme).toList();
+    MixinFields mixinFields =
+        new MixinFields(node, fields, startInclusive, endInclusive);
+    currentContainer.addChild(mixinFields, map);
+    log("Hello from mixin fields ${fields.join(", ")}");
+    super.visitMixinFields(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitMixinMethod(
+      MixinMethodEnd node, Token startInclusive, Token endInclusive) {
+    assert(currentContainer is Mixin);
+    MixinMethod classMethod = new MixinMethod(
+        node, node.getNameIdentifier(), startInclusive, endInclusive);
+    currentContainer.addChild(classMethod, map);
+    log("Hello from mixin method ${node.getNameIdentifier()}");
+    super.visitMixinMethod(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitNamedMixin(
+      NamedMixinApplicationEnd node, Token startInclusive, Token endInclusive) {
+    TopLevelDeclarationEnd parent = node.parent! as TopLevelDeclarationEnd;
+    IdentifierHandle identifier = parent.getIdentifier();
+    log("Hello from named mixin ${identifier.token}");
+
+    Mixin mixin = new Mixin(
+        parent, identifier.token.lexeme, startInclusive, endInclusive);
+    currentContainer.addChild(mixin, map);
+
+    Container previousContainer = currentContainer;
+    currentContainer = mixin;
+    super.visitNamedMixin(node, startInclusive, endInclusive);
+    currentContainer = previousContainer;
+  }
+
+  @override
+  void visitPart(PartEnd node, Token startInclusive, Token endInclusive) {
+    String uriString = node.getPartUriString();
+    Uri partUri = uri.resolve(uriString);
+
+    Part i = new Part(node, partUri, startInclusive, endInclusive);
+    currentContainer.addChild(i, map);
+    log("Hello part");
+  }
+
+  @override
+  void visitPartOf(PartOfEnd node, Token startInclusive, Token endInclusive) {
+    // We'll assume we've gotten here via a "part" so we'll ignore that for now.
+    // TODO: partOfUri could - in an error case - be null.
+    PartOf partof = new PartOf(node, partOfUri!, startInclusive, endInclusive);
+    partof.marked = Coloring.Marked;
+    currentContainer.addChild(partof, map);
+  }
+
+  @override
+  void visitTopLevelFields(
+      TopLevelFieldsEnd node, Token startInclusive, Token endInclusive) {
+    List<String> fields =
+        node.getFieldIdentifiers().map((e) => e.token.lexeme).toList();
+    TopLevelFields f =
+        new TopLevelFields(node, fields, startInclusive, endInclusive);
+    currentContainer.addChild(f, map);
+    log("Hello from top level fields ${fields.join(", ")}");
+    super.visitTopLevelFields(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitTopLevelMethod(
+      TopLevelMethodEnd node, Token startInclusive, Token endInclusive) {
+    TopLevelMethod m = new TopLevelMethod(node,
+        node.getNameIdentifier().token.lexeme, startInclusive, endInclusive);
+    currentContainer.addChild(m, map);
+    log("Hello from top level method ${node.getNameIdentifier().token}");
+    super.visitTopLevelMethod(node, startInclusive, endInclusive);
+  }
+
+  @override
+  void visitTypedef(TypedefEnd node, Token startInclusive, Token endInclusive) {
+    Typedef t = new Typedef(node, node.getNameIdentifier().token.lexeme,
+        startInclusive, endInclusive);
+    currentContainer.addChild(t, map);
+    log("Hello from typedef ${node.getNameIdentifier().token}");
+    super.visitTypedef(node, startInclusive, endInclusive);
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/util/parser_ast.dart b/pkg/front_end/lib/src/fasta/util/parser_ast.dart
new file mode 100644
index 0000000..b648bfc
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/util/parser_ast.dart
@@ -0,0 +1,1578 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data' show Uint8List;
+
+import 'dart:io' show File;
+
+import 'package:_fe_analyzer_shared/src/messages/codes.dart';
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+    show ScannerConfiguration;
+
+import 'package:_fe_analyzer_shared/src/parser/parser.dart'
+    show ClassMemberParser, Parser;
+
+import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
+    show Utf8BytesScanner;
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+
+import 'package:_fe_analyzer_shared/src/parser/listener.dart'
+    show UnescapeErrorListener;
+
+import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
+
+import 'package:_fe_analyzer_shared/src/parser/quote.dart' show unescapeString;
+
+import '../source/diet_parser.dart';
+
+import 'parser_ast_helper.dart';
+
+CompilationUnitEnd getAST(List<int> rawBytes,
+    {bool includeBody: true,
+    bool includeComments: false,
+    bool enableExtensionMethods: false,
+    bool enableNonNullable: false,
+    bool enableTripleShift: false,
+    List<Token>? languageVersionsSeen}) {
+  Uint8List bytes = new Uint8List(rawBytes.length + 1);
+  bytes.setRange(0, rawBytes.length, rawBytes);
+
+  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+      enableExtensionMethods: enableExtensionMethods,
+      enableNonNullable: enableNonNullable,
+      enableTripleShift: enableTripleShift);
+
+  Utf8BytesScanner scanner = new Utf8BytesScanner(
+    bytes,
+    includeComments: includeComments,
+    configuration: scannerConfiguration,
+    languageVersionChanged: (scanner, languageVersion) {
+      // For now don't do anything, but having it (making it non-null) means the
+      // configuration won't be reset.
+      languageVersionsSeen?.add(languageVersion);
+    },
+  );
+  Token firstToken = scanner.tokenize();
+  // ignore: unnecessary_null_comparison
+  if (firstToken == null) {
+    throw "firstToken is null";
+  }
+
+  ParserASTListener listener = new ParserASTListener();
+  Parser parser;
+  if (includeBody) {
+    parser = new Parser(listener,
+        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
+  } else {
+    parser = new ClassMemberParser(listener,
+        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
+  }
+  parser.parseUnit(firstToken);
+  return listener.data.single as CompilationUnitEnd;
+}
+
+/// Best-effort visitor for ParserAstNode that visits top-level entries
+/// and class members only (i.e. no bodies, no field initializer content, no
+/// names etc).
+class ParserAstVisitor {
+  void accept(ParserAstNode node) {
+    if (node is CompilationUnitEnd ||
+        node is TopLevelDeclarationEnd ||
+        node is ClassOrMixinOrExtensionBodyEnd ||
+        node is MemberEnd) {
+      visitChildren(node);
+      return;
+    }
+
+    if (node.type == ParserAstType.BEGIN) {
+      // Ignored. These are basically just dummy nodes anyway.
+      assert(node.children == null);
+      return;
+    }
+    if (node.type == ParserAstType.HANDLE) {
+      // Ignored at least for know.
+      assert(node.children == null);
+      return;
+    }
+    if (node is TypeVariablesEnd ||
+        node is TypeArgumentsEnd ||
+        node is TypeListEnd ||
+        node is FunctionTypeEnd ||
+        node is BlockEnd) {
+      // Ignored at least for know.
+      return;
+    }
+    if (node is MetadataStarEnd) {
+      MetadataStarEnd metadata = node;
+      visitMetadataStar(metadata);
+      return;
+    }
+    if (node is TypedefEnd) {
+      TypedefEnd typedefDecl = node;
+      visitTypedef(
+          typedefDecl, typedefDecl.typedefKeyword, typedefDecl.endToken);
+      return;
+    }
+    if (node is ClassDeclarationEnd) {
+      ClassDeclarationEnd cls = node;
+      visitClass(cls, cls.beginToken, cls.endToken);
+      return;
+    }
+    if (node is TopLevelMethodEnd) {
+      TopLevelMethodEnd method = node;
+      visitTopLevelMethod(method, method.beginToken, method.endToken);
+      return;
+    }
+    if (node is ClassMethodEnd) {
+      ClassMethodEnd method = node;
+      visitClassMethod(method, method.beginToken, method.endToken);
+      return;
+    }
+    if (node is ExtensionMethodEnd) {
+      ExtensionMethodEnd method = node;
+      visitExtensionMethod(method, method.beginToken, method.endToken);
+      return;
+    }
+    if (node is MixinMethodEnd) {
+      MixinMethodEnd method = node;
+      visitMixinMethod(method, method.beginToken, method.endToken);
+      return;
+    }
+    if (node is ImportEnd) {
+      ImportEnd import = node;
+      visitImport(import, import.importKeyword, import.semicolon);
+      return;
+    }
+    if (node is ExportEnd) {
+      ExportEnd export = node;
+      visitExport(export, export.exportKeyword, export.semicolon);
+      return;
+    }
+    if (node is TopLevelFieldsEnd) {
+      // TODO(jensj): Possibly this could go into more details too
+      // (e.g. to split up a field declaration).
+      TopLevelFieldsEnd fields = node;
+      visitTopLevelFields(fields, fields.beginToken, fields.endToken);
+      return;
+    }
+    if (node is ClassFieldsEnd) {
+      // TODO(jensj): Possibly this could go into more details too
+      // (e.g. to split up a field declaration).
+      ClassFieldsEnd fields = node;
+      visitClassFields(fields, fields.beginToken, fields.endToken);
+      return;
+    }
+    if (node is ExtensionFieldsEnd) {
+      // TODO(jensj): Possibly this could go into more details too
+      // (e.g. to split up a field declaration).
+      ExtensionFieldsEnd fields = node;
+      visitExtensionFields(fields, fields.beginToken, fields.endToken);
+      return;
+    }
+    if (node is MixinFieldsEnd) {
+      // TODO(jensj): Possibly this could go into more details too
+      // (e.g. to split up a field declaration).
+      MixinFieldsEnd fields = node;
+      visitMixinFields(fields, fields.beginToken, fields.endToken);
+      return;
+    }
+    if (node is NamedMixinApplicationEnd) {
+      NamedMixinApplicationEnd namedMixin = node;
+      visitNamedMixin(namedMixin, namedMixin.begin, namedMixin.endToken);
+      return;
+    }
+    if (node is MixinDeclarationEnd) {
+      MixinDeclarationEnd declaration = node;
+      visitMixin(declaration, declaration.mixinKeyword, declaration.endToken);
+      return;
+    }
+    if (node is EnumEnd) {
+      EnumEnd declaration = node;
+      visitEnum(declaration, declaration.enumKeyword,
+          declaration.leftBrace.endGroup!);
+      return;
+    }
+    if (node is LibraryNameEnd) {
+      LibraryNameEnd name = node;
+      visitLibraryName(name, name.libraryKeyword, name.semicolon);
+      return;
+    }
+    if (node is PartEnd) {
+      PartEnd part = node;
+      visitPart(part, part.partKeyword, part.semicolon);
+      return;
+    }
+    if (node is PartOfEnd) {
+      PartOfEnd partOf = node;
+      visitPartOf(partOf, partOf.partKeyword, partOf.semicolon);
+      return;
+    }
+    if (node is ExtensionDeclarationEnd) {
+      ExtensionDeclarationEnd ext = node;
+      visitExtension(ext, ext.extensionKeyword, ext.endToken);
+      return;
+    }
+    if (node is ClassConstructorEnd) {
+      ClassConstructorEnd decl = node;
+      visitClassConstructor(decl, decl.beginToken, decl.endToken);
+      return;
+    }
+    if (node is ExtensionConstructorEnd) {
+      ExtensionConstructorEnd decl = node;
+      visitExtensionConstructor(decl, decl.beginToken, decl.endToken);
+      return;
+    }
+    if (node is ClassFactoryMethodEnd) {
+      ClassFactoryMethodEnd decl = node;
+      visitClassFactoryMethod(decl, decl.beginToken, decl.endToken);
+      return;
+    }
+    if (node is ExtensionFactoryMethodEnd) {
+      ExtensionFactoryMethodEnd decl = node;
+      visitExtensionFactoryMethod(decl, decl.beginToken, decl.endToken);
+      return;
+    }
+    if (node is MetadataEnd) {
+      MetadataEnd decl = node;
+      // TODO(jensj): endToken is not part of the metadata! It's the first token
+      // of the next thing.
+      visitMetadata(decl, decl.beginToken, decl.endToken.previous!);
+      return;
+    }
+
+    throw "Unknown: $node (${node.runtimeType} @ ${node.what})";
+  }
+
+  void visitChildren(ParserAstNode node) {
+    if (node.children == null) return;
+    final int numChildren = node.children!.length;
+    for (int i = 0; i < numChildren; i++) {
+      ParserAstNode child = node.children![i];
+      accept(child);
+    }
+  }
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitImport(ImportEnd node, Token startInclusive, Token? endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitExport(ExportEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitTypedef(
+      TypedefEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers can call visitChildren on this node.
+  void visitMetadataStar(MetadataStarEnd node) {
+    visitChildren(node);
+  }
+
+  /// Note: Implementers can call visitChildren on this node.
+  void visitClass(
+      ClassDeclarationEnd node, Token startInclusive, Token endInclusive) {
+    visitChildren(node);
+  }
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitTopLevelMethod(
+      TopLevelMethodEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitClassMethod(
+      ClassMethodEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitExtensionMethod(
+      ExtensionMethodEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitMixinMethod(
+      MixinMethodEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitTopLevelFields(
+      TopLevelFieldsEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitClassFields(
+      ClassFieldsEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitExtensionFields(
+      ExtensionFieldsEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitMixinFields(
+      MixinFieldsEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers can call visitChildren on this node.
+  void visitNamedMixin(
+      NamedMixinApplicationEnd node, Token startInclusive, Token endInclusive) {
+    visitChildren(node);
+  }
+
+  /// Note: Implementers can call visitChildren on this node.
+  void visitMixin(
+      MixinDeclarationEnd node, Token startInclusive, Token endInclusive) {
+    visitChildren(node);
+  }
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitEnum(EnumEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitLibraryName(
+      LibraryNameEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitPart(PartEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitPartOf(PartOfEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers can call visitChildren on this node.
+  void visitExtension(
+      ExtensionDeclarationEnd node, Token startInclusive, Token endInclusive) {
+    visitChildren(node);
+  }
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitClassConstructor(
+      ClassConstructorEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitExtensionConstructor(
+      ExtensionConstructorEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitClassFactoryMethod(
+      ClassFactoryMethodEnd node, Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitExtensionFactoryMethod(ExtensionFactoryMethodEnd node,
+      Token startInclusive, Token endInclusive) {}
+
+  /// Note: Implementers are NOT expected to call visitChildren on this node.
+  void visitMetadata(
+      MetadataEnd node, Token startInclusive, Token endInclusive) {}
+}
+
+extension GeneralASTContentExtension on ParserAstNode {
+  bool isClass() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first
+        // ignore: lines_longer_than_80_chars
+        is! ClassOrMixinOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children!.last is! ClassDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  ClassDeclarationEnd asClass() {
+    if (!isClass()) throw "Not class";
+    return children!.last as ClassDeclarationEnd;
+  }
+
+  bool isImport() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! ImportEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  ImportEnd asImport() {
+    if (!isImport()) throw "Not import";
+    return children!.last as ImportEnd;
+  }
+
+  bool isExport() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! ExportEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  ExportEnd asExport() {
+    if (!isExport()) throw "Not export";
+    return children!.last as ExportEnd;
+  }
+
+  bool isEnum() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! EnumEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  EnumEnd asEnum() {
+    if (!isEnum()) throw "Not enum";
+    return children!.last as EnumEnd;
+  }
+
+  bool isTypedef() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! TypedefEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  TypedefEnd asTypedef() {
+    if (!isTypedef()) throw "Not typedef";
+    return children!.last as TypedefEnd;
+  }
+
+  bool isScript() {
+    if (this is! ScriptHandle) {
+      return false;
+    }
+    return true;
+  }
+
+  ScriptHandle asScript() {
+    if (!isScript()) throw "Not script";
+    return this as ScriptHandle;
+  }
+
+  bool isExtension() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! ExtensionDeclarationPreludeBegin) {
+      return false;
+    }
+    if (children!.last is! ExtensionDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  ExtensionDeclarationEnd asExtension() {
+    if (!isExtension()) throw "Not extension";
+    return children!.last as ExtensionDeclarationEnd;
+  }
+
+  bool isInvalidTopLevelDeclaration() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! TopLevelMemberBegin) {
+      return false;
+    }
+    if (children!.last is! InvalidTopLevelDeclarationHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isRecoverableError() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! RecoverableErrorHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isRecoverImport() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! RecoverImportHandle) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isMixinDeclaration() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first
+        // ignore: lines_longer_than_80_chars
+        is! ClassOrMixinOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children!.last is! MixinDeclarationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  MixinDeclarationEnd asMixinDeclaration() {
+    if (!isMixinDeclaration()) throw "Not mixin declaration";
+    return children!.last as MixinDeclarationEnd;
+  }
+
+  bool isNamedMixinDeclaration() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first
+        // ignore: lines_longer_than_80_chars
+        is! ClassOrMixinOrNamedMixinApplicationPreludeBegin) {
+      return false;
+    }
+    if (children!.last is! NamedMixinApplicationEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  NamedMixinApplicationEnd asNamedMixinDeclaration() {
+    if (!isNamedMixinDeclaration()) throw "Not named mixin declaration";
+    return children!.last as NamedMixinApplicationEnd;
+  }
+
+  bool isTopLevelMethod() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! TopLevelMemberBegin) {
+      return false;
+    }
+    if (children!.last is! TopLevelMethodEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  TopLevelMethodEnd asTopLevelMethod() {
+    if (!isTopLevelMethod()) throw "Not top level method";
+    return children!.last as TopLevelMethodEnd;
+  }
+
+  bool isTopLevelFields() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! TopLevelMemberBegin) {
+      return false;
+    }
+    if (children!.last is! TopLevelFieldsEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  TopLevelFieldsEnd asTopLevelFields() {
+    if (!isTopLevelFields()) throw "Not top level fields";
+    return children!.last as TopLevelFieldsEnd;
+  }
+
+  bool isLibraryName() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! LibraryNameEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  LibraryNameEnd asLibraryName() {
+    if (!isLibraryName()) throw "Not library name";
+    return children!.last as LibraryNameEnd;
+  }
+
+  bool isPart() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! PartEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  PartEnd asPart() {
+    if (!isPart()) throw "Not part";
+    return children!.last as PartEnd;
+  }
+
+  bool isPartOf() {
+    if (this is! TopLevelDeclarationEnd) {
+      return false;
+    }
+    if (children!.first is! UncategorizedTopLevelDeclarationBegin) {
+      return false;
+    }
+    if (children!.last is! PartOfEnd) {
+      return false;
+    }
+
+    return true;
+  }
+
+  PartOfEnd asPartOf() {
+    if (!isPartOf()) throw "Not part of";
+    return children!.last as PartOfEnd;
+  }
+
+  bool isMetadata() {
+    if (this is! MetadataStarEnd) {
+      return false;
+    }
+    if (children!.first is! MetadataStarBegin) {
+      return false;
+    }
+    return true;
+  }
+
+  MetadataStarEnd asMetadata() {
+    if (!isMetadata()) throw "Not metadata";
+    return this as MetadataStarEnd;
+  }
+
+  bool isFunctionBody() {
+    if (this is BlockFunctionBodyEnd) return true;
+    return false;
+  }
+
+  BlockFunctionBodyEnd asFunctionBody() {
+    if (!isFunctionBody()) throw "Not function body";
+    return this as BlockFunctionBodyEnd;
+  }
+
+  List<E> recursivelyFind<E extends ParserAstNode>() {
+    Set<E> result = {};
+    _recursivelyFindInternal(this, result);
+    return result.toList();
+  }
+
+  static void _recursivelyFindInternal<E extends ParserAstNode>(
+      ParserAstNode node, Set<E> result) {
+    if (node is E) {
+      result.add(node);
+      return;
+    }
+    if (node.children == null) return;
+    for (ParserAstNode child in node.children!) {
+      _recursivelyFindInternal(child, result);
+    }
+  }
+
+  void debugDumpNodeRecursively({String indent = ""}) {
+    print("$indent${runtimeType} (${what}) "
+        "(${deprecatedArguments})");
+    if (children == null) return;
+    for (ParserAstNode child in children!) {
+      child.debugDumpNodeRecursively(indent: "  $indent");
+    }
+  }
+}
+
+extension MetadataStarExtension on MetadataStarEnd {
+  List<MetadataEnd> getMetadataEntries() {
+    List<MetadataEnd> result = [];
+    for (ParserAstNode topLevel in children!) {
+      if (topLevel is! MetadataEnd) continue;
+      result.add(topLevel);
+    }
+    return result;
+  }
+}
+
+extension CompilationUnitExtension on CompilationUnitEnd {
+  List<TopLevelDeclarationEnd> getClasses() {
+    List<TopLevelDeclarationEnd> result = [];
+    for (ParserAstNode topLevel in children!) {
+      if (!topLevel.isClass()) continue;
+      result.add(topLevel as TopLevelDeclarationEnd);
+    }
+    return result;
+  }
+
+  List<TopLevelDeclarationEnd> getMixinDeclarations() {
+    List<TopLevelDeclarationEnd> result = [];
+    for (ParserAstNode topLevel in children!) {
+      if (!topLevel.isMixinDeclaration()) continue;
+      result.add(topLevel as TopLevelDeclarationEnd);
+    }
+    return result;
+  }
+
+  List<ImportEnd> getImports() {
+    List<ImportEnd> result = [];
+    for (ParserAstNode topLevel in children!) {
+      if (!topLevel.isImport()) continue;
+      result.add(topLevel.children!.last as ImportEnd);
+    }
+    return result;
+  }
+
+  List<ExportEnd> getExports() {
+    List<ExportEnd> result = [];
+    for (ParserAstNode topLevel in children!) {
+      if (!topLevel.isExport()) continue;
+      result.add(topLevel.children!.last as ExportEnd);
+    }
+    return result;
+  }
+
+  // List<MetadataStarEnd> getMetadata() {
+  //   List<MetadataStarEnd> result = [];
+  //   for (ParserAstNode topLevel in children) {
+  //     if (!topLevel.isMetadata()) continue;
+  //     result.add(topLevel);
+  //   }
+  //   return result;
+  // }
+
+  // List<EnumEnd> getEnums() {
+  //   List<EnumEnd> result = [];
+  //   for (ParserAstNode topLevel in children) {
+  //     if (!topLevel.isEnum()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<FunctionTypeAliasEnd> getTypedefs() {
+  //   List<FunctionTypeAliasEnd> result = [];
+  //   for (ParserAstNode topLevel in children) {
+  //     if (!topLevel.isTypedef()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<MixinDeclarationEnd> getMixinDeclarations() {
+  //   List<MixinDeclarationEnd> result = [];
+  //   for (ParserAstNode topLevel in children) {
+  //     if (!topLevel.isMixinDeclaration()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  // List<TopLevelMethodEnd> getTopLevelMethods() {
+  //   List<TopLevelMethodEnd> result = [];
+  //   for (ParserAstNode topLevel in children) {
+  //     if (!topLevel.isTopLevelMethod()) continue;
+  //     result.add(topLevel.children.last);
+  //   }
+  //   return result;
+  // }
+
+  CompilationUnitBegin getBegin() {
+    return children!.first as CompilationUnitBegin;
+  }
+}
+
+extension TopLevelDeclarationExtension on TopLevelDeclarationEnd {
+  IdentifierHandle getIdentifier() {
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) return child;
+    }
+    throw "Not found.";
+  }
+
+  ClassDeclarationEnd getClassDeclaration() {
+    if (!isClass()) {
+      throw "Not a class";
+    }
+    for (ParserAstNode child in children!) {
+      if (child is ClassDeclarationEnd) {
+        return child;
+      }
+    }
+    throw "Not found.";
+  }
+}
+
+extension MixinDeclarationExtension on MixinDeclarationEnd {
+  ClassOrMixinOrExtensionBodyEnd getClassOrMixinOrExtensionBody() {
+    for (ParserAstNode child in children!) {
+      if (child is ClassOrMixinOrExtensionBodyEnd) {
+        return child;
+      }
+    }
+    throw "Not found.";
+  }
+}
+
+extension ClassDeclarationExtension on ClassDeclarationEnd {
+  ClassOrMixinOrExtensionBodyEnd getClassOrMixinOrExtensionBody() {
+    for (ParserAstNode child in children!) {
+      if (child is ClassOrMixinOrExtensionBodyEnd) {
+        return child;
+      }
+    }
+    throw "Not found.";
+  }
+
+  ClassExtendsHandle getClassExtends() {
+    for (ParserAstNode child in children!) {
+      if (child is ClassExtendsHandle) return child;
+    }
+    throw "Not found.";
+  }
+
+  ImplementsHandle getClassImplements() {
+    for (ParserAstNode child in children!) {
+      if (child is ImplementsHandle) {
+        return child;
+      }
+    }
+    throw "Not found.";
+  }
+
+  ClassWithClauseHandle? getClassWithClause() {
+    for (ParserAstNode child in children!) {
+      if (child is ClassWithClauseHandle) {
+        return child;
+      }
+    }
+    return null;
+  }
+}
+
+extension ClassOrMixinBodyExtension on ClassOrMixinOrExtensionBodyEnd {
+  List<MemberEnd> getMembers() {
+    List<MemberEnd> members = [];
+    for (ParserAstNode child in children!) {
+      if (child is MemberEnd) {
+        members.add(child);
+      }
+    }
+    return members;
+  }
+}
+
+extension MemberExtension on MemberEnd {
+  bool isClassConstructor() {
+    ParserAstNode child = children![1];
+    if (child is ClassConstructorEnd) return true;
+    return false;
+  }
+
+  ClassConstructorEnd getClassConstructor() {
+    ParserAstNode child = children![1];
+    if (child is ClassConstructorEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassFactoryMethod() {
+    ParserAstNode child = children![1];
+    if (child is ClassFactoryMethodEnd) return true;
+    return false;
+  }
+
+  ClassFactoryMethodEnd getClassFactoryMethod() {
+    ParserAstNode child = children![1];
+    if (child is ClassFactoryMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassFields() {
+    ParserAstNode child = children![1];
+    if (child is ClassFieldsEnd) return true;
+    return false;
+  }
+
+  ClassFieldsEnd getClassFields() {
+    ParserAstNode child = children![1];
+    if (child is ClassFieldsEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinFields() {
+    ParserAstNode child = children![1];
+    if (child is MixinFieldsEnd) return true;
+    return false;
+  }
+
+  MixinFieldsEnd getMixinFields() {
+    ParserAstNode child = children![1];
+    if (child is MixinFieldsEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinMethod() {
+    ParserAstNode child = children![1];
+    if (child is MixinMethodEnd) return true;
+    return false;
+  }
+
+  MixinMethodEnd getMixinMethod() {
+    ParserAstNode child = children![1];
+    if (child is MixinMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinFactoryMethod() {
+    ParserAstNode child = children![1];
+    if (child is MixinFactoryMethodEnd) return true;
+    return false;
+  }
+
+  MixinFactoryMethodEnd getMixinFactoryMethod() {
+    ParserAstNode child = children![1];
+    if (child is MixinFactoryMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isMixinConstructor() {
+    ParserAstNode child = children![1];
+    if (child is MixinConstructorEnd) return true;
+    return false;
+  }
+
+  MixinConstructorEnd getMixinConstructor() {
+    ParserAstNode child = children![1];
+    if (child is MixinConstructorEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassMethod() {
+    ParserAstNode child = children![1];
+    if (child is ClassMethodEnd) return true;
+    return false;
+  }
+
+  ClassMethodEnd getClassMethod() {
+    ParserAstNode child = children![1];
+    if (child is ClassMethodEnd) return child;
+    throw "Not found";
+  }
+
+  bool isClassRecoverableError() {
+    ParserAstNode child = children![1];
+    if (child is RecoverableErrorHandle) return true;
+    return false;
+  }
+}
+
+extension MixinFieldsExtension on MixinFieldsEnd {
+  List<IdentifierHandle> getFieldIdentifiers() {
+    int countLeft = count;
+    List<IdentifierHandle>? identifiers;
+    for (int i = children!.length - 1; i >= 0; i--) {
+      ParserAstNode child = children![i];
+      if (child is IdentifierHandle &&
+          child.context == IdentifierContext.fieldDeclaration) {
+        countLeft--;
+        if (identifiers == null) {
+          identifiers = new List<IdentifierHandle>.filled(count, child);
+        } else {
+          identifiers[countLeft] = child;
+        }
+        if (countLeft == 0) break;
+      }
+    }
+    if (countLeft != 0) throw "Didn't find the expected number of identifiers";
+    return identifiers ?? [];
+  }
+}
+
+extension ExtensionFieldsExtension on ExtensionFieldsEnd {
+  List<IdentifierHandle> getFieldIdentifiers() {
+    int countLeft = count;
+    List<IdentifierHandle>? identifiers;
+    for (int i = children!.length - 1; i >= 0; i--) {
+      ParserAstNode child = children![i];
+      if (child is IdentifierHandle &&
+          child.context == IdentifierContext.fieldDeclaration) {
+        countLeft--;
+        if (identifiers == null) {
+          identifiers = new List<IdentifierHandle>.filled(count, child);
+        } else {
+          identifiers[countLeft] = child;
+        }
+        if (countLeft == 0) break;
+      }
+    }
+    if (countLeft != 0) throw "Didn't find the expected number of identifiers";
+    return identifiers ?? [];
+  }
+}
+
+extension ClassFieldsExtension on ClassFieldsEnd {
+  List<IdentifierHandle> getFieldIdentifiers() {
+    int countLeft = count;
+    List<IdentifierHandle>? identifiers;
+    for (int i = children!.length - 1; i >= 0; i--) {
+      ParserAstNode child = children![i];
+      if (child is IdentifierHandle &&
+          child.context == IdentifierContext.fieldDeclaration) {
+        countLeft--;
+        if (identifiers == null) {
+          identifiers = new List<IdentifierHandle>.filled(count, child);
+        } else {
+          identifiers[countLeft] = child;
+        }
+        if (countLeft == 0) break;
+      }
+    }
+    if (countLeft != 0) throw "Didn't find the expected number of identifiers";
+    return identifiers ?? [];
+  }
+
+  TypeHandle? getFirstType() {
+    for (ParserAstNode child in children!) {
+      if (child is TypeHandle) return child;
+    }
+    return null;
+  }
+
+  FieldInitializerEnd? getFieldInitializer() {
+    for (ParserAstNode child in children!) {
+      if (child is FieldInitializerEnd) return child;
+    }
+    return null;
+  }
+}
+
+extension EnumExtension on EnumEnd {
+  List<IdentifierHandle> getIdentifiers() {
+    List<IdentifierHandle> ids = [];
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) ids.add(child);
+    }
+    return ids;
+  }
+}
+
+extension ExtensionDeclarationExtension on ExtensionDeclarationEnd {
+  List<IdentifierHandle> getIdentifiers() {
+    List<IdentifierHandle> ids = [];
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) ids.add(child);
+    }
+    return ids;
+  }
+}
+
+extension TopLevelMethodExtension on TopLevelMethodEnd {
+  IdentifierHandle getNameIdentifier() {
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) {
+        if (child.context == IdentifierContext.topLevelFunctionDeclaration) {
+          return child;
+        }
+      }
+    }
+    throw "Didn't find the name identifier!";
+  }
+}
+
+extension TypedefExtension on TypedefEnd {
+  IdentifierHandle getNameIdentifier() {
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) {
+        if (child.context == IdentifierContext.typedefDeclaration) {
+          return child;
+        }
+      }
+    }
+    throw "Didn't find the name identifier!";
+  }
+}
+
+extension ImportExtension on ImportEnd {
+  IdentifierHandle? getImportPrefix() {
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) {
+        if (child.context == IdentifierContext.importPrefixDeclaration) {
+          return child;
+        }
+      }
+    }
+  }
+
+  String getImportUriString() {
+    StringBuffer sb = new StringBuffer();
+    bool foundOne = false;
+    for (ParserAstNode child in children!) {
+      if (child is LiteralStringEnd) {
+        LiteralStringBegin uri = child.children!.single as LiteralStringBegin;
+        sb.write(unescapeString(
+            uri.token.lexeme, uri.token, const UnescapeErrorListenerDummy()));
+        foundOne = true;
+      }
+    }
+    if (!foundOne) throw "Didn't find any";
+    return sb.toString();
+  }
+
+  List<String>? getConditionalImportUriStrings() {
+    List<String>? result;
+    for (ParserAstNode child in children!) {
+      if (child is ConditionalUrisEnd) {
+        for (ParserAstNode child2 in child.children!) {
+          if (child2 is ConditionalUriEnd) {
+            LiteralStringEnd end = child2.children!.last as LiteralStringEnd;
+            LiteralStringBegin uri = end.children!.single as LiteralStringBegin;
+            (result ??= []).add(unescapeString(uri.token.lexeme, uri.token,
+                const UnescapeErrorListenerDummy()));
+          }
+        }
+        return result;
+      }
+    }
+    return result;
+  }
+}
+
+extension ExportExtension on ExportEnd {
+  String getExportUriString() {
+    StringBuffer sb = new StringBuffer();
+    bool foundOne = false;
+    for (ParserAstNode child in children!) {
+      if (child is LiteralStringEnd) {
+        LiteralStringBegin uri = child.children!.single as LiteralStringBegin;
+        sb.write(unescapeString(
+            uri.token.lexeme, uri.token, const UnescapeErrorListenerDummy()));
+        foundOne = true;
+      }
+    }
+    if (!foundOne) throw "Didn't find any";
+    return sb.toString();
+  }
+
+  List<String>? getConditionalExportUriStrings() {
+    List<String>? result;
+    for (ParserAstNode child in children!) {
+      if (child is ConditionalUrisEnd) {
+        for (ParserAstNode child2 in child.children!) {
+          if (child2 is ConditionalUriEnd) {
+            LiteralStringEnd end = child2.children!.last as LiteralStringEnd;
+            LiteralStringBegin uri = end.children!.single as LiteralStringBegin;
+            (result ??= []).add(unescapeString(uri.token.lexeme, uri.token,
+                const UnescapeErrorListenerDummy()));
+          }
+        }
+        return result;
+      }
+    }
+    return result;
+  }
+}
+
+extension PartExtension on PartEnd {
+  String getPartUriString() {
+    StringBuffer sb = new StringBuffer();
+    bool foundOne = false;
+    for (ParserAstNode child in children!) {
+      if (child is LiteralStringEnd) {
+        LiteralStringBegin uri = child.children!.single as LiteralStringBegin;
+        sb.write(unescapeString(
+            uri.token.lexeme, uri.token, const UnescapeErrorListenerDummy()));
+        foundOne = true;
+      }
+    }
+    if (!foundOne) throw "Didn't find any";
+    return sb.toString();
+  }
+}
+
+class UnescapeErrorListenerDummy implements UnescapeErrorListener {
+  const UnescapeErrorListenerDummy();
+
+  @override
+  void handleUnescapeError(
+      Message message, covariant location, int offset, int length) {
+    // Purposely doesn't do anything.
+  }
+}
+
+extension TopLevelFieldsExtension on TopLevelFieldsEnd {
+  List<IdentifierHandle> getFieldIdentifiers() {
+    int countLeft = count;
+    List<IdentifierHandle>? identifiers;
+    for (int i = children!.length - 1; i >= 0; i--) {
+      ParserAstNode child = children![i];
+      if (child is IdentifierHandle &&
+          child.context == IdentifierContext.topLevelVariableDeclaration) {
+        countLeft--;
+        if (identifiers == null) {
+          identifiers = new List<IdentifierHandle>.filled(count, child);
+        } else {
+          identifiers[countLeft] = child;
+        }
+        if (countLeft == 0) break;
+      }
+    }
+    if (countLeft != 0) throw "Didn't find the expected number of identifiers";
+    return identifiers ?? [];
+  }
+}
+
+extension ClassMethodExtension on ClassMethodEnd {
+  BlockFunctionBodyEnd? getBlockFunctionBody() {
+    for (ParserAstNode child in children!) {
+      if (child is BlockFunctionBodyEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+
+  String getNameIdentifier() {
+    bool foundType = false;
+    for (ParserAstNode child in children!) {
+      if (child is TypeHandle ||
+          child is NoTypeHandle ||
+          child is VoidKeywordHandle ||
+          child is FunctionTypeEnd) {
+        foundType = true;
+      }
+      if (foundType && child is IdentifierHandle) {
+        return child.token.lexeme;
+      } else if (foundType && child is OperatorNameHandle) {
+        return child.token.lexeme;
+      }
+    }
+    throw "No identifier found: $children";
+  }
+}
+
+extension MixinMethodExtension on MixinMethodEnd {
+  String getNameIdentifier() {
+    bool foundType = false;
+    for (ParserAstNode child in children!) {
+      if (child is TypeHandle ||
+          child is NoTypeHandle ||
+          child is VoidKeywordHandle) {
+        foundType = true;
+      }
+      if (foundType && child is IdentifierHandle) {
+        return child.token.lexeme;
+      } else if (foundType && child is OperatorNameHandle) {
+        return child.token.lexeme;
+      }
+    }
+    throw "No identifier found: $children";
+  }
+}
+
+extension ExtensionMethodExtension on ExtensionMethodEnd {
+  String getNameIdentifier() {
+    bool foundType = false;
+    for (ParserAstNode child in children!) {
+      if (child is TypeHandle ||
+          child is NoTypeHandle ||
+          child is VoidKeywordHandle) {
+        foundType = true;
+      }
+      if (foundType && child is IdentifierHandle) {
+        return child.token.lexeme;
+      } else if (foundType && child is OperatorNameHandle) {
+        return child.token.lexeme;
+      }
+    }
+    throw "No identifier found: $children";
+  }
+}
+
+extension ClassFactoryMethodExtension on ClassFactoryMethodEnd {
+  List<IdentifierHandle> getIdentifiers() {
+    List<IdentifierHandle> result = [];
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) {
+        result.add(child);
+      } else if (child is FormalParametersEnd) {
+        break;
+      }
+    }
+    return result;
+  }
+}
+
+extension ClassConstructorExtension on ClassConstructorEnd {
+  FormalParametersEnd getFormalParameters() {
+    for (ParserAstNode child in children!) {
+      if (child is FormalParametersEnd) {
+        return child;
+      }
+    }
+    throw "Not found";
+  }
+
+  InitializersEnd? getInitializers() {
+    for (ParserAstNode child in children!) {
+      if (child is InitializersEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+
+  BlockFunctionBodyEnd? getBlockFunctionBody() {
+    for (ParserAstNode child in children!) {
+      if (child is BlockFunctionBodyEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+
+  List<IdentifierHandle> getIdentifiers() {
+    List<IdentifierHandle> result = [];
+    for (ParserAstNode child in children!) {
+      if (child is IdentifierHandle) {
+        result.add(child);
+      }
+    }
+    return result;
+  }
+}
+
+extension FormalParametersExtension on FormalParametersEnd {
+  List<FormalParameterEnd> getFormalParameters() {
+    List<FormalParameterEnd> result = [];
+    for (ParserAstNode child in children!) {
+      if (child is FormalParameterEnd) {
+        result.add(child);
+      }
+    }
+    return result;
+  }
+
+  OptionalFormalParametersEnd? getOptionalFormalParameters() {
+    for (ParserAstNode child in children!) {
+      if (child is OptionalFormalParametersEnd) {
+        return child;
+      }
+    }
+    return null;
+  }
+}
+
+extension FormalParameterExtension on FormalParameterEnd {
+  FormalParameterBegin getBegin() {
+    return children!.first as FormalParameterBegin;
+  }
+}
+
+extension OptionalFormalParametersExtension on OptionalFormalParametersEnd {
+  List<FormalParameterEnd> getFormalParameters() {
+    List<FormalParameterEnd> result = [];
+    for (ParserAstNode child in children!) {
+      if (child is FormalParameterEnd) {
+        result.add(child);
+      }
+    }
+    return result;
+  }
+}
+
+extension InitializersExtension on InitializersEnd {
+  List<InitializerEnd> getInitializers() {
+    List<InitializerEnd> result = [];
+    for (ParserAstNode child in children!) {
+      if (child is InitializerEnd) {
+        result.add(child);
+      }
+    }
+    return result;
+  }
+
+  InitializersBegin getBegin() {
+    return children!.first as InitializersBegin;
+  }
+}
+
+extension InitializerExtension on InitializerEnd {
+  InitializerBegin getBegin() {
+    return children!.first as InitializerBegin;
+  }
+}
+
+void main(List<String> args) {
+  File f = new File(args[0]);
+  Uint8List data = f.readAsBytesSync();
+  ParserAstNode ast = getAST(data);
+  if (args.length > 1 && args[1] == "--benchmark") {
+    Stopwatch stopwatch = new Stopwatch()..start();
+    int numRuns = 100;
+    for (int i = 0; i < numRuns; i++) {
+      ParserAstNode ast2 = getAST(data);
+      if (ast.what != ast2.what) {
+        throw "Not the same result every time";
+      }
+    }
+    stopwatch.stop();
+    print("First $numRuns took ${stopwatch.elapsedMilliseconds} ms "
+        "(i.e. ${stopwatch.elapsedMilliseconds / numRuns}ms/iteration)");
+    stopwatch = new Stopwatch()..start();
+    numRuns = 2500;
+    for (int i = 0; i < numRuns; i++) {
+      ParserAstNode ast2 = getAST(data);
+      if (ast.what != ast2.what) {
+        throw "Not the same result every time";
+      }
+    }
+    stopwatch.stop();
+    print("Next $numRuns took ${stopwatch.elapsedMilliseconds} ms "
+        "(i.e. ${stopwatch.elapsedMilliseconds / numRuns}ms/iteration)");
+  } else {
+    print(ast);
+  }
+}
+
+class ParserASTListener extends AbstractParserAstListener {
+  @override
+  void seen(ParserAstNode entry) {
+    switch (entry.type) {
+      case ParserAstType.BEGIN:
+      case ParserAstType.HANDLE:
+        // This just adds stuff.
+        data.add(entry);
+        break;
+      case ParserAstType.END:
+        // End should gobble up everything until the corresponding begin (which
+        // should be the latest begin).
+        int? beginIndex;
+        for (int i = data.length - 1; i >= 0; i--) {
+          if (data[i].type == ParserAstType.BEGIN) {
+            beginIndex = i;
+            break;
+          }
+        }
+        if (beginIndex == null) {
+          throw "Couldn't find a begin for ${entry.what}. Has:\n"
+              "${data.map((e) => "${e.what}: ${e.type}").join("\n")}";
+        }
+        String begin = data[beginIndex].what;
+        String end = entry.what;
+        if (begin == end) {
+          // Exact match.
+        } else if (end == "TopLevelDeclaration" &&
+            (begin == "ExtensionDeclarationPrelude" ||
+                begin == "ClassOrMixinOrNamedMixinApplicationPrelude" ||
+                begin == "TopLevelMember" ||
+                begin == "UncategorizedTopLevelDeclaration")) {
+          // endTopLevelDeclaration is started by one of
+          // beginExtensionDeclarationPrelude,
+          // beginClassOrNamedMixinApplicationPrelude
+          // beginTopLevelMember or beginUncategorizedTopLevelDeclaration.
+        } else if (begin == "Method" &&
+            (end == "ClassConstructor" ||
+                end == "ClassMethod" ||
+                end == "ExtensionConstructor" ||
+                end == "ExtensionMethod" ||
+                end == "MixinConstructor" ||
+                end == "MixinMethod" ||
+                end == "EnumConstructor" ||
+                end == "EnumMethod")) {
+          // beginMethod is ended by one of endClassConstructor,
+          // endClassMethod, endExtensionMethod, endMixinConstructor,
+          // endMixinMethod, endEnumMethod or endEnumConstructor.
+        } else if (begin == "Fields" &&
+            (end == "TopLevelFields" ||
+                end == "ClassFields" ||
+                end == "MixinFields" ||
+                end == "ExtensionFields" ||
+                end == "EnumFields")) {
+          // beginFields is ended by one of endTopLevelFields, endMixinFields,
+          // endEnumFields or endExtensionFields.
+        } else if (begin == "ForStatement" && end == "ForIn") {
+          // beginForStatement is ended by either endForStatement or endForIn.
+        } else if (begin == "FactoryMethod" &&
+            (end == "ClassFactoryMethod" ||
+                end == "MixinFactoryMethod" ||
+                end == "ExtensionFactoryMethod" ||
+                end == "EnumFactoryMethod")) {
+          // beginFactoryMethod is ended by either endClassFactoryMethod,
+          // endMixinFactoryMethod, endExtensionFactoryMethod, or
+          // endEnumFactoryMethod.
+        } else if (begin == "ForControlFlow" && (end == "ForInControlFlow")) {
+          // beginForControlFlow is ended by either endForControlFlow or
+          // endForInControlFlow.
+        } else if (begin == "IfControlFlow" && (end == "IfElseControlFlow")) {
+          // beginIfControlFlow is ended by either endIfControlFlow or
+          // endIfElseControlFlow.
+        } else if (begin == "AwaitExpression" &&
+            (end == "InvalidAwaitExpression")) {
+          // beginAwaitExpression is ended by either endAwaitExpression or
+          // endInvalidAwaitExpression.
+        } else if (begin == "YieldStatement" &&
+            (end == "InvalidYieldStatement")) {
+          // beginYieldStatement is ended by either endYieldStatement or
+          // endInvalidYieldStatement.
+        } else {
+          throw "Unknown combination: begin$begin and end$end";
+        }
+        List<ParserAstNode> children = data.sublist(beginIndex);
+        for (ParserAstNode child in children) {
+          child.parent = entry;
+        }
+        data.length = beginIndex;
+        data.add(entry..children = children);
+        break;
+    }
+  }
+
+  @override
+  void reportVarianceModifierNotEnabled(Token? variance) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  Uri get uri => throw new UnimplementedError();
+
+  @override
+  void logEvent(String name) {
+    throw new UnimplementedError();
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart b/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart
new file mode 100644
index 0000000..13348fd
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/util/parser_ast_helper.dart
@@ -0,0 +1,7167 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/parser/assert.dart';
+import 'package:_fe_analyzer_shared/src/parser/block_kind.dart';
+import 'package:_fe_analyzer_shared/src/parser/constructor_reference_context.dart';
+import 'package:_fe_analyzer_shared/src/parser/declaration_kind.dart';
+import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
+import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
+import 'package:_fe_analyzer_shared/src/parser/listener.dart';
+import 'package:_fe_analyzer_shared/src/parser/member_kind.dart';
+import 'package:_fe_analyzer_shared/src/scanner/error_token.dart';
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:front_end/src/fasta/messages.dart';
+
+// ignore_for_file: lines_longer_than_80_chars
+
+// THIS FILE IS AUTO GENERATED BY
+// 'tool/_fasta/parser_ast_helper_creator.dart'
+// Run this command to update it:
+// 'dart pkg/front_end/tool/_fasta/parser_ast_helper_creator.dart'
+
+abstract class ParserAstNode {
+  final String what;
+  final ParserAstType type;
+  Map<String, Object?> get deprecatedArguments;
+  List<ParserAstNode>? children;
+  ParserAstNode? parent;
+
+  ParserAstNode(this.what, this.type);
+
+  // TODO(jensj): Compare two ASTs.
+}
+
+enum ParserAstType { BEGIN, END, HANDLE }
+
+abstract class AbstractParserAstListener implements Listener {
+  List<ParserAstNode> data = [];
+
+  void seen(ParserAstNode entry);
+
+  @override
+  void beginArguments(Token token) {
+    ArgumentsBegin data = new ArgumentsBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endArguments(int count, Token beginToken, Token endToken) {
+    ArgumentsEnd data = new ArgumentsEnd(ParserAstType.END,
+        count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleAsyncModifier(Token? asyncToken, Token? starToken) {
+    AsyncModifierHandle data = new AsyncModifierHandle(ParserAstType.HANDLE,
+        asyncToken: asyncToken, starToken: starToken);
+    seen(data);
+  }
+
+  @override
+  void beginAwaitExpression(Token token) {
+    AwaitExpressionBegin data =
+        new AwaitExpressionBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endAwaitExpression(Token beginToken, Token endToken) {
+    AwaitExpressionEnd data = new AwaitExpressionEnd(ParserAstType.END,
+        beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endInvalidAwaitExpression(
+      Token beginToken, Token endToken, MessageCode errorCode) {
+    InvalidAwaitExpressionEnd data = new InvalidAwaitExpressionEnd(
+        ParserAstType.END,
+        beginToken: beginToken,
+        endToken: endToken,
+        errorCode: errorCode);
+    seen(data);
+  }
+
+  @override
+  void beginBlock(Token token, BlockKind blockKind) {
+    BlockBegin data =
+        new BlockBegin(ParserAstType.BEGIN, token: token, blockKind: blockKind);
+    seen(data);
+  }
+
+  @override
+  void endBlock(
+      int count, Token beginToken, Token endToken, BlockKind blockKind) {
+    BlockEnd data = new BlockEnd(ParserAstType.END,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken,
+        blockKind: blockKind);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidTopLevelBlock(Token token) {
+    InvalidTopLevelBlockHandle data =
+        new InvalidTopLevelBlockHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginCascade(Token token) {
+    CascadeBegin data = new CascadeBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endCascade() {
+    CascadeEnd data = new CascadeEnd(ParserAstType.END);
+    seen(data);
+  }
+
+  @override
+  void beginCaseExpression(Token caseKeyword) {
+    CaseExpressionBegin data =
+        new CaseExpressionBegin(ParserAstType.BEGIN, caseKeyword: caseKeyword);
+    seen(data);
+  }
+
+  @override
+  void endCaseExpression(Token colon) {
+    CaseExpressionEnd data =
+        new CaseExpressionEnd(ParserAstType.END, colon: colon);
+    seen(data);
+  }
+
+  @override
+  void beginClassOrMixinOrExtensionBody(DeclarationKind kind, Token token) {
+    ClassOrMixinOrExtensionBodyBegin data =
+        new ClassOrMixinOrExtensionBodyBegin(ParserAstType.BEGIN,
+            kind: kind, token: token);
+    seen(data);
+  }
+
+  @override
+  void endClassOrMixinOrExtensionBody(
+      DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
+    ClassOrMixinOrExtensionBodyEnd data = new ClassOrMixinOrExtensionBodyEnd(
+        ParserAstType.END,
+        kind: kind,
+        memberCount: memberCount,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginClassOrMixinOrNamedMixinApplicationPrelude(Token token) {
+    ClassOrMixinOrNamedMixinApplicationPreludeBegin data =
+        new ClassOrMixinOrNamedMixinApplicationPreludeBegin(ParserAstType.BEGIN,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void beginClassDeclaration(Token begin, Token? abstractToken, Token name) {
+    ClassDeclarationBegin data = new ClassDeclarationBegin(ParserAstType.BEGIN,
+        begin: begin, abstractToken: abstractToken, name: name);
+    seen(data);
+  }
+
+  @override
+  void handleClassExtends(Token? extendsKeyword, int typeCount) {
+    ClassExtendsHandle data = new ClassExtendsHandle(ParserAstType.HANDLE,
+        extendsKeyword: extendsKeyword, typeCount: typeCount);
+    seen(data);
+  }
+
+  @override
+  void handleImplements(Token? implementsKeyword, int interfacesCount) {
+    ImplementsHandle data = new ImplementsHandle(ParserAstType.HANDLE,
+        implementsKeyword: implementsKeyword, interfacesCount: interfacesCount);
+    seen(data);
+  }
+
+  @override
+  void handleExtensionShowHide(Token? showKeyword, int showElementCount,
+      Token? hideKeyword, int hideElementCount) {
+    ExtensionShowHideHandle data = new ExtensionShowHideHandle(
+        ParserAstType.HANDLE,
+        showKeyword: showKeyword,
+        showElementCount: showElementCount,
+        hideKeyword: hideKeyword,
+        hideElementCount: hideElementCount);
+    seen(data);
+  }
+
+  @override
+  void handleClassHeader(Token begin, Token classKeyword, Token? nativeToken) {
+    ClassHeaderHandle data = new ClassHeaderHandle(ParserAstType.HANDLE,
+        begin: begin, classKeyword: classKeyword, nativeToken: nativeToken);
+    seen(data);
+  }
+
+  @override
+  void handleRecoverClassHeader() {
+    RecoverClassHeaderHandle data =
+        new RecoverClassHeaderHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void endClassDeclaration(Token beginToken, Token endToken) {
+    ClassDeclarationEnd data = new ClassDeclarationEnd(ParserAstType.END,
+        beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginMixinDeclaration(Token mixinKeyword, Token name) {
+    MixinDeclarationBegin data = new MixinDeclarationBegin(ParserAstType.BEGIN,
+        mixinKeyword: mixinKeyword, name: name);
+    seen(data);
+  }
+
+  @override
+  void handleMixinOn(Token? onKeyword, int typeCount) {
+    MixinOnHandle data = new MixinOnHandle(ParserAstType.HANDLE,
+        onKeyword: onKeyword, typeCount: typeCount);
+    seen(data);
+  }
+
+  @override
+  void handleMixinHeader(Token mixinKeyword) {
+    MixinHeaderHandle data =
+        new MixinHeaderHandle(ParserAstType.HANDLE, mixinKeyword: mixinKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleRecoverMixinHeader() {
+    RecoverMixinHeaderHandle data =
+        new RecoverMixinHeaderHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
+    MixinDeclarationEnd data = new MixinDeclarationEnd(ParserAstType.END,
+        mixinKeyword: mixinKeyword, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginUncategorizedTopLevelDeclaration(Token token) {
+    UncategorizedTopLevelDeclarationBegin data =
+        new UncategorizedTopLevelDeclarationBegin(ParserAstType.BEGIN,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void beginExtensionDeclarationPrelude(Token extensionKeyword) {
+    ExtensionDeclarationPreludeBegin data =
+        new ExtensionDeclarationPreludeBegin(ParserAstType.BEGIN,
+            extensionKeyword: extensionKeyword);
+    seen(data);
+  }
+
+  @override
+  void beginExtensionDeclaration(Token extensionKeyword, Token? name) {
+    ExtensionDeclarationBegin data = new ExtensionDeclarationBegin(
+        ParserAstType.BEGIN,
+        extensionKeyword: extensionKeyword,
+        name: name);
+    seen(data);
+  }
+
+  @override
+  void endExtensionDeclaration(Token extensionKeyword, Token? typeKeyword,
+      Token onKeyword, Token? showKeyword, Token? hideKeyword, Token endToken) {
+    ExtensionDeclarationEnd data = new ExtensionDeclarationEnd(
+        ParserAstType.END,
+        extensionKeyword: extensionKeyword,
+        typeKeyword: typeKeyword,
+        onKeyword: onKeyword,
+        showKeyword: showKeyword,
+        hideKeyword: hideKeyword,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginCombinators(Token token) {
+    CombinatorsBegin data =
+        new CombinatorsBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endCombinators(int count) {
+    CombinatorsEnd data = new CombinatorsEnd(ParserAstType.END, count: count);
+    seen(data);
+  }
+
+  @override
+  void beginCompilationUnit(Token token) {
+    CompilationUnitBegin data =
+        new CompilationUnitBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleDirectivesOnly() {
+    DirectivesOnlyHandle data = new DirectivesOnlyHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void endCompilationUnit(int count, Token token) {
+    CompilationUnitEnd data =
+        new CompilationUnitEnd(ParserAstType.END, count: count, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginConstLiteral(Token token) {
+    ConstLiteralBegin data =
+        new ConstLiteralBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endConstLiteral(Token token) {
+    ConstLiteralEnd data = new ConstLiteralEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginConstructorReference(Token start) {
+    ConstructorReferenceBegin data =
+        new ConstructorReferenceBegin(ParserAstType.BEGIN, start: start);
+    seen(data);
+  }
+
+  @override
+  void endConstructorReference(Token start, Token? periodBeforeName,
+      Token endToken, ConstructorReferenceContext constructorReferenceContext) {
+    ConstructorReferenceEnd data = new ConstructorReferenceEnd(
+        ParserAstType.END,
+        start: start,
+        periodBeforeName: periodBeforeName,
+        endToken: endToken,
+        constructorReferenceContext: constructorReferenceContext);
+    seen(data);
+  }
+
+  @override
+  void beginDoWhileStatement(Token token) {
+    DoWhileStatementBegin data =
+        new DoWhileStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endDoWhileStatement(
+      Token doKeyword, Token whileKeyword, Token endToken) {
+    DoWhileStatementEnd data = new DoWhileStatementEnd(ParserAstType.END,
+        doKeyword: doKeyword, whileKeyword: whileKeyword, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginDoWhileStatementBody(Token token) {
+    DoWhileStatementBodyBegin data =
+        new DoWhileStatementBodyBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endDoWhileStatementBody(Token token) {
+    DoWhileStatementBodyEnd data =
+        new DoWhileStatementBodyEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginWhileStatementBody(Token token) {
+    WhileStatementBodyBegin data =
+        new WhileStatementBodyBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endWhileStatementBody(Token token) {
+    WhileStatementBodyEnd data =
+        new WhileStatementBodyEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginEnum(Token enumKeyword) {
+    EnumBegin data =
+        new EnumBegin(ParserAstType.BEGIN, enumKeyword: enumKeyword);
+    seen(data);
+  }
+
+  @override
+  void endEnum(Token enumKeyword, Token leftBrace, int memberCount) {
+    EnumEnd data = new EnumEnd(ParserAstType.END,
+        enumKeyword: enumKeyword,
+        leftBrace: leftBrace,
+        memberCount: memberCount);
+    seen(data);
+  }
+
+  @override
+  void endEnumConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    EnumConstructorEnd data = new EnumConstructorEnd(ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleEnumElements(Token elementsEndToken, int elementsCount) {
+    EnumElementsHandle data = new EnumElementsHandle(ParserAstType.HANDLE,
+        elementsEndToken: elementsEndToken, elementsCount: elementsCount);
+    seen(data);
+  }
+
+  @override
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
+    EnumHeaderHandle data = new EnumHeaderHandle(ParserAstType.HANDLE,
+        enumKeyword: enumKeyword, leftBrace: leftBrace);
+    seen(data);
+  }
+
+  @override
+  void handleEnumElement(Token beginToken) {
+    EnumElementHandle data =
+        new EnumElementHandle(ParserAstType.HANDLE, beginToken: beginToken);
+    seen(data);
+  }
+
+  @override
+  void endEnumFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    EnumFactoryMethodEnd data = new EnumFactoryMethodEnd(ParserAstType.END,
+        beginToken: beginToken,
+        factoryKeyword: factoryKeyword,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginExport(Token token) {
+    ExportBegin data = new ExportBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endExport(Token exportKeyword, Token semicolon) {
+    ExportEnd data = new ExportEnd(ParserAstType.END,
+        exportKeyword: exportKeyword, semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void handleExtraneousExpression(Token token, Message message) {
+    ExtraneousExpressionHandle data = new ExtraneousExpressionHandle(
+        ParserAstType.HANDLE,
+        token: token,
+        message: message);
+    seen(data);
+  }
+
+  @override
+  void handleExpressionStatement(Token token) {
+    ExpressionStatementHandle data =
+        new ExpressionStatementHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginFactoryMethod(DeclarationKind declarationKind, Token lastConsumed,
+      Token? externalToken, Token? constToken) {
+    FactoryMethodBegin data = new FactoryMethodBegin(ParserAstType.BEGIN,
+        declarationKind: declarationKind,
+        lastConsumed: lastConsumed,
+        externalToken: externalToken,
+        constToken: constToken);
+    seen(data);
+  }
+
+  @override
+  void endClassFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    ClassFactoryMethodEnd data = new ClassFactoryMethodEnd(ParserAstType.END,
+        beginToken: beginToken,
+        factoryKeyword: factoryKeyword,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endMixinFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    MixinFactoryMethodEnd data = new MixinFactoryMethodEnd(ParserAstType.END,
+        beginToken: beginToken,
+        factoryKeyword: factoryKeyword,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endExtensionFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    ExtensionFactoryMethodEnd data = new ExtensionFactoryMethodEnd(
+        ParserAstType.END,
+        beginToken: beginToken,
+        factoryKeyword: factoryKeyword,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginFormalParameter(Token token, MemberKind kind, Token? requiredToken,
+      Token? covariantToken, Token? varFinalOrConst) {
+    FormalParameterBegin data = new FormalParameterBegin(ParserAstType.BEGIN,
+        token: token,
+        kind: kind,
+        requiredToken: requiredToken,
+        covariantToken: covariantToken,
+        varFinalOrConst: varFinalOrConst);
+    seen(data);
+  }
+
+  @override
+  void endFormalParameter(
+      Token? thisKeyword,
+      Token? superKeyword,
+      Token? periodAfterThisOrSuper,
+      Token nameToken,
+      Token? initializerStart,
+      Token? initializerEnd,
+      FormalParameterKind kind,
+      MemberKind memberKind) {
+    FormalParameterEnd data = new FormalParameterEnd(ParserAstType.END,
+        thisKeyword: thisKeyword,
+        superKeyword: superKeyword,
+        periodAfterThisOrSuper: periodAfterThisOrSuper,
+        nameToken: nameToken,
+        initializerStart: initializerStart,
+        initializerEnd: initializerEnd,
+        kind: kind,
+        memberKind: memberKind);
+    seen(data);
+  }
+
+  @override
+  void handleNoFormalParameters(Token token, MemberKind kind) {
+    NoFormalParametersHandle data = new NoFormalParametersHandle(
+        ParserAstType.HANDLE,
+        token: token,
+        kind: kind);
+    seen(data);
+  }
+
+  @override
+  void beginFormalParameters(Token token, MemberKind kind) {
+    FormalParametersBegin data = new FormalParametersBegin(ParserAstType.BEGIN,
+        token: token, kind: kind);
+    seen(data);
+  }
+
+  @override
+  void endFormalParameters(
+      int count, Token beginToken, Token endToken, MemberKind kind) {
+    FormalParametersEnd data = new FormalParametersEnd(ParserAstType.END,
+        count: count, beginToken: beginToken, endToken: endToken, kind: kind);
+    seen(data);
+  }
+
+  @override
+  void endClassFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    ClassFieldsEnd data = new ClassFieldsEnd(ParserAstType.END,
+        abstractToken: abstractToken,
+        externalToken: externalToken,
+        staticToken: staticToken,
+        covariantToken: covariantToken,
+        lateToken: lateToken,
+        varFinalOrConst: varFinalOrConst,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endMixinFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    MixinFieldsEnd data = new MixinFieldsEnd(ParserAstType.END,
+        abstractToken: abstractToken,
+        externalToken: externalToken,
+        staticToken: staticToken,
+        covariantToken: covariantToken,
+        lateToken: lateToken,
+        varFinalOrConst: varFinalOrConst,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endExtensionFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    ExtensionFieldsEnd data = new ExtensionFieldsEnd(ParserAstType.END,
+        abstractToken: abstractToken,
+        externalToken: externalToken,
+        staticToken: staticToken,
+        covariantToken: covariantToken,
+        lateToken: lateToken,
+        varFinalOrConst: varFinalOrConst,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endEnumFields(
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    EnumFieldsEnd data = new EnumFieldsEnd(ParserAstType.END,
+        abstractToken: abstractToken,
+        externalToken: externalToken,
+        staticToken: staticToken,
+        covariantToken: covariantToken,
+        lateToken: lateToken,
+        varFinalOrConst: varFinalOrConst,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endEnumMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    EnumMethodEnd data = new EnumMethodEnd(ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleForInitializerEmptyStatement(Token token) {
+    ForInitializerEmptyStatementHandle data =
+        new ForInitializerEmptyStatementHandle(ParserAstType.HANDLE,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void handleForInitializerExpressionStatement(Token token, bool forIn) {
+    ForInitializerExpressionStatementHandle data =
+        new ForInitializerExpressionStatementHandle(ParserAstType.HANDLE,
+            token: token, forIn: forIn);
+    seen(data);
+  }
+
+  @override
+  void handleForInitializerLocalVariableDeclaration(Token token, bool forIn) {
+    ForInitializerLocalVariableDeclarationHandle data =
+        new ForInitializerLocalVariableDeclarationHandle(ParserAstType.HANDLE,
+            token: token, forIn: forIn);
+    seen(data);
+  }
+
+  @override
+  void beginForStatement(Token token) {
+    ForStatementBegin data =
+        new ForStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {
+    ForLoopPartsHandle data = new ForLoopPartsHandle(ParserAstType.HANDLE,
+        forKeyword: forKeyword,
+        leftParen: leftParen,
+        leftSeparator: leftSeparator,
+        updateExpressionCount: updateExpressionCount);
+    seen(data);
+  }
+
+  @override
+  void endForStatement(Token endToken) {
+    ForStatementEnd data =
+        new ForStatementEnd(ParserAstType.END, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginForStatementBody(Token token) {
+    ForStatementBodyBegin data =
+        new ForStatementBodyBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endForStatementBody(Token token) {
+    ForStatementBodyEnd data =
+        new ForStatementBodyEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleForInLoopParts(Token? awaitToken, Token forToken,
+      Token leftParenthesis, Token inKeyword) {
+    ForInLoopPartsHandle data = new ForInLoopPartsHandle(ParserAstType.HANDLE,
+        awaitToken: awaitToken,
+        forToken: forToken,
+        leftParenthesis: leftParenthesis,
+        inKeyword: inKeyword);
+    seen(data);
+  }
+
+  @override
+  void endForIn(Token endToken) {
+    ForInEnd data = new ForInEnd(ParserAstType.END, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginForInExpression(Token token) {
+    ForInExpressionBegin data =
+        new ForInExpressionBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endForInExpression(Token token) {
+    ForInExpressionEnd data =
+        new ForInExpressionEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginForInBody(Token token) {
+    ForInBodyBegin data = new ForInBodyBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endForInBody(Token token) {
+    ForInBodyEnd data = new ForInBodyEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginNamedFunctionExpression(Token token) {
+    NamedFunctionExpressionBegin data =
+        new NamedFunctionExpressionBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endNamedFunctionExpression(Token endToken) {
+    NamedFunctionExpressionEnd data =
+        new NamedFunctionExpressionEnd(ParserAstType.END, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginLocalFunctionDeclaration(Token token) {
+    LocalFunctionDeclarationBegin data =
+        new LocalFunctionDeclarationBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endLocalFunctionDeclaration(Token endToken) {
+    LocalFunctionDeclarationEnd data =
+        new LocalFunctionDeclarationEnd(ParserAstType.END, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginBlockFunctionBody(Token token) {
+    BlockFunctionBodyBegin data =
+        new BlockFunctionBodyBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
+    BlockFunctionBodyEnd data = new BlockFunctionBodyEnd(ParserAstType.END,
+        count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleNoFunctionBody(Token token) {
+    NoFunctionBodyHandle data =
+        new NoFunctionBodyHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
+    FunctionBodySkippedHandle data = new FunctionBodySkippedHandle(
+        ParserAstType.HANDLE,
+        token: token,
+        isExpressionBody: isExpressionBody);
+    seen(data);
+  }
+
+  @override
+  void beginFunctionName(Token token) {
+    FunctionNameBegin data =
+        new FunctionNameBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endFunctionName(Token beginToken, Token token) {
+    FunctionNameEnd data = new FunctionNameEnd(ParserAstType.END,
+        beginToken: beginToken, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginTypedef(Token token) {
+    TypedefBegin data = new TypedefBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endTypedef(Token typedefKeyword, Token? equals, Token endToken) {
+    TypedefEnd data = new TypedefEnd(ParserAstType.END,
+        typedefKeyword: typedefKeyword, equals: equals, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleClassWithClause(Token withKeyword) {
+    ClassWithClauseHandle data = new ClassWithClauseHandle(ParserAstType.HANDLE,
+        withKeyword: withKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleClassNoWithClause() {
+    ClassNoWithClauseHandle data =
+        new ClassNoWithClauseHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void handleEnumWithClause(Token withKeyword) {
+    EnumWithClauseHandle data = new EnumWithClauseHandle(ParserAstType.HANDLE,
+        withKeyword: withKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleEnumNoWithClause() {
+    EnumNoWithClauseHandle data =
+        new EnumNoWithClauseHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void beginNamedMixinApplication(
+      Token begin, Token? abstractToken, Token name) {
+    NamedMixinApplicationBegin data = new NamedMixinApplicationBegin(
+        ParserAstType.BEGIN,
+        begin: begin,
+        abstractToken: abstractToken,
+        name: name);
+    seen(data);
+  }
+
+  @override
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    NamedMixinApplicationWithClauseHandle data =
+        new NamedMixinApplicationWithClauseHandle(ParserAstType.HANDLE,
+            withKeyword: withKeyword);
+    seen(data);
+  }
+
+  @override
+  void endNamedMixinApplication(Token begin, Token classKeyword, Token equals,
+      Token? implementsKeyword, Token endToken) {
+    NamedMixinApplicationEnd data = new NamedMixinApplicationEnd(
+        ParserAstType.END,
+        begin: begin,
+        classKeyword: classKeyword,
+        equals: equals,
+        implementsKeyword: implementsKeyword,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginHide(Token hideKeyword) {
+    HideBegin data =
+        new HideBegin(ParserAstType.BEGIN, hideKeyword: hideKeyword);
+    seen(data);
+  }
+
+  @override
+  void endHide(Token hideKeyword) {
+    HideEnd data = new HideEnd(ParserAstType.END, hideKeyword: hideKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleIdentifierList(int count) {
+    IdentifierListHandle data =
+        new IdentifierListHandle(ParserAstType.HANDLE, count: count);
+    seen(data);
+  }
+
+  @override
+  void beginTypeList(Token token) {
+    TypeListBegin data = new TypeListBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endTypeList(int count) {
+    TypeListEnd data = new TypeListEnd(ParserAstType.END, count: count);
+    seen(data);
+  }
+
+  @override
+  void beginIfStatement(Token token) {
+    IfStatementBegin data =
+        new IfStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endIfStatement(Token ifToken, Token? elseToken) {
+    IfStatementEnd data = new IfStatementEnd(ParserAstType.END,
+        ifToken: ifToken, elseToken: elseToken);
+    seen(data);
+  }
+
+  @override
+  void beginThenStatement(Token token) {
+    ThenStatementBegin data =
+        new ThenStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endThenStatement(Token token) {
+    ThenStatementEnd data =
+        new ThenStatementEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginElseStatement(Token token) {
+    ElseStatementBegin data =
+        new ElseStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endElseStatement(Token token) {
+    ElseStatementEnd data =
+        new ElseStatementEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginImport(Token importKeyword) {
+    ImportBegin data =
+        new ImportBegin(ParserAstType.BEGIN, importKeyword: importKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleImportPrefix(Token? deferredKeyword, Token? asKeyword) {
+    ImportPrefixHandle data = new ImportPrefixHandle(ParserAstType.HANDLE,
+        deferredKeyword: deferredKeyword, asKeyword: asKeyword);
+    seen(data);
+  }
+
+  @override
+  void endImport(Token importKeyword, Token? semicolon) {
+    ImportEnd data = new ImportEnd(ParserAstType.END,
+        importKeyword: importKeyword, semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void handleRecoverImport(Token? semicolon) {
+    RecoverImportHandle data =
+        new RecoverImportHandle(ParserAstType.HANDLE, semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void beginConditionalUris(Token token) {
+    ConditionalUrisBegin data =
+        new ConditionalUrisBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endConditionalUris(int count) {
+    ConditionalUrisEnd data =
+        new ConditionalUrisEnd(ParserAstType.END, count: count);
+    seen(data);
+  }
+
+  @override
+  void beginConditionalUri(Token ifKeyword) {
+    ConditionalUriBegin data =
+        new ConditionalUriBegin(ParserAstType.BEGIN, ifKeyword: ifKeyword);
+    seen(data);
+  }
+
+  @override
+  void endConditionalUri(Token ifKeyword, Token leftParen, Token? equalSign) {
+    ConditionalUriEnd data = new ConditionalUriEnd(ParserAstType.END,
+        ifKeyword: ifKeyword, leftParen: leftParen, equalSign: equalSign);
+    seen(data);
+  }
+
+  @override
+  void handleDottedName(int count, Token firstIdentifier) {
+    DottedNameHandle data = new DottedNameHandle(ParserAstType.HANDLE,
+        count: count, firstIdentifier: firstIdentifier);
+    seen(data);
+  }
+
+  @override
+  void beginImplicitCreationExpression(Token token) {
+    ImplicitCreationExpressionBegin data =
+        new ImplicitCreationExpressionBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endImplicitCreationExpression(Token token, Token openAngleBracket) {
+    ImplicitCreationExpressionEnd data = new ImplicitCreationExpressionEnd(
+        ParserAstType.END,
+        token: token,
+        openAngleBracket: openAngleBracket);
+    seen(data);
+  }
+
+  @override
+  void beginInitializedIdentifier(Token token) {
+    InitializedIdentifierBegin data =
+        new InitializedIdentifierBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endInitializedIdentifier(Token nameToken) {
+    InitializedIdentifierEnd data =
+        new InitializedIdentifierEnd(ParserAstType.END, nameToken: nameToken);
+    seen(data);
+  }
+
+  @override
+  void beginFieldInitializer(Token token) {
+    FieldInitializerBegin data =
+        new FieldInitializerBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endFieldInitializer(Token assignment, Token token) {
+    FieldInitializerEnd data = new FieldInitializerEnd(ParserAstType.END,
+        assignment: assignment, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNoFieldInitializer(Token token) {
+    NoFieldInitializerHandle data =
+        new NoFieldInitializerHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginVariableInitializer(Token token) {
+    VariableInitializerBegin data =
+        new VariableInitializerBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endVariableInitializer(Token assignmentOperator) {
+    VariableInitializerEnd data = new VariableInitializerEnd(ParserAstType.END,
+        assignmentOperator: assignmentOperator);
+    seen(data);
+  }
+
+  @override
+  void handleNoVariableInitializer(Token token) {
+    NoVariableInitializerHandle data =
+        new NoVariableInitializerHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginInitializer(Token token) {
+    InitializerBegin data =
+        new InitializerBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endInitializer(Token token) {
+    InitializerEnd data = new InitializerEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginInitializers(Token token) {
+    InitializersBegin data =
+        new InitializersBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endInitializers(int count, Token beginToken, Token endToken) {
+    InitializersEnd data = new InitializersEnd(ParserAstType.END,
+        count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleNoInitializers() {
+    NoInitializersHandle data = new NoInitializersHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidExpression(Token token) {
+    InvalidExpressionHandle data =
+        new InvalidExpressionHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidFunctionBody(Token token) {
+    InvalidFunctionBodyHandle data =
+        new InvalidFunctionBodyHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidTypeReference(Token token) {
+    InvalidTypeReferenceHandle data =
+        new InvalidTypeReferenceHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleLabel(Token token) {
+    LabelHandle data = new LabelHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginLabeledStatement(Token token, int labelCount) {
+    LabeledStatementBegin data = new LabeledStatementBegin(ParserAstType.BEGIN,
+        token: token, labelCount: labelCount);
+    seen(data);
+  }
+
+  @override
+  void endLabeledStatement(int labelCount) {
+    LabeledStatementEnd data =
+        new LabeledStatementEnd(ParserAstType.END, labelCount: labelCount);
+    seen(data);
+  }
+
+  @override
+  void beginLibraryName(Token token) {
+    LibraryNameBegin data =
+        new LibraryNameBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endLibraryName(Token libraryKeyword, Token semicolon) {
+    LibraryNameEnd data = new LibraryNameEnd(ParserAstType.END,
+        libraryKeyword: libraryKeyword, semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void handleLiteralMapEntry(Token colon, Token endToken) {
+    LiteralMapEntryHandle data = new LiteralMapEntryHandle(ParserAstType.HANDLE,
+        colon: colon, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginLiteralString(Token token) {
+    LiteralStringBegin data =
+        new LiteralStringBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleInterpolationExpression(Token leftBracket, Token? rightBracket) {
+    InterpolationExpressionHandle data = new InterpolationExpressionHandle(
+        ParserAstType.HANDLE,
+        leftBracket: leftBracket,
+        rightBracket: rightBracket);
+    seen(data);
+  }
+
+  @override
+  void endLiteralString(int interpolationCount, Token endToken) {
+    LiteralStringEnd data = new LiteralStringEnd(ParserAstType.END,
+        interpolationCount: interpolationCount, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleStringJuxtaposition(Token startToken, int literalCount) {
+    StringJuxtapositionHandle data = new StringJuxtapositionHandle(
+        ParserAstType.HANDLE,
+        startToken: startToken,
+        literalCount: literalCount);
+    seen(data);
+  }
+
+  @override
+  void beginMember() {
+    MemberBegin data = new MemberBegin(ParserAstType.BEGIN);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidMember(Token endToken) {
+    InvalidMemberHandle data =
+        new InvalidMemberHandle(ParserAstType.HANDLE, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endMember() {
+    MemberEnd data = new MemberEnd(ParserAstType.END);
+    seen(data);
+  }
+
+  @override
+  void beginMethod(
+      DeclarationKind declarationKind,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? varFinalOrConst,
+      Token? getOrSet,
+      Token name) {
+    MethodBegin data = new MethodBegin(ParserAstType.BEGIN,
+        declarationKind: declarationKind,
+        externalToken: externalToken,
+        staticToken: staticToken,
+        covariantToken: covariantToken,
+        varFinalOrConst: varFinalOrConst,
+        getOrSet: getOrSet,
+        name: name);
+    seen(data);
+  }
+
+  @override
+  void endClassMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    ClassMethodEnd data = new ClassMethodEnd(ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endMixinMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    MixinMethodEnd data = new MixinMethodEnd(ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endExtensionMethod(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    ExtensionMethodEnd data = new ExtensionMethodEnd(ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endClassConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    ClassConstructorEnd data = new ClassConstructorEnd(ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endMixinConstructor(Token? getOrSet, Token beginToken, Token beginParam,
+      Token? beginInitializers, Token endToken) {
+    MixinConstructorEnd data = new MixinConstructorEnd(ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endExtensionConstructor(Token? getOrSet, Token beginToken,
+      Token beginParam, Token? beginInitializers, Token endToken) {
+    ExtensionConstructorEnd data = new ExtensionConstructorEnd(
+        ParserAstType.END,
+        getOrSet: getOrSet,
+        beginToken: beginToken,
+        beginParam: beginParam,
+        beginInitializers: beginInitializers,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginMetadataStar(Token token) {
+    MetadataStarBegin data =
+        new MetadataStarBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endMetadataStar(int count) {
+    MetadataStarEnd data = new MetadataStarEnd(ParserAstType.END, count: count);
+    seen(data);
+  }
+
+  @override
+  void beginMetadata(Token token) {
+    MetadataBegin data = new MetadataBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endMetadata(Token beginToken, Token? periodBeforeName, Token endToken) {
+    MetadataEnd data = new MetadataEnd(ParserAstType.END,
+        beginToken: beginToken,
+        periodBeforeName: periodBeforeName,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginOptionalFormalParameters(Token token) {
+    OptionalFormalParametersBegin data =
+        new OptionalFormalParametersBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endOptionalFormalParameters(
+      int count, Token beginToken, Token endToken) {
+    OptionalFormalParametersEnd data = new OptionalFormalParametersEnd(
+        ParserAstType.END,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginPart(Token token) {
+    PartBegin data = new PartBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endPart(Token partKeyword, Token semicolon) {
+    PartEnd data = new PartEnd(ParserAstType.END,
+        partKeyword: partKeyword, semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void beginPartOf(Token token) {
+    PartOfBegin data = new PartOfBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endPartOf(
+      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
+    PartOfEnd data = new PartOfEnd(ParserAstType.END,
+        partKeyword: partKeyword,
+        ofKeyword: ofKeyword,
+        semicolon: semicolon,
+        hasName: hasName);
+    seen(data);
+  }
+
+  @override
+  void beginRedirectingFactoryBody(Token token) {
+    RedirectingFactoryBodyBegin data =
+        new RedirectingFactoryBodyBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endRedirectingFactoryBody(Token beginToken, Token endToken) {
+    RedirectingFactoryBodyEnd data = new RedirectingFactoryBodyEnd(
+        ParserAstType.END,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginReturnStatement(Token token) {
+    ReturnStatementBegin data =
+        new ReturnStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
+    NativeFunctionBodyHandle data = new NativeFunctionBodyHandle(
+        ParserAstType.HANDLE,
+        nativeToken: nativeToken,
+        semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
+    NativeFunctionBodyIgnoredHandle data = new NativeFunctionBodyIgnoredHandle(
+        ParserAstType.HANDLE,
+        nativeToken: nativeToken,
+        semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
+    NativeFunctionBodySkippedHandle data = new NativeFunctionBodySkippedHandle(
+        ParserAstType.HANDLE,
+        nativeToken: nativeToken,
+        semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void handleEmptyFunctionBody(Token semicolon) {
+    EmptyFunctionBodyHandle data =
+        new EmptyFunctionBodyHandle(ParserAstType.HANDLE, semicolon: semicolon);
+    seen(data);
+  }
+
+  @override
+  void handleExpressionFunctionBody(Token arrowToken, Token? endToken) {
+    ExpressionFunctionBodyHandle data = new ExpressionFunctionBodyHandle(
+        ParserAstType.HANDLE,
+        arrowToken: arrowToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endReturnStatement(
+      bool hasExpression, Token beginToken, Token endToken) {
+    ReturnStatementEnd data = new ReturnStatementEnd(ParserAstType.END,
+        hasExpression: hasExpression,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleSend(Token beginToken, Token endToken) {
+    SendHandle data = new SendHandle(ParserAstType.HANDLE,
+        beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginShow(Token showKeyword) {
+    ShowBegin data =
+        new ShowBegin(ParserAstType.BEGIN, showKeyword: showKeyword);
+    seen(data);
+  }
+
+  @override
+  void endShow(Token showKeyword) {
+    ShowEnd data = new ShowEnd(ParserAstType.END, showKeyword: showKeyword);
+    seen(data);
+  }
+
+  @override
+  void beginSwitchStatement(Token token) {
+    SwitchStatementBegin data =
+        new SwitchStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endSwitchStatement(Token switchKeyword, Token endToken) {
+    SwitchStatementEnd data = new SwitchStatementEnd(ParserAstType.END,
+        switchKeyword: switchKeyword, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginSwitchBlock(Token token) {
+    SwitchBlockBegin data =
+        new SwitchBlockBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
+    SwitchBlockEnd data = new SwitchBlockEnd(ParserAstType.END,
+        caseCount: caseCount, beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginLiteralSymbol(Token token) {
+    LiteralSymbolBegin data =
+        new LiteralSymbolBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endLiteralSymbol(Token hashToken, int identifierCount) {
+    LiteralSymbolEnd data = new LiteralSymbolEnd(ParserAstType.END,
+        hashToken: hashToken, identifierCount: identifierCount);
+    seen(data);
+  }
+
+  @override
+  void handleThrowExpression(Token throwToken, Token endToken) {
+    ThrowExpressionHandle data = new ThrowExpressionHandle(ParserAstType.HANDLE,
+        throwToken: throwToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginRethrowStatement(Token token) {
+    RethrowStatementBegin data =
+        new RethrowStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endRethrowStatement(Token rethrowToken, Token endToken) {
+    RethrowStatementEnd data = new RethrowStatementEnd(ParserAstType.END,
+        rethrowToken: rethrowToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endTopLevelDeclaration(Token nextToken) {
+    TopLevelDeclarationEnd data =
+        new TopLevelDeclarationEnd(ParserAstType.END, nextToken: nextToken);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidTopLevelDeclaration(Token endToken) {
+    InvalidTopLevelDeclarationHandle data =
+        new InvalidTopLevelDeclarationHandle(ParserAstType.HANDLE,
+            endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginTopLevelMember(Token token) {
+    TopLevelMemberBegin data =
+        new TopLevelMemberBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginFields(
+      DeclarationKind declarationKind,
+      Token? abstractToken,
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      Token lastConsumed) {
+    FieldsBegin data = new FieldsBegin(ParserAstType.BEGIN,
+        declarationKind: declarationKind,
+        abstractToken: abstractToken,
+        externalToken: externalToken,
+        staticToken: staticToken,
+        covariantToken: covariantToken,
+        lateToken: lateToken,
+        varFinalOrConst: varFinalOrConst,
+        lastConsumed: lastConsumed);
+    seen(data);
+  }
+
+  @override
+  void endTopLevelFields(
+      Token? externalToken,
+      Token? staticToken,
+      Token? covariantToken,
+      Token? lateToken,
+      Token? varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    TopLevelFieldsEnd data = new TopLevelFieldsEnd(ParserAstType.END,
+        externalToken: externalToken,
+        staticToken: staticToken,
+        covariantToken: covariantToken,
+        lateToken: lateToken,
+        varFinalOrConst: varFinalOrConst,
+        count: count,
+        beginToken: beginToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginTopLevelMethod(Token lastConsumed, Token? externalToken) {
+    TopLevelMethodBegin data = new TopLevelMethodBegin(ParserAstType.BEGIN,
+        lastConsumed: lastConsumed, externalToken: externalToken);
+    seen(data);
+  }
+
+  @override
+  void endTopLevelMethod(Token beginToken, Token? getOrSet, Token endToken) {
+    TopLevelMethodEnd data = new TopLevelMethodEnd(ParserAstType.END,
+        beginToken: beginToken, getOrSet: getOrSet, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginTryStatement(Token token) {
+    TryStatementBegin data =
+        new TryStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleCaseMatch(Token caseKeyword, Token colon) {
+    CaseMatchHandle data = new CaseMatchHandle(ParserAstType.HANDLE,
+        caseKeyword: caseKeyword, colon: colon);
+    seen(data);
+  }
+
+  @override
+  void beginCatchClause(Token token) {
+    CatchClauseBegin data =
+        new CatchClauseBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endCatchClause(Token token) {
+    CatchClauseEnd data = new CatchClauseEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleCatchBlock(Token? onKeyword, Token? catchKeyword, Token? comma) {
+    CatchBlockHandle data = new CatchBlockHandle(ParserAstType.HANDLE,
+        onKeyword: onKeyword, catchKeyword: catchKeyword, comma: comma);
+    seen(data);
+  }
+
+  @override
+  void handleFinallyBlock(Token finallyKeyword) {
+    FinallyBlockHandle data = new FinallyBlockHandle(ParserAstType.HANDLE,
+        finallyKeyword: finallyKeyword);
+    seen(data);
+  }
+
+  @override
+  void endTryStatement(
+      int catchCount, Token tryKeyword, Token? finallyKeyword) {
+    TryStatementEnd data = new TryStatementEnd(ParserAstType.END,
+        catchCount: catchCount,
+        tryKeyword: tryKeyword,
+        finallyKeyword: finallyKeyword);
+    seen(data);
+  }
+
+  @override
+  void handleType(Token beginToken, Token? questionMark) {
+    TypeHandle data = new TypeHandle(ParserAstType.HANDLE,
+        beginToken: beginToken, questionMark: questionMark);
+    seen(data);
+  }
+
+  @override
+  void handleNonNullAssertExpression(Token bang) {
+    NonNullAssertExpressionHandle data =
+        new NonNullAssertExpressionHandle(ParserAstType.HANDLE, bang: bang);
+    seen(data);
+  }
+
+  @override
+  void handleNoName(Token token) {
+    NoNameHandle data = new NoNameHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginFunctionType(Token beginToken) {
+    FunctionTypeBegin data =
+        new FunctionTypeBegin(ParserAstType.BEGIN, beginToken: beginToken);
+    seen(data);
+  }
+
+  @override
+  void endFunctionType(Token functionToken, Token? questionMark) {
+    FunctionTypeEnd data = new FunctionTypeEnd(ParserAstType.END,
+        functionToken: functionToken, questionMark: questionMark);
+    seen(data);
+  }
+
+  @override
+  void beginTypeArguments(Token token) {
+    TypeArgumentsBegin data =
+        new TypeArgumentsBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endTypeArguments(int count, Token beginToken, Token endToken) {
+    TypeArgumentsEnd data = new TypeArgumentsEnd(ParserAstType.END,
+        count: count, beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidTypeArguments(Token token) {
+    InvalidTypeArgumentsHandle data =
+        new InvalidTypeArgumentsHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNoTypeArguments(Token token) {
+    NoTypeArgumentsHandle data =
+        new NoTypeArgumentsHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginTypeVariable(Token token) {
+    TypeVariableBegin data =
+        new TypeVariableBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleTypeVariablesDefined(Token token, int count) {
+    TypeVariablesDefinedHandle data = new TypeVariablesDefinedHandle(
+        ParserAstType.HANDLE,
+        token: token,
+        count: count);
+    seen(data);
+  }
+
+  @override
+  void endTypeVariable(
+      Token token, int index, Token? extendsOrSuper, Token? variance) {
+    TypeVariableEnd data = new TypeVariableEnd(ParserAstType.END,
+        token: token,
+        index: index,
+        extendsOrSuper: extendsOrSuper,
+        variance: variance);
+    seen(data);
+  }
+
+  @override
+  void beginTypeVariables(Token token) {
+    TypeVariablesBegin data =
+        new TypeVariablesBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endTypeVariables(Token beginToken, Token endToken) {
+    TypeVariablesEnd data = new TypeVariablesEnd(ParserAstType.END,
+        beginToken: beginToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginFunctionExpression(Token token) {
+    FunctionExpressionBegin data =
+        new FunctionExpressionBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endFunctionExpression(Token beginToken, Token token) {
+    FunctionExpressionEnd data = new FunctionExpressionEnd(ParserAstType.END,
+        beginToken: beginToken, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginVariablesDeclaration(
+      Token token, Token? lateToken, Token? varFinalOrConst) {
+    VariablesDeclarationBegin data = new VariablesDeclarationBegin(
+        ParserAstType.BEGIN,
+        token: token,
+        lateToken: lateToken,
+        varFinalOrConst: varFinalOrConst);
+    seen(data);
+  }
+
+  @override
+  void endVariablesDeclaration(int count, Token? endToken) {
+    VariablesDeclarationEnd data = new VariablesDeclarationEnd(
+        ParserAstType.END,
+        count: count,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginWhileStatement(Token token) {
+    WhileStatementBegin data =
+        new WhileStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endWhileStatement(Token whileKeyword, Token endToken) {
+    WhileStatementEnd data = new WhileStatementEnd(ParserAstType.END,
+        whileKeyword: whileKeyword, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void beginAsOperatorType(Token operator) {
+    AsOperatorTypeBegin data =
+        new AsOperatorTypeBegin(ParserAstType.BEGIN, operator: operator);
+    seen(data);
+  }
+
+  @override
+  void endAsOperatorType(Token operator) {
+    AsOperatorTypeEnd data =
+        new AsOperatorTypeEnd(ParserAstType.END, operator: operator);
+    seen(data);
+  }
+
+  @override
+  void handleAsOperator(Token operator) {
+    AsOperatorHandle data =
+        new AsOperatorHandle(ParserAstType.HANDLE, operator: operator);
+    seen(data);
+  }
+
+  @override
+  void handleAssignmentExpression(Token token) {
+    AssignmentExpressionHandle data =
+        new AssignmentExpressionHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginBinaryExpression(Token token) {
+    BinaryExpressionBegin data =
+        new BinaryExpressionBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endBinaryExpression(Token token) {
+    BinaryExpressionEnd data =
+        new BinaryExpressionEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleEndingBinaryExpression(Token token) {
+    EndingBinaryExpressionHandle data =
+        new EndingBinaryExpressionHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginConditionalExpression(Token question) {
+    ConditionalExpressionBegin data =
+        new ConditionalExpressionBegin(ParserAstType.BEGIN, question: question);
+    seen(data);
+  }
+
+  @override
+  void handleConditionalExpressionColon() {
+    ConditionalExpressionColonHandle data =
+        new ConditionalExpressionColonHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void endConditionalExpression(Token question, Token colon) {
+    ConditionalExpressionEnd data = new ConditionalExpressionEnd(
+        ParserAstType.END,
+        question: question,
+        colon: colon);
+    seen(data);
+  }
+
+  @override
+  void beginConstExpression(Token constKeyword) {
+    ConstExpressionBegin data = new ConstExpressionBegin(ParserAstType.BEGIN,
+        constKeyword: constKeyword);
+    seen(data);
+  }
+
+  @override
+  void endConstExpression(Token token) {
+    ConstExpressionEnd data =
+        new ConstExpressionEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleConstFactory(Token constKeyword) {
+    ConstFactoryHandle data = new ConstFactoryHandle(ParserAstType.HANDLE,
+        constKeyword: constKeyword);
+    seen(data);
+  }
+
+  @override
+  void beginForControlFlow(Token? awaitToken, Token forToken) {
+    ForControlFlowBegin data = new ForControlFlowBegin(ParserAstType.BEGIN,
+        awaitToken: awaitToken, forToken: forToken);
+    seen(data);
+  }
+
+  @override
+  void endForControlFlow(Token token) {
+    ForControlFlowEnd data =
+        new ForControlFlowEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void endForInControlFlow(Token token) {
+    ForInControlFlowEnd data =
+        new ForInControlFlowEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginIfControlFlow(Token ifToken) {
+    IfControlFlowBegin data =
+        new IfControlFlowBegin(ParserAstType.BEGIN, ifToken: ifToken);
+    seen(data);
+  }
+
+  @override
+  void handleThenControlFlow(Token token) {
+    ThenControlFlowHandle data =
+        new ThenControlFlowHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleElseControlFlow(Token elseToken) {
+    ElseControlFlowHandle data =
+        new ElseControlFlowHandle(ParserAstType.HANDLE, elseToken: elseToken);
+    seen(data);
+  }
+
+  @override
+  void endIfControlFlow(Token token) {
+    IfControlFlowEnd data =
+        new IfControlFlowEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void endIfElseControlFlow(Token token) {
+    IfElseControlFlowEnd data =
+        new IfElseControlFlowEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleSpreadExpression(Token spreadToken) {
+    SpreadExpressionHandle data = new SpreadExpressionHandle(
+        ParserAstType.HANDLE,
+        spreadToken: spreadToken);
+    seen(data);
+  }
+
+  @override
+  void beginFunctionTypedFormalParameter(Token token) {
+    FunctionTypedFormalParameterBegin data =
+        new FunctionTypedFormalParameterBegin(ParserAstType.BEGIN,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void endFunctionTypedFormalParameter(Token nameToken, Token? question) {
+    FunctionTypedFormalParameterEnd data = new FunctionTypedFormalParameterEnd(
+        ParserAstType.END,
+        nameToken: nameToken,
+        question: question);
+    seen(data);
+  }
+
+  @override
+  void handleIdentifier(Token token, IdentifierContext context) {
+    IdentifierHandle data = new IdentifierHandle(ParserAstType.HANDLE,
+        token: token, context: context);
+    seen(data);
+  }
+
+  @override
+  void handleShowHideIdentifier(Token? modifier, Token identifier) {
+    ShowHideIdentifierHandle data = new ShowHideIdentifierHandle(
+        ParserAstType.HANDLE,
+        modifier: modifier,
+        identifier: identifier);
+    seen(data);
+  }
+
+  @override
+  void handleIndexedExpression(
+      Token? question, Token openSquareBracket, Token closeSquareBracket) {
+    IndexedExpressionHandle data = new IndexedExpressionHandle(
+        ParserAstType.HANDLE,
+        question: question,
+        openSquareBracket: openSquareBracket,
+        closeSquareBracket: closeSquareBracket);
+    seen(data);
+  }
+
+  @override
+  void beginIsOperatorType(Token operator) {
+    IsOperatorTypeBegin data =
+        new IsOperatorTypeBegin(ParserAstType.BEGIN, operator: operator);
+    seen(data);
+  }
+
+  @override
+  void endIsOperatorType(Token operator) {
+    IsOperatorTypeEnd data =
+        new IsOperatorTypeEnd(ParserAstType.END, operator: operator);
+    seen(data);
+  }
+
+  @override
+  void handleIsOperator(Token isOperator, Token? not) {
+    IsOperatorHandle data = new IsOperatorHandle(ParserAstType.HANDLE,
+        isOperator: isOperator, not: not);
+    seen(data);
+  }
+
+  @override
+  void handleLiteralBool(Token token) {
+    LiteralBoolHandle data =
+        new LiteralBoolHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleBreakStatement(
+      bool hasTarget, Token breakKeyword, Token endToken) {
+    BreakStatementHandle data = new BreakStatementHandle(ParserAstType.HANDLE,
+        hasTarget: hasTarget, breakKeyword: breakKeyword, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleContinueStatement(
+      bool hasTarget, Token continueKeyword, Token endToken) {
+    ContinueStatementHandle data = new ContinueStatementHandle(
+        ParserAstType.HANDLE,
+        hasTarget: hasTarget,
+        continueKeyword: continueKeyword,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleEmptyStatement(Token token) {
+    EmptyStatementHandle data =
+        new EmptyStatementHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void beginAssert(Token assertKeyword, Assert kind) {
+    AssertBegin data = new AssertBegin(ParserAstType.BEGIN,
+        assertKeyword: assertKeyword, kind: kind);
+    seen(data);
+  }
+
+  @override
+  void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis,
+      Token? commaToken, Token semicolonToken) {
+    AssertEnd data = new AssertEnd(ParserAstType.END,
+        assertKeyword: assertKeyword,
+        kind: kind,
+        leftParenthesis: leftParenthesis,
+        commaToken: commaToken,
+        semicolonToken: semicolonToken);
+    seen(data);
+  }
+
+  @override
+  void handleLiteralDouble(Token token) {
+    LiteralDoubleHandle data =
+        new LiteralDoubleHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleLiteralInt(Token token) {
+    LiteralIntHandle data =
+        new LiteralIntHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleLiteralList(
+      int count, Token leftBracket, Token? constKeyword, Token rightBracket) {
+    LiteralListHandle data = new LiteralListHandle(ParserAstType.HANDLE,
+        count: count,
+        leftBracket: leftBracket,
+        constKeyword: constKeyword,
+        rightBracket: rightBracket);
+    seen(data);
+  }
+
+  @override
+  void handleLiteralSetOrMap(
+    int count,
+    Token leftBrace,
+    Token? constKeyword,
+    Token rightBrace,
+    bool hasSetEntry,
+  ) {
+    LiteralSetOrMapHandle data = new LiteralSetOrMapHandle(ParserAstType.HANDLE,
+        count: count,
+        leftBrace: leftBrace,
+        constKeyword: constKeyword,
+        rightBrace: rightBrace,
+        hasSetEntry: hasSetEntry);
+    seen(data);
+  }
+
+  @override
+  void handleLiteralNull(Token token) {
+    LiteralNullHandle data =
+        new LiteralNullHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNativeClause(Token nativeToken, bool hasName) {
+    NativeClauseHandle data = new NativeClauseHandle(ParserAstType.HANDLE,
+        nativeToken: nativeToken, hasName: hasName);
+    seen(data);
+  }
+
+  @override
+  void handleNamedArgument(Token colon) {
+    NamedArgumentHandle data =
+        new NamedArgumentHandle(ParserAstType.HANDLE, colon: colon);
+    seen(data);
+  }
+
+  @override
+  void beginNewExpression(Token token) {
+    NewExpressionBegin data =
+        new NewExpressionBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endNewExpression(Token token) {
+    NewExpressionEnd data =
+        new NewExpressionEnd(ParserAstType.END, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNoArguments(Token token) {
+    NoArgumentsHandle data =
+        new NoArgumentsHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
+    NoConstructorReferenceContinuationAfterTypeArgumentsHandle data =
+        new NoConstructorReferenceContinuationAfterTypeArgumentsHandle(
+            ParserAstType.HANDLE,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNoTypeNameInConstructorReference(Token token) {
+    NoTypeNameInConstructorReferenceHandle data =
+        new NoTypeNameInConstructorReferenceHandle(ParserAstType.HANDLE,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNoType(Token lastConsumed) {
+    NoTypeHandle data =
+        new NoTypeHandle(ParserAstType.HANDLE, lastConsumed: lastConsumed);
+    seen(data);
+  }
+
+  @override
+  void handleNoTypeVariables(Token token) {
+    NoTypeVariablesHandle data =
+        new NoTypeVariablesHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleOperator(Token token) {
+    OperatorHandle data =
+        new OperatorHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleSymbolVoid(Token token) {
+    SymbolVoidHandle data =
+        new SymbolVoidHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleOperatorName(Token operatorKeyword, Token token) {
+    OperatorNameHandle data = new OperatorNameHandle(ParserAstType.HANDLE,
+        operatorKeyword: operatorKeyword, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidOperatorName(Token operatorKeyword, Token token) {
+    InvalidOperatorNameHandle data = new InvalidOperatorNameHandle(
+        ParserAstType.HANDLE,
+        operatorKeyword: operatorKeyword,
+        token: token);
+    seen(data);
+  }
+
+  @override
+  void handleParenthesizedCondition(Token token) {
+    ParenthesizedConditionHandle data =
+        new ParenthesizedConditionHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleParenthesizedExpression(Token token) {
+    ParenthesizedExpressionHandle data =
+        new ParenthesizedExpressionHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleQualified(Token period) {
+    QualifiedHandle data =
+        new QualifiedHandle(ParserAstType.HANDLE, period: period);
+    seen(data);
+  }
+
+  @override
+  void handleStringPart(Token token) {
+    StringPartHandle data =
+        new StringPartHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleSuperExpression(Token token, IdentifierContext context) {
+    SuperExpressionHandle data = new SuperExpressionHandle(ParserAstType.HANDLE,
+        token: token, context: context);
+    seen(data);
+  }
+
+  @override
+  void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
+    SwitchCaseBegin data = new SwitchCaseBegin(ParserAstType.BEGIN,
+        labelCount: labelCount,
+        expressionCount: expressionCount,
+        firstToken: firstToken);
+    seen(data);
+  }
+
+  @override
+  void endSwitchCase(
+      int labelCount,
+      int expressionCount,
+      Token? defaultKeyword,
+      Token? colonAfterDefault,
+      int statementCount,
+      Token firstToken,
+      Token endToken) {
+    SwitchCaseEnd data = new SwitchCaseEnd(ParserAstType.END,
+        labelCount: labelCount,
+        expressionCount: expressionCount,
+        defaultKeyword: defaultKeyword,
+        colonAfterDefault: colonAfterDefault,
+        statementCount: statementCount,
+        firstToken: firstToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleThisExpression(Token token, IdentifierContext context) {
+    ThisExpressionHandle data = new ThisExpressionHandle(ParserAstType.HANDLE,
+        token: token, context: context);
+    seen(data);
+  }
+
+  @override
+  void handleUnaryPostfixAssignmentExpression(Token token) {
+    UnaryPostfixAssignmentExpressionHandle data =
+        new UnaryPostfixAssignmentExpressionHandle(ParserAstType.HANDLE,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void handleUnaryPrefixExpression(Token token) {
+    UnaryPrefixExpressionHandle data =
+        new UnaryPrefixExpressionHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleUnaryPrefixAssignmentExpression(Token token) {
+    UnaryPrefixAssignmentExpressionHandle data =
+        new UnaryPrefixAssignmentExpressionHandle(ParserAstType.HANDLE,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void beginFormalParameterDefaultValueExpression() {
+    FormalParameterDefaultValueExpressionBegin data =
+        new FormalParameterDefaultValueExpressionBegin(ParserAstType.BEGIN);
+    seen(data);
+  }
+
+  @override
+  void endFormalParameterDefaultValueExpression() {
+    FormalParameterDefaultValueExpressionEnd data =
+        new FormalParameterDefaultValueExpressionEnd(ParserAstType.END);
+    seen(data);
+  }
+
+  @override
+  void handleValuedFormalParameter(Token equals, Token token) {
+    ValuedFormalParameterHandle data = new ValuedFormalParameterHandle(
+        ParserAstType.HANDLE,
+        equals: equals,
+        token: token);
+    seen(data);
+  }
+
+  @override
+  void handleFormalParameterWithoutValue(Token token) {
+    FormalParameterWithoutValueHandle data =
+        new FormalParameterWithoutValueHandle(ParserAstType.HANDLE,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void handleVoidKeyword(Token token) {
+    VoidKeywordHandle data =
+        new VoidKeywordHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleVoidKeywordWithTypeArguments(Token token) {
+    VoidKeywordWithTypeArgumentsHandle data =
+        new VoidKeywordWithTypeArgumentsHandle(ParserAstType.HANDLE,
+            token: token);
+    seen(data);
+  }
+
+  @override
+  void beginYieldStatement(Token token) {
+    YieldStatementBegin data =
+        new YieldStatementBegin(ParserAstType.BEGIN, token: token);
+    seen(data);
+  }
+
+  @override
+  void endYieldStatement(Token yieldToken, Token? starToken, Token endToken) {
+    YieldStatementEnd data = new YieldStatementEnd(ParserAstType.END,
+        yieldToken: yieldToken, starToken: starToken, endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void endInvalidYieldStatement(Token beginToken, Token? starToken,
+      Token endToken, MessageCode errorCode) {
+    InvalidYieldStatementEnd data = new InvalidYieldStatementEnd(
+        ParserAstType.END,
+        beginToken: beginToken,
+        starToken: starToken,
+        endToken: endToken,
+        errorCode: errorCode);
+    seen(data);
+  }
+
+  @override
+  void handleRecoverableError(
+      Message message, Token startToken, Token endToken) {
+    RecoverableErrorHandle data = new RecoverableErrorHandle(
+        ParserAstType.HANDLE,
+        message: message,
+        startToken: startToken,
+        endToken: endToken);
+    seen(data);
+  }
+
+  @override
+  void handleErrorToken(ErrorToken token) {
+    ErrorTokenHandle data =
+        new ErrorTokenHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleUnescapeError(
+      Message message, Token location, int stringOffset, int length) {
+    UnescapeErrorHandle data = new UnescapeErrorHandle(ParserAstType.HANDLE,
+        message: message,
+        location: location,
+        stringOffset: stringOffset,
+        length: length);
+    seen(data);
+  }
+
+  @override
+  void handleInvalidStatement(Token token, Message message) {
+    InvalidStatementHandle data = new InvalidStatementHandle(
+        ParserAstType.HANDLE,
+        token: token,
+        message: message);
+    seen(data);
+  }
+
+  @override
+  void handleScript(Token token) {
+    ScriptHandle data = new ScriptHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+
+  @override
+  void handleCommentReferenceText(String referenceSource, int referenceOffset) {
+    CommentReferenceTextHandle data = new CommentReferenceTextHandle(
+        ParserAstType.HANDLE,
+        referenceSource: referenceSource,
+        referenceOffset: referenceOffset);
+    seen(data);
+  }
+
+  @override
+  void handleCommentReference(
+      Token? newKeyword, Token? prefix, Token? period, Token token) {
+    CommentReferenceHandle data = new CommentReferenceHandle(
+        ParserAstType.HANDLE,
+        newKeyword: newKeyword,
+        prefix: prefix,
+        period: period,
+        token: token);
+    seen(data);
+  }
+
+  @override
+  void handleNoCommentReference() {
+    NoCommentReferenceHandle data =
+        new NoCommentReferenceHandle(ParserAstType.HANDLE);
+    seen(data);
+  }
+
+  @override
+  void handleTypeArgumentApplication(Token openAngleBracket) {
+    TypeArgumentApplicationHandle data = new TypeArgumentApplicationHandle(
+        ParserAstType.HANDLE,
+        openAngleBracket: openAngleBracket);
+    seen(data);
+  }
+
+  @override
+  void handleNewAsIdentifier(Token token) {
+    NewAsIdentifierHandle data =
+        new NewAsIdentifierHandle(ParserAstType.HANDLE, token: token);
+    seen(data);
+  }
+}
+
+class ArgumentsBegin extends ParserAstNode {
+  final Token token;
+
+  ArgumentsBegin(ParserAstType type, {required this.token})
+      : super("Arguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ArgumentsEnd extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  ArgumentsEnd(ParserAstType type,
+      {required this.count, required this.beginToken, required this.endToken})
+      : super("Arguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class AsyncModifierHandle extends ParserAstNode {
+  final Token? asyncToken;
+  final Token? starToken;
+
+  AsyncModifierHandle(ParserAstType type, {this.asyncToken, this.starToken})
+      : super("AsyncModifier", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "asyncToken": asyncToken,
+        "starToken": starToken,
+      };
+}
+
+class AwaitExpressionBegin extends ParserAstNode {
+  final Token token;
+
+  AwaitExpressionBegin(ParserAstType type, {required this.token})
+      : super("AwaitExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class AwaitExpressionEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token endToken;
+
+  AwaitExpressionEnd(ParserAstType type,
+      {required this.beginToken, required this.endToken})
+      : super("AwaitExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class InvalidAwaitExpressionEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token endToken;
+  final MessageCode errorCode;
+
+  InvalidAwaitExpressionEnd(ParserAstType type,
+      {required this.beginToken,
+      required this.endToken,
+      required this.errorCode})
+      : super("InvalidAwaitExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+        "errorCode": errorCode,
+      };
+}
+
+class BlockBegin extends ParserAstNode {
+  final Token token;
+  final BlockKind blockKind;
+
+  BlockBegin(ParserAstType type, {required this.token, required this.blockKind})
+      : super("Block", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "blockKind": blockKind,
+      };
+}
+
+class BlockEnd extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+  final BlockKind blockKind;
+
+  BlockEnd(ParserAstType type,
+      {required this.count,
+      required this.beginToken,
+      required this.endToken,
+      required this.blockKind})
+      : super("Block", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+        "blockKind": blockKind,
+      };
+}
+
+class InvalidTopLevelBlockHandle extends ParserAstNode {
+  final Token token;
+
+  InvalidTopLevelBlockHandle(ParserAstType type, {required this.token})
+      : super("InvalidTopLevelBlock", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class CascadeBegin extends ParserAstNode {
+  final Token token;
+
+  CascadeBegin(ParserAstType type, {required this.token})
+      : super("Cascade", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class CascadeEnd extends ParserAstNode {
+  CascadeEnd(ParserAstType type) : super("Cascade", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class CaseExpressionBegin extends ParserAstNode {
+  final Token caseKeyword;
+
+  CaseExpressionBegin(ParserAstType type, {required this.caseKeyword})
+      : super("CaseExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "caseKeyword": caseKeyword,
+      };
+}
+
+class CaseExpressionEnd extends ParserAstNode {
+  final Token colon;
+
+  CaseExpressionEnd(ParserAstType type, {required this.colon})
+      : super("CaseExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "colon": colon,
+      };
+}
+
+class ClassOrMixinOrExtensionBodyBegin extends ParserAstNode {
+  final DeclarationKind kind;
+  final Token token;
+
+  ClassOrMixinOrExtensionBodyBegin(ParserAstType type,
+      {required this.kind, required this.token})
+      : super("ClassOrMixinOrExtensionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "kind": kind,
+        "token": token,
+      };
+}
+
+class ClassOrMixinOrExtensionBodyEnd extends ParserAstNode {
+  final DeclarationKind kind;
+  final int memberCount;
+  final Token beginToken;
+  final Token endToken;
+
+  ClassOrMixinOrExtensionBodyEnd(ParserAstType type,
+      {required this.kind,
+      required this.memberCount,
+      required this.beginToken,
+      required this.endToken})
+      : super("ClassOrMixinOrExtensionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "kind": kind,
+        "memberCount": memberCount,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class ClassOrMixinOrNamedMixinApplicationPreludeBegin extends ParserAstNode {
+  final Token token;
+
+  ClassOrMixinOrNamedMixinApplicationPreludeBegin(ParserAstType type,
+      {required this.token})
+      : super("ClassOrMixinOrNamedMixinApplicationPrelude", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ClassDeclarationBegin extends ParserAstNode {
+  final Token begin;
+  final Token? abstractToken;
+  final Token name;
+
+  ClassDeclarationBegin(ParserAstType type,
+      {required this.begin, this.abstractToken, required this.name})
+      : super("ClassDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "begin": begin,
+        "abstractToken": abstractToken,
+        "name": name,
+      };
+}
+
+class ClassExtendsHandle extends ParserAstNode {
+  final Token? extendsKeyword;
+  final int typeCount;
+
+  ClassExtendsHandle(ParserAstType type,
+      {this.extendsKeyword, required this.typeCount})
+      : super("ClassExtends", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "extendsKeyword": extendsKeyword,
+        "typeCount": typeCount,
+      };
+}
+
+class ImplementsHandle extends ParserAstNode {
+  final Token? implementsKeyword;
+  final int interfacesCount;
+
+  ImplementsHandle(ParserAstType type,
+      {this.implementsKeyword, required this.interfacesCount})
+      : super("Implements", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "implementsKeyword": implementsKeyword,
+        "interfacesCount": interfacesCount,
+      };
+}
+
+class ExtensionShowHideHandle extends ParserAstNode {
+  final Token? showKeyword;
+  final int showElementCount;
+  final Token? hideKeyword;
+  final int hideElementCount;
+
+  ExtensionShowHideHandle(ParserAstType type,
+      {this.showKeyword,
+      required this.showElementCount,
+      this.hideKeyword,
+      required this.hideElementCount})
+      : super("ExtensionShowHide", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "showKeyword": showKeyword,
+        "showElementCount": showElementCount,
+        "hideKeyword": hideKeyword,
+        "hideElementCount": hideElementCount,
+      };
+}
+
+class ClassHeaderHandle extends ParserAstNode {
+  final Token begin;
+  final Token classKeyword;
+  final Token? nativeToken;
+
+  ClassHeaderHandle(ParserAstType type,
+      {required this.begin, required this.classKeyword, this.nativeToken})
+      : super("ClassHeader", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "begin": begin,
+        "classKeyword": classKeyword,
+        "nativeToken": nativeToken,
+      };
+}
+
+class RecoverClassHeaderHandle extends ParserAstNode {
+  RecoverClassHeaderHandle(ParserAstType type)
+      : super("RecoverClassHeader", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class ClassDeclarationEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token endToken;
+
+  ClassDeclarationEnd(ParserAstType type,
+      {required this.beginToken, required this.endToken})
+      : super("ClassDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class MixinDeclarationBegin extends ParserAstNode {
+  final Token mixinKeyword;
+  final Token name;
+
+  MixinDeclarationBegin(ParserAstType type,
+      {required this.mixinKeyword, required this.name})
+      : super("MixinDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "mixinKeyword": mixinKeyword,
+        "name": name,
+      };
+}
+
+class MixinOnHandle extends ParserAstNode {
+  final Token? onKeyword;
+  final int typeCount;
+
+  MixinOnHandle(ParserAstType type, {this.onKeyword, required this.typeCount})
+      : super("MixinOn", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "onKeyword": onKeyword,
+        "typeCount": typeCount,
+      };
+}
+
+class MixinHeaderHandle extends ParserAstNode {
+  final Token mixinKeyword;
+
+  MixinHeaderHandle(ParserAstType type, {required this.mixinKeyword})
+      : super("MixinHeader", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "mixinKeyword": mixinKeyword,
+      };
+}
+
+class RecoverMixinHeaderHandle extends ParserAstNode {
+  RecoverMixinHeaderHandle(ParserAstType type)
+      : super("RecoverMixinHeader", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class MixinDeclarationEnd extends ParserAstNode {
+  final Token mixinKeyword;
+  final Token endToken;
+
+  MixinDeclarationEnd(ParserAstType type,
+      {required this.mixinKeyword, required this.endToken})
+      : super("MixinDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "mixinKeyword": mixinKeyword,
+        "endToken": endToken,
+      };
+}
+
+class UncategorizedTopLevelDeclarationBegin extends ParserAstNode {
+  final Token token;
+
+  UncategorizedTopLevelDeclarationBegin(ParserAstType type,
+      {required this.token})
+      : super("UncategorizedTopLevelDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ExtensionDeclarationPreludeBegin extends ParserAstNode {
+  final Token extensionKeyword;
+
+  ExtensionDeclarationPreludeBegin(ParserAstType type,
+      {required this.extensionKeyword})
+      : super("ExtensionDeclarationPrelude", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "extensionKeyword": extensionKeyword,
+      };
+}
+
+class ExtensionDeclarationBegin extends ParserAstNode {
+  final Token extensionKeyword;
+  final Token? name;
+
+  ExtensionDeclarationBegin(ParserAstType type,
+      {required this.extensionKeyword, this.name})
+      : super("ExtensionDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "extensionKeyword": extensionKeyword,
+        "name": name,
+      };
+}
+
+class ExtensionDeclarationEnd extends ParserAstNode {
+  final Token extensionKeyword;
+  final Token? typeKeyword;
+  final Token onKeyword;
+  final Token? showKeyword;
+  final Token? hideKeyword;
+  final Token endToken;
+
+  ExtensionDeclarationEnd(ParserAstType type,
+      {required this.extensionKeyword,
+      this.typeKeyword,
+      required this.onKeyword,
+      this.showKeyword,
+      this.hideKeyword,
+      required this.endToken})
+      : super("ExtensionDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "extensionKeyword": extensionKeyword,
+        "typeKeyword": typeKeyword,
+        "onKeyword": onKeyword,
+        "showKeyword": showKeyword,
+        "hideKeyword": hideKeyword,
+        "endToken": endToken,
+      };
+}
+
+class CombinatorsBegin extends ParserAstNode {
+  final Token token;
+
+  CombinatorsBegin(ParserAstType type, {required this.token})
+      : super("Combinators", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class CombinatorsEnd extends ParserAstNode {
+  final int count;
+
+  CombinatorsEnd(ParserAstType type, {required this.count})
+      : super("Combinators", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class CompilationUnitBegin extends ParserAstNode {
+  final Token token;
+
+  CompilationUnitBegin(ParserAstType type, {required this.token})
+      : super("CompilationUnit", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DirectivesOnlyHandle extends ParserAstNode {
+  DirectivesOnlyHandle(ParserAstType type) : super("DirectivesOnly", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class CompilationUnitEnd extends ParserAstNode {
+  final int count;
+  final Token token;
+
+  CompilationUnitEnd(ParserAstType type,
+      {required this.count, required this.token})
+      : super("CompilationUnit", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "token": token,
+      };
+}
+
+class ConstLiteralBegin extends ParserAstNode {
+  final Token token;
+
+  ConstLiteralBegin(ParserAstType type, {required this.token})
+      : super("ConstLiteral", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ConstLiteralEnd extends ParserAstNode {
+  final Token token;
+
+  ConstLiteralEnd(ParserAstType type, {required this.token})
+      : super("ConstLiteral", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ConstructorReferenceBegin extends ParserAstNode {
+  final Token start;
+
+  ConstructorReferenceBegin(ParserAstType type, {required this.start})
+      : super("ConstructorReference", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "start": start,
+      };
+}
+
+class ConstructorReferenceEnd extends ParserAstNode {
+  final Token start;
+  final Token? periodBeforeName;
+  final Token endToken;
+  final ConstructorReferenceContext constructorReferenceContext;
+
+  ConstructorReferenceEnd(ParserAstType type,
+      {required this.start,
+      this.periodBeforeName,
+      required this.endToken,
+      required this.constructorReferenceContext})
+      : super("ConstructorReference", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "start": start,
+        "periodBeforeName": periodBeforeName,
+        "endToken": endToken,
+        "constructorReferenceContext": constructorReferenceContext,
+      };
+}
+
+class DoWhileStatementBegin extends ParserAstNode {
+  final Token token;
+
+  DoWhileStatementBegin(ParserAstType type, {required this.token})
+      : super("DoWhileStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DoWhileStatementEnd extends ParserAstNode {
+  final Token doKeyword;
+  final Token whileKeyword;
+  final Token endToken;
+
+  DoWhileStatementEnd(ParserAstType type,
+      {required this.doKeyword,
+      required this.whileKeyword,
+      required this.endToken})
+      : super("DoWhileStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "doKeyword": doKeyword,
+        "whileKeyword": whileKeyword,
+        "endToken": endToken,
+      };
+}
+
+class DoWhileStatementBodyBegin extends ParserAstNode {
+  final Token token;
+
+  DoWhileStatementBodyBegin(ParserAstType type, {required this.token})
+      : super("DoWhileStatementBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class DoWhileStatementBodyEnd extends ParserAstNode {
+  final Token token;
+
+  DoWhileStatementBodyEnd(ParserAstType type, {required this.token})
+      : super("DoWhileStatementBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class WhileStatementBodyBegin extends ParserAstNode {
+  final Token token;
+
+  WhileStatementBodyBegin(ParserAstType type, {required this.token})
+      : super("WhileStatementBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class WhileStatementBodyEnd extends ParserAstNode {
+  final Token token;
+
+  WhileStatementBodyEnd(ParserAstType type, {required this.token})
+      : super("WhileStatementBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class EnumBegin extends ParserAstNode {
+  final Token enumKeyword;
+
+  EnumBegin(ParserAstType type, {required this.enumKeyword})
+      : super("Enum", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "enumKeyword": enumKeyword,
+      };
+}
+
+class EnumEnd extends ParserAstNode {
+  final Token enumKeyword;
+  final Token leftBrace;
+  final int memberCount;
+
+  EnumEnd(ParserAstType type,
+      {required this.enumKeyword,
+      required this.leftBrace,
+      required this.memberCount})
+      : super("Enum", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "enumKeyword": enumKeyword,
+        "leftBrace": leftBrace,
+        "memberCount": memberCount,
+      };
+}
+
+class EnumConstructorEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  EnumConstructorEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("EnumConstructor", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class EnumElementsHandle extends ParserAstNode {
+  final Token elementsEndToken;
+  final int elementsCount;
+
+  EnumElementsHandle(ParserAstType type,
+      {required this.elementsEndToken, required this.elementsCount})
+      : super("EnumElements", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "elementsEndToken": elementsEndToken,
+        "elementsCount": elementsCount,
+      };
+}
+
+class EnumHeaderHandle extends ParserAstNode {
+  final Token enumKeyword;
+  final Token leftBrace;
+
+  EnumHeaderHandle(ParserAstType type,
+      {required this.enumKeyword, required this.leftBrace})
+      : super("EnumHeader", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "enumKeyword": enumKeyword,
+        "leftBrace": leftBrace,
+      };
+}
+
+class EnumElementHandle extends ParserAstNode {
+  final Token beginToken;
+
+  EnumElementHandle(ParserAstType type, {required this.beginToken})
+      : super("EnumElement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+      };
+}
+
+class EnumFactoryMethodEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token factoryKeyword;
+  final Token endToken;
+
+  EnumFactoryMethodEnd(ParserAstType type,
+      {required this.beginToken,
+      required this.factoryKeyword,
+      required this.endToken})
+      : super("EnumFactoryMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "factoryKeyword": factoryKeyword,
+        "endToken": endToken,
+      };
+}
+
+class ExportBegin extends ParserAstNode {
+  final Token token;
+
+  ExportBegin(ParserAstType type, {required this.token})
+      : super("Export", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ExportEnd extends ParserAstNode {
+  final Token exportKeyword;
+  final Token semicolon;
+
+  ExportEnd(ParserAstType type,
+      {required this.exportKeyword, required this.semicolon})
+      : super("Export", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "exportKeyword": exportKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class ExtraneousExpressionHandle extends ParserAstNode {
+  final Token token;
+  final Message message;
+
+  ExtraneousExpressionHandle(ParserAstType type,
+      {required this.token, required this.message})
+      : super("ExtraneousExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "message": message,
+      };
+}
+
+class ExpressionStatementHandle extends ParserAstNode {
+  final Token token;
+
+  ExpressionStatementHandle(ParserAstType type, {required this.token})
+      : super("ExpressionStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FactoryMethodBegin extends ParserAstNode {
+  final DeclarationKind declarationKind;
+  final Token lastConsumed;
+  final Token? externalToken;
+  final Token? constToken;
+
+  FactoryMethodBegin(ParserAstType type,
+      {required this.declarationKind,
+      required this.lastConsumed,
+      this.externalToken,
+      this.constToken})
+      : super("FactoryMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "declarationKind": declarationKind,
+        "lastConsumed": lastConsumed,
+        "externalToken": externalToken,
+        "constToken": constToken,
+      };
+}
+
+class ClassFactoryMethodEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token factoryKeyword;
+  final Token endToken;
+
+  ClassFactoryMethodEnd(ParserAstType type,
+      {required this.beginToken,
+      required this.factoryKeyword,
+      required this.endToken})
+      : super("ClassFactoryMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "factoryKeyword": factoryKeyword,
+        "endToken": endToken,
+      };
+}
+
+class MixinFactoryMethodEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token factoryKeyword;
+  final Token endToken;
+
+  MixinFactoryMethodEnd(ParserAstType type,
+      {required this.beginToken,
+      required this.factoryKeyword,
+      required this.endToken})
+      : super("MixinFactoryMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "factoryKeyword": factoryKeyword,
+        "endToken": endToken,
+      };
+}
+
+class ExtensionFactoryMethodEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token factoryKeyword;
+  final Token endToken;
+
+  ExtensionFactoryMethodEnd(ParserAstType type,
+      {required this.beginToken,
+      required this.factoryKeyword,
+      required this.endToken})
+      : super("ExtensionFactoryMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "factoryKeyword": factoryKeyword,
+        "endToken": endToken,
+      };
+}
+
+class FormalParameterBegin extends ParserAstNode {
+  final Token token;
+  final MemberKind kind;
+  final Token? requiredToken;
+  final Token? covariantToken;
+  final Token? varFinalOrConst;
+
+  FormalParameterBegin(ParserAstType type,
+      {required this.token,
+      required this.kind,
+      this.requiredToken,
+      this.covariantToken,
+      this.varFinalOrConst})
+      : super("FormalParameter", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "kind": kind,
+        "requiredToken": requiredToken,
+        "covariantToken": covariantToken,
+        "varFinalOrConst": varFinalOrConst,
+      };
+}
+
+class FormalParameterEnd extends ParserAstNode {
+  final Token? thisKeyword;
+  final Token? superKeyword;
+  final Token? periodAfterThisOrSuper;
+  final Token nameToken;
+  final Token? initializerStart;
+  final Token? initializerEnd;
+  final FormalParameterKind kind;
+  final MemberKind memberKind;
+
+  FormalParameterEnd(ParserAstType type,
+      {this.thisKeyword,
+      this.superKeyword,
+      this.periodAfterThisOrSuper,
+      required this.nameToken,
+      this.initializerStart,
+      this.initializerEnd,
+      required this.kind,
+      required this.memberKind})
+      : super("FormalParameter", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "thisKeyword": thisKeyword,
+        "superKeyword": superKeyword,
+        "periodAfterThisOrSuper": periodAfterThisOrSuper,
+        "nameToken": nameToken,
+        "initializerStart": initializerStart,
+        "initializerEnd": initializerEnd,
+        "kind": kind,
+        "memberKind": memberKind,
+      };
+}
+
+class NoFormalParametersHandle extends ParserAstNode {
+  final Token token;
+  final MemberKind kind;
+
+  NoFormalParametersHandle(ParserAstType type,
+      {required this.token, required this.kind})
+      : super("NoFormalParameters", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "kind": kind,
+      };
+}
+
+class FormalParametersBegin extends ParserAstNode {
+  final Token token;
+  final MemberKind kind;
+
+  FormalParametersBegin(ParserAstType type,
+      {required this.token, required this.kind})
+      : super("FormalParameters", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "kind": kind,
+      };
+}
+
+class FormalParametersEnd extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+  final MemberKind kind;
+
+  FormalParametersEnd(ParserAstType type,
+      {required this.count,
+      required this.beginToken,
+      required this.endToken,
+      required this.kind})
+      : super("FormalParameters", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+        "kind": kind,
+      };
+}
+
+class ClassFieldsEnd extends ParserAstNode {
+  final Token? abstractToken;
+  final Token? externalToken;
+  final Token? staticToken;
+  final Token? covariantToken;
+  final Token? lateToken;
+  final Token? varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  ClassFieldsEnd(ParserAstType type,
+      {this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      required this.count,
+      required this.beginToken,
+      required this.endToken})
+      : super("ClassFields", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class MixinFieldsEnd extends ParserAstNode {
+  final Token? abstractToken;
+  final Token? externalToken;
+  final Token? staticToken;
+  final Token? covariantToken;
+  final Token? lateToken;
+  final Token? varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  MixinFieldsEnd(ParserAstType type,
+      {this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      required this.count,
+      required this.beginToken,
+      required this.endToken})
+      : super("MixinFields", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class ExtensionFieldsEnd extends ParserAstNode {
+  final Token? abstractToken;
+  final Token? externalToken;
+  final Token? staticToken;
+  final Token? covariantToken;
+  final Token? lateToken;
+  final Token? varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  ExtensionFieldsEnd(ParserAstType type,
+      {this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      required this.count,
+      required this.beginToken,
+      required this.endToken})
+      : super("ExtensionFields", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class EnumFieldsEnd extends ParserAstNode {
+  final Token? abstractToken;
+  final Token? externalToken;
+  final Token? staticToken;
+  final Token? covariantToken;
+  final Token? lateToken;
+  final Token? varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  EnumFieldsEnd(ParserAstType type,
+      {this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      required this.count,
+      required this.beginToken,
+      required this.endToken})
+      : super("EnumFields", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class EnumMethodEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  EnumMethodEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("EnumMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class ForInitializerEmptyStatementHandle extends ParserAstNode {
+  final Token token;
+
+  ForInitializerEmptyStatementHandle(ParserAstType type, {required this.token})
+      : super("ForInitializerEmptyStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForInitializerExpressionStatementHandle extends ParserAstNode {
+  final Token token;
+  final bool forIn;
+
+  ForInitializerExpressionStatementHandle(ParserAstType type,
+      {required this.token, required this.forIn})
+      : super("ForInitializerExpressionStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "forIn": forIn,
+      };
+}
+
+class ForInitializerLocalVariableDeclarationHandle extends ParserAstNode {
+  final Token token;
+  final bool forIn;
+
+  ForInitializerLocalVariableDeclarationHandle(ParserAstType type,
+      {required this.token, required this.forIn})
+      : super("ForInitializerLocalVariableDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "forIn": forIn,
+      };
+}
+
+class ForStatementBegin extends ParserAstNode {
+  final Token token;
+
+  ForStatementBegin(ParserAstType type, {required this.token})
+      : super("ForStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForLoopPartsHandle extends ParserAstNode {
+  final Token forKeyword;
+  final Token leftParen;
+  final Token leftSeparator;
+  final int updateExpressionCount;
+
+  ForLoopPartsHandle(ParserAstType type,
+      {required this.forKeyword,
+      required this.leftParen,
+      required this.leftSeparator,
+      required this.updateExpressionCount})
+      : super("ForLoopParts", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "forKeyword": forKeyword,
+        "leftParen": leftParen,
+        "leftSeparator": leftSeparator,
+        "updateExpressionCount": updateExpressionCount,
+      };
+}
+
+class ForStatementEnd extends ParserAstNode {
+  final Token endToken;
+
+  ForStatementEnd(ParserAstType type, {required this.endToken})
+      : super("ForStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class ForStatementBodyBegin extends ParserAstNode {
+  final Token token;
+
+  ForStatementBodyBegin(ParserAstType type, {required this.token})
+      : super("ForStatementBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForStatementBodyEnd extends ParserAstNode {
+  final Token token;
+
+  ForStatementBodyEnd(ParserAstType type, {required this.token})
+      : super("ForStatementBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForInLoopPartsHandle extends ParserAstNode {
+  final Token? awaitToken;
+  final Token forToken;
+  final Token leftParenthesis;
+  final Token inKeyword;
+
+  ForInLoopPartsHandle(ParserAstType type,
+      {this.awaitToken,
+      required this.forToken,
+      required this.leftParenthesis,
+      required this.inKeyword})
+      : super("ForInLoopParts", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "awaitToken": awaitToken,
+        "forToken": forToken,
+        "leftParenthesis": leftParenthesis,
+        "inKeyword": inKeyword,
+      };
+}
+
+class ForInEnd extends ParserAstNode {
+  final Token endToken;
+
+  ForInEnd(ParserAstType type, {required this.endToken}) : super("ForIn", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class ForInExpressionBegin extends ParserAstNode {
+  final Token token;
+
+  ForInExpressionBegin(ParserAstType type, {required this.token})
+      : super("ForInExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForInExpressionEnd extends ParserAstNode {
+  final Token token;
+
+  ForInExpressionEnd(ParserAstType type, {required this.token})
+      : super("ForInExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForInBodyBegin extends ParserAstNode {
+  final Token token;
+
+  ForInBodyBegin(ParserAstType type, {required this.token})
+      : super("ForInBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForInBodyEnd extends ParserAstNode {
+  final Token token;
+
+  ForInBodyEnd(ParserAstType type, {required this.token})
+      : super("ForInBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NamedFunctionExpressionBegin extends ParserAstNode {
+  final Token token;
+
+  NamedFunctionExpressionBegin(ParserAstType type, {required this.token})
+      : super("NamedFunctionExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NamedFunctionExpressionEnd extends ParserAstNode {
+  final Token endToken;
+
+  NamedFunctionExpressionEnd(ParserAstType type, {required this.endToken})
+      : super("NamedFunctionExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class LocalFunctionDeclarationBegin extends ParserAstNode {
+  final Token token;
+
+  LocalFunctionDeclarationBegin(ParserAstType type, {required this.token})
+      : super("LocalFunctionDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class LocalFunctionDeclarationEnd extends ParserAstNode {
+  final Token endToken;
+
+  LocalFunctionDeclarationEnd(ParserAstType type, {required this.endToken})
+      : super("LocalFunctionDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class BlockFunctionBodyBegin extends ParserAstNode {
+  final Token token;
+
+  BlockFunctionBodyBegin(ParserAstType type, {required this.token})
+      : super("BlockFunctionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class BlockFunctionBodyEnd extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  BlockFunctionBodyEnd(ParserAstType type,
+      {required this.count, required this.beginToken, required this.endToken})
+      : super("BlockFunctionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class NoFunctionBodyHandle extends ParserAstNode {
+  final Token token;
+
+  NoFunctionBodyHandle(ParserAstType type, {required this.token})
+      : super("NoFunctionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FunctionBodySkippedHandle extends ParserAstNode {
+  final Token token;
+  final bool isExpressionBody;
+
+  FunctionBodySkippedHandle(ParserAstType type,
+      {required this.token, required this.isExpressionBody})
+      : super("FunctionBodySkipped", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "isExpressionBody": isExpressionBody,
+      };
+}
+
+class FunctionNameBegin extends ParserAstNode {
+  final Token token;
+
+  FunctionNameBegin(ParserAstType type, {required this.token})
+      : super("FunctionName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FunctionNameEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token token;
+
+  FunctionNameEnd(ParserAstType type,
+      {required this.beginToken, required this.token})
+      : super("FunctionName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "token": token,
+      };
+}
+
+class TypedefBegin extends ParserAstNode {
+  final Token token;
+
+  TypedefBegin(ParserAstType type, {required this.token})
+      : super("Typedef", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class TypedefEnd extends ParserAstNode {
+  final Token typedefKeyword;
+  final Token? equals;
+  final Token endToken;
+
+  TypedefEnd(ParserAstType type,
+      {required this.typedefKeyword, this.equals, required this.endToken})
+      : super("Typedef", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "typedefKeyword": typedefKeyword,
+        "equals": equals,
+        "endToken": endToken,
+      };
+}
+
+class ClassWithClauseHandle extends ParserAstNode {
+  final Token withKeyword;
+
+  ClassWithClauseHandle(ParserAstType type, {required this.withKeyword})
+      : super("ClassWithClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "withKeyword": withKeyword,
+      };
+}
+
+class ClassNoWithClauseHandle extends ParserAstNode {
+  ClassNoWithClauseHandle(ParserAstType type)
+      : super("ClassNoWithClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class EnumWithClauseHandle extends ParserAstNode {
+  final Token withKeyword;
+
+  EnumWithClauseHandle(ParserAstType type, {required this.withKeyword})
+      : super("EnumWithClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "withKeyword": withKeyword,
+      };
+}
+
+class EnumNoWithClauseHandle extends ParserAstNode {
+  EnumNoWithClauseHandle(ParserAstType type) : super("EnumNoWithClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class NamedMixinApplicationBegin extends ParserAstNode {
+  final Token begin;
+  final Token? abstractToken;
+  final Token name;
+
+  NamedMixinApplicationBegin(ParserAstType type,
+      {required this.begin, this.abstractToken, required this.name})
+      : super("NamedMixinApplication", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "begin": begin,
+        "abstractToken": abstractToken,
+        "name": name,
+      };
+}
+
+class NamedMixinApplicationWithClauseHandle extends ParserAstNode {
+  final Token withKeyword;
+
+  NamedMixinApplicationWithClauseHandle(ParserAstType type,
+      {required this.withKeyword})
+      : super("NamedMixinApplicationWithClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "withKeyword": withKeyword,
+      };
+}
+
+class NamedMixinApplicationEnd extends ParserAstNode {
+  final Token begin;
+  final Token classKeyword;
+  final Token equals;
+  final Token? implementsKeyword;
+  final Token endToken;
+
+  NamedMixinApplicationEnd(ParserAstType type,
+      {required this.begin,
+      required this.classKeyword,
+      required this.equals,
+      this.implementsKeyword,
+      required this.endToken})
+      : super("NamedMixinApplication", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "begin": begin,
+        "classKeyword": classKeyword,
+        "equals": equals,
+        "implementsKeyword": implementsKeyword,
+        "endToken": endToken,
+      };
+}
+
+class HideBegin extends ParserAstNode {
+  final Token hideKeyword;
+
+  HideBegin(ParserAstType type, {required this.hideKeyword})
+      : super("Hide", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "hideKeyword": hideKeyword,
+      };
+}
+
+class HideEnd extends ParserAstNode {
+  final Token hideKeyword;
+
+  HideEnd(ParserAstType type, {required this.hideKeyword})
+      : super("Hide", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "hideKeyword": hideKeyword,
+      };
+}
+
+class IdentifierListHandle extends ParserAstNode {
+  final int count;
+
+  IdentifierListHandle(ParserAstType type, {required this.count})
+      : super("IdentifierList", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class TypeListBegin extends ParserAstNode {
+  final Token token;
+
+  TypeListBegin(ParserAstType type, {required this.token})
+      : super("TypeList", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class TypeListEnd extends ParserAstNode {
+  final int count;
+
+  TypeListEnd(ParserAstType type, {required this.count})
+      : super("TypeList", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class IfStatementBegin extends ParserAstNode {
+  final Token token;
+
+  IfStatementBegin(ParserAstType type, {required this.token})
+      : super("IfStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class IfStatementEnd extends ParserAstNode {
+  final Token ifToken;
+  final Token? elseToken;
+
+  IfStatementEnd(ParserAstType type, {required this.ifToken, this.elseToken})
+      : super("IfStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "ifToken": ifToken,
+        "elseToken": elseToken,
+      };
+}
+
+class ThenStatementBegin extends ParserAstNode {
+  final Token token;
+
+  ThenStatementBegin(ParserAstType type, {required this.token})
+      : super("ThenStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ThenStatementEnd extends ParserAstNode {
+  final Token token;
+
+  ThenStatementEnd(ParserAstType type, {required this.token})
+      : super("ThenStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ElseStatementBegin extends ParserAstNode {
+  final Token token;
+
+  ElseStatementBegin(ParserAstType type, {required this.token})
+      : super("ElseStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ElseStatementEnd extends ParserAstNode {
+  final Token token;
+
+  ElseStatementEnd(ParserAstType type, {required this.token})
+      : super("ElseStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ImportBegin extends ParserAstNode {
+  final Token importKeyword;
+
+  ImportBegin(ParserAstType type, {required this.importKeyword})
+      : super("Import", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "importKeyword": importKeyword,
+      };
+}
+
+class ImportPrefixHandle extends ParserAstNode {
+  final Token? deferredKeyword;
+  final Token? asKeyword;
+
+  ImportPrefixHandle(ParserAstType type, {this.deferredKeyword, this.asKeyword})
+      : super("ImportPrefix", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "deferredKeyword": deferredKeyword,
+        "asKeyword": asKeyword,
+      };
+}
+
+class ImportEnd extends ParserAstNode {
+  final Token importKeyword;
+  final Token? semicolon;
+
+  ImportEnd(ParserAstType type, {required this.importKeyword, this.semicolon})
+      : super("Import", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "importKeyword": importKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class RecoverImportHandle extends ParserAstNode {
+  final Token? semicolon;
+
+  RecoverImportHandle(ParserAstType type, {this.semicolon})
+      : super("RecoverImport", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "semicolon": semicolon,
+      };
+}
+
+class ConditionalUrisBegin extends ParserAstNode {
+  final Token token;
+
+  ConditionalUrisBegin(ParserAstType type, {required this.token})
+      : super("ConditionalUris", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ConditionalUrisEnd extends ParserAstNode {
+  final int count;
+
+  ConditionalUrisEnd(ParserAstType type, {required this.count})
+      : super("ConditionalUris", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class ConditionalUriBegin extends ParserAstNode {
+  final Token ifKeyword;
+
+  ConditionalUriBegin(ParserAstType type, {required this.ifKeyword})
+      : super("ConditionalUri", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "ifKeyword": ifKeyword,
+      };
+}
+
+class ConditionalUriEnd extends ParserAstNode {
+  final Token ifKeyword;
+  final Token leftParen;
+  final Token? equalSign;
+
+  ConditionalUriEnd(ParserAstType type,
+      {required this.ifKeyword, required this.leftParen, this.equalSign})
+      : super("ConditionalUri", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "ifKeyword": ifKeyword,
+        "leftParen": leftParen,
+        "equalSign": equalSign,
+      };
+}
+
+class DottedNameHandle extends ParserAstNode {
+  final int count;
+  final Token firstIdentifier;
+
+  DottedNameHandle(ParserAstType type,
+      {required this.count, required this.firstIdentifier})
+      : super("DottedName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "firstIdentifier": firstIdentifier,
+      };
+}
+
+class ImplicitCreationExpressionBegin extends ParserAstNode {
+  final Token token;
+
+  ImplicitCreationExpressionBegin(ParserAstType type, {required this.token})
+      : super("ImplicitCreationExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ImplicitCreationExpressionEnd extends ParserAstNode {
+  final Token token;
+  final Token openAngleBracket;
+
+  ImplicitCreationExpressionEnd(ParserAstType type,
+      {required this.token, required this.openAngleBracket})
+      : super("ImplicitCreationExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "openAngleBracket": openAngleBracket,
+      };
+}
+
+class InitializedIdentifierBegin extends ParserAstNode {
+  final Token token;
+
+  InitializedIdentifierBegin(ParserAstType type, {required this.token})
+      : super("InitializedIdentifier", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InitializedIdentifierEnd extends ParserAstNode {
+  final Token nameToken;
+
+  InitializedIdentifierEnd(ParserAstType type, {required this.nameToken})
+      : super("InitializedIdentifier", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "nameToken": nameToken,
+      };
+}
+
+class FieldInitializerBegin extends ParserAstNode {
+  final Token token;
+
+  FieldInitializerBegin(ParserAstType type, {required this.token})
+      : super("FieldInitializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FieldInitializerEnd extends ParserAstNode {
+  final Token assignment;
+  final Token token;
+
+  FieldInitializerEnd(ParserAstType type,
+      {required this.assignment, required this.token})
+      : super("FieldInitializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "assignment": assignment,
+        "token": token,
+      };
+}
+
+class NoFieldInitializerHandle extends ParserAstNode {
+  final Token token;
+
+  NoFieldInitializerHandle(ParserAstType type, {required this.token})
+      : super("NoFieldInitializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class VariableInitializerBegin extends ParserAstNode {
+  final Token token;
+
+  VariableInitializerBegin(ParserAstType type, {required this.token})
+      : super("VariableInitializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class VariableInitializerEnd extends ParserAstNode {
+  final Token assignmentOperator;
+
+  VariableInitializerEnd(ParserAstType type, {required this.assignmentOperator})
+      : super("VariableInitializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "assignmentOperator": assignmentOperator,
+      };
+}
+
+class NoVariableInitializerHandle extends ParserAstNode {
+  final Token token;
+
+  NoVariableInitializerHandle(ParserAstType type, {required this.token})
+      : super("NoVariableInitializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InitializerBegin extends ParserAstNode {
+  final Token token;
+
+  InitializerBegin(ParserAstType type, {required this.token})
+      : super("Initializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InitializerEnd extends ParserAstNode {
+  final Token token;
+
+  InitializerEnd(ParserAstType type, {required this.token})
+      : super("Initializer", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InitializersBegin extends ParserAstNode {
+  final Token token;
+
+  InitializersBegin(ParserAstType type, {required this.token})
+      : super("Initializers", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InitializersEnd extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  InitializersEnd(ParserAstType type,
+      {required this.count, required this.beginToken, required this.endToken})
+      : super("Initializers", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class NoInitializersHandle extends ParserAstNode {
+  NoInitializersHandle(ParserAstType type) : super("NoInitializers", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class InvalidExpressionHandle extends ParserAstNode {
+  final Token token;
+
+  InvalidExpressionHandle(ParserAstType type, {required this.token})
+      : super("InvalidExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InvalidFunctionBodyHandle extends ParserAstNode {
+  final Token token;
+
+  InvalidFunctionBodyHandle(ParserAstType type, {required this.token})
+      : super("InvalidFunctionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InvalidTypeReferenceHandle extends ParserAstNode {
+  final Token token;
+
+  InvalidTypeReferenceHandle(ParserAstType type, {required this.token})
+      : super("InvalidTypeReference", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class LabelHandle extends ParserAstNode {
+  final Token token;
+
+  LabelHandle(ParserAstType type, {required this.token}) : super("Label", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class LabeledStatementBegin extends ParserAstNode {
+  final Token token;
+  final int labelCount;
+
+  LabeledStatementBegin(ParserAstType type,
+      {required this.token, required this.labelCount})
+      : super("LabeledStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "labelCount": labelCount,
+      };
+}
+
+class LabeledStatementEnd extends ParserAstNode {
+  final int labelCount;
+
+  LabeledStatementEnd(ParserAstType type, {required this.labelCount})
+      : super("LabeledStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "labelCount": labelCount,
+      };
+}
+
+class LibraryNameBegin extends ParserAstNode {
+  final Token token;
+
+  LibraryNameBegin(ParserAstType type, {required this.token})
+      : super("LibraryName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class LibraryNameEnd extends ParserAstNode {
+  final Token libraryKeyword;
+  final Token semicolon;
+
+  LibraryNameEnd(ParserAstType type,
+      {required this.libraryKeyword, required this.semicolon})
+      : super("LibraryName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "libraryKeyword": libraryKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class LiteralMapEntryHandle extends ParserAstNode {
+  final Token colon;
+  final Token endToken;
+
+  LiteralMapEntryHandle(ParserAstType type,
+      {required this.colon, required this.endToken})
+      : super("LiteralMapEntry", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "colon": colon,
+        "endToken": endToken,
+      };
+}
+
+class LiteralStringBegin extends ParserAstNode {
+  final Token token;
+
+  LiteralStringBegin(ParserAstType type, {required this.token})
+      : super("LiteralString", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class InterpolationExpressionHandle extends ParserAstNode {
+  final Token leftBracket;
+  final Token? rightBracket;
+
+  InterpolationExpressionHandle(ParserAstType type,
+      {required this.leftBracket, this.rightBracket})
+      : super("InterpolationExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "leftBracket": leftBracket,
+        "rightBracket": rightBracket,
+      };
+}
+
+class LiteralStringEnd extends ParserAstNode {
+  final int interpolationCount;
+  final Token endToken;
+
+  LiteralStringEnd(ParserAstType type,
+      {required this.interpolationCount, required this.endToken})
+      : super("LiteralString", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "interpolationCount": interpolationCount,
+        "endToken": endToken,
+      };
+}
+
+class StringJuxtapositionHandle extends ParserAstNode {
+  final Token startToken;
+  final int literalCount;
+
+  StringJuxtapositionHandle(ParserAstType type,
+      {required this.startToken, required this.literalCount})
+      : super("StringJuxtaposition", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "startToken": startToken,
+        "literalCount": literalCount,
+      };
+}
+
+class MemberBegin extends ParserAstNode {
+  MemberBegin(ParserAstType type) : super("Member", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class InvalidMemberHandle extends ParserAstNode {
+  final Token endToken;
+
+  InvalidMemberHandle(ParserAstType type, {required this.endToken})
+      : super("InvalidMember", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class MemberEnd extends ParserAstNode {
+  MemberEnd(ParserAstType type) : super("Member", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class MethodBegin extends ParserAstNode {
+  final DeclarationKind declarationKind;
+  final Token? externalToken;
+  final Token? staticToken;
+  final Token? covariantToken;
+  final Token? varFinalOrConst;
+  final Token? getOrSet;
+  final Token name;
+
+  MethodBegin(ParserAstType type,
+      {required this.declarationKind,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.varFinalOrConst,
+      this.getOrSet,
+      required this.name})
+      : super("Method", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "declarationKind": declarationKind,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "varFinalOrConst": varFinalOrConst,
+        "getOrSet": getOrSet,
+        "name": name,
+      };
+}
+
+class ClassMethodEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  ClassMethodEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("ClassMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class MixinMethodEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  MixinMethodEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("MixinMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class ExtensionMethodEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  ExtensionMethodEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("ExtensionMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class ClassConstructorEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  ClassConstructorEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("ClassConstructor", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class MixinConstructorEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  MixinConstructorEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("MixinConstructor", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class ExtensionConstructorEnd extends ParserAstNode {
+  final Token? getOrSet;
+  final Token beginToken;
+  final Token beginParam;
+  final Token? beginInitializers;
+  final Token endToken;
+
+  ExtensionConstructorEnd(ParserAstType type,
+      {this.getOrSet,
+      required this.beginToken,
+      required this.beginParam,
+      this.beginInitializers,
+      required this.endToken})
+      : super("ExtensionConstructor", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "getOrSet": getOrSet,
+        "beginToken": beginToken,
+        "beginParam": beginParam,
+        "beginInitializers": beginInitializers,
+        "endToken": endToken,
+      };
+}
+
+class MetadataStarBegin extends ParserAstNode {
+  final Token token;
+
+  MetadataStarBegin(ParserAstType type, {required this.token})
+      : super("MetadataStar", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class MetadataStarEnd extends ParserAstNode {
+  final int count;
+
+  MetadataStarEnd(ParserAstType type, {required this.count})
+      : super("MetadataStar", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+      };
+}
+
+class MetadataBegin extends ParserAstNode {
+  final Token token;
+
+  MetadataBegin(ParserAstType type, {required this.token})
+      : super("Metadata", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class MetadataEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token? periodBeforeName;
+  final Token endToken;
+
+  MetadataEnd(ParserAstType type,
+      {required this.beginToken, this.periodBeforeName, required this.endToken})
+      : super("Metadata", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "periodBeforeName": periodBeforeName,
+        "endToken": endToken,
+      };
+}
+
+class OptionalFormalParametersBegin extends ParserAstNode {
+  final Token token;
+
+  OptionalFormalParametersBegin(ParserAstType type, {required this.token})
+      : super("OptionalFormalParameters", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class OptionalFormalParametersEnd extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  OptionalFormalParametersEnd(ParserAstType type,
+      {required this.count, required this.beginToken, required this.endToken})
+      : super("OptionalFormalParameters", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class PartBegin extends ParserAstNode {
+  final Token token;
+
+  PartBegin(ParserAstType type, {required this.token}) : super("Part", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class PartEnd extends ParserAstNode {
+  final Token partKeyword;
+  final Token semicolon;
+
+  PartEnd(ParserAstType type,
+      {required this.partKeyword, required this.semicolon})
+      : super("Part", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "partKeyword": partKeyword,
+        "semicolon": semicolon,
+      };
+}
+
+class PartOfBegin extends ParserAstNode {
+  final Token token;
+
+  PartOfBegin(ParserAstType type, {required this.token})
+      : super("PartOf", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class PartOfEnd extends ParserAstNode {
+  final Token partKeyword;
+  final Token ofKeyword;
+  final Token semicolon;
+  final bool hasName;
+
+  PartOfEnd(ParserAstType type,
+      {required this.partKeyword,
+      required this.ofKeyword,
+      required this.semicolon,
+      required this.hasName})
+      : super("PartOf", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "partKeyword": partKeyword,
+        "ofKeyword": ofKeyword,
+        "semicolon": semicolon,
+        "hasName": hasName,
+      };
+}
+
+class RedirectingFactoryBodyBegin extends ParserAstNode {
+  final Token token;
+
+  RedirectingFactoryBodyBegin(ParserAstType type, {required this.token})
+      : super("RedirectingFactoryBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class RedirectingFactoryBodyEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token endToken;
+
+  RedirectingFactoryBodyEnd(ParserAstType type,
+      {required this.beginToken, required this.endToken})
+      : super("RedirectingFactoryBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class ReturnStatementBegin extends ParserAstNode {
+  final Token token;
+
+  ReturnStatementBegin(ParserAstType type, {required this.token})
+      : super("ReturnStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NativeFunctionBodyHandle extends ParserAstNode {
+  final Token nativeToken;
+  final Token semicolon;
+
+  NativeFunctionBodyHandle(ParserAstType type,
+      {required this.nativeToken, required this.semicolon})
+      : super("NativeFunctionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "semicolon": semicolon,
+      };
+}
+
+class NativeFunctionBodyIgnoredHandle extends ParserAstNode {
+  final Token nativeToken;
+  final Token semicolon;
+
+  NativeFunctionBodyIgnoredHandle(ParserAstType type,
+      {required this.nativeToken, required this.semicolon})
+      : super("NativeFunctionBodyIgnored", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "semicolon": semicolon,
+      };
+}
+
+class NativeFunctionBodySkippedHandle extends ParserAstNode {
+  final Token nativeToken;
+  final Token semicolon;
+
+  NativeFunctionBodySkippedHandle(ParserAstType type,
+      {required this.nativeToken, required this.semicolon})
+      : super("NativeFunctionBodySkipped", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "semicolon": semicolon,
+      };
+}
+
+class EmptyFunctionBodyHandle extends ParserAstNode {
+  final Token semicolon;
+
+  EmptyFunctionBodyHandle(ParserAstType type, {required this.semicolon})
+      : super("EmptyFunctionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "semicolon": semicolon,
+      };
+}
+
+class ExpressionFunctionBodyHandle extends ParserAstNode {
+  final Token arrowToken;
+  final Token? endToken;
+
+  ExpressionFunctionBodyHandle(ParserAstType type,
+      {required this.arrowToken, this.endToken})
+      : super("ExpressionFunctionBody", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "arrowToken": arrowToken,
+        "endToken": endToken,
+      };
+}
+
+class ReturnStatementEnd extends ParserAstNode {
+  final bool hasExpression;
+  final Token beginToken;
+  final Token endToken;
+
+  ReturnStatementEnd(ParserAstType type,
+      {required this.hasExpression,
+      required this.beginToken,
+      required this.endToken})
+      : super("ReturnStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "hasExpression": hasExpression,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class SendHandle extends ParserAstNode {
+  final Token beginToken;
+  final Token endToken;
+
+  SendHandle(ParserAstType type,
+      {required this.beginToken, required this.endToken})
+      : super("Send", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class ShowBegin extends ParserAstNode {
+  final Token showKeyword;
+
+  ShowBegin(ParserAstType type, {required this.showKeyword})
+      : super("Show", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "showKeyword": showKeyword,
+      };
+}
+
+class ShowEnd extends ParserAstNode {
+  final Token showKeyword;
+
+  ShowEnd(ParserAstType type, {required this.showKeyword})
+      : super("Show", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "showKeyword": showKeyword,
+      };
+}
+
+class SwitchStatementBegin extends ParserAstNode {
+  final Token token;
+
+  SwitchStatementBegin(ParserAstType type, {required this.token})
+      : super("SwitchStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class SwitchStatementEnd extends ParserAstNode {
+  final Token switchKeyword;
+  final Token endToken;
+
+  SwitchStatementEnd(ParserAstType type,
+      {required this.switchKeyword, required this.endToken})
+      : super("SwitchStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "switchKeyword": switchKeyword,
+        "endToken": endToken,
+      };
+}
+
+class SwitchBlockBegin extends ParserAstNode {
+  final Token token;
+
+  SwitchBlockBegin(ParserAstType type, {required this.token})
+      : super("SwitchBlock", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class SwitchBlockEnd extends ParserAstNode {
+  final int caseCount;
+  final Token beginToken;
+  final Token endToken;
+
+  SwitchBlockEnd(ParserAstType type,
+      {required this.caseCount,
+      required this.beginToken,
+      required this.endToken})
+      : super("SwitchBlock", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "caseCount": caseCount,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class LiteralSymbolBegin extends ParserAstNode {
+  final Token token;
+
+  LiteralSymbolBegin(ParserAstType type, {required this.token})
+      : super("LiteralSymbol", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class LiteralSymbolEnd extends ParserAstNode {
+  final Token hashToken;
+  final int identifierCount;
+
+  LiteralSymbolEnd(ParserAstType type,
+      {required this.hashToken, required this.identifierCount})
+      : super("LiteralSymbol", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "hashToken": hashToken,
+        "identifierCount": identifierCount,
+      };
+}
+
+class ThrowExpressionHandle extends ParserAstNode {
+  final Token throwToken;
+  final Token endToken;
+
+  ThrowExpressionHandle(ParserAstType type,
+      {required this.throwToken, required this.endToken})
+      : super("ThrowExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "throwToken": throwToken,
+        "endToken": endToken,
+      };
+}
+
+class RethrowStatementBegin extends ParserAstNode {
+  final Token token;
+
+  RethrowStatementBegin(ParserAstType type, {required this.token})
+      : super("RethrowStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class RethrowStatementEnd extends ParserAstNode {
+  final Token rethrowToken;
+  final Token endToken;
+
+  RethrowStatementEnd(ParserAstType type,
+      {required this.rethrowToken, required this.endToken})
+      : super("RethrowStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "rethrowToken": rethrowToken,
+        "endToken": endToken,
+      };
+}
+
+class TopLevelDeclarationEnd extends ParserAstNode {
+  final Token nextToken;
+
+  TopLevelDeclarationEnd(ParserAstType type, {required this.nextToken})
+      : super("TopLevelDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "nextToken": nextToken,
+      };
+}
+
+class InvalidTopLevelDeclarationHandle extends ParserAstNode {
+  final Token endToken;
+
+  InvalidTopLevelDeclarationHandle(ParserAstType type, {required this.endToken})
+      : super("InvalidTopLevelDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "endToken": endToken,
+      };
+}
+
+class TopLevelMemberBegin extends ParserAstNode {
+  final Token token;
+
+  TopLevelMemberBegin(ParserAstType type, {required this.token})
+      : super("TopLevelMember", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FieldsBegin extends ParserAstNode {
+  final DeclarationKind declarationKind;
+  final Token? abstractToken;
+  final Token? externalToken;
+  final Token? staticToken;
+  final Token? covariantToken;
+  final Token? lateToken;
+  final Token? varFinalOrConst;
+  final Token lastConsumed;
+
+  FieldsBegin(ParserAstType type,
+      {required this.declarationKind,
+      this.abstractToken,
+      this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      required this.lastConsumed})
+      : super("Fields", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "declarationKind": declarationKind,
+        "abstractToken": abstractToken,
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "lastConsumed": lastConsumed,
+      };
+}
+
+class TopLevelFieldsEnd extends ParserAstNode {
+  final Token? externalToken;
+  final Token? staticToken;
+  final Token? covariantToken;
+  final Token? lateToken;
+  final Token? varFinalOrConst;
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  TopLevelFieldsEnd(ParserAstType type,
+      {this.externalToken,
+      this.staticToken,
+      this.covariantToken,
+      this.lateToken,
+      this.varFinalOrConst,
+      required this.count,
+      required this.beginToken,
+      required this.endToken})
+      : super("TopLevelFields", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "externalToken": externalToken,
+        "staticToken": staticToken,
+        "covariantToken": covariantToken,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class TopLevelMethodBegin extends ParserAstNode {
+  final Token lastConsumed;
+  final Token? externalToken;
+
+  TopLevelMethodBegin(ParserAstType type,
+      {required this.lastConsumed, this.externalToken})
+      : super("TopLevelMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "lastConsumed": lastConsumed,
+        "externalToken": externalToken,
+      };
+}
+
+class TopLevelMethodEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token? getOrSet;
+  final Token endToken;
+
+  TopLevelMethodEnd(ParserAstType type,
+      {required this.beginToken, this.getOrSet, required this.endToken})
+      : super("TopLevelMethod", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "getOrSet": getOrSet,
+        "endToken": endToken,
+      };
+}
+
+class TryStatementBegin extends ParserAstNode {
+  final Token token;
+
+  TryStatementBegin(ParserAstType type, {required this.token})
+      : super("TryStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class CaseMatchHandle extends ParserAstNode {
+  final Token caseKeyword;
+  final Token colon;
+
+  CaseMatchHandle(ParserAstType type,
+      {required this.caseKeyword, required this.colon})
+      : super("CaseMatch", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "caseKeyword": caseKeyword,
+        "colon": colon,
+      };
+}
+
+class CatchClauseBegin extends ParserAstNode {
+  final Token token;
+
+  CatchClauseBegin(ParserAstType type, {required this.token})
+      : super("CatchClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class CatchClauseEnd extends ParserAstNode {
+  final Token token;
+
+  CatchClauseEnd(ParserAstType type, {required this.token})
+      : super("CatchClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class CatchBlockHandle extends ParserAstNode {
+  final Token? onKeyword;
+  final Token? catchKeyword;
+  final Token? comma;
+
+  CatchBlockHandle(ParserAstType type,
+      {this.onKeyword, this.catchKeyword, this.comma})
+      : super("CatchBlock", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "onKeyword": onKeyword,
+        "catchKeyword": catchKeyword,
+        "comma": comma,
+      };
+}
+
+class FinallyBlockHandle extends ParserAstNode {
+  final Token finallyKeyword;
+
+  FinallyBlockHandle(ParserAstType type, {required this.finallyKeyword})
+      : super("FinallyBlock", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "finallyKeyword": finallyKeyword,
+      };
+}
+
+class TryStatementEnd extends ParserAstNode {
+  final int catchCount;
+  final Token tryKeyword;
+  final Token? finallyKeyword;
+
+  TryStatementEnd(ParserAstType type,
+      {required this.catchCount, required this.tryKeyword, this.finallyKeyword})
+      : super("TryStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "catchCount": catchCount,
+        "tryKeyword": tryKeyword,
+        "finallyKeyword": finallyKeyword,
+      };
+}
+
+class TypeHandle extends ParserAstNode {
+  final Token beginToken;
+  final Token? questionMark;
+
+  TypeHandle(ParserAstType type, {required this.beginToken, this.questionMark})
+      : super("Type", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "questionMark": questionMark,
+      };
+}
+
+class NonNullAssertExpressionHandle extends ParserAstNode {
+  final Token bang;
+
+  NonNullAssertExpressionHandle(ParserAstType type, {required this.bang})
+      : super("NonNullAssertExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "bang": bang,
+      };
+}
+
+class NoNameHandle extends ParserAstNode {
+  final Token token;
+
+  NoNameHandle(ParserAstType type, {required this.token})
+      : super("NoName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FunctionTypeBegin extends ParserAstNode {
+  final Token beginToken;
+
+  FunctionTypeBegin(ParserAstType type, {required this.beginToken})
+      : super("FunctionType", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+      };
+}
+
+class FunctionTypeEnd extends ParserAstNode {
+  final Token functionToken;
+  final Token? questionMark;
+
+  FunctionTypeEnd(ParserAstType type,
+      {required this.functionToken, this.questionMark})
+      : super("FunctionType", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "functionToken": functionToken,
+        "questionMark": questionMark,
+      };
+}
+
+class TypeArgumentsBegin extends ParserAstNode {
+  final Token token;
+
+  TypeArgumentsBegin(ParserAstType type, {required this.token})
+      : super("TypeArguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class TypeArgumentsEnd extends ParserAstNode {
+  final int count;
+  final Token beginToken;
+  final Token endToken;
+
+  TypeArgumentsEnd(ParserAstType type,
+      {required this.count, required this.beginToken, required this.endToken})
+      : super("TypeArguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class InvalidTypeArgumentsHandle extends ParserAstNode {
+  final Token token;
+
+  InvalidTypeArgumentsHandle(ParserAstType type, {required this.token})
+      : super("InvalidTypeArguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NoTypeArgumentsHandle extends ParserAstNode {
+  final Token token;
+
+  NoTypeArgumentsHandle(ParserAstType type, {required this.token})
+      : super("NoTypeArguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class TypeVariableBegin extends ParserAstNode {
+  final Token token;
+
+  TypeVariableBegin(ParserAstType type, {required this.token})
+      : super("TypeVariable", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class TypeVariablesDefinedHandle extends ParserAstNode {
+  final Token token;
+  final int count;
+
+  TypeVariablesDefinedHandle(ParserAstType type,
+      {required this.token, required this.count})
+      : super("TypeVariablesDefined", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "count": count,
+      };
+}
+
+class TypeVariableEnd extends ParserAstNode {
+  final Token token;
+  final int index;
+  final Token? extendsOrSuper;
+  final Token? variance;
+
+  TypeVariableEnd(ParserAstType type,
+      {required this.token,
+      required this.index,
+      this.extendsOrSuper,
+      this.variance})
+      : super("TypeVariable", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "index": index,
+        "extendsOrSuper": extendsOrSuper,
+        "variance": variance,
+      };
+}
+
+class TypeVariablesBegin extends ParserAstNode {
+  final Token token;
+
+  TypeVariablesBegin(ParserAstType type, {required this.token})
+      : super("TypeVariables", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class TypeVariablesEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token endToken;
+
+  TypeVariablesEnd(ParserAstType type,
+      {required this.beginToken, required this.endToken})
+      : super("TypeVariables", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "endToken": endToken,
+      };
+}
+
+class FunctionExpressionBegin extends ParserAstNode {
+  final Token token;
+
+  FunctionExpressionBegin(ParserAstType type, {required this.token})
+      : super("FunctionExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FunctionExpressionEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token token;
+
+  FunctionExpressionEnd(ParserAstType type,
+      {required this.beginToken, required this.token})
+      : super("FunctionExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "token": token,
+      };
+}
+
+class VariablesDeclarationBegin extends ParserAstNode {
+  final Token token;
+  final Token? lateToken;
+  final Token? varFinalOrConst;
+
+  VariablesDeclarationBegin(ParserAstType type,
+      {required this.token, this.lateToken, this.varFinalOrConst})
+      : super("VariablesDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "lateToken": lateToken,
+        "varFinalOrConst": varFinalOrConst,
+      };
+}
+
+class VariablesDeclarationEnd extends ParserAstNode {
+  final int count;
+  final Token? endToken;
+
+  VariablesDeclarationEnd(ParserAstType type,
+      {required this.count, this.endToken})
+      : super("VariablesDeclaration", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "endToken": endToken,
+      };
+}
+
+class WhileStatementBegin extends ParserAstNode {
+  final Token token;
+
+  WhileStatementBegin(ParserAstType type, {required this.token})
+      : super("WhileStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class WhileStatementEnd extends ParserAstNode {
+  final Token whileKeyword;
+  final Token endToken;
+
+  WhileStatementEnd(ParserAstType type,
+      {required this.whileKeyword, required this.endToken})
+      : super("WhileStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "whileKeyword": whileKeyword,
+        "endToken": endToken,
+      };
+}
+
+class AsOperatorTypeBegin extends ParserAstNode {
+  final Token operator;
+
+  AsOperatorTypeBegin(ParserAstType type, {required this.operator})
+      : super("AsOperatorType", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class AsOperatorTypeEnd extends ParserAstNode {
+  final Token operator;
+
+  AsOperatorTypeEnd(ParserAstType type, {required this.operator})
+      : super("AsOperatorType", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class AsOperatorHandle extends ParserAstNode {
+  final Token operator;
+
+  AsOperatorHandle(ParserAstType type, {required this.operator})
+      : super("AsOperator", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class AssignmentExpressionHandle extends ParserAstNode {
+  final Token token;
+
+  AssignmentExpressionHandle(ParserAstType type, {required this.token})
+      : super("AssignmentExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class BinaryExpressionBegin extends ParserAstNode {
+  final Token token;
+
+  BinaryExpressionBegin(ParserAstType type, {required this.token})
+      : super("BinaryExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class BinaryExpressionEnd extends ParserAstNode {
+  final Token token;
+
+  BinaryExpressionEnd(ParserAstType type, {required this.token})
+      : super("BinaryExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class EndingBinaryExpressionHandle extends ParserAstNode {
+  final Token token;
+
+  EndingBinaryExpressionHandle(ParserAstType type, {required this.token})
+      : super("EndingBinaryExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ConditionalExpressionBegin extends ParserAstNode {
+  final Token question;
+
+  ConditionalExpressionBegin(ParserAstType type, {required this.question})
+      : super("ConditionalExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "question": question,
+      };
+}
+
+class ConditionalExpressionColonHandle extends ParserAstNode {
+  ConditionalExpressionColonHandle(ParserAstType type)
+      : super("ConditionalExpressionColon", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class ConditionalExpressionEnd extends ParserAstNode {
+  final Token question;
+  final Token colon;
+
+  ConditionalExpressionEnd(ParserAstType type,
+      {required this.question, required this.colon})
+      : super("ConditionalExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "question": question,
+        "colon": colon,
+      };
+}
+
+class ConstExpressionBegin extends ParserAstNode {
+  final Token constKeyword;
+
+  ConstExpressionBegin(ParserAstType type, {required this.constKeyword})
+      : super("ConstExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "constKeyword": constKeyword,
+      };
+}
+
+class ConstExpressionEnd extends ParserAstNode {
+  final Token token;
+
+  ConstExpressionEnd(ParserAstType type, {required this.token})
+      : super("ConstExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ConstFactoryHandle extends ParserAstNode {
+  final Token constKeyword;
+
+  ConstFactoryHandle(ParserAstType type, {required this.constKeyword})
+      : super("ConstFactory", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "constKeyword": constKeyword,
+      };
+}
+
+class ForControlFlowBegin extends ParserAstNode {
+  final Token? awaitToken;
+  final Token forToken;
+
+  ForControlFlowBegin(ParserAstType type,
+      {this.awaitToken, required this.forToken})
+      : super("ForControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "awaitToken": awaitToken,
+        "forToken": forToken,
+      };
+}
+
+class ForControlFlowEnd extends ParserAstNode {
+  final Token token;
+
+  ForControlFlowEnd(ParserAstType type, {required this.token})
+      : super("ForControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ForInControlFlowEnd extends ParserAstNode {
+  final Token token;
+
+  ForInControlFlowEnd(ParserAstType type, {required this.token})
+      : super("ForInControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class IfControlFlowBegin extends ParserAstNode {
+  final Token ifToken;
+
+  IfControlFlowBegin(ParserAstType type, {required this.ifToken})
+      : super("IfControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "ifToken": ifToken,
+      };
+}
+
+class ThenControlFlowHandle extends ParserAstNode {
+  final Token token;
+
+  ThenControlFlowHandle(ParserAstType type, {required this.token})
+      : super("ThenControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ElseControlFlowHandle extends ParserAstNode {
+  final Token elseToken;
+
+  ElseControlFlowHandle(ParserAstType type, {required this.elseToken})
+      : super("ElseControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "elseToken": elseToken,
+      };
+}
+
+class IfControlFlowEnd extends ParserAstNode {
+  final Token token;
+
+  IfControlFlowEnd(ParserAstType type, {required this.token})
+      : super("IfControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class IfElseControlFlowEnd extends ParserAstNode {
+  final Token token;
+
+  IfElseControlFlowEnd(ParserAstType type, {required this.token})
+      : super("IfElseControlFlow", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class SpreadExpressionHandle extends ParserAstNode {
+  final Token spreadToken;
+
+  SpreadExpressionHandle(ParserAstType type, {required this.spreadToken})
+      : super("SpreadExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "spreadToken": spreadToken,
+      };
+}
+
+class FunctionTypedFormalParameterBegin extends ParserAstNode {
+  final Token token;
+
+  FunctionTypedFormalParameterBegin(ParserAstType type, {required this.token})
+      : super("FunctionTypedFormalParameter", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FunctionTypedFormalParameterEnd extends ParserAstNode {
+  final Token nameToken;
+  final Token? question;
+
+  FunctionTypedFormalParameterEnd(ParserAstType type,
+      {required this.nameToken, this.question})
+      : super("FunctionTypedFormalParameter", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "nameToken": nameToken,
+        "question": question,
+      };
+}
+
+class IdentifierHandle extends ParserAstNode {
+  final Token token;
+  final IdentifierContext context;
+
+  IdentifierHandle(ParserAstType type,
+      {required this.token, required this.context})
+      : super("Identifier", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "context": context,
+      };
+}
+
+class ShowHideIdentifierHandle extends ParserAstNode {
+  final Token? modifier;
+  final Token identifier;
+
+  ShowHideIdentifierHandle(ParserAstType type,
+      {this.modifier, required this.identifier})
+      : super("ShowHideIdentifier", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "modifier": modifier,
+        "identifier": identifier,
+      };
+}
+
+class IndexedExpressionHandle extends ParserAstNode {
+  final Token? question;
+  final Token openSquareBracket;
+  final Token closeSquareBracket;
+
+  IndexedExpressionHandle(ParserAstType type,
+      {this.question,
+      required this.openSquareBracket,
+      required this.closeSquareBracket})
+      : super("IndexedExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "question": question,
+        "openSquareBracket": openSquareBracket,
+        "closeSquareBracket": closeSquareBracket,
+      };
+}
+
+class IsOperatorTypeBegin extends ParserAstNode {
+  final Token operator;
+
+  IsOperatorTypeBegin(ParserAstType type, {required this.operator})
+      : super("IsOperatorType", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class IsOperatorTypeEnd extends ParserAstNode {
+  final Token operator;
+
+  IsOperatorTypeEnd(ParserAstType type, {required this.operator})
+      : super("IsOperatorType", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operator": operator,
+      };
+}
+
+class IsOperatorHandle extends ParserAstNode {
+  final Token isOperator;
+  final Token? not;
+
+  IsOperatorHandle(ParserAstType type, {required this.isOperator, this.not})
+      : super("IsOperator", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "isOperator": isOperator,
+        "not": not,
+      };
+}
+
+class LiteralBoolHandle extends ParserAstNode {
+  final Token token;
+
+  LiteralBoolHandle(ParserAstType type, {required this.token})
+      : super("LiteralBool", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class BreakStatementHandle extends ParserAstNode {
+  final bool hasTarget;
+  final Token breakKeyword;
+  final Token endToken;
+
+  BreakStatementHandle(ParserAstType type,
+      {required this.hasTarget,
+      required this.breakKeyword,
+      required this.endToken})
+      : super("BreakStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "hasTarget": hasTarget,
+        "breakKeyword": breakKeyword,
+        "endToken": endToken,
+      };
+}
+
+class ContinueStatementHandle extends ParserAstNode {
+  final bool hasTarget;
+  final Token continueKeyword;
+  final Token endToken;
+
+  ContinueStatementHandle(ParserAstType type,
+      {required this.hasTarget,
+      required this.continueKeyword,
+      required this.endToken})
+      : super("ContinueStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "hasTarget": hasTarget,
+        "continueKeyword": continueKeyword,
+        "endToken": endToken,
+      };
+}
+
+class EmptyStatementHandle extends ParserAstNode {
+  final Token token;
+
+  EmptyStatementHandle(ParserAstType type, {required this.token})
+      : super("EmptyStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class AssertBegin extends ParserAstNode {
+  final Token assertKeyword;
+  final Assert kind;
+
+  AssertBegin(ParserAstType type,
+      {required this.assertKeyword, required this.kind})
+      : super("Assert", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "assertKeyword": assertKeyword,
+        "kind": kind,
+      };
+}
+
+class AssertEnd extends ParserAstNode {
+  final Token assertKeyword;
+  final Assert kind;
+  final Token leftParenthesis;
+  final Token? commaToken;
+  final Token semicolonToken;
+
+  AssertEnd(ParserAstType type,
+      {required this.assertKeyword,
+      required this.kind,
+      required this.leftParenthesis,
+      this.commaToken,
+      required this.semicolonToken})
+      : super("Assert", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "assertKeyword": assertKeyword,
+        "kind": kind,
+        "leftParenthesis": leftParenthesis,
+        "commaToken": commaToken,
+        "semicolonToken": semicolonToken,
+      };
+}
+
+class LiteralDoubleHandle extends ParserAstNode {
+  final Token token;
+
+  LiteralDoubleHandle(ParserAstType type, {required this.token})
+      : super("LiteralDouble", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class LiteralIntHandle extends ParserAstNode {
+  final Token token;
+
+  LiteralIntHandle(ParserAstType type, {required this.token})
+      : super("LiteralInt", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class LiteralListHandle extends ParserAstNode {
+  final int count;
+  final Token leftBracket;
+  final Token? constKeyword;
+  final Token rightBracket;
+
+  LiteralListHandle(ParserAstType type,
+      {required this.count,
+      required this.leftBracket,
+      this.constKeyword,
+      required this.rightBracket})
+      : super("LiteralList", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "leftBracket": leftBracket,
+        "constKeyword": constKeyword,
+        "rightBracket": rightBracket,
+      };
+}
+
+class LiteralSetOrMapHandle extends ParserAstNode {
+  final int count;
+  final Token leftBrace;
+  final Token? constKeyword;
+  final Token rightBrace;
+  final bool hasSetEntry;
+
+  LiteralSetOrMapHandle(ParserAstType type,
+      {required this.count,
+      required this.leftBrace,
+      this.constKeyword,
+      required this.rightBrace,
+      required this.hasSetEntry})
+      : super("LiteralSetOrMap", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "count": count,
+        "leftBrace": leftBrace,
+        "constKeyword": constKeyword,
+        "rightBrace": rightBrace,
+        "hasSetEntry": hasSetEntry,
+      };
+}
+
+class LiteralNullHandle extends ParserAstNode {
+  final Token token;
+
+  LiteralNullHandle(ParserAstType type, {required this.token})
+      : super("LiteralNull", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NativeClauseHandle extends ParserAstNode {
+  final Token nativeToken;
+  final bool hasName;
+
+  NativeClauseHandle(ParserAstType type,
+      {required this.nativeToken, required this.hasName})
+      : super("NativeClause", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "nativeToken": nativeToken,
+        "hasName": hasName,
+      };
+}
+
+class NamedArgumentHandle extends ParserAstNode {
+  final Token colon;
+
+  NamedArgumentHandle(ParserAstType type, {required this.colon})
+      : super("NamedArgument", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "colon": colon,
+      };
+}
+
+class NewExpressionBegin extends ParserAstNode {
+  final Token token;
+
+  NewExpressionBegin(ParserAstType type, {required this.token})
+      : super("NewExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NewExpressionEnd extends ParserAstNode {
+  final Token token;
+
+  NewExpressionEnd(ParserAstType type, {required this.token})
+      : super("NewExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NoArgumentsHandle extends ParserAstNode {
+  final Token token;
+
+  NoArgumentsHandle(ParserAstType type, {required this.token})
+      : super("NoArguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NoConstructorReferenceContinuationAfterTypeArgumentsHandle
+    extends ParserAstNode {
+  final Token token;
+
+  NoConstructorReferenceContinuationAfterTypeArgumentsHandle(ParserAstType type,
+      {required this.token})
+      : super("NoConstructorReferenceContinuationAfterTypeArguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NoTypeNameInConstructorReferenceHandle extends ParserAstNode {
+  final Token token;
+
+  NoTypeNameInConstructorReferenceHandle(ParserAstType type,
+      {required this.token})
+      : super("NoTypeNameInConstructorReference", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class NoTypeHandle extends ParserAstNode {
+  final Token lastConsumed;
+
+  NoTypeHandle(ParserAstType type, {required this.lastConsumed})
+      : super("NoType", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "lastConsumed": lastConsumed,
+      };
+}
+
+class NoTypeVariablesHandle extends ParserAstNode {
+  final Token token;
+
+  NoTypeVariablesHandle(ParserAstType type, {required this.token})
+      : super("NoTypeVariables", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class OperatorHandle extends ParserAstNode {
+  final Token token;
+
+  OperatorHandle(ParserAstType type, {required this.token})
+      : super("Operator", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class SymbolVoidHandle extends ParserAstNode {
+  final Token token;
+
+  SymbolVoidHandle(ParserAstType type, {required this.token})
+      : super("SymbolVoid", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class OperatorNameHandle extends ParserAstNode {
+  final Token operatorKeyword;
+  final Token token;
+
+  OperatorNameHandle(ParserAstType type,
+      {required this.operatorKeyword, required this.token})
+      : super("OperatorName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operatorKeyword": operatorKeyword,
+        "token": token,
+      };
+}
+
+class InvalidOperatorNameHandle extends ParserAstNode {
+  final Token operatorKeyword;
+  final Token token;
+
+  InvalidOperatorNameHandle(ParserAstType type,
+      {required this.operatorKeyword, required this.token})
+      : super("InvalidOperatorName", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "operatorKeyword": operatorKeyword,
+        "token": token,
+      };
+}
+
+class ParenthesizedConditionHandle extends ParserAstNode {
+  final Token token;
+
+  ParenthesizedConditionHandle(ParserAstType type, {required this.token})
+      : super("ParenthesizedCondition", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class ParenthesizedExpressionHandle extends ParserAstNode {
+  final Token token;
+
+  ParenthesizedExpressionHandle(ParserAstType type, {required this.token})
+      : super("ParenthesizedExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class QualifiedHandle extends ParserAstNode {
+  final Token period;
+
+  QualifiedHandle(ParserAstType type, {required this.period})
+      : super("Qualified", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "period": period,
+      };
+}
+
+class StringPartHandle extends ParserAstNode {
+  final Token token;
+
+  StringPartHandle(ParserAstType type, {required this.token})
+      : super("StringPart", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class SuperExpressionHandle extends ParserAstNode {
+  final Token token;
+  final IdentifierContext context;
+
+  SuperExpressionHandle(ParserAstType type,
+      {required this.token, required this.context})
+      : super("SuperExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "context": context,
+      };
+}
+
+class SwitchCaseBegin extends ParserAstNode {
+  final int labelCount;
+  final int expressionCount;
+  final Token firstToken;
+
+  SwitchCaseBegin(ParserAstType type,
+      {required this.labelCount,
+      required this.expressionCount,
+      required this.firstToken})
+      : super("SwitchCase", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "labelCount": labelCount,
+        "expressionCount": expressionCount,
+        "firstToken": firstToken,
+      };
+}
+
+class SwitchCaseEnd extends ParserAstNode {
+  final int labelCount;
+  final int expressionCount;
+  final Token? defaultKeyword;
+  final Token? colonAfterDefault;
+  final int statementCount;
+  final Token firstToken;
+  final Token endToken;
+
+  SwitchCaseEnd(ParserAstType type,
+      {required this.labelCount,
+      required this.expressionCount,
+      this.defaultKeyword,
+      this.colonAfterDefault,
+      required this.statementCount,
+      required this.firstToken,
+      required this.endToken})
+      : super("SwitchCase", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "labelCount": labelCount,
+        "expressionCount": expressionCount,
+        "defaultKeyword": defaultKeyword,
+        "colonAfterDefault": colonAfterDefault,
+        "statementCount": statementCount,
+        "firstToken": firstToken,
+        "endToken": endToken,
+      };
+}
+
+class ThisExpressionHandle extends ParserAstNode {
+  final Token token;
+  final IdentifierContext context;
+
+  ThisExpressionHandle(ParserAstType type,
+      {required this.token, required this.context})
+      : super("ThisExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "context": context,
+      };
+}
+
+class UnaryPostfixAssignmentExpressionHandle extends ParserAstNode {
+  final Token token;
+
+  UnaryPostfixAssignmentExpressionHandle(ParserAstType type,
+      {required this.token})
+      : super("UnaryPostfixAssignmentExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class UnaryPrefixExpressionHandle extends ParserAstNode {
+  final Token token;
+
+  UnaryPrefixExpressionHandle(ParserAstType type, {required this.token})
+      : super("UnaryPrefixExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class UnaryPrefixAssignmentExpressionHandle extends ParserAstNode {
+  final Token token;
+
+  UnaryPrefixAssignmentExpressionHandle(ParserAstType type,
+      {required this.token})
+      : super("UnaryPrefixAssignmentExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class FormalParameterDefaultValueExpressionBegin extends ParserAstNode {
+  FormalParameterDefaultValueExpressionBegin(ParserAstType type)
+      : super("FormalParameterDefaultValueExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class FormalParameterDefaultValueExpressionEnd extends ParserAstNode {
+  FormalParameterDefaultValueExpressionEnd(ParserAstType type)
+      : super("FormalParameterDefaultValueExpression", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class ValuedFormalParameterHandle extends ParserAstNode {
+  final Token equals;
+  final Token token;
+
+  ValuedFormalParameterHandle(ParserAstType type,
+      {required this.equals, required this.token})
+      : super("ValuedFormalParameter", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "equals": equals,
+        "token": token,
+      };
+}
+
+class FormalParameterWithoutValueHandle extends ParserAstNode {
+  final Token token;
+
+  FormalParameterWithoutValueHandle(ParserAstType type, {required this.token})
+      : super("FormalParameterWithoutValue", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class VoidKeywordHandle extends ParserAstNode {
+  final Token token;
+
+  VoidKeywordHandle(ParserAstType type, {required this.token})
+      : super("VoidKeyword", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class VoidKeywordWithTypeArgumentsHandle extends ParserAstNode {
+  final Token token;
+
+  VoidKeywordWithTypeArgumentsHandle(ParserAstType type, {required this.token})
+      : super("VoidKeywordWithTypeArguments", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class YieldStatementBegin extends ParserAstNode {
+  final Token token;
+
+  YieldStatementBegin(ParserAstType type, {required this.token})
+      : super("YieldStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class YieldStatementEnd extends ParserAstNode {
+  final Token yieldToken;
+  final Token? starToken;
+  final Token endToken;
+
+  YieldStatementEnd(ParserAstType type,
+      {required this.yieldToken, this.starToken, required this.endToken})
+      : super("YieldStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "yieldToken": yieldToken,
+        "starToken": starToken,
+        "endToken": endToken,
+      };
+}
+
+class InvalidYieldStatementEnd extends ParserAstNode {
+  final Token beginToken;
+  final Token? starToken;
+  final Token endToken;
+  final MessageCode errorCode;
+
+  InvalidYieldStatementEnd(ParserAstType type,
+      {required this.beginToken,
+      this.starToken,
+      required this.endToken,
+      required this.errorCode})
+      : super("InvalidYieldStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "beginToken": beginToken,
+        "starToken": starToken,
+        "endToken": endToken,
+        "errorCode": errorCode,
+      };
+}
+
+class RecoverableErrorHandle extends ParserAstNode {
+  final Message message;
+  final Token startToken;
+  final Token endToken;
+
+  RecoverableErrorHandle(ParserAstType type,
+      {required this.message, required this.startToken, required this.endToken})
+      : super("RecoverableError", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "message": message,
+        "startToken": startToken,
+        "endToken": endToken,
+      };
+}
+
+class ErrorTokenHandle extends ParserAstNode {
+  final ErrorToken token;
+
+  ErrorTokenHandle(ParserAstType type, {required this.token})
+      : super("ErrorToken", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class UnescapeErrorHandle extends ParserAstNode {
+  final Message message;
+  final Token location;
+  final int stringOffset;
+  final int length;
+
+  UnescapeErrorHandle(ParserAstType type,
+      {required this.message,
+      required this.location,
+      required this.stringOffset,
+      required this.length})
+      : super("UnescapeError", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "message": message,
+        "location": location,
+        "stringOffset": stringOffset,
+        "length": length,
+      };
+}
+
+class InvalidStatementHandle extends ParserAstNode {
+  final Token token;
+  final Message message;
+
+  InvalidStatementHandle(ParserAstType type,
+      {required this.token, required this.message})
+      : super("InvalidStatement", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+        "message": message,
+      };
+}
+
+class ScriptHandle extends ParserAstNode {
+  final Token token;
+
+  ScriptHandle(ParserAstType type, {required this.token})
+      : super("Script", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
+
+class CommentReferenceTextHandle extends ParserAstNode {
+  final String referenceSource;
+  final int referenceOffset;
+
+  CommentReferenceTextHandle(ParserAstType type,
+      {required this.referenceSource, required this.referenceOffset})
+      : super("CommentReferenceText", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "referenceSource": referenceSource,
+        "referenceOffset": referenceOffset,
+      };
+}
+
+class CommentReferenceHandle extends ParserAstNode {
+  final Token? newKeyword;
+  final Token? prefix;
+  final Token? period;
+  final Token token;
+
+  CommentReferenceHandle(ParserAstType type,
+      {this.newKeyword, this.prefix, this.period, required this.token})
+      : super("CommentReference", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "newKeyword": newKeyword,
+        "prefix": prefix,
+        "period": period,
+        "token": token,
+      };
+}
+
+class NoCommentReferenceHandle extends ParserAstNode {
+  NoCommentReferenceHandle(ParserAstType type)
+      : super("NoCommentReference", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {};
+}
+
+class TypeArgumentApplicationHandle extends ParserAstNode {
+  final Token openAngleBracket;
+
+  TypeArgumentApplicationHandle(ParserAstType type,
+      {required this.openAngleBracket})
+      : super("TypeArgumentApplication", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "openAngleBracket": openAngleBracket,
+      };
+}
+
+class NewAsIdentifierHandle extends ParserAstNode {
+  final Token token;
+
+  NewAsIdentifierHandle(ParserAstType type, {required this.token})
+      : super("NewAsIdentifier", type);
+
+  @override
+  Map<String, Object?> get deprecatedArguments => {
+        "token": token,
+      };
+}
diff --git a/pkg/front_end/lib/src/fasta/util/textual_outline.dart b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
index b72d8b6..e902eab 100644
--- a/pkg/front_end/lib/src/fasta/util/textual_outline.dart
+++ b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
@@ -759,7 +759,7 @@
   }
 
   @override
-  void endEnum(Token enumKeyword, Token leftBrace, int count) {
+  void handleEnumHeader(Token enumKeyword, Token leftBrace) {
     elementStartToChunk[enumKeyword] =
         new _EnumChunk(enumKeyword, leftBrace.endGroup!);
   }
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index 2a8c8c8..77a6a44 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -52,6 +52,7 @@
   final Map<ExperimentalFlag, bool> explicitExperimentalFlags;
   final AllowedExperimentalFlags? allowedExperimentalFlags;
   final Uri? librariesSpecificationUri;
+  final Uri? packageConfigUri;
   // TODO(johnniwinther): Tailor support to redefine selected platform
   // classes/members only.
   final bool compileSdk;
@@ -62,6 +63,7 @@
       {this.explicitExperimentalFlags = const {},
       this.allowedExperimentalFlags,
       this.librariesSpecificationUri,
+      this.packageConfigUri,
       this.compileSdk: false,
       this.targetFlags: const TestTargetFlags(),
       this.nnbdMode: NnbdMode.Weak});
@@ -322,6 +324,7 @@
       options.compileSdk = config.compileSdk;
     }
   }
+  options.packagesFileUri = config.packageConfigUri;
   config.customizeCompilerOptions(options, testData);
   InternalCompilerResult compilerResult = await compileScript(
       testData.memorySourceFiles,
diff --git a/pkg/front_end/lib/widget_cache.dart b/pkg/front_end/lib/widget_cache.dart
index f80f493..752b969 100644
--- a/pkg/front_end/lib/widget_cache.dart
+++ b/pkg/front_end/lib/widget_cache.dart
@@ -59,7 +59,7 @@
   String? checkSingleWidgetTypeModified(
     Component? lastGoodComponent,
     Component partialComponent,
-    ClassHierarchy classHierarchy,
+    ClassHierarchy? classHierarchy,
   ) {
     if (!_frameworkTypesLocated ||
         lastGoodComponent == null ||
@@ -124,7 +124,7 @@
     }
 
     // Update the class references to stateless, stateful, and state classes.
-    for (Library library in classHierarchy.knownLibraries) {
+    for (Library library in classHierarchy!.knownLibraries) {
       if (library.importUri == _frameworkLibrary) {
         _locatedClassDeclarations(library);
       }
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index b217478..c7aca29 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -212,6 +212,8 @@
 DuplicatedParameterName/example: Fail
 Encoding/analyzerCode: Fail
 EnumConstantSameNameAsEnclosing/example: Fail
+EnumDeclaresFactory/analyzerCode: Fail
+EnumDeclaresFactory/example: Fail
 EnumInstantiation/example: Fail
 EqualityCannotBeEqualityOperand/part_wrapped_script1: Fail
 EqualityCannotBeEqualityOperand/part_wrapped_script2: Fail
@@ -525,10 +527,6 @@
 JsInteropExternalMemberNotJSAnnotated/example: Fail # Web compiler specific
 JsInteropIndexNotSupported/analyzerCode: Fail # Web compiler specific
 JsInteropIndexNotSupported/example: Fail # Web compiler specific
-JsInteropStaticInteropWithInstanceMembers/analyzerCode: Fail # Web compiler specific
-JsInteropStaticInteropWithInstanceMembers/example: Fail # Web compiler specific
-JsInteropStaticInteropWithNonStaticSupertype/analyzerCode: Fail # Web compiler specific
-JsInteropStaticInteropWithNonStaticSupertype/example: Fail # Web compiler specific
 JsInteropJSClassExtendsDartClass/analyzerCode: Fail # Web compiler specific
 JsInteropJSClassExtendsDartClass/example: Fail # Web compiler specific
 JsInteropNamedParameters/analyzerCode: Fail # Web compiler specific
@@ -539,6 +537,10 @@
 JsInteropNonExternalConstructor/example: Fail # Web compiler specific
 JsInteropNonExternalMember/analyzerCode: Fail # Web compiler specific
 JsInteropNonExternalMember/example: Fail # Web compiler specific
+JsInteropStaticInteropWithInstanceMembers/analyzerCode: Fail # Web compiler specific
+JsInteropStaticInteropWithInstanceMembers/example: Fail # Web compiler specific
+JsInteropStaticInteropWithNonStaticSupertype/analyzerCode: Fail # Web compiler specific
+JsInteropStaticInteropWithNonStaticSupertype/example: Fail # Web compiler specific
 LanguageVersionInvalidInDotPackages/analyzerCode: Fail
 LanguageVersionMismatchInPart/analyzerCode: Fail
 LanguageVersionMismatchInPart/part_wrapped_script: Fail # Part in (now) part.
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 5eac795..043ebae 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -929,7 +929,7 @@
 
 SuperInitializerNotLast:
   problemMessage: "Can't have initializers after 'super'."
-  analyzerCode: INVALID_SUPER_INVOCATION
+  analyzerCode: SUPER_INVOCATION_NOT_LAST
   script:
     - "class C { int x; C.bad() : super(), x = 5; }"
 
@@ -2069,6 +2069,10 @@
   problemMessage: "Unsupported nullability value '#string' on type '#type'."
   severity: INTERNAL_PROBLEM
 
+InternalProblemOmittedTypeNameInConstructorReference:
+  problemMessage: "Unsupported omission of the type name in a constructor reference outside of an enum element declaration."
+  severity: INTERNAL_PROBLEM
+
 IncrementalCompilerIllegalParameter:
   problemMessage: "Illegal parameter name '#string' found during expression compilation."
 
@@ -5436,3 +5440,7 @@
   experiments: constructor-tearoffs
   script: |
     method(dynamic d) => d.new;
+
+EnumDeclaresFactory:
+  problemMessage: "Enums can't declare factory constructors."
+  correctionMessage: "Try removing the factory constructor declaration."
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/a.dart b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/a.dart
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/a.dart
@@ -0,0 +1 @@
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/a2.dart b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/a2.dart
new file mode 100644
index 0000000..8c26988
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/a2.dart
@@ -0,0 +1 @@
+class Foo2 {}
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/b.dart b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/b.dart
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/b.dart
@@ -0,0 +1 @@
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/b2.dart b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/b2.dart
new file mode 100644
index 0000000..8c26988
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/b2.dart
@@ -0,0 +1 @@
+class Foo2 {}
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/c.dart b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/c.dart
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/c.dart
@@ -0,0 +1 @@
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/c2.dart b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/c2.dart
new file mode 100644
index 0000000..8c26988
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/c2.dart
@@ -0,0 +1 @@
+class Foo2 {}
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/main.dart b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/main.dart
new file mode 100644
index 0000000..bc74a47
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/main.dart
@@ -0,0 +1,8 @@
+import 'a.dart' if (dart.library.html) 'b.dart' if (dart.library.io) 'c.dart';
+export 'a2.dart'
+    if (dart.library.html) 'b2.dart'
+    if (dart.library.io) 'c2.dart';
+
+Foo x() {
+  return new Foo();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/main.dart.outline_extracted
new file mode 100644
index 0000000..a516b91
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/conditional_imports_exports/main.dart.outline_extracted
@@ -0,0 +1,40 @@
+org-dartlang-testcase:///main.dart:
+import 'a.dart' if (dart.library.html) 'b.dart' if (dart.library.io) 'c.dart';
+export 'a2.dart' if (dart.library.html) 'b2.dart' if (dart.library.io) 'c2.dart';
+Foo x() {}
+
+
+
+
+org-dartlang-testcase:///a2.dart:
+class Foo2 {}
+
+
+
+
+org-dartlang-testcase:///b2.dart:
+class Foo2 {}
+
+
+
+
+org-dartlang-testcase:///c2.dart:
+class Foo2 {}
+
+
+
+
+org-dartlang-testcase:///a.dart:
+class Foo {}
+
+
+
+
+org-dartlang-testcase:///b.dart:
+class Foo {}
+
+
+
+
+org-dartlang-testcase:///c.dart:
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/exports_export_01/main.dart b/pkg/front_end/outline_extraction_testcases/exports_export_01/main.dart
new file mode 100644
index 0000000..997da89
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_export_01/main.dart
@@ -0,0 +1,3 @@
+import "test8.dart";
+
+ClassFromImportsExportsExport? zyx____xyz;
diff --git a/pkg/front_end/outline_extraction_testcases/exports_export_01/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/exports_export_01/main.dart.outline_extracted
new file mode 100644
index 0000000..1f5cc58
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_export_01/main.dart.outline_extracted
@@ -0,0 +1,22 @@
+org-dartlang-testcase:///main.dart:
+import "test8.dart";
+ClassFromImportsExportsExport? zyx____xyz;
+
+
+
+
+org-dartlang-testcase:///test8.dart:
+export "test9.dart";
+
+
+
+
+org-dartlang-testcase:///test9.dart:
+export "test10.dart";
+
+
+
+
+org-dartlang-testcase:///test10.dart:
+export "dart:async";
+class ClassFromImportsExportsExport {}
diff --git a/pkg/front_end/outline_extraction_testcases/exports_export_01/test10.dart b/pkg/front_end/outline_extraction_testcases/exports_export_01/test10.dart
new file mode 100644
index 0000000..8513138
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_export_01/test10.dart
@@ -0,0 +1,5 @@
+export "dart:async";
+
+void test10Method() {}
+
+class ClassFromImportsExportsExport {}
diff --git a/pkg/front_end/outline_extraction_testcases/exports_export_01/test8.dart b/pkg/front_end/outline_extraction_testcases/exports_export_01/test8.dart
new file mode 100644
index 0000000..c83a90a
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_export_01/test8.dart
@@ -0,0 +1,3 @@
+export "test9.dart";
+
+void test8Method() {}
diff --git a/pkg/front_end/outline_extraction_testcases/exports_export_01/test9.dart b/pkg/front_end/outline_extraction_testcases/exports_export_01/test9.dart
new file mode 100644
index 0000000..d0fcb31
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_export_01/test9.dart
@@ -0,0 +1,3 @@
+export "test10.dart";
+
+void test9Method() {}
diff --git a/pkg/front_end/outline_extraction_testcases/exports_included/main.dart b/pkg/front_end/outline_extraction_testcases/exports_included/main.dart
new file mode 100644
index 0000000..52091d7
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_included/main.dart
@@ -0,0 +1 @@
+export "test6.dart";
diff --git a/pkg/front_end/outline_extraction_testcases/exports_included/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/exports_included/main.dart.outline_extracted
new file mode 100644
index 0000000..c2b824d
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_included/main.dart.outline_extracted
@@ -0,0 +1,15 @@
+org-dartlang-testcase:///main.dart:
+export "test6.dart";
+
+
+
+
+org-dartlang-testcase:///test6.dart:
+export "test7.dart";
+void test6() {}
+
+
+
+
+org-dartlang-testcase:///test7.dart:
+void test7() {}
diff --git a/pkg/front_end/outline_extraction_testcases/exports_included/test6.dart b/pkg/front_end/outline_extraction_testcases/exports_included/test6.dart
new file mode 100644
index 0000000..c130634
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_included/test6.dart
@@ -0,0 +1,3 @@
+export "test7.dart";
+
+void test6() {}
diff --git a/pkg/front_end/outline_extraction_testcases/exports_included/test7.dart b/pkg/front_end/outline_extraction_testcases/exports_included/test7.dart
new file mode 100644
index 0000000..5b3e78d
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/exports_included/test7.dart
@@ -0,0 +1 @@
+void test7() {}
diff --git a/pkg/front_end/outline_extraction_testcases/extends/foo.dart b/pkg/front_end/outline_extraction_testcases/extends/foo.dart
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/extends/foo.dart
@@ -0,0 +1 @@
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/extends/main.dart b/pkg/front_end/outline_extraction_testcases/extends/main.dart
new file mode 100644
index 0000000..a126b2a
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/extends/main.dart
@@ -0,0 +1,3 @@
+import "foo.dart";
+
+class X extends Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/extends/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/extends/main.dart.outline_extracted
new file mode 100644
index 0000000..09b7413
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/extends/main.dart.outline_extracted
@@ -0,0 +1,9 @@
+org-dartlang-testcase:///main.dart:
+import "foo.dart";
+class X extends Foo {}
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/factories/main.dart b/pkg/front_end/outline_extraction_testcases/factories/main.dart
new file mode 100644
index 0000000..316b9c5
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/factories/main.dart
@@ -0,0 +1,12 @@
+import 'package:foo/test11.dart';
+
+class Abc {
+  Abc() {}
+  factory Abc.a() {
+    return Abc2();
+  }
+  // Abc3 currently gets in --- it doesn't have to.
+  factory Abc.b() => Abc3();
+  var v1 = Abc4();
+  var v2 = new Abc5();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/factories/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/factories/main.dart.outline_extracted
new file mode 100644
index 0000000..4127b46
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/factories/main.dart.outline_extracted
@@ -0,0 +1,24 @@
+org-dartlang-testcase:///main.dart:
+import 'package:foo/test11.dart';
+class Abc {
+  Abc() {}
+  factory Abc.a() {}
+  factory Abc.b() => Abc3();
+  var v1 = Abc4();
+  var v2 = new Abc5();
+}
+
+
+
+
+org-dartlang-testcase:///test11.dart:
+import 'package:foo/main.dart';
+class Abc3 extends Abc {
+  Abc3() {}
+}
+class Abc4 extends Abc {
+  Abc4() {}
+}
+class Abc5 extends Abc {
+  Abc5() {}
+}
diff --git a/pkg/front_end/outline_extraction_testcases/factories/test11.dart b/pkg/front_end/outline_extraction_testcases/factories/test11.dart
new file mode 100644
index 0000000..105387c
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/factories/test11.dart
@@ -0,0 +1,21 @@
+import 'package:foo/main.dart';
+
+class Abc2 extends Abc {
+  Abc2() {}
+}
+
+class Abc3 extends Abc {
+  Abc3() {}
+}
+
+class Abc4 extends Abc {
+  Abc4() {}
+}
+
+class Abc5 extends Abc {
+  Abc5() {}
+}
+
+class Abc6 extends Abc {
+  Abc6() {}
+}
diff --git a/pkg/front_end/outline_extraction_testcases/field_dotting_in/b.dart b/pkg/front_end/outline_extraction_testcases/field_dotting_in/b.dart
new file mode 100644
index 0000000..112fdbc
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/field_dotting_in/b.dart
@@ -0,0 +1,9 @@
+import "c.dart";
+
+class B {
+  C c() {
+    return new C();
+  }
+}
+
+class BPrime {}
diff --git a/pkg/front_end/outline_extraction_testcases/field_dotting_in/c.dart b/pkg/front_end/outline_extraction_testcases/field_dotting_in/c.dart
new file mode 100644
index 0000000..356bd56
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/field_dotting_in/c.dart
@@ -0,0 +1,9 @@
+import "d.dart";
+
+class C {
+  D d() {
+    return new D();
+  }
+}
+
+class CPrime {}
diff --git a/pkg/front_end/outline_extraction_testcases/field_dotting_in/d.dart b/pkg/front_end/outline_extraction_testcases/field_dotting_in/d.dart
new file mode 100644
index 0000000..8655cd4
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/field_dotting_in/d.dart
@@ -0,0 +1,7 @@
+class D {
+  String d() {
+    return "hello";
+  }
+}
+
+class DPrime {}
diff --git a/pkg/front_end/outline_extraction_testcases/field_dotting_in/main.dart b/pkg/front_end/outline_extraction_testcases/field_dotting_in/main.dart
new file mode 100644
index 0000000..3d53be6
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/field_dotting_in/main.dart
@@ -0,0 +1,9 @@
+import "b.dart";
+
+var x = A.b().c().d;
+
+class A {
+  static B b() {
+    return new B();
+  }
+}
diff --git a/pkg/front_end/outline_extraction_testcases/field_dotting_in/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/field_dotting_in/main.dart.outline_extracted
new file mode 100644
index 0000000..e9a8f51
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/field_dotting_in/main.dart.outline_extracted
@@ -0,0 +1,32 @@
+org-dartlang-testcase:///main.dart:
+import "b.dart";
+var x = A.b().c().d;
+class A {
+  static B b() {}
+}
+
+
+
+
+org-dartlang-testcase:///b.dart:
+import "c.dart";
+class B {
+  C c() {}
+}
+
+
+
+
+org-dartlang-testcase:///c.dart:
+import "d.dart";
+class C {
+  D d() {}
+}
+
+
+
+
+org-dartlang-testcase:///d.dart:
+class D {
+  String d() {}
+}
diff --git a/pkg/front_end/outline_extraction_testcases/fields/bar.dart b/pkg/front_end/outline_extraction_testcases/fields/bar.dart
new file mode 100644
index 0000000..79f980a
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/fields/bar.dart
@@ -0,0 +1,11 @@
+class Bar {}
+
+class Bar2 {}
+
+class Bar3 {}
+
+class Bar4 {}
+
+class Foo3 {}
+
+class Foo4 {}
diff --git a/pkg/front_end/outline_extraction_testcases/fields/foo.dart b/pkg/front_end/outline_extraction_testcases/fields/foo.dart
new file mode 100644
index 0000000..43434c3
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/fields/foo.dart
@@ -0,0 +1,13 @@
+export "bar.dart";
+
+class Baz {}
+
+class Baz2 {}
+
+class Baz3 {}
+
+class Baz4 {}
+
+class Foo {}
+
+class Foo2 {}
diff --git a/pkg/front_end/outline_extraction_testcases/fields/main.dart b/pkg/front_end/outline_extraction_testcases/fields/main.dart
new file mode 100644
index 0000000..bf52fd9
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/fields/main.dart
@@ -0,0 +1,19 @@
+import "foo.dart";
+
+class A {
+  Bar field = new Bar();
+  Bar2 field2 = new Bar2();
+  var field3 = new Bar3(), field4 = new Bar4();
+}
+
+mixin A2 {
+  Baz field = new Baz();
+  Baz2 field2 = new Baz2();
+  var field3 = new Baz3(), field4 = new Baz4();
+}
+
+extension A3 on Object {
+  static Foo field = new Foo();
+  static Foo2 field2 = new Foo2();
+  static var field3 = new Foo3(), field4 = new Foo4();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/fields/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/fields/main.dart.outline_extracted
new file mode 100644
index 0000000..13e239a
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/fields/main.dart.outline_extracted
@@ -0,0 +1,40 @@
+org-dartlang-testcase:///main.dart:
+import "foo.dart";
+class A {
+  Bar field = new Bar();
+  Bar2 field2 = new Bar2();
+  var field3 = new Bar3(), field4 = new Bar4();
+}
+mixin A2 {
+  Baz field = new Baz();
+  Baz2 field2 = new Baz2();
+  var field3 = new Baz3(), field4 = new Baz4();
+}
+extension A3 on Object {
+  static Foo field = new Foo();
+  static Foo2 field2 = new Foo2();
+  static var field3 = new Foo3(), field4 = new Foo4();
+}
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+export "bar.dart";
+class Baz {}
+class Baz2 {}
+class Baz3 {}
+class Baz4 {}
+class Foo {}
+class Foo2 {}
+
+
+
+
+org-dartlang-testcase:///bar.dart:
+class Bar {}
+class Bar2 {}
+class Bar3 {}
+class Bar4 {}
+class Foo3 {}
+class Foo4 {}
diff --git a/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/main.dart b/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/main.dart
new file mode 100644
index 0000000..3cfbb90
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/main.dart
@@ -0,0 +1,6 @@
+import "test16.dart" as test16;
+
+class Test16ClassHelper {
+  // the naming matching is what makes it annoying!
+  final test16toplevel = test16.test16toplevel("hello");
+}
diff --git a/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/main.dart.outline_extracted
new file mode 100644
index 0000000..e0a42eb
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/main.dart.outline_extracted
@@ -0,0 +1,11 @@
+org-dartlang-testcase:///main.dart:
+import "test16.dart" as test16;
+class Test16ClassHelper {
+  final test16toplevel = test16.test16toplevel("hello");
+}
+
+
+
+
+org-dartlang-testcase:///test16.dart:
+String test16toplevel(String s) {}
diff --git a/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/test16.dart b/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/test16.dart
new file mode 100644
index 0000000..41d882e
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_prefix_overlap_with_field/test16.dart
@@ -0,0 +1,3 @@
+String test16toplevel(String s) {
+  return s * 2;
+}
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix/bar.dart b/pkg/front_end/outline_extraction_testcases/import_with_prefix/bar.dart
new file mode 100644
index 0000000..91b2144
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix/bar.dart
@@ -0,0 +1,5 @@
+int bar() {
+  return 42;
+}
+
+class Baz {}
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix/foo.dart b/pkg/front_end/outline_extraction_testcases/import_with_prefix/foo.dart
new file mode 100644
index 0000000..0ec48dd
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix/foo.dart
@@ -0,0 +1,5 @@
+String bar() {
+  return "hello";
+}
+
+class Baz {}
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix/main.dart b/pkg/front_end/outline_extraction_testcases/import_with_prefix/main.dart
new file mode 100644
index 0000000..aef942d
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix/main.dart
@@ -0,0 +1,7 @@
+import 'foo.dart' as foo;
+// This import isn't used --- foo.bar below explicitly wants bar from foo.
+import 'bar.dart';
+
+var x = foo.bar();
+
+foo.Baz? baz;
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/import_with_prefix/main.dart.outline_extracted
new file mode 100644
index 0000000..1c804cb
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix/main.dart.outline_extracted
@@ -0,0 +1,17 @@
+org-dartlang-testcase:///main.dart:
+import 'foo.dart' as foo;
+import 'bar.dart';
+var x = foo.bar();
+foo.Baz? baz;
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+String bar() {}
+class Baz {}
+
+
+
+
+org-dartlang-testcase:///bar.dart:
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/a.dart b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/a.dart
new file mode 100644
index 0000000..ff840ec
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/a.dart
@@ -0,0 +1,3 @@
+String foo() {
+  return "foo";
+}
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/b.dart b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/b.dart
new file mode 100644
index 0000000..07f55de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/b.dart
@@ -0,0 +1,3 @@
+String bar() {
+  return "bar";
+}
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/main.dart b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/main.dart
new file mode 100644
index 0000000..73d125a
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/main.dart
@@ -0,0 +1,5 @@
+import 'a.dart' as x;
+import 'b.dart' as x;
+
+var foo = x.foo();
+var bar = x.bar();
diff --git a/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/main.dart.outline_extracted
new file mode 100644
index 0000000..166189c
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/import_with_prefix_02/main.dart.outline_extracted
@@ -0,0 +1,17 @@
+org-dartlang-testcase:///main.dart:
+import 'a.dart' as x;
+import 'b.dart' as x;
+var foo = x.foo();
+var bar = x.bar();
+
+
+
+
+org-dartlang-testcase:///a.dart:
+String foo() {}
+
+
+
+
+org-dartlang-testcase:///b.dart:
+String bar() {}
diff --git a/pkg/front_end/outline_extraction_testcases/initial_various/main.dart b/pkg/front_end/outline_extraction_testcases/initial_various/main.dart
new file mode 100644
index 0000000..2ff0638
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/initial_various/main.dart
@@ -0,0 +1,28 @@
+import "main.dart" as self;
+import "test3.dart";
+
+class Foo<E> extends Bar<int> with Qux1<int> implements Baz<Bar<int>> {
+  Foo<E>? parent;
+
+  Foo() {}
+  Foo.bar() {}
+  F? fooMethod1<F>() {
+    print(foo);
+    print(F);
+    print(x.A);
+  }
+
+  E? fooMethod2() {
+    print(E);
+    print(x.A);
+  }
+
+  self.Foo? fooMethod3() {
+    print(E);
+    print(x.A);
+  }
+
+  x fooMethod4() {
+    return x.A;
+  }
+}
diff --git a/pkg/front_end/outline_extraction_testcases/initial_various/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/initial_various/main.dart.outline_extracted
new file mode 100644
index 0000000..3426756
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/initial_various/main.dart.outline_extracted
@@ -0,0 +1,24 @@
+org-dartlang-testcase:///main.dart:
+import "main.dart" as self;
+import "test3.dart";
+class Foo<E> extends Bar<int> with Qux1<int> implements Baz<Bar<int>> {
+  Foo<E>? parent;
+  Foo() {}
+  Foo.bar() {}
+  F? fooMethod1<F>() {}
+  E? fooMethod2() {}
+  self.Foo? fooMethod3() {}
+  x fooMethod4() {}
+}
+
+
+
+
+org-dartlang-testcase:///test3.dart:
+class Bar<E> {}
+class Baz<E> {}
+class Qux1<E> {
+  Qux1AndAHalf? qux1AndAHalf() {}
+}
+class Qux1AndAHalf<E> {}
+enum x { A, B, C }
diff --git a/pkg/front_end/outline_extraction_testcases/initial_various/test3.dart b/pkg/front_end/outline_extraction_testcases/initial_various/test3.dart
new file mode 100644
index 0000000..530644b
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/initial_various/test3.dart
@@ -0,0 +1,25 @@
+import "test4.dart";
+
+class Bar<E> {}
+
+class Baz<E> {}
+
+class Qux1<E> {
+  Qux1AndAHalf? qux1AndAHalf() {
+    // nothing...
+  }
+}
+
+class Qux1AndAHalf<E> {}
+
+class Qux2<E> {
+  Qux3? foo() {}
+}
+
+enum x { A, B, C }
+
+int foo() {
+  return 42;
+}
+
+int foo2 = foo() * 2, foo3 = foo() * 3;
diff --git a/pkg/front_end/outline_extraction_testcases/initial_various/test4.dart b/pkg/front_end/outline_extraction_testcases/initial_various/test4.dart
new file mode 100644
index 0000000..3215ebf
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/initial_various/test4.dart
@@ -0,0 +1,8 @@
+import "test5.dart";
+export "test5.dart";
+
+class Qux3<E> {
+  Qux4? foo() {}
+}
+
+class Qux4<E> {}
diff --git a/pkg/front_end/outline_extraction_testcases/initial_various/test5.dart b/pkg/front_end/outline_extraction_testcases/initial_various/test5.dart
new file mode 100644
index 0000000..0315739
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/initial_various/test5.dart
@@ -0,0 +1,5 @@
+class Qux3x<E> {
+  Qux4x? foo() {}
+}
+
+class Qux4x<E> {}
diff --git a/pkg/front_end/outline_extraction_testcases/keeps_dart_version/bar.dart b/pkg/front_end/outline_extraction_testcases/keeps_dart_version/bar.dart
new file mode 100644
index 0000000..62e4db2
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/keeps_dart_version/bar.dart
@@ -0,0 +1,5 @@
+// @dart = 2.12
+
+class Bar {}
+
+class Baz {}
diff --git a/pkg/front_end/outline_extraction_testcases/keeps_dart_version/main.dart b/pkg/front_end/outline_extraction_testcases/keeps_dart_version/main.dart
new file mode 100644
index 0000000..f20e3af
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/keeps_dart_version/main.dart
@@ -0,0 +1,3 @@
+import "bar.dart";
+
+void foo(Bar bar) {}
diff --git a/pkg/front_end/outline_extraction_testcases/keeps_dart_version/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/keeps_dart_version/main.dart.outline_extracted
new file mode 100644
index 0000000..9a0da03
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/keeps_dart_version/main.dart.outline_extracted
@@ -0,0 +1,10 @@
+org-dartlang-testcase:///main.dart:
+import "bar.dart";
+void foo(Bar bar) {}
+
+
+
+
+org-dartlang-testcase:///bar.dart:
+// @dart = 2.12
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_01/a.dart b/pkg/front_end/outline_extraction_testcases/metadata_01/a.dart
new file mode 100644
index 0000000..e7267c5
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_01/a.dart
@@ -0,0 +1 @@
+class AUnused {}
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_01/b.dart b/pkg/front_end/outline_extraction_testcases/metadata_01/b.dart
new file mode 100644
index 0000000..8b42bda
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_01/b.dart
@@ -0,0 +1,9 @@
+const AbcX = const _AbcX();
+
+class _AbcX {
+  const _AbcX();
+}
+
+class AbcX2 {
+  const AbcX2();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_01/main.dart b/pkg/front_end/outline_extraction_testcases/metadata_01/main.dart
new file mode 100644
index 0000000..a55d3df
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_01/main.dart
@@ -0,0 +1,5 @@
+import "a.dart";
+import "b.dart";
+
+@AbcX
+void foo() {}
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_01/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/metadata_01/main.dart.outline_extracted
new file mode 100644
index 0000000..6d8ae63
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_01/main.dart.outline_extracted
@@ -0,0 +1,19 @@
+org-dartlang-testcase:///main.dart:
+import "a.dart";
+import "b.dart";
+@AbcX
+void foo() {}
+
+
+
+
+org-dartlang-testcase:///a.dart:
+
+
+
+
+org-dartlang-testcase:///b.dart:
+const AbcX = const _AbcX();
+class _AbcX {
+  const _AbcX();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_02/main.dart b/pkg/front_end/outline_extraction_testcases/metadata_02/main.dart
new file mode 100644
index 0000000..851e231
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_02/main.dart
@@ -0,0 +1,5 @@
+import "test15.dart" as $test15;
+import "nottest15.dart";
+
+@$test15.Test15()
+void test15thing() {}
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_02/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/metadata_02/main.dart.outline_extracted
new file mode 100644
index 0000000..123667f
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_02/main.dart.outline_extracted
@@ -0,0 +1,18 @@
+org-dartlang-testcase:///main.dart:
+import "test15.dart" as $test15;
+import "nottest15.dart";
+@$test15.Test15()
+void test15thing() {}
+
+
+
+
+org-dartlang-testcase:///test15.dart:
+class Test15 {
+  const Test15();
+}
+
+
+
+
+org-dartlang-testcase:///nottest15.dart:
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_02/nottest15.dart b/pkg/front_end/outline_extraction_testcases/metadata_02/nottest15.dart
new file mode 100644
index 0000000..41594d9
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_02/nottest15.dart
@@ -0,0 +1,7 @@
+class Test15 {
+  const Test15();
+}
+
+class Test16 {
+  const Test16();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/metadata_02/test15.dart b/pkg/front_end/outline_extraction_testcases/metadata_02/test15.dart
new file mode 100644
index 0000000..41594d9
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/metadata_02/test15.dart
@@ -0,0 +1,7 @@
+class Test15 {
+  const Test15();
+}
+
+class Test16 {
+  const Test16();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/a.dart b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/a.dart
new file mode 100644
index 0000000..bde7250
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/a.dart
@@ -0,0 +1,5 @@
+library foo.a;
+
+export 'b.dart';
+export 'c.dart';
+export 'd.dart';
diff --git a/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/b.dart b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/b.dart
new file mode 100644
index 0000000..3a43d09
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/b.dart
@@ -0,0 +1 @@
+class B {}
diff --git a/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/c.dart b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/c.dart
new file mode 100644
index 0000000..ed37d13
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/c.dart
@@ -0,0 +1,7 @@
+class C<T> {
+  const C.b();
+}
+
+class C2<T> {
+  const C2.b();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/d.dart b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/d.dart
new file mode 100644
index 0000000..40416ad
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/d.dart
@@ -0,0 +1 @@
+class D {}
diff --git a/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/main.dart b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/main.dart
new file mode 100644
index 0000000..afbc02d
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/main.dart
@@ -0,0 +1,6 @@
+import 'package:foo/a.dart' as foo;
+
+class A {
+  var c1 = foo.C<A>.b();
+  var c2 = new foo.C2<A>.b();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/main.dart.outline_extracted
new file mode 100644
index 0000000..c1a663e
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_import_with_export_and_named_constructor_and_class_type_parameter/main.dart.outline_extracted
@@ -0,0 +1,36 @@
+org-dartlang-testcase:///main.dart:
+import 'package:foo/a.dart' as foo;
+class A {
+  var c1 = foo.C<A>.b();
+  var c2 = new foo.C2<A>.b();
+}
+
+
+
+
+org-dartlang-testcase:///a.dart:
+library foo.a;
+export 'b.dart';
+export 'c.dart';
+export 'd.dart';
+
+
+
+
+org-dartlang-testcase:///b.dart:
+
+
+
+
+org-dartlang-testcase:///c.dart:
+class C<T> {
+  const C.b();
+}
+class C2<T> {
+  const C2.b();
+}
+
+
+
+
+org-dartlang-testcase:///d.dart:
diff --git a/pkg/front_end/outline_extraction_testcases/named_mixin/bar.dart b/pkg/front_end/outline_extraction_testcases/named_mixin/bar.dart
new file mode 100644
index 0000000..512eabb
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_mixin/bar.dart
@@ -0,0 +1,3 @@
+export "baz.dart";
+
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/named_mixin/baz.dart b/pkg/front_end/outline_extraction_testcases/named_mixin/baz.dart
new file mode 100644
index 0000000..f1e00d1
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_mixin/baz.dart
@@ -0,0 +1 @@
+class Baz {}
diff --git a/pkg/front_end/outline_extraction_testcases/named_mixin/main.dart b/pkg/front_end/outline_extraction_testcases/named_mixin/main.dart
new file mode 100644
index 0000000..4e0e374
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_mixin/main.dart
@@ -0,0 +1,3 @@
+import "bar.dart";
+
+class Foo = Object with Bar implements Baz;
diff --git a/pkg/front_end/outline_extraction_testcases/named_mixin/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/named_mixin/main.dart.outline_extracted
new file mode 100644
index 0000000..5ff64b3
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/named_mixin/main.dart.outline_extracted
@@ -0,0 +1,16 @@
+org-dartlang-testcase:///main.dart:
+import "bar.dart";
+class Foo = Object with Bar implements Baz;
+
+
+
+
+org-dartlang-testcase:///bar.dart:
+export "baz.dart";
+class Bar {}
+
+
+
+
+org-dartlang-testcase:///baz.dart:
+class Baz {}
diff --git a/pkg/front_end/outline_extraction_testcases/outline_extractor.status b/pkg/front_end/outline_extraction_testcases/outline_extractor.status
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/outline_extractor.status
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/main.dart b/pkg/front_end/outline_extraction_testcases/part_01/main.dart
new file mode 100644
index 0000000..1d7ff4e
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/main.dart
@@ -0,0 +1,4 @@
+import "test12.dart";
+
+void test12part1usage(Test12Part1 x) {}
+void secondtest12part1usage(SecondTest12 x) {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/part_01/main.dart.outline_extracted
new file mode 100644
index 0000000..ee384f7
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/main.dart.outline_extracted
@@ -0,0 +1,47 @@
+org-dartlang-testcase:///main.dart:
+import "test12.dart";
+void test12part1usage(Test12Part1 x) {}
+void secondtest12part1usage(SecondTest12 x) {}
+
+
+
+
+org-dartlang-testcase:///test12.dart:
+import "test13.dart";
+import "test14.dart";
+part 'test12_part1.dart';
+part 'test12_part2.dart';
+class Test12 {}
+class SecondTest12 {
+  void foo(SecondTest12Part1 x) {}
+}
+
+
+
+
+org-dartlang-testcase:///test12_part1.dart:
+part of "test12.dart";
+class Test12Part1 {
+  void foo(Test12 x) {}
+  void bar(Test12Part2 x) {}
+  void baz(Test13 x) {}
+}
+class SecondTest12Part1 {}
+
+
+
+
+org-dartlang-testcase:///test12_part2.dart:
+part of "test12.dart";
+class Test12Part2 {}
+
+
+
+
+org-dartlang-testcase:///test13.dart:
+class Test13 {}
+
+
+
+
+org-dartlang-testcase:///test14.dart:
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/test12.dart b/pkg/front_end/outline_extraction_testcases/part_01/test12.dart
new file mode 100644
index 0000000..07c621e
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/test12.dart
@@ -0,0 +1,11 @@
+import "test13.dart";
+import "test14.dart";
+
+part 'test12_part1.dart';
+part 'test12_part2.dart';
+
+class Test12 {}
+
+class SecondTest12 {
+  void foo(SecondTest12Part1 x) {}
+}
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/test12_part1.dart b/pkg/front_end/outline_extraction_testcases/part_01/test12_part1.dart
new file mode 100644
index 0000000..44473ff
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/test12_part1.dart
@@ -0,0 +1,9 @@
+part of "test12.dart";
+
+class Test12Part1 {
+  void foo(Test12 x) {}
+  void bar(Test12Part2 x) {}
+  void baz(Test13 x) {}
+}
+
+class SecondTest12Part1 {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/test12_part2.dart b/pkg/front_end/outline_extraction_testcases/part_01/test12_part2.dart
new file mode 100644
index 0000000..413d50d
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/test12_part2.dart
@@ -0,0 +1,3 @@
+part of "test12.dart";
+
+class Test12Part2 {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/test13.dart b/pkg/front_end/outline_extraction_testcases/part_01/test13.dart
new file mode 100644
index 0000000..caa3ed4
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/test13.dart
@@ -0,0 +1,3 @@
+import "test13andahalf.dart";
+
+class Test13 {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/test13andahalf.dart b/pkg/front_end/outline_extraction_testcases/part_01/test13andahalf.dart
new file mode 100644
index 0000000..16bc96b
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/test13andahalf.dart
@@ -0,0 +1 @@
+class Test13AndAHalf {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_01/test14.dart b/pkg/front_end/outline_extraction_testcases/part_01/test14.dart
new file mode 100644
index 0000000..023fefd
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_01/test14.dart
@@ -0,0 +1 @@
+class Test14 {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_and_library_name/main.dart b/pkg/front_end/outline_extraction_testcases/part_and_library_name/main.dart
new file mode 100644
index 0000000..d9163f5
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_and_library_name/main.dart
@@ -0,0 +1,3 @@
+import 'test3.dart';
+
+var x = test3partfoo();
diff --git a/pkg/front_end/outline_extraction_testcases/part_and_library_name/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/part_and_library_name/main.dart.outline_extracted
new file mode 100644
index 0000000..2d108c7
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_and_library_name/main.dart.outline_extracted
@@ -0,0 +1,17 @@
+org-dartlang-testcase:///main.dart:
+import 'test3.dart';
+var x = test3partfoo();
+
+
+
+
+org-dartlang-testcase:///test3.dart:
+library test3;
+part "test3_part.dart";
+
+
+
+
+org-dartlang-testcase:///test3_part.dart:
+part of test3;
+void test3partfoo() {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_and_library_name/test3.dart b/pkg/front_end/outline_extraction_testcases/part_and_library_name/test3.dart
new file mode 100644
index 0000000..8fdefdd
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_and_library_name/test3.dart
@@ -0,0 +1,5 @@
+library test3;
+
+part "test3_part.dart";
+
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/part_and_library_name/test3_part.dart b/pkg/front_end/outline_extraction_testcases/part_and_library_name/test3_part.dart
new file mode 100644
index 0000000..e6e3fc4
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/part_and_library_name/test3_part.dart
@@ -0,0 +1,5 @@
+part of test3;
+
+void test3partfoo() {}
+
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/split_import_export_part/foo.dart b/pkg/front_end/outline_extraction_testcases/split_import_export_part/foo.dart
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/split_import_export_part/foo.dart
@@ -0,0 +1 @@
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/split_import_export_part/main.dart b/pkg/front_end/outline_extraction_testcases/split_import_export_part/main.dart
new file mode 100644
index 0000000..85d6722
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/split_import_export_part/main.dart
@@ -0,0 +1,25 @@
+import "package:f"
+    "oobar"
+    "/"
+    "foo"
+    ".dart";
+
+export "package:f"
+    "oobar"
+    "/"
+    "foo"
+    ".dart";
+
+part "package:f"
+    "oobar"
+    "/"
+    "part"
+    ".dart";
+
+Foo giveFoo() {
+  return new Foo();
+}
+
+Bar giveBar() {
+  return new Bar();
+}
diff --git a/pkg/front_end/outline_extraction_testcases/split_import_export_part/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/split_import_export_part/main.dart.outline_extracted
new file mode 100644
index 0000000..ed23c5a
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/split_import_export_part/main.dart.outline_extracted
@@ -0,0 +1,19 @@
+org-dartlang-testcase:///main.dart:
+import "package:f" "oobar" "/" "foo" ".dart";
+export "package:f" "oobar" "/" "foo" ".dart";
+part "package:f" "oobar" "/" "part" ".dart";
+Foo giveFoo() {}
+Bar giveBar() {}
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+class Foo {}
+
+
+
+
+org-dartlang-testcase:///part.dart:
+part of "package:f" "oobar" "/" "main" ".dart";
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/split_import_export_part/part.dart b/pkg/front_end/outline_extraction_testcases/split_import_export_part/part.dart
new file mode 100644
index 0000000..009eb8e
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/split_import_export_part/part.dart
@@ -0,0 +1,7 @@
+part of "package:f"
+    "oobar"
+    "/"
+    "main"
+    ".dart";
+
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/type_parameter_extends/bar.dart b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/bar.dart
new file mode 100644
index 0000000..3507a7f
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/bar.dart
@@ -0,0 +1,5 @@
+class Bar {}
+
+class Bar2 {}
+
+class Bar3 {}
diff --git a/pkg/front_end/outline_extraction_testcases/type_parameter_extends/foo.dart b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/foo.dart
new file mode 100644
index 0000000..820b17e
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/foo.dart
@@ -0,0 +1,7 @@
+export "bar.dart";
+
+class Baz {}
+
+class Baz2 {}
+
+class Baz3 {}
diff --git a/pkg/front_end/outline_extraction_testcases/type_parameter_extends/main.dart b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/main.dart
new file mode 100644
index 0000000..73b5565
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/main.dart
@@ -0,0 +1,16 @@
+import "foo.dart";
+
+class A<T extends Bar, U extends Baz> {
+  T? aMethod1() {}
+  U? aMethod2() {}
+}
+
+mixin A2<T extends Bar2, U extends Baz2> {
+  T? aMethod1() {}
+  U? aMethod2() {}
+}
+
+extension A3<T extends Bar3, U extends Baz3> on Object {
+  T? aMethod1() {}
+  U? aMethod2() {}
+}
diff --git a/pkg/front_end/outline_extraction_testcases/type_parameter_extends/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/main.dart.outline_extracted
new file mode 100644
index 0000000..8b4f0c5
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/type_parameter_extends/main.dart.outline_extracted
@@ -0,0 +1,31 @@
+org-dartlang-testcase:///main.dart:
+import "foo.dart";
+class A<T extends Bar, U extends Baz> {
+  T? aMethod1() {}
+  U? aMethod2() {}
+}
+mixin A2<T extends Bar2, U extends Baz2> {
+  T? aMethod1() {}
+  U? aMethod2() {}
+}
+extension A3<T extends Bar3, U extends Baz3> on Object {
+  T? aMethod1() {}
+  U? aMethod2() {}
+}
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+export "bar.dart";
+class Baz {}
+class Baz2 {}
+class Baz3 {}
+
+
+
+
+org-dartlang-testcase:///bar.dart:
+class Bar {}
+class Bar2 {}
+class Bar3 {}
diff --git a/pkg/front_end/outline_extraction_testcases/type_parameter_on_extension/main.dart b/pkg/front_end/outline_extraction_testcases/type_parameter_on_extension/main.dart
new file mode 100644
index 0000000..5093237
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/type_parameter_on_extension/main.dart
@@ -0,0 +1,5 @@
+class Foo<E> {}
+
+extension HiExtension<T extends Foo> on T {
+  void sayHi() {}
+}
diff --git a/pkg/front_end/outline_extraction_testcases/type_parameter_on_extension/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/type_parameter_on_extension/main.dart.outline_extracted
new file mode 100644
index 0000000..c561270
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/type_parameter_on_extension/main.dart.outline_extracted
@@ -0,0 +1,5 @@
+org-dartlang-testcase:///main.dart:
+class Foo<E> {}
+extension HiExtension<T extends Foo> on T {
+  void sayHi() {}
+}
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import/foo.dart b/pkg/front_end/outline_extraction_testcases/unused_import/foo.dart
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import/foo.dart
@@ -0,0 +1 @@
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import/main.dart b/pkg/front_end/outline_extraction_testcases/unused_import/main.dart
new file mode 100644
index 0000000..8713cd2
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import/main.dart
@@ -0,0 +1,6 @@
+import "foo.dart";
+
+void main() {
+  Foo foo = new Foo();
+  print(foo);
+}
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/unused_import/main.dart.outline_extracted
new file mode 100644
index 0000000..aea942e
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import/main.dart.outline_extracted
@@ -0,0 +1,8 @@
+org-dartlang-testcase:///main.dart:
+import "foo.dart";
+void main() {}
+
+
+
+
+org-dartlang-testcase:///foo.dart:
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import_02/bar.dart b/pkg/front_end/outline_extraction_testcases/unused_import_02/bar.dart
new file mode 100644
index 0000000..5db1c42
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import_02/bar.dart
@@ -0,0 +1,8 @@
+import "baz.dart";
+
+class Bar {
+  void bar() {
+    Baz baz = new Baz();
+    print(baz);
+  }
+}
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import_02/baz.dart b/pkg/front_end/outline_extraction_testcases/unused_import_02/baz.dart
new file mode 100644
index 0000000..f1e00d1
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import_02/baz.dart
@@ -0,0 +1 @@
+class Baz {}
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import_02/foo.dart b/pkg/front_end/outline_extraction_testcases/unused_import_02/foo.dart
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import_02/foo.dart
@@ -0,0 +1 @@
+class Foo {}
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import_02/main.dart b/pkg/front_end/outline_extraction_testcases/unused_import_02/main.dart
new file mode 100644
index 0000000..732d2c4
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import_02/main.dart
@@ -0,0 +1,8 @@
+import "dart:core";
+import "foo.dart";
+export "bar.dart";
+
+void main() {
+  Foo foo = new Foo();
+  print(foo);
+}
diff --git a/pkg/front_end/outline_extraction_testcases/unused_import_02/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/unused_import_02/main.dart.outline_extracted
new file mode 100644
index 0000000..5e0cec5
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/unused_import_02/main.dart.outline_extracted
@@ -0,0 +1,24 @@
+org-dartlang-testcase:///main.dart:
+import "dart:core";
+import "foo.dart";
+export "bar.dart";
+void main() {}
+
+
+
+
+org-dartlang-testcase:///bar.dart:
+import "baz.dart";
+class Bar {
+  void bar() {}
+}
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+
+
+
+
+org-dartlang-testcase:///baz.dart:
diff --git a/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/foo.dart b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/foo.dart
new file mode 100644
index 0000000..9a99089
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/foo.dart
@@ -0,0 +1,11 @@
+extension Foo on String {
+  int get giveInt => 42;
+}
+
+// The below doesn't have to be included.
+
+extension BarExtension on Bar {
+  int get giveInt => 42;
+}
+
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/main.dart b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/main.dart
new file mode 100644
index 0000000..1b39ff1
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/main.dart
@@ -0,0 +1,5 @@
+import "foo.dart";
+
+int get giveInt => 43;
+
+var x = "hello".giveInt;
diff --git a/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/main.dart.outline_extracted
new file mode 100644
index 0000000..cb49619
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension/main.dart.outline_extracted
@@ -0,0 +1,16 @@
+org-dartlang-testcase:///main.dart:
+import "foo.dart";
+int get giveInt => 43;
+var x = "hello".giveInt;
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+extension Foo on String {
+  int get giveInt => 42;
+}
+extension BarExtension on Bar {
+  int get giveInt => 42;
+}
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/foo.dart b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/foo.dart
new file mode 100644
index 0000000..bd036e7
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/foo.dart
@@ -0,0 +1,17 @@
+enum Foo {
+  a,
+  b,
+  c,
+  d,
+  e,
+}
+
+extension FooExtension on Foo {
+  int get giveInt => 42;
+}
+
+extension BarExtension on Bar {
+  int get giveInt => 42;
+}
+
+class Bar {}
diff --git a/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/main.dart b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/main.dart
new file mode 100644
index 0000000..5deb533
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/main.dart
@@ -0,0 +1,5 @@
+import "foo.dart";
+
+final foo = [Foo.d, Foo.b];
+
+final foo2 = foo.map((f) => f.giveInt).toList();
diff --git a/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/main.dart.outline_extracted b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/main.dart.outline_extracted
new file mode 100644
index 0000000..1b7506a
--- /dev/null
+++ b/pkg/front_end/outline_extraction_testcases/use_of_imported_extension_2/main.dart.outline_extracted
@@ -0,0 +1,17 @@
+org-dartlang-testcase:///main.dart:
+import "foo.dart";
+final foo = [Foo.d, Foo.b];
+final foo2 = foo.map((f) => f.giveInt).toList();
+
+
+
+
+org-dartlang-testcase:///foo.dart:
+enum Foo { a, b, c, d, e, }
+extension FooExtension on Foo {
+  int get giveInt => 42;
+}
+extension BarExtension on Bar {
+  int get giveInt => 42;
+}
+class Bar {}
diff --git a/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart
new file mode 100644
index 0000000..145b799
--- /dev/null
+++ b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart
@@ -0,0 +1,8 @@
+enum E<X, Y> {
+  one<int, String>(),
+  two<double, num>(),
+  three<int, int>.named(42);
+
+  const E();
+  const E.named(int value);
+}
diff --git a/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.expect b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.expect
new file mode 100644
index 0000000..69b148f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.expect
@@ -0,0 +1,122 @@
+beginCompilationUnit(enum)
+  beginMetadataStar(enum)
+  endMetadataStar(0)
+  beginUncategorizedTopLevelDeclaration(enum)
+    handleIdentifier(E, enumDeclaration)
+    beginEnum(enum)
+      beginTypeVariables(<)
+        beginMetadataStar(X)
+        endMetadataStar(0)
+        handleIdentifier(X, typeVariableDeclaration)
+        beginTypeVariable(X)
+          beginMetadataStar(Y)
+          endMetadataStar(0)
+          handleIdentifier(Y, typeVariableDeclaration)
+          beginTypeVariable(Y)
+            handleTypeVariablesDefined(Y, 2)
+            handleNoType(Y)
+          endTypeVariable(>, 1, null, null)
+          handleNoType(X)
+        endTypeVariable(,, 0, null, null)
+      endTypeVariables(<, >)
+      handleEnumNoWithClause()
+      handleImplements(null, 0)
+      handleEnumHeader(enum, {)
+      beginMetadataStar(one)
+      endMetadataStar(0)
+      handleIdentifier(one, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(<)
+      beginConstructorReference(one)
+        beginTypeArguments(<)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(,)
+          handleType(int, null)
+          handleIdentifier(String, typeReference)
+          handleNoTypeArguments(>)
+          handleType(String, null)
+        endTypeArguments(2, <, >)
+        handleNoConstructorReferenceContinuationAfterTypeArguments(()
+      endConstructorReference(one, null, (, ConstructorReferenceContext.Const)
+      beginArguments(()
+      endArguments(0, (, ))
+      handleEnumElement({)
+      beginMetadataStar(two)
+      endMetadataStar(0)
+      handleIdentifier(two, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(<)
+      beginConstructorReference(two)
+        beginTypeArguments(<)
+          handleIdentifier(double, typeReference)
+          handleNoTypeArguments(,)
+          handleType(double, null)
+          handleIdentifier(num, typeReference)
+          handleNoTypeArguments(>)
+          handleType(num, null)
+        endTypeArguments(2, <, >)
+        handleNoConstructorReferenceContinuationAfterTypeArguments(()
+      endConstructorReference(two, null, (, ConstructorReferenceContext.Const)
+      beginArguments(()
+      endArguments(0, (, ))
+      handleEnumElement(,)
+      beginMetadataStar(three)
+      endMetadataStar(0)
+      handleIdentifier(three, enumValueDeclaration)
+      handleNoTypeNameInConstructorReference(<)
+      beginConstructorReference(three)
+        beginTypeArguments(<)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(,)
+          handleType(int, null)
+          handleIdentifier(int, typeReference)
+          handleNoTypeArguments(>)
+          handleType(int, null)
+        endTypeArguments(2, <, >)
+        handleIdentifier(named, constructorReferenceContinuationAfterTypeArguments)
+      endConstructorReference(three, ., (, ConstructorReferenceContext.Const)
+      beginArguments(()
+        handleLiteralInt(42)
+      endArguments(1, (, ))
+      handleEnumElement(,)
+      handleEnumElements(;, 3)
+      beginMetadataStar(const)
+      endMetadataStar(0)
+      beginMember()
+        beginMethod(DeclarationKind.Enum, null, null, null, const, null, E)
+          handleNoType(const)
+          handleIdentifier(E, methodDeclaration)
+          handleNoTypeVariables(()
+          beginFormalParameters((, MemberKind.NonStaticMethod)
+          endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+          handleNoInitializers()
+          handleAsyncModifier(null, null)
+          handleEmptyFunctionBody(;)
+        endEnumConstructor(null, const, (, null, ;)
+      endMember()
+      beginMetadataStar(const)
+      endMetadataStar(0)
+      beginMember()
+        beginMethod(DeclarationKind.Enum, null, null, null, const, null, E)
+          handleNoType(const)
+          handleIdentifier(E, methodDeclaration)
+          handleIdentifier(named, methodDeclarationContinuation)
+          handleQualified(.)
+          handleNoTypeVariables(()
+          beginFormalParameters((, MemberKind.NonStaticMethod)
+            beginMetadataStar(int)
+            endMetadataStar(0)
+            beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+              handleIdentifier(int, typeReference)
+              handleNoTypeArguments(value)
+              handleType(int, null)
+              handleIdentifier(value, formalParameterDeclaration)
+              handleFormalParameterWithoutValue())
+            endFormalParameter(null, null, null, value, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+          endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+          handleNoInitializers()
+          handleAsyncModifier(null, null)
+          handleEmptyFunctionBody(;)
+        endEnumConstructor(null, const, (, null, ;)
+      endMember()
+    endEnum(enum, {, 2)
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.intertwined.expect b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.intertwined.expect
new file mode 100644
index 0000000..04b3942
--- /dev/null
+++ b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.intertwined.expect
@@ -0,0 +1,199 @@
+parseUnit(enum)
+  skipErrorTokens(enum)
+  listener: beginCompilationUnit(enum)
+  syntheticPreviousToken(enum)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(enum)
+      listener: endMetadataStar(0)
+    parseTopLevelKeywordDeclaration(, enum, Instance of 'DirectiveContext')
+      parseTopLevelKeywordModifiers(, enum)
+      parseEnum(enum)
+        listener: beginUncategorizedTopLevelDeclaration(enum)
+        ensureIdentifier(enum, enumDeclaration)
+          listener: handleIdentifier(E, enumDeclaration)
+        listener: beginEnum(enum)
+        parseEnumHeaderOpt(E, enum)
+          listener: beginTypeVariables(<)
+          parseMetadataStar(<)
+            listener: beginMetadataStar(X)
+            listener: endMetadataStar(0)
+          ensureIdentifier(<, typeVariableDeclaration)
+            listener: handleIdentifier(X, typeVariableDeclaration)
+          listener: beginTypeVariable(X)
+          parseMetadataStar(,)
+            listener: beginMetadataStar(Y)
+            listener: endMetadataStar(0)
+          ensureIdentifier(,, typeVariableDeclaration)
+            listener: handleIdentifier(Y, typeVariableDeclaration)
+          listener: beginTypeVariable(Y)
+          listener: handleTypeVariablesDefined(Y, 2)
+          listener: handleNoType(Y)
+          listener: endTypeVariable(>, 1, null, null)
+          listener: handleNoType(X)
+          listener: endTypeVariable(,, 0, null, null)
+          listener: endTypeVariables(<, >)
+          parseEnumWithClauseOpt(>)
+            listener: handleEnumNoWithClause()
+          parseClassOrMixinOrEnumImplementsOpt(>)
+            listener: handleImplements(null, 0)
+        listener: handleEnumHeader(enum, {)
+        parseEnumElement({)
+          parseMetadataStar({)
+            listener: beginMetadataStar(one)
+            listener: endMetadataStar(0)
+          ensureIdentifier({, enumValueDeclaration)
+            listener: handleIdentifier(one, enumValueDeclaration)
+          parseConstructorReference(one, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(<)
+            listener: beginConstructorReference(one)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleIdentifier(String, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(String, null)
+            listener: endTypeArguments(2, <, >)
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+            listener: endConstructorReference(one, null, (, ConstructorReferenceContext.Const)
+          parseConstructorInvocationArguments(>)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              listener: endArguments(0, (, ))
+          listener: handleEnumElement({)
+        parseEnumElement(,)
+          parseMetadataStar(,)
+            listener: beginMetadataStar(two)
+            listener: endMetadataStar(0)
+          ensureIdentifier(,, enumValueDeclaration)
+            listener: handleIdentifier(two, enumValueDeclaration)
+          parseConstructorReference(two, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(<)
+            listener: beginConstructorReference(two)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(double, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(double, null)
+            listener: handleIdentifier(num, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(num, null)
+            listener: endTypeArguments(2, <, >)
+            listener: handleNoConstructorReferenceContinuationAfterTypeArguments(()
+            listener: endConstructorReference(two, null, (, ConstructorReferenceContext.Const)
+          parseConstructorInvocationArguments(>)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              listener: endArguments(0, (, ))
+          listener: handleEnumElement(,)
+        parseEnumElement(,)
+          parseMetadataStar(,)
+            listener: beginMetadataStar(three)
+            listener: endMetadataStar(0)
+          ensureIdentifier(,, enumValueDeclaration)
+            listener: handleIdentifier(three, enumValueDeclaration)
+          parseConstructorReference(three, ConstructorReferenceContext.Const, null, true)
+            listener: handleNoTypeNameInConstructorReference(<)
+            listener: beginConstructorReference(three)
+            listener: beginTypeArguments(<)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(,)
+            listener: handleType(int, null)
+            listener: handleIdentifier(int, typeReference)
+            listener: handleNoTypeArguments(>)
+            listener: handleType(int, null)
+            listener: endTypeArguments(2, <, >)
+            ensureIdentifier(., constructorReferenceContinuationAfterTypeArguments)
+              listener: handleIdentifier(named, constructorReferenceContinuationAfterTypeArguments)
+            listener: endConstructorReference(three, ., (, ConstructorReferenceContext.Const)
+          parseConstructorInvocationArguments(named)
+            parseArgumentsRest(()
+              listener: beginArguments(()
+              parseExpression(()
+                parsePrecedenceExpression((, 1, true)
+                  parseUnaryExpression((, true)
+                    parsePrimary((, expression)
+                      parseLiteralInt(()
+                        listener: handleLiteralInt(42)
+              listener: endArguments(1, (, ))
+          listener: handleEnumElement(,)
+        listener: handleEnumElements(;, 3)
+        notEofOrValue(}, const)
+        parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Enum, E)
+          parseMetadataStar(;)
+            listener: beginMetadataStar(const)
+            listener: endMetadataStar(0)
+          listener: beginMember()
+          parseMethod(;, null, null, null, null, null, const, const, Instance of 'NoType', null, E, DeclarationKind.Enum, E, false)
+            listener: beginMethod(DeclarationKind.Enum, null, null, null, const, null, E)
+            listener: handleNoType(const)
+            ensureIdentifierPotentiallyRecovered(const, methodDeclaration, false)
+              listener: handleIdentifier(E, methodDeclaration)
+            parseQualifiedRestOpt(E, methodDeclarationContinuation)
+            parseMethodTypeVar(E)
+              listener: handleNoTypeVariables(()
+            parseGetterOrFormalParameters(E, E, false, MemberKind.NonStaticMethod)
+              parseFormalParameters(E, MemberKind.NonStaticMethod)
+                parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                  listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                  listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+            parseInitializersOpt())
+              listener: handleNoInitializers()
+            parseAsyncModifierOpt())
+              listener: handleAsyncModifier(null, null)
+              inPlainSync()
+            inPlainSync()
+            parseFunctionBody(), false, true)
+              listener: handleEmptyFunctionBody(;)
+            listener: endEnumConstructor(null, const, (, null, ;)
+          listener: endMember()
+        notEofOrValue(}, const)
+        parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Enum, E)
+          parseMetadataStar(;)
+            listener: beginMetadataStar(const)
+            listener: endMetadataStar(0)
+          listener: beginMember()
+          parseMethod(;, null, null, null, null, null, const, const, Instance of 'NoType', null, E, DeclarationKind.Enum, E, false)
+            listener: beginMethod(DeclarationKind.Enum, null, null, null, const, null, E)
+            listener: handleNoType(const)
+            ensureIdentifierPotentiallyRecovered(const, methodDeclaration, false)
+              listener: handleIdentifier(E, methodDeclaration)
+            parseQualifiedRestOpt(E, methodDeclarationContinuation)
+              parseQualifiedRest(E, methodDeclarationContinuation)
+                ensureIdentifier(., methodDeclarationContinuation)
+                  listener: handleIdentifier(named, methodDeclarationContinuation)
+                listener: handleQualified(.)
+            parseMethodTypeVar(named)
+              listener: handleNoTypeVariables(()
+            parseGetterOrFormalParameters(named, E, false, MemberKind.NonStaticMethod)
+              parseFormalParameters(named, MemberKind.NonStaticMethod)
+                parseFormalParametersRest((, MemberKind.NonStaticMethod)
+                  listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+                  parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                    parseMetadataStar(()
+                      listener: beginMetadataStar(int)
+                      listener: endMetadataStar(0)
+                    listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
+                    listener: handleIdentifier(int, typeReference)
+                    listener: handleNoTypeArguments(value)
+                    listener: handleType(int, null)
+                    ensureIdentifier(int, formalParameterDeclaration)
+                      listener: handleIdentifier(value, formalParameterDeclaration)
+                    listener: handleFormalParameterWithoutValue())
+                    listener: endFormalParameter(null, null, null, value, null, null, FormalParameterKind.mandatory, MemberKind.NonStaticMethod)
+                  listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
+            parseInitializersOpt())
+              listener: handleNoInitializers()
+            parseAsyncModifierOpt())
+              listener: handleAsyncModifier(null, null)
+              inPlainSync()
+            inPlainSync()
+            parseFunctionBody(), false, true)
+              listener: handleEmptyFunctionBody(;)
+            listener: endEnumConstructor(null, const, (, null, ;)
+          listener: endMember()
+        notEofOrValue(}, })
+        listener: endEnum(enum, {, 2)
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(enum)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.parser.expect b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.parser.expect
new file mode 100644
index 0000000..9f86055
--- /dev/null
+++ b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.parser.expect
@@ -0,0 +1,19 @@
+enum E<X, Y> {
+one<int, String>(),
+two<double, num>(),
+three<int, int>.named(42);
+
+const E();
+const E.named(int value);
+}
+
+
+enum[KeywordToken] E[StringToken]<[BeginToken]X[StringToken],[SimpleToken] Y[StringToken]>[SimpleToken] {[BeginToken]
+one[StringToken]<[BeginToken]int[StringToken],[SimpleToken] String[StringToken]>[SimpleToken]([BeginToken])[SimpleToken],[SimpleToken]
+two[StringToken]<[BeginToken]double[StringToken],[SimpleToken] num[StringToken]>[SimpleToken]([BeginToken])[SimpleToken],[SimpleToken]
+three[StringToken]<[BeginToken]int[StringToken],[SimpleToken] int[StringToken]>[SimpleToken].[SimpleToken]named[StringToken]([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
+
+const[KeywordToken] E[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+const[KeywordToken] E[StringToken].[SimpleToken]named[StringToken]([BeginToken]int[StringToken] value[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.scanner.expect b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.scanner.expect
new file mode 100644
index 0000000..9f86055
--- /dev/null
+++ b/pkg/front_end/parser_testcases/enhanced_enums/entries_with_type_arguments.dart.scanner.expect
@@ -0,0 +1,19 @@
+enum E<X, Y> {
+one<int, String>(),
+two<double, num>(),
+three<int, int>.named(42);
+
+const E();
+const E.named(int value);
+}
+
+
+enum[KeywordToken] E[StringToken]<[BeginToken]X[StringToken],[SimpleToken] Y[StringToken]>[SimpleToken] {[BeginToken]
+one[StringToken]<[BeginToken]int[StringToken],[SimpleToken] String[StringToken]>[SimpleToken]([BeginToken])[SimpleToken],[SimpleToken]
+two[StringToken]<[BeginToken]double[StringToken],[SimpleToken] num[StringToken]>[SimpleToken]([BeginToken])[SimpleToken],[SimpleToken]
+three[StringToken]<[BeginToken]int[StringToken],[SimpleToken] int[StringToken]>[SimpleToken].[SimpleToken]named[StringToken]([BeginToken]42[StringToken])[SimpleToken];[SimpleToken]
+
+const[KeywordToken] E[StringToken]([BeginToken])[SimpleToken];[SimpleToken]
+const[KeywordToken] E[StringToken].[SimpleToken]named[StringToken]([BeginToken]int[StringToken] value[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect
index fbbb63a..9fc344c 100644
--- a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.expect
@@ -18,7 +18,7 @@
       handleNoType(C)
       handleClassExtends(null, 1)
       handleClassNoWithClause()
-      handleClassOrMixinImplements(null, 0)
+      handleImplements(null, 0)
       handleClassHeader(class, class, null)
       beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
         beginMetadataStar(C)
@@ -36,7 +36,7 @@
                   handleNoType({)
                   handleIdentifier(c, formalParameterDeclaration)
                   handleFormalParameterWithoutValue(})
-                endFormalParameter(null, null, c, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
+                endFormalParameter(null, null, null, c, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
               endOptionalFormalParameters(1, {, })
             endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
             handleNoInitializers()
@@ -118,7 +118,7 @@
       handleNoType(D)
       handleClassExtends(null, 1)
       handleClassNoWithClause()
-      handleClassOrMixinImplements(null, 0)
+      handleImplements(null, 0)
       handleClassHeader(class, class, null)
       beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
         beginMetadataStar(D)
@@ -136,7 +136,7 @@
                   handleNoType({)
                   handleIdentifier(d, formalParameterDeclaration)
                   handleFormalParameterWithoutValue(})
-                endFormalParameter(null, null, d, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
+                endFormalParameter(null, null, null, d, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
               endOptionalFormalParameters(1, {, })
             endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
             handleNoInitializers()
diff --git a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect
index 594b6db..07f6de4 100644
--- a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_01.dart.intertwined.expect
@@ -19,15 +19,15 @@
             parseClassExtendsOpt(C)
               listener: handleNoType(C)
               listener: handleClassExtends(null, 1)
-            parseWithClauseOpt(C)
+            parseClassWithClauseOpt(C)
               listener: handleClassNoWithClause()
-            parseClassOrMixinImplementsOpt(C)
-              listener: handleClassOrMixinImplements(null, 0)
+            parseClassOrMixinOrEnumImplementsOpt(C)
+              listener: handleImplements(null, 0)
             listener: handleClassHeader(class, class, null)
           parseClassOrMixinOrExtensionBody(C, DeclarationKind.Class, C)
             listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
             notEofOrValue(}, C)
-            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, C)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, C)
               parseMetadataStar({)
                 listener: beginMetadataStar(C)
                 listener: endMetadataStar(0)
@@ -56,7 +56,7 @@
                           ensureIdentifier({, formalParameterDeclaration)
                             listener: handleIdentifier(c, formalParameterDeclaration)
                           listener: handleFormalParameterWithoutValue(})
-                          listener: endFormalParameter(null, null, c, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
+                          listener: endFormalParameter(null, null, null, c, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
                         listener: endOptionalFormalParameters(1, {, })
                       ensureCloseParen(}, ()
                       listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
@@ -71,7 +71,7 @@
                 listener: endClassConstructor(null, C, (, null, ;)
               listener: endMember()
             notEofOrValue(}, C)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, C)
               parseMetadataStar(;)
                 listener: beginMetadataStar(C)
                 listener: endMetadataStar(0)
@@ -271,15 +271,15 @@
             parseClassExtendsOpt(D)
               listener: handleNoType(D)
               listener: handleClassExtends(null, 1)
-            parseWithClauseOpt(D)
+            parseClassWithClauseOpt(D)
               listener: handleClassNoWithClause()
-            parseClassOrMixinImplementsOpt(D)
-              listener: handleClassOrMixinImplements(null, 0)
+            parseClassOrMixinOrEnumImplementsOpt(D)
+              listener: handleImplements(null, 0)
             listener: handleClassHeader(class, class, null)
           parseClassOrMixinOrExtensionBody(D, DeclarationKind.Class, D)
             listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
             notEofOrValue(}, D)
-            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, D)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, D)
               parseMetadataStar({)
                 listener: beginMetadataStar(D)
                 listener: endMetadataStar(0)
@@ -308,7 +308,7 @@
                           ensureIdentifier({, formalParameterDeclaration)
                             listener: handleIdentifier(d, formalParameterDeclaration)
                           listener: handleFormalParameterWithoutValue(})
-                          listener: endFormalParameter(null, null, d, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
+                          listener: endFormalParameter(null, null, null, d, null, null, FormalParameterKind.optionalNamed, MemberKind.NonStaticMethod)
                         listener: endOptionalFormalParameters(1, {, })
                       ensureCloseParen(}, ()
                       listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
@@ -323,7 +323,7 @@
                 listener: endClassConstructor(null, D, (, null, ;)
               listener: endMember()
             notEofOrValue(}, D)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, D)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, D)
               parseMetadataStar(;)
                 listener: beginMetadataStar(D)
                 listener: endMetadataStar(0)
diff --git a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_06.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_06.dart.intertwined.expect
index e2d55ca..e861c72 100644
--- a/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_06.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/bracket_mismatch_06.dart.intertwined.expect
@@ -40,7 +40,7 @@
                             parseNewExpression({)
                               isNextIdentifier(new)
                               listener: beginNewExpression(new)
-                              parseConstructorReference(new, ConstructorReferenceContext.New, null)
+                              parseConstructorReference(new, ConstructorReferenceContext.New, null, false)
                                 ensureIdentifier(new, constructorReference)
                                   listener: handleIdentifier(C, constructorReference)
                                 listener: beginConstructorReference(C)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect
index 5ee9cdb..acb0f6c 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.expect
@@ -130,7 +130,7 @@
       handleNoType(Foo)
       handleClassExtends(null, 1)
       handleClassNoWithClause()
-      handleClassOrMixinImplements(null, 0)
+      handleImplements(null, 0)
       handleClassHeader(class, class, null)
       beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
         beginMetadataStar(foo)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect
index 7e46b8b..88944b7f 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_general.crash_dart.intertwined.expect
@@ -19,15 +19,15 @@
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
               listener: handleClassExtends(null, 1)
-            parseWithClauseOpt(Foo)
+            parseClassWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
-            parseClassOrMixinImplementsOpt(Foo)
-              listener: handleClassOrMixinImplements(null, 0)
+            parseClassOrMixinOrEnumImplementsOpt(Foo)
+              listener: handleImplements(null, 0)
             listener: handleClassHeader(class, class, null)
           parseClassOrMixinOrExtensionBody(Foo, DeclarationKind.Class, Foo)
             listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
             notEofOrValue(}, foo)
-            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Foo)
               parseMetadataStar({)
                 listener: beginMetadataStar(foo)
                 listener: endMetadataStar(0)
@@ -65,7 +65,7 @@
                 listener: endClassConstructor(null, foo, (, null, })
               listener: endMember()
             notEofOrValue(}, foo)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(foo)
                 listener: endMetadataStar(0)
@@ -128,7 +128,7 @@
                 listener: endClassConstructor(null, foo, (, :, })
               listener: endMember()
             notEofOrValue(}, foo)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(foo)
                 listener: endMetadataStar(0)
@@ -187,7 +187,7 @@
                 listener: endClassConstructor(null, foo, (, :, })
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -224,7 +224,7 @@
                 listener: endClassMethod(get, get, =>, null, ;)
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -268,7 +268,7 @@
                 listener: endClassMethod(get, get, {, null, })
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -315,7 +315,7 @@
                 listener: endClassConstructor(get, get, (, null, ;)
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -369,7 +369,7 @@
                 listener: endClassConstructor(get, get, (, null, })
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -437,7 +437,7 @@
                 listener: endClassConstructor(get, get, (, :, ;)
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -516,7 +516,7 @@
                 listener: endClassConstructor(get, get, (, :, })
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -559,7 +559,7 @@
                 listener: endClassMethod(set, set, (, null, ;)
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -609,7 +609,7 @@
                 listener: endClassMethod(set, set, (, null, })
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -656,7 +656,7 @@
                 listener: endClassConstructor(set, set, (, null, ;)
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -710,7 +710,7 @@
                 listener: endClassConstructor(set, set, (, null, })
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -778,7 +778,7 @@
                 listener: endClassConstructor(set, set, (, :, ;)
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -857,7 +857,7 @@
                 listener: endClassConstructor(set, set, (, :, })
               listener: endMember()
             notEofOrValue(}, external)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(external)
                 listener: endMetadataStar(0)
@@ -914,7 +914,7 @@
                 listener: endClassConstructor(null, external, (, :, ;)
               listener: endMember()
             notEofOrValue(}, external)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(external)
                 listener: endMetadataStar(0)
@@ -993,7 +993,7 @@
                 listener: endClassConstructor(null, external, (, :, })
               listener: endMember()
             notEofOrValue(}, int)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(int)
                 listener: endMetadataStar(0)
@@ -1012,7 +1012,7 @@
                 listener: endClassFields(null, null, null, null, null, null, 1, int, ;)
               listener: endMember()
             notEofOrValue(}, int)
-            parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, Foo)
               parseMetadataStar(;)
                 listener: beginMetadataStar(int)
                 listener: endMetadataStar(0)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect
index 06805796..4b23187 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.expect
@@ -38,7 +38,7 @@
       handleNoType(Foo)
       handleClassExtends(null, 1)
       handleClassNoWithClause()
-      handleClassOrMixinImplements(null, 0)
+      handleImplements(null, 0)
       handleClassHeader(class, class, null)
       beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
         beginMetadataStar(get)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect
index c1bf8ebf..75979e4 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_get.crash_dart.intertwined.expect
@@ -19,15 +19,15 @@
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
               listener: handleClassExtends(null, 1)
-            parseWithClauseOpt(Foo)
+            parseClassWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
-            parseClassOrMixinImplementsOpt(Foo)
-              listener: handleClassOrMixinImplements(null, 0)
+            parseClassOrMixinOrEnumImplementsOpt(Foo)
+              listener: handleImplements(null, 0)
             listener: handleClassHeader(class, class, null)
           parseClassOrMixinOrExtensionBody(Foo, DeclarationKind.Class, Foo)
             listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Foo)
               parseMetadataStar({)
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -66,7 +66,7 @@
                 listener: endClassConstructor(get, get, (, null, })
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
@@ -130,7 +130,7 @@
                 listener: endClassConstructor(get, get, (, :, })
               listener: endMember()
             notEofOrValue(}, get)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(get)
                 listener: endMetadataStar(0)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect
index 7629bd3..77c9204 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.expect
@@ -34,7 +34,7 @@
       handleNoType(Foo)
       handleClassExtends(null, 1)
       handleClassNoWithClause()
-      handleClassOrMixinImplements(null, 0)
+      handleImplements(null, 0)
       handleClassHeader(class, class, null)
       beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
         beginMetadataStar(void)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect
index 1502968..7ab4015 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.intertwined.expect
@@ -19,15 +19,15 @@
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
               listener: handleClassExtends(null, 1)
-            parseWithClauseOpt(Foo)
+            parseClassWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
-            parseClassOrMixinImplementsOpt(Foo)
-              listener: handleClassOrMixinImplements(null, 0)
+            parseClassOrMixinOrEnumImplementsOpt(Foo)
+              listener: handleImplements(null, 0)
             listener: handleClassHeader(class, class, null)
           parseClassOrMixinOrExtensionBody(Foo, DeclarationKind.Class, Foo)
             listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
             notEofOrValue(}, void)
-            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Foo)
               parseMetadataStar({)
                 listener: beginMetadataStar(void)
                 listener: endMetadataStar(0)
@@ -66,7 +66,7 @@
                 listener: endClassConstructor(null, void, (, null, })
               listener: endMember()
             notEofOrValue(}, void)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(void)
                 listener: endMetadataStar(0)
@@ -130,7 +130,7 @@
                 listener: endClassConstructor(null, void, (, :, })
               listener: endMember()
             notEofOrValue(}, void)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(void)
                 listener: endMetadataStar(0)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect
index 26bb64b..f2201dc 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.expect
@@ -34,7 +34,7 @@
       handleNoType(Foo)
       handleClassExtends(null, 1)
       handleClassNoWithClause()
-      handleClassOrMixinImplements(null, 0)
+      handleImplements(null, 0)
       handleClassHeader(class, class, null)
       beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
         beginMetadataStar(set)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect
index ca57772..55c390c 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_bad_name_set.crash_dart.intertwined.expect
@@ -19,15 +19,15 @@
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
               listener: handleClassExtends(null, 1)
-            parseWithClauseOpt(Foo)
+            parseClassWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
-            parseClassOrMixinImplementsOpt(Foo)
-              listener: handleClassOrMixinImplements(null, 0)
+            parseClassOrMixinOrEnumImplementsOpt(Foo)
+              listener: handleImplements(null, 0)
             listener: handleClassHeader(class, class, null)
           parseClassOrMixinOrExtensionBody(Foo, DeclarationKind.Class, Foo)
             listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Foo)
               parseMetadataStar({)
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -66,7 +66,7 @@
                 listener: endClassConstructor(set, set, (, null, })
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
@@ -130,7 +130,7 @@
                 listener: endClassConstructor(set, set, (, :, })
               listener: endMember()
             notEofOrValue(}, set)
-            parseClassOrMixinOrExtensionMemberImpl(}, DeclarationKind.Class, Foo)
+            parseClassOrMixinOrExtensionOrEnumMemberImpl(}, DeclarationKind.Class, Foo)
               parseMetadataStar(})
                 listener: beginMetadataStar(set)
                 listener: endMetadataStar(0)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect
index daaa1b0..4f6c582 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.expect
@@ -34,7 +34,7 @@
       handleNoType(Foo)
       handleClassExtends(null, 1)
       handleClassNoWithClause()
-      handleClassOrMixinImplements(null, 0)
+      handleImplements(null, 0)
       handleClassHeader(class, class, null)
       beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
         beginMetadataStar(get)
diff --git a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect
index 75d8a2f0..21be0f7 100644
--- a/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/constructor_recovery_get.dart.intertwined.expect
@@ -19,15 +19,15 @@
             parseClassExtendsOpt(Foo)
               listener: handleNoType(Foo)
               listener: handleClassExtends(null, 1)
-            parseWithClauseOpt(Foo)
+            parseClassWithClauseOpt(Foo)
               listener: handleClassNoWithClause()
-            parseClassOrMixinImplementsOpt(Foo)
-              listener: handleClassOrMixinImplements(null, 0)
+            parseClassOrMixinOrEnumImplementsOpt(Foo)
+              listener: handleImplements(null, 0)